def api(file_name, login=False): """Factory to create either Mock or Wrap api""" base_name = os.path.basename(file_name).replace('.pyc', '.py') job_name_prefix = _file_name_subst.sub('', base_name) func_name = None func_num_params = 0 if '_test' in file_name: func_name = sys._getframe().f_back.f_code.co_name # pylint: disable=protected-access func_num_params = sys._getframe().f_back.f_code.co_argcount # pylint: disable=protected-access file_name = base_name func_name = func_name.replace('test_', '') assert func_name[0:len(job_name_prefix)] == job_name_prefix, \ "Naming standard not followed: " + repr('test_' + func_name) + " defined in file: " + repr(base_name) + " should be 'test_" + job_name_prefix + "_<sub test>'" job_name_prefix = 'jenkinsflow_test__' + func_name + '__' else: job_name_prefix = 'jenkinsflow_demo__' + job_name_prefix + '__' file_name = base_name.replace('_jobs', '') print() print("--- Preparing api for ", repr(job_name_prefix), "---") global hyperspeed hyperspeed = HyperSpeed() if hyperspeed.is_mocked: print('Using Mocked API') return MockApi(job_name_prefix, test_cfg.direct_url()) else: print('Using Real Jenkins API with wrapper') reload_jobs = not test_cfg.skip_job_load() pre_delete_jobs = not test_cfg.skip_job_delete() return JenkinsTestWrapperApi(file_name, func_name, func_num_params, job_name_prefix, reload_jobs, pre_delete_jobs, test_cfg.direct_url(), security.username, security.password, security.securitytoken, login=login)
def api(file_name, api_type, login=False, fixed_prefix=None, url_or_dir=None, fake_public_uri=None, invocation_class=None, username=None, password=None): """Factory to create either Mock or Wrap api""" base_name = os.path.basename(file_name).replace('.pyc', '.py') job_name_prefix = _file_name_subst.sub('', base_name) func_name = None func_num_params = 0 if fixed_prefix: job_name_prefix = fixed_prefix file_name = base_name elif '_test' in file_name: func_name = sys._getframe().f_back.f_code.co_name # pylint: disable=protected-access func_num_params = sys._getframe().f_back.f_code.co_argcount # pylint: disable=protected-access file_name = base_name func_name = func_name.replace('test_', '') assert func_name[0:len(job_name_prefix)] == job_name_prefix, \ "Naming standard not followed: " + repr('test_' + func_name) + " defined in file: " + repr(base_name) + " should be 'test_" + job_name_prefix + "_<sub test>'" job_name_prefix = 'jenkinsflow_test__' + func_name + '__' else: job_name_prefix = 'jenkinsflow_demo__' + job_name_prefix + '__' file_name = base_name.replace('_jobs', '') print() print("--- Preparing api for ", repr(job_name_prefix), "---") print('Using:', api_type) url_or_dir = url_or_dir or test_cfg.direct_url(api_type) reload_jobs = not test_cfg.skip_job_load() and not fixed_prefix pre_delete_jobs = not test_cfg.skip_job_delete() import demo_security as security if password is not None or username is not None: assert password is not None and username is not None login = True if username is None: assert password is None username = security.username password = security.password if api_type == test_cfg.ApiType.JENKINS: from .api_wrapper import JenkinsTestWrapperApi return JenkinsTestWrapperApi(file_name, func_name, func_num_params, job_name_prefix, reload_jobs, pre_delete_jobs, url_or_dir, fake_public_uri, username, password, security.securitytoken, login=login, invocation_class=invocation_class) if api_type == test_cfg.ApiType.SCRIPT: from .api_wrapper import ScriptTestWrapperApi return ScriptTestWrapperApi(file_name, func_name, func_num_params, job_name_prefix, reload_jobs, pre_delete_jobs, url_or_dir, fake_public_uri, username, password, security.securitytoken, login=login, invocation_class=invocation_class) if api_type == test_cfg.ApiType.MOCK: from .mock_api import MockApi return MockApi(job_name_prefix, test_cfg.speedup(), test_cfg.direct_url(api_type)) else: raise Exception("Unhandled api_type:" + repr(api_type))
def args_parser(): speedup_default = 1000 test_cfg.mock(speedup_default) class EnvAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): name = env_var_prefix + self.dest.replace('-', '_').upper() value = 'true' if self.nargs == 0 and not values else values if value == '': raise argparse.ArgumentError(self, "'' is not a valid value") # print("Env:", self, parser, namespace, name, value, option_string) os.environ[name] = str(value) setattr(namespace, self.dest, value) parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='Test jenkinsflow. First runs all tests mocked in hyperspeed, then runs against Jenkins.') parser.add_argument('--mock-speedup', type=int, default=speedup_default, action=EnvAction, help='Time speedup when running mocked tests') parser.add_argument('--direct-url', default=test_cfg.direct_url(), action=EnvAction, help='Direct Jenkins URL. Must be different from the URL set in Jenkins (and preferably non proxied)') parser.add_argument('--use-jenkinsapi', nargs=0, action=EnvAction, help="Use 'jenkinsapi_wrapper' module for Jenkins access, instead of 'specialized_api'.") parser.add_argument('--pytest-args', default=None, help="String of py.test arguments") jlg = parser.add_argument_group('Job Load', 'Control job loading and parallel test run. Specifying any of these options enables running of tests in parallel.') jlg.add_argument('--skip-job-delete', nargs=0, action=EnvAction, help="Don't delete and re-load jobs into Jenkins (assumes already loaded and up to date).") jlg.add_argument('--skip-job-load', nargs=0, action=EnvAction, help="Don't load jobs into Jenkins (assumes already loaded and up to date).") parser.add_argument('files', default=None, nargs='*', help="File names to pass to py.test") return parser
def api(file_name, login=False, fixed_prefix=None): """Factory to create either Mock or Wrap api""" base_name = os.path.basename(file_name).replace('.pyc', '.py') job_name_prefix = _file_name_subst.sub('', base_name) func_name = None func_num_params = 0 if fixed_prefix: job_name_prefix = fixed_prefix file_name = base_name elif '_test' in file_name: func_name = sys._getframe().f_back.f_code.co_name # pylint: disable=protected-access func_num_params = sys._getframe().f_back.f_code.co_argcount # pylint: disable=protected-access file_name = base_name func_name = func_name.replace('test_', '') assert func_name[0:len(job_name_prefix)] == job_name_prefix, \ "Naming standard not followed: " + repr('test_' + func_name) + " defined in file: " + repr(base_name) + " should be 'test_" + job_name_prefix + "_<sub test>'" job_name_prefix = 'jenkinsflow_test__' + func_name + '__' else: job_name_prefix = 'jenkinsflow_demo__' + job_name_prefix + '__' file_name = base_name.replace('_jobs', '') print() print("--- Preparing api for ", repr(job_name_prefix), "---") if mocked: print('Using Mocked API') from .mock_api import MockApi return MockApi(job_name_prefix, test_cfg.direct_url()) else: api_type = test_cfg.selected_api() print('Using:', api_type) url_or_dir = test_cfg.direct_url() reload_jobs = not test_cfg.skip_job_load() and not fixed_prefix pre_delete_jobs = not test_cfg.skip_job_delete() import demo_security as security from .api_wrapper import JenkinsTestWrapperApi return JenkinsTestWrapperApi(file_name, func_name, func_num_params, job_name_prefix, reload_jobs, pre_delete_jobs, url_or_dir, security.username, security.password, security.securitytoken, login=login)
def args_parser(): test_cfg.select_api(ApiType.SPECIALIZED) doc = opts % dict(speedup_default=1000, direct_url=test_cfg.direct_url()) args = docopt(doc, argv=None, help=True, version=None, options_first=False) speedup = float(args['--mock-speedup']) if speedup and speedup != 1: test_cfg.mock(speedup) if args['--direct-url']: os.environ[test_cfg.DIRECT_URL_NAME] = args['--direct-url'] os.environ[test_cfg.SCRIPT_DIR_NAME] = test_cfg.script_dir() if args['--use-jenkinsapi']: test_cfg.select_api(ApiType.JENKINSAPI) os.environ[test_cfg.SKIP_JOB_DELETE_NAME] = 'true' if args['--skip-job-delete'] else 'false' os.environ[test_cfg.SKIP_JOB_LOAD_NAME] = 'true' if args['--skip-job-load'] else 'false' return args['--pytest-args'], args['<file>']
def cli(mock_speedup=1000, direct_url=test_cfg.direct_url(test_cfg.ApiType.JENKINS), apis=None, pytest_args=None, job_delete=False, job_load=True, testfile=None): """ Test jenkinsflow. First runs all tests mocked in hyperspeed, then runs against Jenkins, using jenkins_api, then run script_api jobs. Normally jobs will be run in parallel, specifying --job-delete disables this. The default options assumes that re-loading without deletions generates correct job config. Tests that require jobs to be deleted/non-existing will delete the jobs, regardless of the --job-delete option. [TESTFILE]... File names to pass to py.test """ os.environ[test_cfg.DIRECT_URL_NAME] = direct_url os.environ[test_cfg.SKIP_JOB_DELETE_NAME] = 'false' if job_delete else 'true' os.environ[test_cfg.SKIP_JOB_LOAD_NAME] = 'false' if job_load else 'true' args = ['--capture=sys', '--instafail'] if apis is None: api_types = [ApiType.MOCK, ApiType.SCRIPT, ApiType.JENKINS] else: api_types = [ApiType[api_name.strip().upper()] for api_name in apis.split(',')] args.extend(['-k', ' or '.join([apit.name for apit in api_types])]) rc = 0 target_dir = "/tmp/jenkinsflow-test/jenkinsflow" try: os.makedirs(target_dir) except OSError as ex: if ex.errno != errno.EEXIST: raise if api_types != [ApiType.MOCK]: print("Creating temporary test installation in", repr(config.pseudo_install_dir), "to make files available to Jenkins.") install_script = jp(here, 'tmp_install.sh') rc = subprocess.call([install_script, target_dir]) if rc: print("Failed test installation to", repr(config.pseudo_install_dir), "Install script is:", repr(install_script), file=sys.stderr) print("Warning: Some tests will fail!", file=sys.stderr) cov_file = ".coverage" for cov_file in jp(here, cov_file), jp(top_dir, cov_file): if os.path.exists(cov_file): os.remove(cov_file) print("\nRunning tests") try: if pytest_args or testfile: coverage = False args.extend(pytest_args.split(' ') + list(testfile) if pytest_args else list(testfile)) else: coverage = True args.append('--ff') hudson = os.environ.get('HUDSON_URL') if hudson: print("Disabling parallel run, Hudson can't handle it :(") parallel = test_cfg.skip_job_load() or test_cfg.skip_job_delete() and not hudson run_tests(parallel, api_types, args, coverage, mock_speedup) # start_msg("Testing setup.py") # user = getpass.getuser() # install_prefix = '/tmp/' + user # tmp_packages_dir = install_prefix + '/lib/python{major}.{minor}/site-packages'.format(major=major_version, minor=sys.version_info.minor) # os.environ['PYTHONPATH'] = tmp_packages_dir # if os.path.exists(tmp_packages_dir): # shutil.rmtree(tmp_packages_dir) # os.makedirs(tmp_packages_dir) # # os.chdir(top_dir) # subprocess.check_call([sys.executable, jp(top_dir, 'setup.py'), 'install', '--prefix', install_prefix]) # shutil.rmtree(jp(top_dir, 'build')) if not testfile and os.environ.get('CI', 'false').lower() != 'true': # This is automatically tested by readdthedocs, so no need to test on Travis start_msg("Testing documentation generation") os.chdir(jp(top_dir, 'doc/source')) del os.environ['PYTHONPATH'] subprocess.check_call(['make', 'html']) except Exception as ex: print('*** ERROR: There were errors! Check output! ***', repr(ex), file=sys.stderr) raise sys.exit(rc)
if not testfile and os.environ.get('CI', 'false').lower() != 'true': # This is automatically tested by readdthedocs, so no need to test on Travis start_msg("Testing documentation generation") os.chdir(jp(top_dir, 'doc/source')) del os.environ['PYTHONPATH'] subprocess.check_call(['make', 'html']) except Exception as ex: print('*** ERROR: There were errors! Check output! ***', repr(ex), file=sys.stderr) raise sys.exit(rc) @click.command() @click.option('--mock-speedup', '-s', help="Time speedup when running mocked tests.", default=1000) @click.option('--direct-url', help="Direct Jenkins URL. Must be different from the URL set in Jenkins (and preferably non proxied)", default=test_cfg.direct_url(test_cfg.ApiType.JENKINS)) @click.option('--apis', help="Select which api(s) to use/test. Comma separated list. Possible values: 'jenkins, 'script', 'mock'. Default is all.", default=None) @click.option('--pytest-args', help="py.test arguments.") @click.option('--job-delete/--no-job-delete', help="Delete and re-load jobs into Jenkins. Default is --no-job-delete.", default=False) @click.option('--job-load/--no-job-load', help="Load jobs into Jenkins (skipping job load assumes all jobs already loaded and up to date). Deafult is --job-load.", default=True) @click.argument('testfile', nargs=-1, type=click.Path(exists=True, readable=True)) def _cli(mock_speedup, direct_url, apis, pytest_args, job_delete, job_load, testfile): cli(mock_speedup, direct_url, apis, pytest_args, job_delete, job_load, testfile) if __name__ == '__main__': _cli() # pylint: disable=no-value-for-parameter
def api(file_name, api_type, login=None, fixed_prefix=None, url_or_dir=None, fake_public_uri=None, invocation_class=None, username=None, password=None): """Factory to create either Mock or Wrap api""" base_name = os.path.basename(file_name).replace('.pyc', '.py') job_name_prefix = _file_name_subst.sub('', base_name) func_name = None func_num_params = 0 if fixed_prefix: job_name_prefix = fixed_prefix file_name = base_name elif '_test' in file_name: func_name = sys._getframe().f_back.f_code.co_name # pylint: disable=protected-access func_num_params = sys._getframe().f_back.f_code.co_argcount # pylint: disable=protected-access file_name = base_name func_name = func_name.replace('test_', '') assert func_name[0:len(job_name_prefix)] == job_name_prefix, \ "Naming standard not followed: " + repr('test_' + func_name) + " defined in file: " + repr(base_name) + " should be 'test_" + job_name_prefix + "_<sub test>'" job_name_prefix = 'jenkinsflow_test__' + func_name + '__' else: job_name_prefix = 'jenkinsflow_demo__' + job_name_prefix + '__' file_name = base_name.replace('_jobs', '') print() print("--- Preparing api for ", repr(job_name_prefix), "---") if api_type == 0: # Invocation from actual Jenkins flow job calls with api_type == 0 api_type = test_cfg.ApiType.JENKINS print('Using:', api_type) url_or_dir = url_or_dir or test_cfg.direct_url(api_type) reload_jobs = not test_cfg.skip_job_load() and not fixed_prefix pre_delete_jobs = not test_cfg.skip_job_delete() import demo_security as security if login is None: login = security.default_use_login if password is not None or username is not None: assert password is not None and username is not None login = True if username is None: assert password is None username = security.username password = security.password if api_type == test_cfg.ApiType.JENKINS: from .api_wrapper import JenkinsTestWrapperApi return JenkinsTestWrapperApi(file_name, func_name, func_num_params, job_name_prefix, reload_jobs, pre_delete_jobs, url_or_dir, fake_public_uri, username, password, security.securitytoken, login=login, invocation_class=invocation_class) if api_type == test_cfg.ApiType.SCRIPT: from .api_wrapper import ScriptTestWrapperApi return ScriptTestWrapperApi(file_name, func_name, func_num_params, job_name_prefix, reload_jobs, pre_delete_jobs, url_or_dir, fake_public_uri, username, password, security.securitytoken, login=login, invocation_class=invocation_class) if api_type == test_cfg.ApiType.MOCK: from .mock_api import MockApi return MockApi(job_name_prefix, test_cfg.speedup(), test_cfg.direct_url(api_type)) raise Exception("Unhandled api_type:" + repr(api_type))
def cli(mock_speedup=1000, direct_url=test_cfg.direct_url(test_cfg.ApiType.JENKINS), apis=None, pytest_args=None, job_delete=False, job_load=True, testfile=None): """ Test jenkinsflow. First runs all tests mocked in hyperspeed, then runs against Jenkins, using jenkins_api, then run script_api jobs. Normally jobs will be run in parallel, specifying --job-delete disables this. The default options assumes that re-loading without deletions generates correct job config. Tests that require jobs to be deleted/non-existing will delete the jobs, regardless of the --job-delete option. [TESTFILE]... File names to pass to py.test """ os.environ[test_cfg.DIRECT_URL_NAME] = direct_url os.environ[ test_cfg.SKIP_JOB_DELETE_NAME] = 'false' if job_delete else 'true' os.environ[test_cfg.SKIP_JOB_LOAD_NAME] = 'false' if job_load else 'true' args = ['--capture=sys', '--instafail'] if apis is None: api_types = [ApiType.MOCK, ApiType.SCRIPT, ApiType.JENKINS] else: api_types = [ ApiType[api_name.strip().upper()] for api_name in apis.split(',') ] args.extend(['-k', ' or '.join([apit.name for apit in api_types])]) rc = 0 target_dir = "/tmp/jenkinsflow-test/jenkinsflow" try: os.makedirs(target_dir) except OSError as ex: if ex.errno != errno.EEXIST: raise if api_types != [ApiType.MOCK]: print("Creating temporary test installation in", repr(config.pseudo_install_dir), "to make files available to Jenkins.") install_script = jp(here, 'tmp_install.sh') rc = subprocess.call([install_script, target_dir]) if rc: print("Failed test installation to", repr(config.pseudo_install_dir), "Install script is:", repr(install_script), file=sys.stderr) print("Warning: Some tests will fail!", file=sys.stderr) cov_file = ".coverage" for cov_file in jp(here, cov_file), jp(top_dir, cov_file): if os.path.exists(cov_file): os.remove(cov_file) print("\nRunning tests") try: if pytest_args or testfile: coverage = False args.extend( pytest_args.split(' ') + list(testfile) if pytest_args else list(testfile)) else: coverage = True args.append('--ff') hudson = os.environ.get('HUDSON_URL') if hudson: print("Disabling parallel run, Hudson can't handle it :(") parallel = test_cfg.skip_job_load( ) or test_cfg.skip_job_delete() and not hudson run_tests(parallel, api_types, args, coverage, mock_speedup) if not testfile and os.environ.get('CI', 'false').lower() != 'true': # This is automatically tested by readdthedocs, so no need to test on Travis start_msg("Testing documentation generation") os.chdir(jp(top_dir, 'doc/source')) del os.environ['PYTHONPATH'] subprocess.check_call(['make', 'html']) except Exception as ex: print('*** ERROR: There were errors! Check output! ***', repr(ex), file=sys.stderr) raise sys.exit(rc)
file=sys.stderr) raise sys.exit(rc) @click.command() @click.option('--mock-speedup', '-s', help="Time speedup when running mocked tests.", default=1000) @click.option( '--direct-url', help= "Direct Jenkins URL. Must be different from the URL set in Jenkins (and preferably non proxied)", default=test_cfg.direct_url(test_cfg.ApiType.JENKINS)) @click.option( '--apis', help= "Select which api(s) to use/test. Comma separated list. Possible values: 'jenkins, 'script', 'mock'. Default is all.", default=None) @click.option('--pytest-args', help="py.test arguments.") @click.option( '--job-delete/--no-job-delete', help="Delete and re-load jobs into Jenkins. Default is --no-job-delete.", default=False) @click.option( '--job-load/--no-job-load', help= "Load jobs into Jenkins (skipping job load assumes all jobs already loaded and up to date). Deafult is --job-load.", default=True)