Exemple #1
0
def parse_mysql_query_generator(config, variable_binds):
    """ Parses configuration options for a mysql_query generator """
    mysql_config = config.get('config')
    sql = config.get('query')
    return_dict_list = config.get('return_dict_list', False)
    mysql_config = templated_var(mysql_config, variable_binds)
    if isinstance(mysql_config, str):
        mysql_config = json.loads(mysql_config)
    sql = templated_var(sql)
    if isinstance(return_dict_list, str):
        return_dict_list = True if return_dict_list.lower(
        ) == 'true' else False
    try:
        with MysqlClient(mysql_config) as cli:
            r = None
            if return_dict_list is False:
                res = cli.query(sql)
                r = list()
                for i in res:
                    if isinstance(i, tuple):
                        i = i[0]
                    r.append(i)
            else:
                r = cli.query(sql, return_dict_list=return_dict_list)
            if len(r) == 0:
                raise Exception(
                    "No data queried in MySQL by '{}'!".format(sql))
            return generators.factory_fixed_sequence(r)()
    except Exception as e:
        logger.error(str(e))
        raise ValueError("Invalid query: " + sql + " : " + str(e))
Exemple #2
0
 def realize(self, context=None):
     if not context:
         context = self.context
     if self.url.startswith('/'):
         self.url = "$default_base_url" + self.url
     self.url = templated_var(self.url, context)
     self.method = templated_var(self.method, context)
     self.body = templated_var(self.body, context)
     self.headers = templated_var(self.headers, context)
def mysql_upsert(config, context=None):
    print("Run mysql_upsert")
    assert isinstance(config, dict)
    assert "config" in config
    assert "sql" in config
    sql = templated_var(config['sql'], context)
    mysql_config = templated_var(config['config'], context)
    mysql_config = json.loads(mysql_config)
    with MysqlClient(mysql_config) as cli:
        cli.execute(sql)
Exemple #4
0
 def extract_internal(self, body=None, headers=None, context=None):
     self.query = templated_var(self.query, context)
     self.mysql_config = templated_var(self.mysql_config, context)
     self.mysql_config = json.loads(self.mysql_config)
     try:
         with MysqlClient(self.mysql_config) as cli:
             res = cli.query(self.query)
             if len(res) == 0:
                 raise Exception("No data queried in MySQL by '{}'!".format(
                     self.query))
             res = res[0]
             if isinstance(res, tuple):
                 res = res[0]
             return res
     except Exception as e:
         raise ValueError("Invalid query: '" + self.query + "' : " + str(e))
Exemple #5
0
def parse_configuration(node, base_config=None):
    """ Parse input config to configuration information """
    test_config = base_config
    if not test_config:
        test_config = TestSetConfig()

    node = lowercase_keys(flatten_dictionaries(node))  # Make it usable

    if "testset" in node:
        test_config.testset_name = node['testset']

    # ahead process variable_binds, other key can use it in template
    if not test_config.variable_binds:
        test_config.variable_binds = dict()

    if 'variable_binds' in node:
        value = node['variable_binds']
        test_config.variable_binds.update(flatten_dictionaries(value))

    # set default_base_url to global variable_binds
    if 'default_base_url' in node:
        value = node['default_base_url']
        default_base_url = templated_var(value, test_config.variable_binds)
        test_config.variable_binds['default_base_url'] = default_base_url

    for key, value in node.items():
        if key == 'timeout':
            test_config.timeout = int(value)
        elif key == 'retries':
            test_config.retries = int(value)
        elif key == 'collect_import_result':
            if isinstance(value, str):
                value = True if value.lower() == 'true' else False
            test_config.collect_import_result = value
        elif key == 'variable_binds':
            pass
        elif key == 'request_client':
            test_config.request_client = str(value)
        elif key == 'generators':
            flat = flatten_dictionaries(value)
            gen_map = dict()
            for generator_name, generator_config in flat.items():
                gen = parse_generator(
                    configuration=generator_config,
                    variable_binds={
                        **test_config.variable_binds,
                        'working_directory': test_config.working_directory
                    })
                gen_map[str(generator_name)] = gen
            test_config.generators = gen_map

    if 'data_driven' in node:
        value = node['data_driven']
        generator_name = value.get('generator', None)
        generator_obj = test_config.generators[generator_name]
        test_config.data_driven_generator = generator_obj
        test_config.data_driven_generator_name = generator_name

    return test_config
Exemple #6
0
def print_operation(config, context=None):
    print("Run print_operation")
    assert isinstance(config, dict)
    assert "print" in config
    pr = config['print']
    pr = templated_var(pr, context)
    print(pr)
    print('')
Exemple #7
0
def sleep_operation(config, context=None):
    print("Run sleep_operation")
    assert isinstance(config, dict)
    assert "seconds" in config
    s = config['seconds']
    s = templated_var(s, context)
    print("Sleep {} s".format(s))
    time.sleep(int(s))
    print()
Exemple #8
0
    def validate(self, body=None, headers=None, context=None):
        try:
            extracted_val = self.extractor.extract(body=body,
                                                   headers=headers,
                                                   context=context)
        except Exception as e:
            trace = traceback.format_exc()
            return Failure(message="Extractor threw exception",
                           details=trace,
                           validator=self,
                           failure_type=FAILURE_EXTRACTOR_EXCEPTION)

        # Compute expected output, either templating or using expected value
        expected_val = None
        if isinstance(self.expected, AbstractExtractor):
            try:
                expected_val = self.expected.extract(body=body,
                                                     headers=headers,
                                                     context=context)
            except Exception as e:
                trace = traceback.format_exc()
                return Failure(
                    message="Expected value extractor threw exception",
                    details=trace,
                    validator=self,
                    failure_type=FAILURE_EXTRACTOR_EXCEPTION)
        elif context:
            expected_val = templated_var(self.expected, context)
        else:
            expected_val = self.expected

        # Handle a bytes-based body and a unicode expected value seamlessly
        if isinstance(extracted_val, bytes) and isinstance(expected_val, str):
            expected_val = expected_val.encode('utf-8')
        comparison = self.comparator(extracted_val, expected_val)

        if not comparison:
            failure = Failure(validator=self)
            failure.message = "Comparison failed, evaluating {0}({1}, {2}) returned False".format(
                self.comparator_name, extracted_val, expected_val)
            failure.details = self.get_readable_config(context=context)
            failure.failure_type = FAILURE_VALIDATOR_FAILED
            return failure
        else:
            return True
Exemple #9
0
 def get_readable_config(self, context=None):
     """ Print a human-readable version of the configuration """
     query = templated_var(data=self.query, context=context)
     output = 'Extractor Type: {0},  Query: "{1}"'.format(
         self.extractor_type, query)
     return output
Exemple #10
0
 def extract(self, body=None, headers=None, context=None):
     """ Extract data """
     self.query = templated_var(data=self.query, context=context)
     return self.extract_internal(body=body,
                                  headers=headers,
                                  context=context)
Exemple #11
0
def run_testset(testset, request_handle=None, test_results=None):
    mytests = testset.tests
    myconfig = testset.config
    context = Context()

    if test_results is None:
        test_results = list()

    # Bind variables & add generators if pertinent
    if myconfig.variable_binds:
        context.bind_variables(myconfig.variable_binds)
    if myconfig.generators:
        for key, value in myconfig.generators.items():
            context.add_generator(key, value)

    # Make sure we actually have tests to execute
    if not mytests:
        # no tests in this test set, probably just imports.. skip to next
        # test set
        return

    def none_generator():
        yield None

    data_driven_generator = None
    if myconfig.data_driven_generator:
        data_driven_generator = myconfig.data_driven_generator
    else:
        data_driven_generator = none_generator()

    for ddt_data in data_driven_generator:
        if ddt_data:
            if not isinstance(ddt_data, dict):
                raise Exception("Data Driven Generator must return a dict, not {}".format(type(ddt_data)))
            logger.info("*************************")
            logger.info("Data Driven: {}".format(ddt_data))
            context.bind_variables(ddt_data)

        # Run tests, collecting statistics as needed
        index = 0
        loop_count = 0

        while index < len(mytests) and loop_count < 100:
            test = mytests[index]
            if hasattr(test.testset_config, "loop_interval"):
                loop_interval = test.testset_config.loop_interval
            else:
                loop_interval = 2

            result = None

            if test.test_type == "operation":
                logger.info("do operation {}, config:{}".format(
                    test.config.get('type'),
                    test.config
                ))
                result = TestResult()
                # result.test_type = "operation"
                result.testset_name = testset.name
                result.test_obj = test
                try:
                    opt_name = test.config.get('type')
                    opt_func = get_operation_function(opt_name)
                    opt_func(test.config, context)
                    result.passed = True
                except Exception as e:
                    result.passed = False
                test_results.append(result)

            elif test.test_type == "testset":
                logger.info("call subtestset {}".format(test.file_path))
                file_path = test.file_path
                input = test.input
                extract = test.extract
                subtestset = testset.subtestsets.get(file_path)
                result = TestResult()
                # result.test_type = "testset"
                result.test_obj = test
                result.testset_name = testset.name
                if subtestset:
                    input = templated_var(input, context)
                    if input:
                        if not subtestset.config.variable_binds:
                            subtestset.config.variable_binds = input
                        else:
                            subtestset.config.variable_binds.update(input)
                    if myconfig.collect_import_result is True:
                        sub_test_results_list = test_results
                    else:
                        sub_test_results_list = None
                    _, extract_data = run_testset(
                        subtestset, request_handle, test_results=sub_test_results_list)
                    if extract_data:
                        context.variables.update(extract_data)
                    result.passed = True
                else:
                    result.passed = False
                test_results.append(result)

            else:
                logger.debug("Run {}".format(test.test_type))
                test.reload()
                result = test.run_test(test_config=myconfig, context=context,
                                       handler=request_handle)

                result.testset_name = testset.name
                result.data_driven_fields = ddt_data
                result.test_obj = test

                if not result.passed:  # Print failure, increase failure counts for that test group
                    error_info = result.to_str(verbose=True)
                    logger.error(error_info)

                    # Print test failure reasons
                    if result.failures:
                        for failure in result.failures:
                            log_failure(failure, context=context,
                                        test_config=myconfig)

                else:  # Test passed, print results
                    logger.info(result.to_str(verbose=False))

                # Add results to the resultset
                if result.loop is False:
                    test_results.append(result)

                # handle stop_on_failure flag
                if not result.passed and test.stop_on_failure is not None and test.stop_on_failure:
                    logger.info(
                        'STOP ON FAILURE! stopping test set execution, continuing with other test sets')
                    break

            if result and result.loop is True:
                loop_count += 1
                time.sleep(loop_interval)
                continue
            else:
                index += 1
                continue

    extract_data = dict()
    if testset.config.extract:
        for key in testset.config.extract:
            if key in context.variables:
                extract_data[key] = context.variables.get(key)
            else:
                raise Exception("Error Extract Var {} in Context".format(key))

    return test_results, extract_data
Exemple #12
0
 def get_body(self, context=None):
     """ Read body from file, applying template if pertinent """
     if self.http_body is None:
         return None
     else:
         return templated_var(self.http_body, context)