Merge pull request #1280 from rafalste/test_permissions
test: Add file permissions test
This commit is contained in:
		| @@ -10,6 +10,54 @@ from connection.local_executor import LocalExecutor | |||||||
| from test_utils.output import CmdException | from test_utils.output import CmdException | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def get_submodules_paths(from_dut: bool = False): | ||||||
|  |     executor = TestRun.executor if from_dut else LocalExecutor() | ||||||
|  |     repo_path = TestRun.usr.working_dir if from_dut else TestRun.usr.repo_dir | ||||||
|  |     git_params = "config --file .gitmodules --get-regexp path | cut -d' ' -f2" | ||||||
|  |  | ||||||
|  |     output = executor.run(f"git -C {repo_path} {git_params}") | ||||||
|  |     if output.exit_code != 0: | ||||||
|  |         raise CmdException("Failed to get submodules paths", output) | ||||||
|  |  | ||||||
|  |     return output.stdout.splitlines() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def get_repo_files( | ||||||
|  |     branch: str = "HEAD", | ||||||
|  |     with_submodules: bool = True, | ||||||
|  |     with_dirs: bool = False, | ||||||
|  |     from_dut: bool = False, | ||||||
|  | ): | ||||||
|  |     executor = TestRun.executor if from_dut else LocalExecutor() | ||||||
|  |     repo_path = TestRun.usr.working_dir if from_dut else TestRun.usr.repo_dir | ||||||
|  |     git_params = f"ls-tree -r --name-only --full-tree {branch}" | ||||||
|  |  | ||||||
|  |     output = executor.run(f"git -C {repo_path} {git_params}") | ||||||
|  |     if output.exit_code != 0: | ||||||
|  |         raise CmdException("Failed to get repo files list", output) | ||||||
|  |  | ||||||
|  |     files = output.stdout.splitlines() | ||||||
|  |  | ||||||
|  |     if with_submodules: | ||||||
|  |         for subm_path in get_submodules_paths(from_dut): | ||||||
|  |             output = executor.run(f"git -C {os.path.join(repo_path, subm_path)} {git_params}") | ||||||
|  |             if output.exit_code != 0: | ||||||
|  |                 raise CmdException(f"Failed to get {subm_path} submodule repo files list", output) | ||||||
|  |  | ||||||
|  |             subm_files = [os.path.join(subm_path, file) for file in output.stdout.splitlines()] | ||||||
|  |             files.extend(subm_files) | ||||||
|  |  | ||||||
|  |     if with_dirs: | ||||||
|  |         # use set() to get unique values only | ||||||
|  |         dirs = set(os.path.dirname(file) for file in files) | ||||||
|  |         files.extend(dirs) | ||||||
|  |  | ||||||
|  |     # change to absolute paths and remove empty values | ||||||
|  |     files = [os.path.realpath(os.path.join(repo_path, file)) for file in files if file] | ||||||
|  |  | ||||||
|  |     return files | ||||||
|  |  | ||||||
|  |  | ||||||
| def get_current_commit_hash(from_dut: bool = False): | def get_current_commit_hash(from_dut: bool = False): | ||||||
|     executor = TestRun.executor if from_dut else LocalExecutor() |     executor = TestRun.executor if from_dut else LocalExecutor() | ||||||
|     repo_path = TestRun.usr.working_dir if from_dut else TestRun.usr.repo_dir |     repo_path = TestRun.usr.working_dir if from_dut else TestRun.usr.repo_dir | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| import logging | import logging | ||||||
|  | import os | ||||||
|  |  | ||||||
| from tests import conftest | from tests import conftest | ||||||
| from core.test_run import TestRun | from core.test_run import TestRun | ||||||
| @@ -17,13 +18,17 @@ from test_utils.output import CmdException | |||||||
| def rsync_opencas_sources(): | def rsync_opencas_sources(): | ||||||
|     TestRun.LOGGER.info("Copying Open CAS repository to DUT") |     TestRun.LOGGER.info("Copying Open CAS repository to DUT") | ||||||
|     TestRun.executor.rsync_to( |     TestRun.executor.rsync_to( | ||||||
|         f"{TestRun.usr.repo_dir}/", |         # Place an empty string as the last argument to os.path.join() | ||||||
|         f"{TestRun.usr.working_dir}/", |         # to make sure path ends with directory separator. | ||||||
|  |         # Needed for rsync to copy only contents of a directory | ||||||
|  |         # and not the directory itself. | ||||||
|  |         os.path.join(TestRun.usr.repo_dir, ''), | ||||||
|  |         os.path.join(TestRun.usr.working_dir, ''), | ||||||
|         exclude_list=["test/functional/results/"], |         exclude_list=["test/functional/results/"], | ||||||
|         delete=True) |         delete=True) | ||||||
|  |  | ||||||
|  |  | ||||||
| def _clean_opencas_repo(): | def clean_opencas_repo(): | ||||||
|     TestRun.LOGGER.info("Cleaning Open CAS repo") |     TestRun.LOGGER.info("Cleaning Open CAS repo") | ||||||
|     output = TestRun.executor.run( |     output = TestRun.executor.run( | ||||||
|         f"cd {TestRun.usr.working_dir} && " |         f"cd {TestRun.usr.working_dir} && " | ||||||
| @@ -42,11 +47,15 @@ def build_opencas(): | |||||||
|         raise CmdException("Make command executed with nonzero status", output) |         raise CmdException("Make command executed with nonzero status", output) | ||||||
|  |  | ||||||
|  |  | ||||||
| def install_opencas(): | def install_opencas(destdir: str = ""): | ||||||
|     TestRun.LOGGER.info("Installing Open CAS") |     TestRun.LOGGER.info("Installing Open CAS") | ||||||
|  |  | ||||||
|  |     if destdir: | ||||||
|  |         destdir = os.path.join(TestRun.usr.working_dir, destdir) | ||||||
|  |  | ||||||
|     output = TestRun.executor.run( |     output = TestRun.executor.run( | ||||||
|         f"cd {TestRun.usr.working_dir} && " |         f"cd {TestRun.usr.working_dir} && " | ||||||
|         f"make install") |         f"make {'DESTDIR='+destdir if destdir else ''} install") | ||||||
|     if output.exit_code != 0: |     if output.exit_code != 0: | ||||||
|         raise CmdException("Failed to install Open CAS", output) |         raise CmdException("Failed to install Open CAS", output) | ||||||
|  |  | ||||||
| @@ -54,6 +63,9 @@ def install_opencas(): | |||||||
|     if output.exit_code != 0: |     if output.exit_code != 0: | ||||||
|         raise CmdException("Failed to reload modules", output) |         raise CmdException("Failed to reload modules", output) | ||||||
|  |  | ||||||
|  |     if destdir: | ||||||
|  |         return | ||||||
|  |  | ||||||
|     TestRun.LOGGER.info("Check if casadm is properly installed.") |     TestRun.LOGGER.info("Check if casadm is properly installed.") | ||||||
|     output = TestRun.executor.run("casadm -V") |     output = TestRun.executor.run("casadm -V") | ||||||
|     if output.exit_code != 0: |     if output.exit_code != 0: | ||||||
| @@ -63,7 +75,7 @@ def install_opencas(): | |||||||
|  |  | ||||||
|  |  | ||||||
| def set_up_opencas(version: str = ""): | def set_up_opencas(version: str = ""): | ||||||
|     _clean_opencas_repo() |     clean_opencas_repo() | ||||||
|  |  | ||||||
|     if version: |     if version: | ||||||
|         git.checkout_cas_version(version) |         git.checkout_cas_version(version) | ||||||
|   | |||||||
							
								
								
									
										172
									
								
								test/functional/tests/misc/test_files_permissions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								test/functional/tests/misc/test_files_permissions.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,172 @@ | |||||||
|  | # | ||||||
|  | # Copyright(c) 2022 Intel Corporation | ||||||
|  | # SPDX-License-Identifier: BSD-3-Clause | ||||||
|  | # | ||||||
|  |  | ||||||
|  |  | ||||||
|  | import os | ||||||
|  |  | ||||||
|  | from api.cas.git import get_repo_files | ||||||
|  | from api.cas.installer import ( | ||||||
|  |     clean_opencas_repo, | ||||||
|  |     build_opencas, | ||||||
|  |     install_opencas, | ||||||
|  |     rsync_opencas_sources, | ||||||
|  | ) | ||||||
|  | from core.test_run import TestRun | ||||||
|  | from test_tools.fs_utils import ( | ||||||
|  |     FilesPermissions, | ||||||
|  |     find_all_files, | ||||||
|  |     find_all_dirs, | ||||||
|  |     find_all_items, | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | repo_files_perms_exceptions = { | ||||||
|  |     ".github/verify_header.sh": 755, | ||||||
|  |     "configure": 755, | ||||||
|  |     "doc/reqparse": 755, | ||||||
|  |     "test/smoke_test/basic/01": 755, | ||||||
|  |     "test/smoke_test/basic/02": 755, | ||||||
|  |     "test/smoke_test/basic/03": 755, | ||||||
|  |     "test/smoke_test/basic/04": 755, | ||||||
|  |     "test/smoke_test/basic/05": 755, | ||||||
|  |     "test/smoke_test/basic/06": 755, | ||||||
|  |     "test/smoke_test/basic/07": 755, | ||||||
|  |     "test/smoke_test/basic/08": 755, | ||||||
|  |     "test/smoke_test/basic/09": 755, | ||||||
|  |     "test/smoke_test/basic/10": 755, | ||||||
|  |     "test/smoke_test/basic/11": 755, | ||||||
|  |     "test/smoke_test/basic/12": 755, | ||||||
|  |     "test/smoke_test/basic/13": 755, | ||||||
|  |     "test/smoke_test/cache_suspend/01": 755, | ||||||
|  |     "test/smoke_test/cache_suspend/02": 755, | ||||||
|  |     "test/smoke_test/cache_suspend/03": 755, | ||||||
|  |     "test/smoke_test/eviction_policy/01": 755, | ||||||
|  |     "test/smoke_test/eviction_policy/02": 755, | ||||||
|  |     "test/smoke_test/eviction_policy/03": 755, | ||||||
|  |     "test/smoke_test/fio/01": 755, | ||||||
|  |     "test/smoke_test/incremental_load/01": 755, | ||||||
|  |     "test/smoke_test/incremental_load/02": 755, | ||||||
|  |     "test/smoke_test/init_script/01": 755, | ||||||
|  |     "test/smoke_test/init_script/02": 755, | ||||||
|  |     "test/smoke_test/init_script/03": 755, | ||||||
|  |     "test/smoke_test/io_class/01_wlth": 755, | ||||||
|  |     "test/smoke_test/io_class/02_wlth": 755, | ||||||
|  |     "test/smoke_test/metadata_corrupt/01": 755, | ||||||
|  |     "test/smoke_test/metadata_corrupt/02": 755, | ||||||
|  |     "test/smoke_test/promotion/01": 755, | ||||||
|  |     "test/smoke_test/recovery/01": 755, | ||||||
|  |     "test/smoke_test/recovery/02": 755, | ||||||
|  |     "test/smoke_test/run_tests": 755, | ||||||
|  |     "test/smoke_test/write_back/01": 755, | ||||||
|  |     "test/smoke_test/write_back/02": 755, | ||||||
|  |     "tools/cas_version_gen": 755, | ||||||
|  |     "tools/pckgen": 755, | ||||||
|  |     "tools/pckgen.d/deb/debian/rules": 755, | ||||||
|  |     "tools/version2sha": 755, | ||||||
|  |     "utils/casctl": 755, | ||||||
|  |     "utils/open-cas-loader": 755, | ||||||
|  |     "utils/open-cas.shutdown": 755, | ||||||
|  |     "ocf/.github/verify_header.sh": 755, | ||||||
|  |     "ocf/tests/functional/utils/configure_random.py": 755, | ||||||
|  |     "ocf/tests/unit/framework/add_new_test_file.py": 755, | ||||||
|  |     "ocf/tests/unit/framework/prepare_sources_for_testing.py": 755, | ||||||
|  |     "ocf/tests/unit/framework/run_unit_tests.py": 755, | ||||||
|  |     "ocf/tests/unit/tests/add_new_test_file.py": 755, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | build_files_perms_exceptions = { | ||||||
|  |     "casadm/casadm": 755, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | installed_files_perms_exceptions = { | ||||||
|  |     "lib/opencas/casctl": 755, | ||||||
|  |     "lib/opencas/open-cas-loader": 755, | ||||||
|  |     "sbin/casadm": 755, | ||||||
|  |     "sbin/casctl": 755, | ||||||
|  |     "usr/lib/systemd/system-shutdown/open-cas.shutdown": 755, | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def test_files_permissions(): | ||||||
|  |     """ | ||||||
|  |     title: Test for files and directories permissions | ||||||
|  |     description: | | ||||||
|  |       Check if all files and directories have proper permissions set. | ||||||
|  |       This icludes repo files and dirs, build artifacts and all | ||||||
|  |       installed items. | ||||||
|  |     pass_criteria: | ||||||
|  |       - all files and directories have proper permissions | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     with TestRun.step("Copy sources to working directory and cleanup"): | ||||||
|  |         rsync_opencas_sources() | ||||||
|  |         clean_opencas_repo() | ||||||
|  |  | ||||||
|  |     with TestRun.step("Check repo files and directories permissions"): | ||||||
|  |         files_list = get_repo_files(with_dirs=True, from_dut=True) | ||||||
|  |         repo_perms = FilesPermissions(files_list) | ||||||
|  |  | ||||||
|  |         perms_exceptions = { | ||||||
|  |             os.path.join(TestRun.usr.working_dir, file): perm | ||||||
|  |             for file, perm in repo_files_perms_exceptions.items() | ||||||
|  |         } | ||||||
|  |         repo_perms.add_exceptions(perms_exceptions) | ||||||
|  |  | ||||||
|  |         failed_perms = repo_perms.check() | ||||||
|  |         if failed_perms: | ||||||
|  |             message = "" | ||||||
|  |             for item in failed_perms: | ||||||
|  |                 message += ( | ||||||
|  |                     f"{item.file} current permissions: {item.current_perm}, " | ||||||
|  |                     f"expected: {item.expected_perm}\n" | ||||||
|  |                 ) | ||||||
|  |             TestRun.fail(f"Those files have wrong permissions:\n{message}") | ||||||
|  |  | ||||||
|  |     with TestRun.step("Check build files and directories permissions"): | ||||||
|  |         files_before_build = find_all_items(TestRun.usr.working_dir) | ||||||
|  |         build_opencas() | ||||||
|  |         files_after_build = find_all_items(TestRun.usr.working_dir) | ||||||
|  |  | ||||||
|  |         files_list = [file for file in files_after_build if file not in files_before_build] | ||||||
|  |         build_perms = FilesPermissions(files_list) | ||||||
|  |  | ||||||
|  |         perms_exceptions = { | ||||||
|  |             os.path.join(TestRun.usr.working_dir, file): perm | ||||||
|  |             for file, perm in build_files_perms_exceptions.items() | ||||||
|  |         } | ||||||
|  |         build_perms.add_exceptions(perms_exceptions) | ||||||
|  |  | ||||||
|  |         failed_perms = build_perms.check() | ||||||
|  |         if failed_perms: | ||||||
|  |             message = "" | ||||||
|  |             for item in failed_perms: | ||||||
|  |                 message += ( | ||||||
|  |                     f"{item.file} current permissions: {item.current_perm}, " | ||||||
|  |                     f"expected: {item.expected_perm}\n" | ||||||
|  |                 ) | ||||||
|  |             TestRun.fail(f"Those files have wrong permissions:\n{message}") | ||||||
|  |  | ||||||
|  |     with TestRun.step("Check installed files and directories permissions"): | ||||||
|  |         destdir = "install_destdir" | ||||||
|  |         install_opencas(destdir) | ||||||
|  |  | ||||||
|  |         files_list = find_all_items(os.path.join(TestRun.usr.working_dir, destdir)) | ||||||
|  |         installed_perms = FilesPermissions(files_list) | ||||||
|  |  | ||||||
|  |         perms_exceptions = { | ||||||
|  |             os.path.join(TestRun.usr.working_dir, destdir, file): perm | ||||||
|  |             for file, perm in installed_files_perms_exceptions.items() | ||||||
|  |         } | ||||||
|  |         installed_perms.add_exceptions(perms_exceptions) | ||||||
|  |  | ||||||
|  |         failed_perms = installed_perms.check() | ||||||
|  |         if failed_perms: | ||||||
|  |             message = "" | ||||||
|  |             for item in failed_perms: | ||||||
|  |                 message += ( | ||||||
|  |                     f"{item.file} current permissions: {item.current_perm}, " | ||||||
|  |                     f"expected: {item.expected_perm}\n" | ||||||
|  |                 ) | ||||||
|  |             TestRun.fail(f"Those files have wrong permissions:\n{message}") | ||||||
		Reference in New Issue
	
	Block a user
	 Karolina Rogowska
					Karolina Rogowska