From 53b4d4e729fcf9734ba51061441e88b3ddb9273f Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Wed, 6 Oct 2021 09:59:42 -0700 Subject: [PATCH] storage: tests: Convert class based tests to simple tests Signed-off-by: Sunil Mohan Adapa [jvalleroy: Fix conflicts with 9bd1f80d] Signed-off-by: James Valleroy Reviewed-by: James Valleroy --- plinth/modules/storage/tests/test_storage.py | 349 ++++++++++--------- 1 file changed, 177 insertions(+), 172 deletions(-) diff --git a/plinth/modules/storage/tests/test_storage.py b/plinth/modules/storage/tests/test_storage.py index 8b2290952..30bbf55a0 100644 --- a/plinth/modules/storage/tests/test_storage.py +++ b/plinth/modules/storage/tests/test_storage.py @@ -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)