Example #1
0
    def stop_testcase(self, status, **kwargs):
        from tiden.tidenfabric import TidenFabric
        result_lines_collector = TidenFabric().getResultLinesCollector()
        test_result_lines = result_lines_collector.get_lines()

        # do not change fail status in iterations
        if self.tests[self.current_test]['status'] == 'fail':
            return

        if self.tests[self.current_test]['status'] != status:
            if self.tests[self.current_test]['status'] != 'running':
                prev_status = self.tests[self.current_test]['status']
                self.tests_num[prev_status] -= 1

            self.tests_num[status] += 1
            self.tests[self.current_test]['status'] = status

        self.tests[self.current_test]['time'] = str(
            exec_time(self.testcase_started, 1))

        if status != 'pass':
            self.tests[self.current_test]['xunit_info'] = {
                'type':
                kwargs.get('e').__class__.__name__,
                'message':
                self.util_filter_escape_seqs('\n'.join(test_result_lines) +
                                             str(kwargs.get('tb')))
            }
        else:
            self.tests[self.current_test]['xunit_info'] = {
                'type':
                None,
                'message':
                None if not test_result_lines else
                self.util_filter_escape_seqs('\n'.join(test_result_lines))
            }

        if kwargs.get('known_issue'):
            self.tests[self.current_test]['known_issue'] = kwargs.get(
                'known_issue')
            if self.tests[self.current_test]['status'] == "pass":
                self.passed_with_issue[self.current_test] = kwargs.get(
                    'known_issue')

            message = self.tests[self.current_test]['xunit_info']['message']
            if message is None:
                message = ''

            if self.tests[self.current_test].get('xunit_info'):
                self.tests[self.current_test]['xunit_info']['message'] = \
                    "*** Known issue: %s\n" % kwargs.get('known_issue') \
                    + message

        if kwargs.get('run_info'):
            self.tests[self.current_test]['run_info'] = kwargs.get('run_info')

        self.update_xunit()
Example #2
0
def test_java_app(with_java_app_classpath, local_config, tmpdir, mock_pm):
    from tiden.result import Result
    from tiden.localpool import LocalPool
    from tiden.tidenfabric import TidenFabric
    from copy import deepcopy
    from datetime import datetime

    var_dir = str(tmpdir.mkdir('var'))
    xunit_file = str(tmpdir.join('var').join('xunit.xml'))
    tmpdir.join('var').join('xunit.xml').write('', ensure=True)
    report_path = 'report.yaml'

    config = deepcopy(local_config)

    config.update({
        'suite_name': 'mock',
        'test_name': '*',
        'suite_dir': join(dirname(__file__), 'res', 'java_app', 'suites'),
        'dir_prefix': f'mock-{datetime.now().strftime("%y%m%d-%H%M%S")}',
    })
    config.update({
        'suite_var_dir': str(tmpdir.join('var').mkdir(config['dir_prefix'])),
        'remote': {
            'artifacts': join(config['environment']['home'], 'artifacts'),
            'suite_var_dir': join(config['environment']['home'], config['dir_prefix']),
        },
        'config_path': str(tmpdir.join('var').join('config.yaml')),
    })
    config.update({
        'artifacts': {
            'mockapp': {
                'type': 'mockapp',
                'path': join(var_dir, 'artifacts', 'mockapp'),
                'remote_path': join(config['remote']['artifacts'], 'mockapp'),
            }
        },
    })

    ssh_pool = LocalPool(local_config['ssh'])
    res = Result(xunit_path=xunit_file)
    modules = {
        'mock.mock_test_app': {
            'path': '%s/mock/mock_test_app.py' % config['suite_dir'],
            'module_short_name': 'mock_test_app',
        },
    }
    from tiden.tidenrunner import TidenRunner
    ssh_pool.connect()
    TidenFabric().setSshPool(ssh_pool)
    TidenFabric().setConfig(config)
    tr = TidenRunner(config, modules=modules, ssh_pool=ssh_pool, plugin_manager=mock_pm, xunit_path=xunit_file)
    tr.process_tests()
    res = tr.get_tests_results()
    res.flush_xunit()
    res.create_testrail_report(config, report_file=str(report_path))
Example #3
0
def test_fabric_not_assigned_option(example_dict_config):
    config = TidenFabric().setConfig(example_dict_config)

    assert 'config' == config.__doc__

    # unknown option with '_enabled' in name should be treated as AttrObj
    option = config.not_set_option_enabled
    assert hasattr(option, '__parent__')
    assert hasattr(option, '__name__')
    assert 'config.not_set_option_enabled' == config.not_set_option_enabled.__name__(
    )
    assert hasattr(option, 'value')
    assert option.value is None

    # negating such AttrObj should return another AttrObj with inverted '__negated__' attribute
    assert not option is None
    assert not ~option is None
    assert (~option).value
    assert hasattr(option, '__negated__')
    assert not option.__negated__
    assert hasattr((~option), '__negated__')
    assert (~option).__negated__

    # other unknown options should be just None
    option1 = config.not_set_option
    assert not hasattr(option1, '__parent__')
    assert not hasattr(option1, '__name__')
    assert option1 is None
Example #4
0
    def start_testcase(self, tested_class, tested_attr):
        from tiden.tidenfabric import TidenFabric
        result_lines_collector = TidenFabric().getResultLinesCollector()
        result_lines_collector.reset()
        self.testcase_started = time()
        self.tested_class = tested_class
        self.tested_attr = tested_attr
        tested_attr_name = tested_attr.split(
            '(')[0] if '(' in tested_attr else tested_attr
        self.current_test = "{}.{}.{}".format(tested_class.__module__,
                                              tested_class.__class__.__name__,
                                              tested_attr)
        test_case_id = None

        if hasattr(getattr(tested_class.__class__, tested_attr_name),
                   "__test_id__"):
            test_ids = (getattr(
                getattr(tested_class.__class__, tested_attr_name),
                "__test_id__"))
            test_case_id = int(test_ids[0])
            if test_case_id == 0:
                test_case_id = None

        if self.tests.get(self.current_test):
            self.tests[self.current_test].update({
                "started": time(),
            })
        else:
            self.tests_num['total'] += 1
            self.tests[self.current_test] = {
                'status':
                'running',
                'classname':
                "%s.%s" %
                (tested_class.__module__, tested_class.__class__.__name__),
                'name':
                str(tested_attr),
                'time':
                str(0),
                'started':
                time()
            }
            if test_case_id:
                self.tests[self.current_test].update({
                    'test_case_id':
                    test_case_id,
                })
Example #5
0
def log_put(msg, level=3, **kwargs):
    line_nums = __is_called_from_line()
    prefix_str = ''
    if len(line_nums) > 0:
        line_num = "[%s]" % ' '.join(line_nums)
        prefix_str = '[%s]%s ' % (
            datetime.now().isoformat()[11:-7],
            line_num
        )
    stdout.write('\r%s%s' % (prefix_str, msg))
    stdout.flush()
    logger = get_logger('tiden')
    logger.info(msg)
    if kwargs.get('report'):
        from tiden.tidenfabric import TidenFabric
        result_lines_collector = TidenFabric().getResultLinesCollector()
        result_lines_collector.add_line(msg)
Example #6
0
def init_ssh_pool(config):
    log_print("*** Create SSH Pool ***", color='blue')
    # Collect unique hosts
    hosts = []
    for name, data in config['environment'].items():
        if name.endswith(
                '_hosts'
        ) and not name == 'apps_use_global_hosts' and data is not None:
            hosts.extend(data)
    for name, data in config['environment'].items():
        if isinstance(data, dict):
            for inner_name, inner_data in data.items():
                if inner_name.endswith('_hosts'):
                    hosts.extend(inner_data)

    hosts = set(hosts)
    config['ssh']['hosts'] = list(hosts)
    # Calculate threads number
    config['ssh']['threads_num'] = floor(sqrt(len(hosts)))
    if config['ssh']['threads_num'] < cpu_count():
        config['ssh']['threads_num'] = cpu_count()

    if config['environment'].get('env_vars'):
        config['ssh']['env_vars'] = config['environment']['env_vars']
    write_yaml_file(config['config_path'], config)

    # Make SSH connection pool
    ssh_pool = None
    if 'ansible' == config['connection_mode']:
        try:
            from tiden.ansiblepool import AnsiblePool
            ssh_pool = AnsiblePool(config['ssh'])
        except ImportError as e:
            log_put('ERROR: unable to import AnsiblePool: %s' % e)
            exit(1)
    elif 'paramiko' == config['connection_mode']:
        ssh_pool = SshPool(config['ssh'])
    elif 'local' == config['connection_mode']:
        config['ignite']['bind_to_host'] = True
        config['ignite']['unique_node_ports'] = True
        try:
            from tiden.localpool import LocalPool
            ssh_pool = LocalPool(config['ssh'])
        except ImportError as e:
            log_put('ERROR: unable to import LocalPool: %s' % e)
            exit(1)
        except NotImplementedError as e:
            log_put('ERROR: %s' % e)
            exit(1)
    else:
        log_put("ERROR: Unknown 'connection_mode' %s" %
                config['connection_mode'])
        exit(1)

    if ssh_pool:
        TidenFabric().setSshPool(ssh_pool)
        ssh_pool.connect()
    return ssh_pool
Example #7
0
def log_print(msg=None, level=3, **kwargs):
    if msg is None:
        msg = ''
    fmt_str = '{}{}'
    colors = {'green': f'\033[32m{fmt_str}\033[0m',
              'red': f'\033[91m{fmt_str}\033[0m',
              'blue': f'\033[94m{fmt_str}\033[0m',
              'yellow': f'\033[93m{fmt_str}\033[0m',
              'pink': f'\033[95m{fmt_str}\033[0m',
              'bold': f'\033[1m{fmt_str}\033[0m',
              'debug': f'\033[35m{fmt_str}\033[0m'}

    prefix_str = ''
    if msg != '':
        line_nums = __is_called_from_line()
        if len(line_nums) > 0:
            line_num = "[{}]".format(' '.join(line_nums))
            prefix_str = '[{}]{} '.format(
                datetime.now().isoformat()[11:-7],
                line_num
            )
    if kwargs.get('color'):
        fmt_str = colors.get(kwargs.get('color'), fmt_str)
    if msg is not None:
        print(fmt_str.format(prefix_str, msg))
        logger = get_logger('tiden')
        logger.info(msg)
    else:
        # stdout.write('\n')
        # stdout.flush()
        logger = get_logger('tiden')
        logger.info('', skip_prefix=True)
    if kwargs.get('report'):
        from tiden.tidenfabric import TidenFabric
        result_lines_collector = TidenFabric().getResultLinesCollector()
        result_lines_collector.add_line(msg)
Example #8
0
def test_fabric_simple(example_dict_config):
    config = TidenFabric().setConfig(example_dict_config)

    assert 'config' == config.__doc__

    assert config.ignite
    assert "ignite" == config.ignite.__doc__
    assert config == config.ignite.__parent__

    # assert config.ignite == config.ignite.pitr_enabled.__parent__ # this is not true anymore
    assert config.ignite.pitr_enabled, "pitr_enabled should be True"
    assert "pitr_enabled" == config.ignite.pitr_enabled.__doc__

    assert 'config.ignite.pitr_enabled' == config.ignite.pitr_enabled.__name__(
    )
    assert not config.ignite.baseline_enabled, "baseline_enabled should be False"
    assert not config.unknown_option_enabled, "unknown_option_enabled should be equal to False"
Example #9
0
def test_tiden_hook():
    hook_mgr = TidenFabric().get_hook_mgr()
    plugins_path = hook_mgr.hook.tiden_get_plugins_path()
    assert type(plugins_path) == list
    assert len(plugins_path) == 1
    assert type(plugins_path[0]) == list
    assert len(plugins_path[0]) == 2
    assert plugins_path[0][0] == join(dirname(dirname(abspath(__file__))), 'src', 'tiden', 'plugins')
    assert plugins_path[0][1] == join(getcwd(), 'plugins')
    pm = PluginManager({})
    assert pm.plugins_paths == plugins_path[0]
    assert pm.plugins == {}
    pm = PluginManager({
        'plugins': {
            'DockerCleaner': {}
        }
    })
    assert 'DockerCleaner' in pm.plugins
    plugin = pm.plugins['DockerCleaner']
    assert plugin['file'] == join(dirname(dirname(abspath(__file__))), 'src', 'tiden', 'plugins', 'dockercleaner.py')
    assert plugin['class'] == 'DockerCleaner'
    assert plugin['TIDEN_PLUGIN_VERSION'] == '1.0.0'
    assert isinstance(plugin['instance'], TidenPlugin)
Example #10
0
def test_fabric_update_dict_after_create(example_dict_config, clean_fabric):
    c = example_dict_config.copy()
    d = {'aa': 1}
    b = d
    d['bb'] = 2
    assert 2 == b['bb']

    class FFF:
        def __init__(self, o):
            self.q = o

    f = FFF(d)
    d['zz'] = 3
    assert 3 == f.q['zz']

    config = TidenFabric().getConfig(c)
    c['simple'] = 42
    c['artifacts'] = {
        'test_artifact': {
            'version': '1.0.0',
        }
    }
    assert 42 == config.simple
    assert '1.0.0' == config.artifacts.test_artifact.version
Example #11
0
 def _create_shared_file(self):
     nas_manager = TidenFabric().getNasManager()
     self.shared_file_path = nas_manager.touch_file(self.shared_file_name)
Example #12
0
def main():
    """
    Run Tiden tests
    """
    log_print("*** Initialization ***", color='blue')
    log_print('(c) 2017-{} GridGain Systems. All Rights Reserved'.format(
        max(datetime.now().year, 2019)))
    log_print(version)
    exit_code = None

    # parse arguments,
    # load configuration,
    # initialize working directories
    config = TidenFabric().setConfig(setup_test_environment(
        process_args())).obj
    log_print('The configuration stored in %s' % config['config_path'])

    logger = _get_default_logger(config)
    sys.path.insert(0, abspath(getcwd()))

    pm = PluginManager(config)

    # prepare artifacts, artifact information is updated into config
    # this must be done before tests collections,
    # because some tests are applicable for specific artifacts only
    log_print('*** Prepare artifacts ***', color='blue')
    pm.do('before_prepare_artifacts', config)
    remote_unzip_files, config = prepare(config)

    if collect_only:
        # we don't run any test, so no ssh pool nor plugin manager required
        ssh_pool = None
        pm = None
    else:
        # otherwise, create ssh pool,
        # and prepare plugins to use it
        ssh_pool = init_ssh_pool(config)
        if pm.plugins:
            log_print('*** Plugins ***', color='blue')
            for name, plugin in pm.plugins.items():
                log_print("%s, version %s" %
                          (name, plugin['TIDEN_PLUGIN_VERSION']))
            pm.set(ssh=ssh_pool)

    # initialize tests runner
    log_print('*** Runner ***', color='blue')
    tr = TidenRunner(config,
                     collect_only=collect_only,
                     ssh_pool=ssh_pool,
                     plugin_manager=pm)
    if len(tr.modules.keys()) == 0:
        log_print("Error: no test modules found")
        exit(1)
    log_print(
        "%s module(s) matched %s.%s" %
        (len(tr.modules.keys()), config['suite_name'], config['test_name']))

    if collect_only:
        tr.collect_tests()
    else:
        pm.do('before_hosts_setup')
        init_remote_hosts(ssh_pool, config)

        pm.do('after_hosts_setup')
        upload_artifacts(ssh_pool, config, remote_unzip_files)

        if pm.do_check('before_tests_run'):
            tr.process_tests()
        else:
            exit_code = -1
        pm.do('after_tests_run')

    result = tr.get_tests_results()
    result.flush_xunit()
    result.print_summary()
    result.create_testrail_report(config,
                                  report_file=config.get('testrail_report'))

    print_blue("Execution time %d:%02d:%02d " %
               hms(int(time()) - result.get_started()))

    if exit_code:
        exit(exit_code)
Example #13
0
def clean_fabric():
    TidenFabric().reset()
Example #14
0
def set_configuration_options(cfg_options, config, configuration):
    from tiden.tidenfabric import TidenFabric
    for i, cfg_option in enumerate(cfg_options):
        config[cfg_option] = configuration[i]
    TidenFabric().setConfig(config)
Example #15
0
def test_runner_skipped_configurations(with_dec_classpath, local_config, tmpdir, mock_pm):
    """
    Test configurations correctly passed to TestRail report for skipped tests
    :return:
    """
    var_dir = _ensure_var_dir(tmpdir)
    xunit_file = _ensure_xunit_file_empty(var_dir)
    testrail_report_file = _ensure_tr_report_file_empty(var_dir)

    suite_var_dir = str(var_dir.mkdir('suite-mock'))
    config_path = str(var_dir.join('config.yaml'))
    source = 'mock_test_module_with_test_configuration'
    suite = 'mock'
    module_name = 'suites.%s.%s.MockTestModuleWithTestConfiguration' % (suite, source)
    test_prefix = module_name + '.'

    config = deepcopy(local_config)

    config.update({
        'artifacts': {},
        # 'attrib': 'test_runner',
        # 'attr_match': 'any',
        'suite_var_dir': suite_var_dir,
        'suite_dir': join(dirname(__file__), 'res', 'decorators', 'suites'),
        'remote': {
            'suite_var_dir': suite_var_dir,
        },
        'config_path': config_path,
        'zookeeper_enabled': False,
        'pitr_enabled': False,
        'compaction_enabled': True,
    })

    ssh_pool = LocalPool(local_config['ssh'])
    test_module_source_file_name = '%s/%s/%s.py' % (config['suite_dir'], suite, source)

    modules = {
        '%s.%s' % (suite, source): {
            'path': test_module_source_file_name,
            'module_short_name': source,
        }
    }
    test_configuration = '(pitr_enabled=false, compaction_enabled=true, zookeeper_enabled=false)'
    expected_configuration_options = ['pitr_enabled', 'compaction_enabled', 'zookeeper_enabled']
    expected_result = {
        'test_main':
            {'status': 'pass', 'type': None, 'message': None},
        'test_zookeeper_only':
            {'status': 'skipped', 'type': 'skipped cause of config.zookeeper_enabled is False', 'message': None},
    }

    expected_statuses_count = {'pass': 1,
                               'fail': 0,
                               'error': 0,
                               'skip': 1,
                               'total': len(expected_result)}

    from tiden.tidenfabric import TidenFabric
    TidenFabric().reset().setConfig(config)
    tr = TidenRunner(config, modules=modules, ssh_pool=ssh_pool, plugin_manager=mock_pm, xunit_path=xunit_file)
    tr.process_tests()
    res = tr.get_tests_results()
    res.create_testrail_report(config, report_file=basename(testrail_report_file))
    _tests = res.get_tests()
    print(_tests)

    # validate raw test results
    assert len(_tests) == len(expected_result)

    for test_to_check in expected_result.keys():
        status, error_type, message, test_name = res.get_test_details('{}{}{}'.format(test_prefix, test_to_check, test_configuration))
        assert expected_result[test_to_check].get('status') == status
        assert expected_result[test_to_check].get('type') == error_type
        if expected_result[test_to_check].get('message') is None:
            assert message is None
        else:
            assert expected_result[test_to_check].get('message') == message \
                   or expected_result[test_to_check].get('message') in message

    for status, count in expected_statuses_count.items():
        assert res.get_tests_num(status) == count

    # validate generated TestRail .yaml report
    tr_report = read_yaml_file(testrail_report_file)
    assert type({}) == type(tr_report)
    assert len(_tests) == len(tr_report)
    for test_run, test in tr_report.items():
        assert 'suite_run_id' in test
        assert 'test_run_id' in test
        assert test_run == test['test_run_id']
        assert 'module' in test
        assert test['module'] == module_name
        assert 'test_configuration_options' in test
        assert expected_configuration_options == test['test_configuration_options']
        assert 'function' in test
        assert test['function'] in expected_result.keys()
        expected_test_result = expected_result[test['function']]
        expected_status = res.util_status_to_testrail_status(expected_test_result['status'])
        assert 'last_status' in test
        assert expected_status == test['last_status']

        # a test message will be either in 'message' or 'type' if 'message' is None
        assert 'asserts' in test
        assert type([]) == type(test['asserts'])

        # currently Tiden generates only one assert per test
        assert len(test['asserts']) == 1
        assert type({}) == type(test['asserts'][0])
        assert 'status' in test['asserts'][0]
        assert expected_status == test['asserts'][0]['status']

        expected_assert_message = expected_test_result['message'] if expected_test_result['message'] is not None else \
        expected_test_result['type']
        if expected_assert_message is not None:
            assert res.util_filter_escape_seqs(expected_assert_message) in test['asserts'][0]['message']

    # check all test run id's are unique
    test_run_ids = [test['test_run_id'] for test in tr_report.values()]
    assert len(test_run_ids) == len(set(test_run_ids))

    # check all suite run id is the same
    suite_run_ids = set([test['suite_run_id'] for test in tr_report.values()])
    assert 1 == len(suite_run_ids)
Example #16
0
def test_runner_collect(with_dec_classpath, local_config, tmpdir, mock_pm):
    var_dir = _ensure_var_dir(tmpdir)
    xunit_file_collect = _ensure_xunit_file_empty(var_dir, '-collect')
    xunit_file_process = _ensure_xunit_file_empty(var_dir, '-process')
    testrail_report_file_collect = _ensure_tr_report_file_empty(var_dir, '-collect')
    testrail_report_file_process = _ensure_tr_report_file_empty(var_dir, '-process')

    suite_var_dir = str(var_dir.mkdir('suite-mock'))
    config_path = str(var_dir.join('config.yaml'))

    source = 'mock_test_module_with_test_configuration'
    suite = 'mock'
    module_name = 'suites.%s.%s.MockTestModuleWithTestConfiguration' % (suite, source)
    test_prefix = module_name + '.'

    config = deepcopy(local_config)

    config.update({
        'artifacts': {},
        'suite_var_dir': suite_var_dir,
        'suite_dir': join(dirname(__file__), 'res', 'decorators', 'suites'),
        'remote': {
            'suite_var_dir': suite_var_dir,
        },
        'config_path': config_path,
        'zookeeper_enabled': False,
        'pitr_enabled': False,
        'compaction_enabled': True,
    })

    ssh_pool = LocalPool(local_config['ssh'])
    test_module_source_file_name = '%s/%s/%s.py' % (config['suite_dir'], suite, source)

    modules = {
        '%s.%s' % (suite, source): {
            'path': test_module_source_file_name,
            'module_short_name': source,
        }
    }
    test_configuration = '(pitr_enabled=false, compaction_enabled=true, zookeeper_enabled=false)'
    expected_configuration_options = ['pitr_enabled', 'compaction_enabled', 'zookeeper_enabled']
    expected_result = {
        'test_main':
            {'status': 'pass', 'type': None, 'message': None},
        'test_zookeeper_only':
            {'status': 'skipped', 'type': 'skipped cause of config.zookeeper_enabled is None', 'message': None},
    }

    from tiden.tidenfabric import TidenFabric
    TidenFabric().reset().setConfig(config)

    tr = TidenRunner(config, modules=modules, ssh_pool=ssh_pool, plugin_manager=mock_pm, xunit_path=xunit_file_collect)
    tr.collect_tests()
    res = tr.get_tests_results()
    res.update_xunit()
    res.create_testrail_report(config, report_file=basename(testrail_report_file_collect))
    _tests = res.get_tests()
    assert 12 == len(_tests)
    print(_tests)

    TidenFabric().reset().setConfig(config)
    tr = TidenRunner(config, modules=modules, ssh_pool=ssh_pool, plugin_manager=mock_pm, xunit_path=xunit_file_process)
    tr.process_tests()
    res = tr.get_tests_results()
    res.create_testrail_report(config, report_file=basename(testrail_report_file_process))
    _tests = res.get_tests()
    assert 2 == len(_tests)
    print(_tests)
Example #17
0
 def _delete_shared_file(self):
     nas_manager = TidenFabric().getNasManager()
     nas_manager.delete_file(self.shared_file_name)
Example #18
0
 def _check_nas_manager_configured(self):
     nas_manager = TidenFabric().getNasManager()
     return nas_manager.is_configured()