From 0e8af0d1953b8d52c1b4146177811bf7db211a93 Mon Sep 17 00:00:00 2001 From: Rafal Stefanowski Date: Mon, 18 Jul 2022 16:52:12 +0200 Subject: [PATCH 1/3] test/api: Add git functionalities - get all files that belong to git repo - get paths of all submodules Signed-off-by: Rafal Stefanowski --- test/functional/api/cas/git.py | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/test/functional/api/cas/git.py b/test/functional/api/cas/git.py index 0a69dd3..cdcc6e7 100644 --- a/test/functional/api/cas/git.py +++ b/test/functional/api/cas/git.py @@ -10,6 +10,54 @@ from connection.local_executor import LocalExecutor 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): executor = TestRun.executor if from_dut else LocalExecutor() repo_path = TestRun.usr.working_dir if from_dut else TestRun.usr.repo_dir From e963cf1ae728e63e5ee1e7d4e79eb0cbb98741fa Mon Sep 17 00:00:00 2001 From: Rafal Stefanowski Date: Mon, 18 Jul 2022 16:58:08 +0200 Subject: [PATCH 2/3] test/api: Add 'destdir' installation option Signed-off-by: Rafal Stefanowski --- test/functional/api/cas/installer.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/test/functional/api/cas/installer.py b/test/functional/api/cas/installer.py index 8e11254..b376bcd 100644 --- a/test/functional/api/cas/installer.py +++ b/test/functional/api/cas/installer.py @@ -5,6 +5,7 @@ import logging +import os from tests import conftest from core.test_run import TestRun @@ -17,13 +18,17 @@ from test_utils.output import CmdException def rsync_opencas_sources(): TestRun.LOGGER.info("Copying Open CAS repository to DUT") TestRun.executor.rsync_to( - f"{TestRun.usr.repo_dir}/", - f"{TestRun.usr.working_dir}/", + # Place an empty string as the last argument to os.path.join() + # 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/"], delete=True) -def _clean_opencas_repo(): +def clean_opencas_repo(): TestRun.LOGGER.info("Cleaning Open CAS repo") output = TestRun.executor.run( f"cd {TestRun.usr.working_dir} && " @@ -42,11 +47,15 @@ def build_opencas(): raise CmdException("Make command executed with nonzero status", output) -def install_opencas(): +def install_opencas(destdir: str = ""): TestRun.LOGGER.info("Installing Open CAS") + + if destdir: + destdir = os.path.join(TestRun.usr.working_dir, destdir) + output = TestRun.executor.run( f"cd {TestRun.usr.working_dir} && " - f"make install") + f"make {'DESTDIR='+destdir if destdir else ''} install") if output.exit_code != 0: raise CmdException("Failed to install Open CAS", output) @@ -54,6 +63,9 @@ def install_opencas(): if output.exit_code != 0: raise CmdException("Failed to reload modules", output) + if destdir: + return + TestRun.LOGGER.info("Check if casadm is properly installed.") output = TestRun.executor.run("casadm -V") if output.exit_code != 0: @@ -63,7 +75,7 @@ def install_opencas(): def set_up_opencas(version: str = ""): - _clean_opencas_repo() + clean_opencas_repo() if version: git.checkout_cas_version(version) From 2309a79d03b31bff2f1d4ee77eab6f41ef4b3a52 Mon Sep 17 00:00:00 2001 From: Rafal Stefanowski Date: Mon, 18 Jul 2022 17:03:59 +0200 Subject: [PATCH 3/3] test: Add file permissions test Test files and directories permissions of git repo, build artifacts and installed files. Signed-off-by: Rafal Stefanowski --- .../tests/misc/test_files_permissions.py | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 test/functional/tests/misc/test_files_permissions.py diff --git a/test/functional/tests/misc/test_files_permissions.py b/test/functional/tests/misc/test_files_permissions.py new file mode 100644 index 0000000..96668c8 --- /dev/null +++ b/test/functional/tests/misc/test_files_permissions.py @@ -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}")