Esempio n. 1
0
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)
Esempio n. 2
0
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))
Esempio n. 3
0
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
Esempio n. 4
0
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)
Esempio n. 5
0
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>']
Esempio n. 6
0
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)
Esempio n. 7
0
        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
Esempio n. 8
0
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))
Esempio n. 9
0
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)
Esempio n. 10
0
              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)