osbuild: error when {Device,Mount} is modified after creation
This is a drive-by change after spending some quality time with the mount code. The `id` field of `Mount` is calculated only once and only when creating a `Mount`. This seems slightly dangerous as any change to an attribute after creation will not update the id. This means two options: 1. dynamically update the `id` on changes 2. forbid changes after the `id` is calculcated I went with (2) but happy to discuss of course but it seems more the spirit of the class. It also does the same change for "devices.Device"
This commit is contained in:
parent
4977501cc6
commit
f5d6d11f1d
5 changed files with 51 additions and 3 deletions
|
|
@ -21,10 +21,11 @@ import stat
|
|||
from typing import Any, Dict, Optional
|
||||
|
||||
from osbuild import host
|
||||
from osbuild.mixins import MixinImmutableID
|
||||
from osbuild.util import ctx
|
||||
|
||||
|
||||
class Device:
|
||||
class Device(MixinImmutableID):
|
||||
"""
|
||||
A single device with its corresponding options
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ class Input:
|
|||
self.id = self.calc_id()
|
||||
|
||||
def calc_id(self):
|
||||
|
||||
# NB: The input `name` is not included here on purpose since it
|
||||
# is either prescribed by the stage itself and thus not actual
|
||||
# parameter or arbitrary and chosen by the manifest generator
|
||||
|
|
|
|||
15
osbuild/mixins.py
Normal file
15
osbuild/mixins.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
"""
|
||||
Mixin helper classes
|
||||
"""
|
||||
|
||||
|
||||
class MixinImmutableID:
|
||||
"""
|
||||
Mixin to ensure that "self.id" attributes are immutable after id is set
|
||||
"""
|
||||
|
||||
def __setattr__(self, name, val):
|
||||
if hasattr(self, "id"):
|
||||
class_name = self.__class__.__name__
|
||||
raise ValueError(f"cannot set '{name}': {class_name} cannot be changed after creation")
|
||||
super().__setattr__(name, val)
|
||||
|
|
@ -16,9 +16,10 @@ from typing import Dict, List
|
|||
|
||||
from osbuild import host
|
||||
from osbuild.devices import DeviceManager
|
||||
from osbuild.mixins import MixinImmutableID
|
||||
|
||||
|
||||
class Mount:
|
||||
class Mount(MixinImmutableID):
|
||||
"""
|
||||
A single mount with its corresponding options
|
||||
"""
|
||||
|
|
|
|||
32
test/mod/test_mixins.py
Normal file
32
test/mod/test_mixins.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
|
||||
from osbuild.devices import Device
|
||||
from osbuild.meta import ModuleInfo
|
||||
from osbuild.mounts import Mount
|
||||
|
||||
|
||||
def test_mount_immutable_mixin():
|
||||
info = Mock(spec=ModuleInfo)
|
||||
info.name = "some-name"
|
||||
device = Mock(spec=ModuleInfo)
|
||||
device.id = "some-id"
|
||||
partition = 1
|
||||
target = "/"
|
||||
opts = {"opt1": 1}
|
||||
mnt = Mount("name", info, device, partition, target, opts)
|
||||
with pytest.raises(ValueError) as e:
|
||||
mnt.name = "new-name"
|
||||
assert str(e.value) == "cannot set 'name': Mount cannot be changed after creation"
|
||||
|
||||
|
||||
def test_device_immutable_mixins():
|
||||
info = Mock(spec=ModuleInfo)
|
||||
info.name = "some-name"
|
||||
parent = None
|
||||
opts = {"opt1": 1}
|
||||
dev = Device("name", info, parent, opts)
|
||||
with pytest.raises(ValueError) as e:
|
||||
dev.name = "new-name"
|
||||
assert str(e.value) == "cannot set 'name': Device cannot be changed after creation"
|
||||
Loading…
Add table
Add a link
Reference in a new issue