mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-03-04 08:53:42 +00:00
storage: tests: Convert class based tests to simple tests
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> [jvalleroy: Fix conflicts with 9bd1f80d] Signed-off-by: James Valleroy <jvalleroy@mailbox.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
3b978148ea
commit
53b4d4e729
@ -143,195 +143,200 @@ class Disk():
|
||||
self._remove_disk_file()
|
||||
|
||||
|
||||
class TestActions:
|
||||
"""Test all actions related to storage."""
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
def test_simple_case():
|
||||
"""Test a simple with no complications"""
|
||||
disk_info = [
|
||||
'mktable msdos', 'mkpart primary btrfs 1 300',
|
||||
'mkpart primary btrfs 301 600', 'mkpart primary btrfs 608 900'
|
||||
]
|
||||
# Btrfs volumes < 256 MiB can't be resized.
|
||||
# https://bugzilla.kernel.org/show_bug.cgi?id=118111
|
||||
with Disk(1024, disk_info, [(1, 'btrfs'), (2, 'btrfs'),
|
||||
(3, 'btrfs')]) as disk:
|
||||
# No free space
|
||||
_assert_free_space(disk, 1, space=False)
|
||||
# < 10 MiB of free space
|
||||
_assert_free_space(disk, 2, space=False)
|
||||
_assert_free_space(disk, 3, space=True)
|
||||
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
def test_simple_case(self):
|
||||
"""Test a simple with no complications"""
|
||||
disk_info = [
|
||||
'mktable msdos', 'mkpart primary btrfs 1 300',
|
||||
'mkpart primary btrfs 301 600', 'mkpart primary btrfs 608 900'
|
||||
]
|
||||
# Btrfs volumes < 256 MiB can't be resized.
|
||||
# https://bugzilla.kernel.org/show_bug.cgi?id=118111
|
||||
with Disk(1024, disk_info, [(1, 'btrfs'), (2, 'btrfs'),
|
||||
(3, 'btrfs')]) as disk:
|
||||
# No free space
|
||||
self.assert_free_space(disk, 1, space=False)
|
||||
# < 10 MiB of free space
|
||||
self.assert_free_space(disk, 2, space=False)
|
||||
self.assert_free_space(disk, 3, space=True)
|
||||
_expand_partition(disk, 1, success=False)
|
||||
_expand_partition(disk, 2, success=False)
|
||||
_expand_partition(disk, 3, success=True)
|
||||
_expand_partition(disk, 3, success=False)
|
||||
|
||||
self.expand_partition(disk, 1, success=False)
|
||||
self.expand_partition(disk, 2, success=False)
|
||||
self.expand_partition(disk, 3, success=True)
|
||||
self.expand_partition(disk, 3, success=False)
|
||||
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
def test_extended_partition_free_space(self):
|
||||
"""Test that free space does not show up when outside extended."""
|
||||
disk_info = [
|
||||
'mktable msdos', 'mkpart primary 1 8', 'mkpart extended 8 500',
|
||||
'mkpart logical btrfs 9 300'
|
||||
]
|
||||
with Disk(512, disk_info, [(5, 'btrfs')]) as disk:
|
||||
self.assert_free_space(disk, 5, space=False)
|
||||
self.expand_partition(disk, 5, success=False)
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
def test_extended_partition_free_space():
|
||||
"""Test that free space does not show up when outside extended."""
|
||||
disk_info = [
|
||||
'mktable msdos', 'mkpart primary 1 8', 'mkpart extended 8 500',
|
||||
'mkpart logical btrfs 9 300'
|
||||
]
|
||||
with Disk(512, disk_info, [(5, 'btrfs')]) as disk:
|
||||
_assert_free_space(disk, 5, space=False)
|
||||
_expand_partition(disk, 5, success=False)
|
||||
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
def test_gpt_partition_free_space(self):
|
||||
"""Test that GPT partitions can be expanded."""
|
||||
# Specifically check for partition number > 4
|
||||
disk_info = [
|
||||
'mktable gpt', 'mkpart primary 1 4', 'mkpart extended 4 8',
|
||||
'mkpart extended 8 12', 'mkpart extended 12 16',
|
||||
'mkpart extended 16 300'
|
||||
]
|
||||
with Disk(512, disk_info, [(5, 'btrfs')]) as disk:
|
||||
# Second header already at the end
|
||||
self.assert_free_space(disk, 5, space=True)
|
||||
self.expand_partition(disk, 5, success=True)
|
||||
self.expand_partition(disk, 5, success=False)
|
||||
disk.expand_disk_file(1024)
|
||||
# Second header not at the end
|
||||
self.assert_free_space(disk, 5, space=True)
|
||||
self.expand_partition(disk, 5, success=True)
|
||||
self.expand_partition(disk, 5, success=False)
|
||||
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
@pytest.mark.parametrize('partition_table_type', ['gpt', 'msdos'])
|
||||
def test_unsupported_file_system(self, partition_table_type):
|
||||
"""Test that free space after unknown file system does not count."""
|
||||
disk_info = [f'mktable {partition_table_type}', 'mkpart primary 1 8']
|
||||
with Disk(32, disk_info) as disk:
|
||||
self.assert_free_space(disk, 1, space=False)
|
||||
self.expand_partition(disk, 1, success=False)
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
def test_gpt_partition_free_space():
|
||||
"""Test that GPT partitions can be expanded."""
|
||||
# Specifically check for partition number > 4
|
||||
disk_info = [
|
||||
'mktable gpt', 'mkpart primary 1 4', 'mkpart extended 4 8',
|
||||
'mkpart extended 8 12', 'mkpart extended 12 16',
|
||||
'mkpart extended 16 300'
|
||||
]
|
||||
with Disk(512, disk_info, [(5, 'btrfs')]) as disk:
|
||||
# Second header already at the end
|
||||
_assert_free_space(disk, 5, space=True)
|
||||
_expand_partition(disk, 5, success=True)
|
||||
_expand_partition(disk, 5, success=False)
|
||||
disk.expand_disk_file(1024)
|
||||
# Second header not at the end
|
||||
_assert_free_space(disk, 5, space=True)
|
||||
_expand_partition(disk, 5, success=True)
|
||||
_expand_partition(disk, 5, success=False)
|
||||
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
@pytest.mark.parametrize('partition_table_type', ['gpt', 'msdos'])
|
||||
def test_btrfs_expansion(self, partition_table_type):
|
||||
"""Test that btrfs file system can be expanded."""
|
||||
disk_info = [
|
||||
f'mktable {partition_table_type}', 'mkpart primary btrfs 1 300'
|
||||
]
|
||||
with Disk(512, disk_info, [(1, 'btrfs')]) as disk:
|
||||
self.expand_partition(disk, 1, success=True)
|
||||
self.expand_partition(disk, 1, success=False)
|
||||
self.assert_btrfs_file_system_healthy(disk, 1)
|
||||
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
@pytest.mark.parametrize('partition_table_type', ['gpt', 'msdos'])
|
||||
def test_ext4_expansion(self, partition_table_type):
|
||||
"""Test that ext4 file system can be expanded."""
|
||||
disk_info = [
|
||||
f'mktable {partition_table_type}', 'mkpart primary ext4 1 64'
|
||||
]
|
||||
with Disk(128, disk_info, [(1, 'ext4')]) as disk:
|
||||
self.expand_partition(disk, 1, success=True)
|
||||
self.expand_partition(disk, 1, success=False)
|
||||
self.assert_ext4_file_system_healthy(disk, 1)
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
@pytest.mark.parametrize('partition_table_type', ['gpt', 'msdos'])
|
||||
def test_unsupported_file_system(partition_table_type):
|
||||
"""Test that free space after unknown file system does not count."""
|
||||
disk_info = [f'mktable {partition_table_type}', 'mkpart primary 1 8']
|
||||
with Disk(32, disk_info) as disk:
|
||||
_assert_free_space(disk, 1, space=False)
|
||||
_expand_partition(disk, 1, success=False)
|
||||
|
||||
def assert_free_space(self, disk, partition_number, space=True):
|
||||
"""Verify that free is available/not available after a partition."""
|
||||
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
@pytest.mark.parametrize('partition_table_type', ['gpt', 'msdos'])
|
||||
def test_btrfs_expansion(partition_table_type):
|
||||
"""Test that btrfs file system can be expanded."""
|
||||
disk_info = [
|
||||
f'mktable {partition_table_type}', 'mkpart primary btrfs 1 300'
|
||||
]
|
||||
with Disk(512, disk_info, [(1, 'btrfs')]) as disk:
|
||||
_expand_partition(disk, 1, success=True)
|
||||
_expand_partition(disk, 1, success=False)
|
||||
_assert_btrfs_file_system_healthy(disk, 1)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
@pytest.mark.parametrize('partition_table_type', ['gpt', 'msdos'])
|
||||
def test_ext4_expansion(partition_table_type):
|
||||
"""Test that ext4 file system can be expanded."""
|
||||
disk_info = [f'mktable {partition_table_type}', 'mkpart primary ext4 1 64']
|
||||
with Disk(128, disk_info, [(1, 'ext4')]) as disk:
|
||||
_expand_partition(disk, 1, success=True)
|
||||
_expand_partition(disk, 1, success=False)
|
||||
_assert_ext4_file_system_healthy(disk, 1)
|
||||
|
||||
|
||||
def _assert_free_space(disk, partition_number, space=True):
|
||||
"""Verify that free is available/not available after a partition."""
|
||||
device = disk.get_partition_device(partition_number)
|
||||
result = _check_action(['storage', 'is-partition-expandable', device])
|
||||
assert result == space
|
||||
|
||||
|
||||
def _expand_partition(disk, partition_number, success=True):
|
||||
"""Expand a partition."""
|
||||
_assert_aligned(disk, partition_number)
|
||||
with disk.mount_partition(partition_number) as mount_point:
|
||||
device = disk.get_partition_device(partition_number)
|
||||
result = self.check_action(
|
||||
['storage', 'is-partition-expandable', device])
|
||||
assert result == space
|
||||
result = _check_action([
|
||||
'storage', 'expand-partition', device, '--mount-point', mount_point
|
||||
])
|
||||
|
||||
def expand_partition(self, disk, partition_number, success=True):
|
||||
"""Expand a partition."""
|
||||
self.assert_aligned(disk, partition_number)
|
||||
with disk.mount_partition(partition_number) as mount_point:
|
||||
device = disk.get_partition_device(partition_number)
|
||||
result = self.check_action([
|
||||
'storage', 'expand-partition', device, '--mount-point',
|
||||
mount_point
|
||||
])
|
||||
assert result == success
|
||||
_assert_aligned(disk, partition_number)
|
||||
|
||||
assert result == success
|
||||
self.assert_aligned(disk, partition_number)
|
||||
|
||||
@staticmethod
|
||||
def call_action(action_command, check=True, **kwargs):
|
||||
"""Call the action script."""
|
||||
test_directory = pathlib.Path(__file__).parent
|
||||
top_directory = (test_directory / '..' / '..' / '..' / '..').resolve()
|
||||
action_command[0] = top_directory / 'actions' / action_command[0]
|
||||
kwargs['stdout'] = kwargs.get('stdout', subprocess.DEVNULL)
|
||||
kwargs['stderr'] = kwargs.get('stderr', subprocess.DEVNULL)
|
||||
env = dict(os.environ, PYTHONPATH=str(top_directory))
|
||||
return subprocess.run(action_command, env=env, check=check, **kwargs)
|
||||
def _call_action(action_command, check=True, **kwargs):
|
||||
"""Call the action script."""
|
||||
test_directory = pathlib.Path(__file__).parent
|
||||
top_directory = (test_directory / '..' / '..' / '..' / '..').resolve()
|
||||
action_command[0] = top_directory / 'actions' / action_command[0]
|
||||
kwargs['stdout'] = kwargs.get('stdout', subprocess.DEVNULL)
|
||||
kwargs['stderr'] = kwargs.get('stderr', subprocess.DEVNULL)
|
||||
env = dict(os.environ, PYTHONPATH=str(top_directory))
|
||||
return subprocess.run(action_command, env=env, check=check, **kwargs)
|
||||
|
||||
def check_action(self, action_command):
|
||||
"""Return success/failure result of the action command."""
|
||||
try:
|
||||
self.call_action(action_command)
|
||||
return True
|
||||
except subprocess.CalledProcessError:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def assert_aligned(disk, partition_number):
|
||||
"""Test that partition is optimally aligned."""
|
||||
subprocess.run([
|
||||
'parted', '--script', disk.device, 'align-check', 'opti',
|
||||
str(partition_number)
|
||||
], check=True)
|
||||
def _check_action(action_command):
|
||||
"""Return success/failure result of the action command."""
|
||||
try:
|
||||
_call_action(action_command)
|
||||
return True
|
||||
except subprocess.CalledProcessError:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def assert_btrfs_file_system_healthy(disk, partition_number):
|
||||
"""Perform a successful ext4 file system check."""
|
||||
device = disk.get_partition_device(partition_number)
|
||||
command = ['btrfs', 'check', '--force', device]
|
||||
subprocess.run(command, stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL, check=True)
|
||||
|
||||
@staticmethod
|
||||
def assert_ext4_file_system_healthy(disk, partition_number):
|
||||
"""Perform a successful ext4 file system check."""
|
||||
device = disk.get_partition_device(partition_number)
|
||||
command = ['e2fsck', '-n', device]
|
||||
subprocess.run(command, stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL, check=True)
|
||||
def _assert_aligned(disk, partition_number):
|
||||
"""Test that partition is optimally aligned."""
|
||||
subprocess.run([
|
||||
'parted', '--script', disk.device, 'align-check', 'opti',
|
||||
str(partition_number)
|
||||
], check=True)
|
||||
|
||||
def assert_validate_directory(self, path, error, check_writable=False,
|
||||
check_creatable=False):
|
||||
"""Perform directory validation checks."""
|
||||
action_command = ['storage', 'validate-directory', '--path', path]
|
||||
if check_writable:
|
||||
action_command += ['--check-writable']
|
||||
if check_creatable:
|
||||
action_command += ['--check-creatable']
|
||||
proc = self.call_action(action_command, stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE)
|
||||
output = proc.stdout.decode()
|
||||
if 'ValidationError' in output:
|
||||
error_nr = output.strip().split()[1]
|
||||
assert error_nr == error
|
||||
else:
|
||||
assert output == error
|
||||
|
||||
@pytest.mark.usefixtures('needs_not_root')
|
||||
@pytest.mark.parametrize('path,error', [('/missing', '1'),
|
||||
('/etc/os-release', '2'),
|
||||
('/root', '3'), ('/', ''),
|
||||
('/etc/..', '')])
|
||||
def test_validate_directory(self, path, error):
|
||||
"""Test that directory validation returns expected output."""
|
||||
self.assert_validate_directory(path, error)
|
||||
def _assert_btrfs_file_system_healthy(disk, partition_number):
|
||||
"""Perform a successful ext4 file system check."""
|
||||
device = disk.get_partition_device(partition_number)
|
||||
command = ['btrfs', 'check', '--force', device]
|
||||
subprocess.run(command, stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL, check=True)
|
||||
|
||||
@pytest.mark.usefixtures('needs_not_root')
|
||||
@pytest.mark.parametrize('path,error', [('/', '4'), ('/tmp', '')])
|
||||
def test_validate_directory_writable(self, path, error):
|
||||
"""Test that directory writable validation returns expected output."""
|
||||
self.assert_validate_directory(path, error, check_writable=True)
|
||||
|
||||
@pytest.mark.usefixtures('needs_not_root')
|
||||
@pytest.mark.parametrize(
|
||||
'path,error', [('/var/lib/plinth_storage_test_not_exists', '4'),
|
||||
('/tmp/plint_storage_test_not_exists', ''),
|
||||
('/var/../tmp/plint_storage_test_not_exists', '')])
|
||||
def test_validate_directory_creatable(self, path, error):
|
||||
"""Test that directory creatable validation returns expected output."""
|
||||
self.assert_validate_directory(path, error, check_creatable=True)
|
||||
def _assert_ext4_file_system_healthy(disk, partition_number):
|
||||
"""Perform a successful ext4 file system check."""
|
||||
device = disk.get_partition_device(partition_number)
|
||||
command = ['e2fsck', '-n', device]
|
||||
subprocess.run(command, stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL, check=True)
|
||||
|
||||
|
||||
def _assert_validate_directory(path, error, check_writable=False,
|
||||
check_creatable=False):
|
||||
"""Perform directory validation checks."""
|
||||
action_command = ['storage', 'validate-directory', '--path', path]
|
||||
if check_writable:
|
||||
action_command += ['--check-writable']
|
||||
if check_creatable:
|
||||
action_command += ['--check-creatable']
|
||||
proc = _call_action(action_command, stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE)
|
||||
output = proc.stdout.decode()
|
||||
if 'ValidationError' in output:
|
||||
error_nr = output.strip().split()[1]
|
||||
assert error_nr == error
|
||||
else:
|
||||
assert output == error
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('needs_not_root')
|
||||
@pytest.mark.parametrize('path,error', [('/missing', '1'),
|
||||
('/etc/os-release', '2'),
|
||||
('/root', '3'), ('/', ''),
|
||||
('/etc/..', '')])
|
||||
def test_validate_directory(path, error):
|
||||
"""Test that directory validation returns expected output."""
|
||||
_assert_validate_directory(path, error)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('needs_not_root')
|
||||
@pytest.mark.parametrize('path,error', [('/', '4'), ('/tmp', '')])
|
||||
def test_validate_directory_writable(path, error):
|
||||
"""Test that directory writable validation returns expected output."""
|
||||
_assert_validate_directory(path, error, check_writable=True)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('needs_not_root')
|
||||
@pytest.mark.parametrize('path,error',
|
||||
[('/var/lib/plinth_storage_test_not_exists', '4'),
|
||||
('/tmp/plint_storage_test_not_exists', ''),
|
||||
('/var/../tmp/plint_storage_test_not_exists', '')])
|
||||
def test_validate_directory_creatable(path, error):
|
||||
"""Test that directory creatable validation returns expected output."""
|
||||
_assert_validate_directory(path, error, check_creatable=True)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user