def run(self): """ The main application execution method """ logger.info("Running Containers Testing Framework cli") try: check_call("git submodule update --init", shell=True) except: pass # TODO: Remove this or rework, once more types are implemented if self._cli_conf.get( CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_EXEC_TYPE) != 'ansible': raise CTFCliError("Wrong ExecType configured. Currently only 'ansible' is supported!") self._working_dir = BehaveWorkingDirectory(self._working_dir_path, self._cli_conf) # Setup Behave structure inside working directory # Clone common Features and steps into the working dir # Add the project specific Features and steps # Prepare the steps.py in the Steps dir that combines all the other self._working_dir.setup() # Execute Behave self._behave_runner = BehaveRunner(self._working_dir, self._cli_conf) sys.exit(self._behave_runner.run())
class Application(object): def __init__(self, cli_args=None): """ The Application implementation. """ self._execution_dir_path = os.getcwd() self._working_dir_path = os.path.join( self._execution_dir_path, '{0}-behave-working-dir'.format( os.path.basename(self._execution_dir_path))) self._working_dir = None self._behave_runner = None if not cli_args.cli_config_path: cli_args.cli_config_path = CTFCliConfig.find_cli_config( self._execution_dir_path) self._cli_conf = CTFCliConfig(cli_args) # If no Dockerfile passed on the cli, try to use one from the execution directory if not self._cli_conf.get(CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_DOCKERFILE): local_file = os.path.join(self._execution_dir_path, 'Dockerfile') if not os.path.isfile(local_file): raise CTFCliError( "No Dockerfile passed on the cli and no Dockerfile " "is present in the current directory!") logger.debug("Using Dockerfile from the current directory.") self._cli_conf.set(CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_DOCKERFILE, local_file) # TODO: Remove this or rework, once more types are implemented if self._cli_conf.get(CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_EXEC_TYPE) != 'ansible': raise CTFCliError( "Wrong ExecType configured. Currently only 'ansible' is supported!" ) def run(self): """ The main application execution method """ logger.info("Running Containers Testing Framework cli") self._working_dir = BehaveWorkingDirectory(self._working_dir_path, self._cli_conf) # Setup Behave structure inside working directory # Clone common Features and steps into the working dir # Add the project specific Features and steps # Prepare the steps.py in the Steps dir that combines all the other self._working_dir.setup() # Execute Behave self._behave_runner = BehaveRunner(self._working_dir, self._cli_conf) return self._behave_runner.run()
def run(self): """ The main application execution method """ logger.info("Running Containers Testing Framework cli") # If no Dockerfile passed on the cli, try to use one from the execution directory if not self._cli_conf.get(CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_DOCKERFILE): local_file = os.path.join(self._execution_dir_path, 'Dockerfile') if not os.path.isfile(local_file): raise CTFCliError("No Dockerfile passed on the cli and no Dockerfile " "is present in the current directory!") logger.debug("Using Dockerfile from the current directory.") self._cli_conf.set(CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_DOCKERFILE, local_file) # TODO: Remove this or rework, once more types are implemented if self._cli_conf.get(CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_EXEC_TYPE) != 'ansible': raise CTFCliError("Wrong ExecType configured. Currently only 'ansible' is supported!") self._working_dir = BehaveWorkingDirectory(self._working_dir_path, self._cli_conf) # Setup Behave structure inside working directory # Clone common Features and steps into the working dir # Add the project specific Features and steps # Prepare the steps.py in the Steps dir that combines all the other self._working_dir.setup() # Execute Behave self._behave_runner = BehaveRunner(self._working_dir, self._cli_conf) return self._behave_runner.run()
def test_find_tests_config_none(self): """ Test that if no configuration file is present, None is returned :return: """ assert BehaveWorkingDirectory.find_tests_config( self.WORKING_DIR) is None
def run(self): """ The main application execution method """ logger.info("Running Containers Testing Framework cli") self._working_dir = BehaveWorkingDirectory(self._working_dir_path, self._cli_conf) # Setup Behave structure inside working directory # Clone common Features and steps into the working dir # Add the project specific Features and steps # Prepare the steps.py in the Steps dir that combines all the other self._working_dir.setup() # Execute Behave self._behave_runner = BehaveRunner(self._working_dir, self._cli_conf) return self._behave_runner.run()
def test_check_and_add_init_py(self): """ Test that __init__.py is created in all directories in which it was missing :return: """ dirs = [ 'myproj/common', 'myproj/specific', 'yourproj', 'theirproj/common', 'theirproj/common/steps', 'theirproj/specific', 'theirproj/.git', 'theirproj/.git/dir', ] files = [ # 'myproj/__init__.py' 'myproj/common/__init__.py', # 'myproj/specific/__init__.py', 'yourproj/__init__.py', 'theirproj/__init__.py', # 'theirproj/common/__init__.py', 'theirproj/common/steps/__init__.py', # 'theirproj/specific/__init__.py', ] f = [ 'myproj/__init__.py', 'myproj/specific/__init__.py', 'theirproj/common/__init__.py', 'theirproj/specific/__init__.py', ] files_to_check = [os.path.join(self.WORKING_DIR, x) for x in f] # create dirs for d in dirs: os.makedirs(d) # create files for f in files: with open(f, 'w') as fw: fw.write(f) output = BehaveWorkingDirectory.check_and_add_init_py(os.getcwd()) print(output) assert len( set(files_to_check).intersection(output)) == len(files_to_check) for f in files_to_check: assert os.path.exists(f)
def test_check_and_add_init_py(self): """ Test that __init__.py is created in all directories in which it was missing :return: """ dirs = [ 'myproj/common', 'myproj/specific', 'yourproj', 'theirproj/common', 'theirproj/common/steps', 'theirproj/specific', 'theirproj/.git', 'theirproj/.git/dir', ] files = [ # 'myproj/__init__.py' 'myproj/common/__init__.py', # 'myproj/specific/__init__.py', 'yourproj/__init__.py', 'theirproj/__init__.py', # 'theirproj/common/__init__.py', 'theirproj/common/steps/__init__.py', # 'theirproj/specific/__init__.py', ] f = [ 'myproj/__init__.py', 'myproj/specific/__init__.py', 'theirproj/common/__init__.py', 'theirproj/specific/__init__.py', ] files_to_check = [os.path.join(self.WORKING_DIR, x) for x in f] # create dirs for d in dirs: os.makedirs(d) # create files for f in files: with open(f, 'w') as fw: fw.write(f) output = BehaveWorkingDirectory.check_and_add_init_py(os.getcwd()) print(output) assert len(set(files_to_check).intersection(output)) == len(files_to_check) for f in files_to_check: assert os.path.exists(f)
def test_get_import_statements(self): """ Test that import statements are generated correctly :return: """ dirs = [ 'myproj/common', 'myproj/specific', 'yourproj', 'theirproj/common', 'theirproj/common/steps', 'theirproj/specific', 'theirproj/.git', 'theirproj/.git/dir', ] files = [ 'myproj/common/file1.py', 'myproj/common/file2.py', 'myproj/specific/your.py', 'yourproj/step.py', 'theirproj/common/file3.py', 'theirproj/common/file4.py', 'theirproj/common/steps/file5.py', 'theirproj/common/steps/file6.py', 'theirproj/common/steps/file7.py', ] expected_out = [ 'from myproj.common.file1 import *', 'from myproj.common.file2 import *', 'from myproj.specific.your import *', 'from yourproj.step import *', 'from theirproj.common.file3 import *', 'from theirproj.common.file4 import *', 'from theirproj.common.steps.file5 import *', 'from theirproj.common.steps.file6 import *', 'from theirproj.common.steps.file7 import *', ] # create dirs for d in dirs: os.makedirs(d) # create files for f in files: with open(f, 'w') as fw: fw.write(f) output = BehaveWorkingDirectory.get_import_statements(os.getcwd()) assert len(set(expected_out).intersection(output)) == len(expected_out)
def test_find_tests_config_multiple(self): """ Test that configuration files are found and that .ini has preference :return: """ files = [ 'test.ini', 'tests.conf', ] for f in files: with open(f, 'w') as fw: fw.write('xyz') assert BehaveWorkingDirectory.find_tests_config(self.WORKING_DIR) == os.path.join(self.WORKING_DIR, files[0])
def test_find_tests_config_multiple(self): """ Test that configuration files are found and that .ini has preference :return: """ files = [ 'test.ini', 'tests.conf', ] for f in files: with open(f, 'w') as fw: fw.write('xyz') assert BehaveWorkingDirectory.find_tests_config( self.WORKING_DIR) == os.path.join(self.WORKING_DIR, files[0])
def test_find_tests_config_existing(self): """ Test that configuration files are successfully found :return: """ files = [ 'test.ini', 'tests.ini', 'test.conf', 'tests.conf', ] for f in files: with open(f, 'w') as fw: fw.write('xyz') assert BehaveWorkingDirectory.find_tests_config(self.WORKING_DIR) == os.path.join(self.WORKING_DIR, f) os.remove(f) assert not os.path.exists(f)
def test_find_tests_config_existing(self): """ Test that configuration files are successfully found :return: """ files = [ 'test.ini', 'tests.ini', 'test.conf', 'tests.conf', ] for f in files: with open(f, 'w') as fw: fw.write('xyz') assert BehaveWorkingDirectory.find_tests_config( self.WORKING_DIR) == os.path.join(self.WORKING_DIR, f) os.remove(f) assert not os.path.exists(f)
def test_find_tests_config_none(self): """ Test that if no configuration file is present, None is returned :return: """ assert BehaveWorkingDirectory.find_tests_config(self.WORKING_DIR) is None
class Application(object): def __init__(self, cli_args=None): """ The Application implementation. """ self._execution_dir_path = os.getcwd() self._working_dir_path = os.path.join(self._execution_dir_path, 'workdir') self._working_dir = None self._behave_runner = None if not cli_args.cli_config_path: cli_args.cli_config_path = CTFCliConfig.find_cli_config(self._execution_dir_path) self._cli_conf = CTFCliConfig(cli_args) def init(self): """ Initialize default app test structure """ logger.info("Initialize default directory structure") # Make sure we're in a directory under git control try: check_call('git rev-parse &> /dev/null', shell=True) except CalledProcessError: logger.info("Directory is not under git control, running git init") check_call("git init &> /dev/null", shell=True) # Create test dir if it is missing tests_dir = os.path.join(self._execution_dir_path, "tests") if os.path.exists(tests_dir): logger.info("Directory tests already exists") else: logger.info("Creating tests directory") os.mkdir(tests_dir) check_call("git add %s" % tests_dir, shell=True) features_dir = os.path.join(tests_dir, "features") if os.path.exists(features_dir): logger.info("Directory tests/features already exists") else: logger.info("Creating tests/features directory") os.mkdir(features_dir) check_call("git add %s" % features_dir, shell=True) steps_dir = os.path.join(tests_dir, "steps") if os.path.exists(steps_dir): logger.info("Directory tests/steps already exists") else: logger.info("Creating tests/steps directory") os.mkdir(steps_dir) check_call("git add %s" % steps_dir, shell=True) # TODO: check that this file is actually necessary steps_init_file = os.path.join(steps_dir, "__init__.py") if os.path.exists(steps_init_file): logger.info("File tests/steps/__init__.py already exists") else: logger.info("Creating tests/steps/__init__.py file") open(steps_init_file, "a").close() check_call("git add %s" % steps_init_file, shell=True) steps_py_file = os.path.join(steps_dir, "steps.py") if os.path.exists(steps_py_file): logger.info("File tests/steps/steps.py already exists") else: logger.info("Creating tests/steps/steps.py file") with open(steps_py_file, "w") as f: f.write(common_steps_py_content) check_call("git add %s" % steps_py_file, shell=True) # Copy sample configuration ctf_conf_file = os.path.join(self._execution_dir_path, "ctf.conf") if os.path.exists(ctf_conf_file): logger.info("File ctf.conf already exists") else: logger.info("Creating ctf.conf file") # Create environment.py with open(ctf_conf_file, "w") as f: f.write(sample_ctl_ctf_config) check_call("git add %s" % ctf_conf_file, shell=True) def add_remote(self): if 'feature' in self._cli_conf.get( CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_REMOTE_TYPE): self.add_remote_feature() else: self.add_remote_step() def add_remote_feature(self): path = "tests/features/" try: project = self._cli_conf.get( CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_REMOTE_PROJECT) assert project path = "tests/features/" + project except Exception: pass self.add_submodule(path) def add_remote_step(self): path = "tests/steps/" try: project = self._cli_conf.get( CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_REMOTE_PROJECT) assert project path = "tests/steps/" + project except Exception: pass self.add_submodule(path) def list_remotes(self): check_call("git submodule -q foreach 'git config --get remote.origin.url'", shell=True) def add_submodule(self, path): url = self._cli_conf.get(CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_REMOTE_URL) dirname = os.path.splitext(os.path.basename(url))[0].replace('-', '_') check_call('git submodule add %s %s' % (url, path + "/" + dirname), shell=True) def remove_remote(self): name = self._cli_conf.get(CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_REMOTE_NAME) check_call('git submodule deinit -f %s' % name, shell=True) check_call('git config -f .gitmodules --remove-section "submodule.%s"' % name, shell=True) gitmodules_dir = os.path.join(os.path.abspath(".git/modules"), name) shutil.rmtree(gitmodules_dir) shutil.rmtree(name) def run(self): """ The main application execution method """ logger.info("Running Containers Testing Framework cli") try: check_call("git submodule update --init", shell=True) except: pass # TODO: Remove this or rework, once more types are implemented if self._cli_conf.get( CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_EXEC_TYPE) != 'ansible': raise CTFCliError("Wrong ExecType configured. Currently only 'ansible' is supported!") self._working_dir = BehaveWorkingDirectory(self._working_dir_path, self._cli_conf) # Setup Behave structure inside working directory # Clone common Features and steps into the working dir # Add the project specific Features and steps # Prepare the steps.py in the Steps dir that combines all the other self._working_dir.setup() # Execute Behave self._behave_runner = BehaveRunner(self._working_dir, self._cli_conf) sys.exit(self._behave_runner.run()) def update(self): """ Update app submodules """ logger.info("Updating remote test and features") check_call("git submodule foreach git pull --rebase origin master", shell=True)
class Application(object): def __init__(self, cli_args=None): """ The Application implementation. """ self._execution_dir_path = os.getcwd() self._working_dir_path = os.path.join(self._execution_dir_path, 'workdir') self._working_dir = None self._behave_runner = None if not cli_args.cli_config_path: cli_args.cli_config_path = CTFCliConfig.find_cli_config(self._execution_dir_path) self._cli_conf = CTFCliConfig(cli_args) def init(self): """ Initialize default app test structure """ logger.info("Initialize default directory structure") # Make sure we're in a directory under git control try: check_call('git rev-parse', shell=True) except CalledProcessError: logger.info("Directory is not under git control, running git init") check_call("git init", shell=True) # Create test dir if it is missing tests_dir = os.path.join(self._execution_dir_path, "tests") if os.path.exists(tests_dir): logger.info("Directory tests already exists") else: logger.info("Creating tests directory") os.mkdir(tests_dir) check_call("git add %s" % tests_dir, shell=True) env_py_path = os.path.join(tests_dir, "environment.py") if os.path.exists(env_py_path): logger.info("File tests/environment.py already exists") else: logger.info("Creating environment.py") # Create environment.py with open(env_py_path, "w") as f: f.write(common_environment_py_content) check_call("git add %s" % env_py_path, shell=True) features_dir = os.path.join(tests_dir, "features") if os.path.exists(features_dir): logger.info("Directory tests/features already exists") else: logger.info("Creating tests/features directory") os.mkdir(features_dir) check_call("git add %s" % features_dir, shell=True) steps_dir = os.path.join(tests_dir, "steps") if os.path.exists(steps_dir): logger.info("Directory tests/steps already exists") else: logger.info("Creating tests/steps directory") os.mkdir(steps_dir) check_call("git add %s" % steps_dir, shell=True) # TODO: check that this file is actually necessary steps_init_file = os.path.join(steps_dir, "__init__.py") if os.path.exists(steps_init_file): logger.info("File tests/steps/__init__.py already exists") else: logger.info("Creating tests/steps/__init__.py file") open(steps_init_file, "a").close() check_call("git add %s" % steps_init_file, shell=True) steps_py_file = os.path.join(steps_dir, "steps.py") if os.path.exists(steps_py_file): logger.info("File tests/steps/steps.py already exists") else: logger.info("Creating tests/steps/steps.py file") with open(steps_py_file, "w") as f: f.write(common_steps_py_content) check_call("git add %s" % steps_py_file, shell=True) # Add common-features and common-steps as submodules # TODO: make this generic when a different type of container is specified common_features_dir = os.path.join(features_dir, "common-features") if os.path.exists(common_features_dir): logger.info("Directory tests/features/common-features already exists") else: logger.info("Adding tests/features/common-features as a submodule") check_call('git submodule add https://github.com/Containers-Testing-Framework/common-features.git tests/features/common-features', shell=True) common_steps_dir = os.path.join(steps_dir, "common_steps") if os.path.exists(common_steps_dir): logger.info("Directory tests/steps/common_steps already exists") else: logger.info("Adding tests/steps/common_steps as a submodule") check_call('git submodule add https://github.com/Containers-Testing-Framework/common-steps.git tests/steps/common_steps', shell=True) # Copy sample configuration ctf_conf_file = os.path.join(self._execution_dir_path, "ctf.conf") if os.path.exists(ctf_conf_file): logger.info("File ctf.conf already exists") else: logger.info("Creating ctf.conf file") # Create environment.py with open(ctf_conf_file, "w") as f: f.write(sample_ctl_ctf_config) check_call("git add %s" % ctf_conf_file, shell=True) def run(self): """ The main application execution method """ logger.info("Running Containers Testing Framework cli") # If no Dockerfile passed on the cli, try to use one from the execution directory if not self._cli_conf.get(CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_DOCKERFILE): local_file = os.path.join(self._execution_dir_path, 'Dockerfile') if not os.path.isfile(local_file): raise CTFCliError("No Dockerfile passed on the cli and no Dockerfile " "is present in the current directory!") logger.debug("Using Dockerfile from the current directory.") self._cli_conf.set(CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_DOCKERFILE, local_file) # TODO: Remove this or rework, once more types are implemented if self._cli_conf.get(CTFCliConfig.GLOBAL_SECTION_NAME, CTFCliConfig.CONFIG_EXEC_TYPE) != 'ansible': raise CTFCliError("Wrong ExecType configured. Currently only 'ansible' is supported!") self._working_dir = BehaveWorkingDirectory(self._working_dir_path, self._cli_conf) # Setup Behave structure inside working directory # Clone common Features and steps into the working dir # Add the project specific Features and steps # Prepare the steps.py in the Steps dir that combines all the other self._working_dir.setup() # Execute Behave self._behave_runner = BehaveRunner(self._working_dir, self._cli_conf) return self._behave_runner.run() def update(self): """ Update app submodules """ logger.info("Updating Containers Testing Framework common steps and features") common_steps_dir = os.path.join(self._execution_dir_path, "tests", "steps", "common_steps") common_features_dir = os.path.join(self._execution_dir_path, "tests", "features", "common-features") for directory in [common_steps_dir, common_features_dir]: logger.info("Updating %s" % directory) check_call("git fetch origin", shell=True, cwd=directory) check_call("git checkout origin/master", shell=True, cwd=directory) # Check that steps are not contradicting with each other logger.info("Checking project steps sanity") check_call("behave tests -d", shell=True)