def generate_transaction_and_attach(step, node):
    """
    Creates a zero value transaction with the specified arguments.

    :param node: The node that the transaction will be generated on.
    :param step.hashes: A gherkin table present in the feature file specifying the
                        arguments and the associated type.
    """
    arg_list = step.hashes
    world.config['nodeId'] = node
    world.config['apiCall'] = 'attachToTangle'

    options = {}
    api = api_utils.prepare_api_call(node)
    api_utils.prepare_options(arg_list, options)

    transaction_args = {}
    for key in options:
        transaction_args[key] = options.get(key)
    api_utils.prepare_transaction_arguments(transaction_args)

    transaction = transactions.create_and_attach_transaction(
        api, transaction_args)
    api.broadcast_and_store(transaction.get('trytes'))

    assert len(
        transaction['trytes']) > 0, "Transaction was not created correctly"

    world.responses['attachToTangle'] = {}
    world.responses['attachToTangle'][node] = transaction
    logger.info('Transaction Sent')

    setattr(static, "TEST_STORE_TRANSACTION", transaction.get('trytes'))
def compare_thread_return(step, api_call):
    """
    Compares the response of a particular asynchronous API call with the expected list of response keys.

    :param api_call: The API call that you would like to check the response of
    :param step.hashes: A gherkin table outlining any arguments that are expected to be in the response
    """

    # Prepare response list for comparison
    response_list = world.responses[api_call][world.config['nodeId']]
    # Exclude duration from response list
    if 'duration' in response_list:
        del response_list['duration']
    response_keys = response_list.keys()

    # Prepare expected values list for comparison
    expected_values = {}
    args = step.hashes
    api_utils.prepare_options(args,expected_values)
    keys = expected_values.keys()

    # Confirm that the lists are of equal length before comparing
    assert len(keys) == len(response_keys), "Response: {} does not contain""\
                                            ""the same number of arguments: {}".format(keys,response_keys)

    for count in range(len(keys)):
        response_key = response_keys[count]
        response_value = response_list[response_key]
        expected_value = expected_values[response_key]

        assert response_value == expected_value, "Returned: {} does not match the expected"" \
        ""value: {}".format(response_value, expected_value)

    logger.info('Responses match')
def compare_thread_return(step, api_call):
    """
    Prepare response list for comparison.

    :param api_call: The API call you would like to find a response for
    :param step.hashes: A gherkin table present in the feature file specifying the
                        values and the associated type to be found in the response.
    """
    logger.debug(world.responses)
    future_results = world.config['future_results'][api_call]

    for result in future_results:
        response_list = pool.fetch_results(result, 5)
        # Exclude duration from response list
        if 'duration' in response_list:
            del response_list['duration']
        if 'info' in response_list:
            del response_list['info']
        response_keys = response_list.keys()

        expected_values = {}
        api_utils.prepare_options(step.hashes, expected_values)
        keys = expected_values.keys()

        # Confirm that the lists are of equal length before comparing
        assert len(keys) == len(response_keys), \
            'Response: {} does not contain the same number of arguments: {}'.format(keys, response_keys)

        for count in range(len(keys)):
            response_key = response_keys[count]
            response_value = response_list[response_key]
            expected_value = expected_values[response_key]
            assert response_value == expected_value, \
                'Returned: {} does not match the expected value: {}'.format(response_value, expected_value)
Пример #4
0
def threaded_call(step, apiCall, node):
    logger.info("Creating thread for {}".format(apiCall))
    world.config['apiCall'] = apiCall
    world.config['nodeId'] = node
    arg_list = step.hashes

    options = {}
    api_utils.prepare_options(arg_list, options)
    api = api_utils.prepare_api_call(node)

    def make_call(node, arg_list):
        response = api_utils.fetch_call(apiCall, arg_list['api'],
                                        arg_list['options'])
        arg_list['responses'][apiCall] = {}
        arg_list['responses'][apiCall][node] = response
        return response

    args = {
        node: {
            'api': api,
            'options': options,
            'responses': world.responses
        }
    }
    future_results = pool.start_pool(make_call, 1, args)

    if 'future_results' not in world.config:
        world.config['future_results'] = {}
    world.config['future_results'][apiCall] = future_results
Пример #5
0
def generate_transaction_and_attach(step, node):
    arg_list = step.hashes
    world.config['nodeId'] = node
    world.config['apiCall'] = 'attachToTangle'
    options = {}
    api = api_utils.prepare_api_call(node)

    api_utils.prepare_options(arg_list, options)
    addresses = options.get('address')
    value = options.get('value')

    transaction = ProposedTransaction(address=Address(addresses[0]),
                                      value=value)

    bundle = ProposedBundle()
    bundle.add_transaction(transaction)
    bundle.finalize()
    trytes = str(bundle[0].as_tryte_string())

    gtta = api.get_transactions_to_approve(depth=3)
    branch = str(gtta['branchTransaction'])
    trunk = str(gtta['trunkTransaction'])

    sent = api.attach_to_tangle(trunk, branch, [trytes], 9)
    world.responses['attachToTangle'] = {}
    world.responses['attachToTangle'][node] = sent
    logger.info('Transaction Sent')

    setattr(static_vals, "TEST_STORE_TRANSACTION", sent.get('trytes'))
Пример #6
0
def compare_thread_return(step, apiCall):
    """Prepare response list for comparison"""
    logger.debug(world.responses)
    future_results = world.config['future_results'][apiCall]

    for result in future_results:
        response_list = pool.fetch_results(result, 1)
        # Exclude duration from response list
        if 'duration' in response_list:
            del response_list['duration']
        response_keys = response_list.keys()

        expected_values = {}
        api_utils.prepare_options(step.hashes, expected_values)
        keys = expected_values.keys()

        # Confirm that the lists are of equal length before comparing
        assert len(keys) == len(
            response_keys
        ), 'Response: {} does not contain the same number of arguments: {}'.format(
            keys, response_keys)

        for count in range(len(keys)):
            response_key = response_keys[count]
            response_value = response_list[response_key]
            expected_value = expected_values[response_key]
            assert response_value == expected_value, \
                'Returned: {} does not match the expected value: {}'.format(response_value,expected_value)

    logger.info('Responses match')
Пример #7
0
def check_response_for_value(step, api_call):
    """
    Compares the response of a particular API call with the expected list of response keys.

    :param api_call: The API call that you would like to check the response of
    :param step.hashes: A gherkin table outlining any arguments that are expected to be in the response
    """
    response_values = world.responses[api_call][world.config['nodeId']]
    expected_values = {}
    args = step.hashes
    api_utils.prepare_options(args, expected_values)

    for expected_value_key in expected_values:
        if expected_value_key in response_values:
            expected_value = expected_values[expected_value_key]
            response_value = response_values[expected_value_key]

            if isinstance(
                    response_value, list
            ) and api_call != 'getTrytes' and api_call != 'getInclusionStates':
                response_value = response_value[0]

            assert expected_value == response_value, "The expected value {} does not match" "\
                                                     " "the response value: {}".format(
                expected_value, response_value)
    logger.info('Response contained expected values')
Пример #8
0
def check_response_for_value(step, apiCall):
    response_values = world.responses[apiCall][world.config['nodeId']]
    expected_values = {}
    args = step.hashes
    api_utils.prepare_options(args, expected_values)

    for expected_value_key in expected_values:
        if expected_value_key in response_values:
            expected_value = expected_values[expected_value_key]
            response_value = response_values[expected_value_key]
            if type(response_value) is list:
                response_value = response_value[0]
            assert expected_value == response_value, \
                "The expected value {} does not match the response value: {}".format(expected_value,response_value)

    logger.info('Response contained expected values')
Пример #9
0
def spam_call(step, api_call, num_tests, node):
    """
    Spams an API call a number of times among the specified nodes in a cluster

    :param api_call: The API call you would like to make
    :param num_tests: The number of iterations you would like to run
    :param node: The node that the call will be sent to. This can be set to 'all nodes' and it will run the test
                 on all the available nodes.
    :param step.hashes: A gherkin table present in the feature file specifying the
                        arguments and the associated type.
    """
    start = time()
    world.config['apiCall'] = api_call
    arg_list = step.hashes
    nodes = {}
    response_val = []

    options = {}
    api_utils.prepare_options(arg_list, options)

    # See if call will be made on one node or all
    api_utils.assign_nodes(node, nodes)
    call_node = world.config['nodeId']

    def run_call(node, args):
        logger.debug('Running Thread on {}'.format(node))
        api = args['api']
        options = args['options']
        response = api_utils.fetch_call(api_call, api, options)
        return response

    for current_node in nodes:
        nodes[current_node]['options'] = options

    future_results = pool.start_pool(run_call, num_tests, nodes)

    responses.fetch_future_results(future_results, num_tests, response_val)

    world.responses[api_call] = {}
    world.responses[api_call][call_node] = response_val

    end = time()
    time_spent = end - start
    logger.info('Time spent on loop: {}'.format(time_spent))
Пример #10
0
def api_method_is_called(step, apiCall, nodeName):
    """
    This is the general api calling function. There are 3 inputs

    :param apiCAll:     The api call that will be requested
    :param nodeName:    The name identifying the node you would like to make this request on
    :param table:       A gherkin table outlining any arguments needed for the call
                        (See tests/features/machine1/1_api+tests.feature for examples)

        The table parameter is unique in that there are several input types available depending on the call
        being made.
            :type string: Basic string argument, will be taken as is
            :type int: Basic integer argument, will be converted to int before call is made
            :type nodeAddress: Node name identifier, will create address from node configuration
            :type staticValue: Static name identifier, will fetch value from util/static_vals.py
            :type staticList: Same as staticValue, except it places the results into a list
            :type responseValue: Identifier for api call response value
            :type responseList: Same as responseValue, ecept it places the results into a list
            :type bool: Bool argument, returns True or False

    """
    logger.info('%s is called on %s', apiCall, nodeName)
    world.config['apiCall'] = apiCall
    world.config['nodeId'] = nodeName
    arg_list = step.hashes

    options = {}
    api_utils.prepare_options(arg_list, options)

    api = api_utils.prepare_api_call(nodeName)
    response = api_utils.fetch_call(apiCall, api, options)

    assert type(
        response
    ) is dict, 'There may be something wrong with the response format: {}'.format(
        response)

    world.responses[apiCall] = {}
    world.responses[apiCall][nodeName] = response
def threaded_call(step, api_call, node):
    """
    Makes an asynchronous API call on the specified node and stores the future result reference in the
    world.config variable.

    :param api_call: The API call you would like to make.
    :param node: The identifier for the node you would like to run the call on.
    :param step.hashes: A gherkin table present in the feature file specifying the
                        arguments and the associated type.
    """
    logger.info("Creating thread for {}".format(api_call))
    world.config['apiCall'] = api_call
    world.config['nodeId'] = node
    arg_list = step.hashes

    options = {}
    api_utils.prepare_options(arg_list, options)
    api = api_utils.prepare_api_call(node)

    def make_call(node, arg_list):
        response = api_utils.fetch_call(api_call, arg_list['api'],
                                        arg_list['options'])
        arg_list['responses'][api_call] = {}
        arg_list['responses'][api_call][node] = response
        return response

    args = {
        node: {
            'api': api,
            'options': options,
            'responses': world.responses
        }
    }
    future_results = pool.start_pool(make_call, 1, args)

    if 'future_results' not in world.config:
        world.config['future_results'] = {}
    world.config['future_results'][api_call] = future_results
Пример #12
0
def read_ls_metadata(step, node):
    """
    Uses an ixi module to check the current snapshot state of the node. It cycles through a provided list of addresses
    to make sure the snapshot state contains them.

    :param step.hashes: A pointer to the list of milestone hashes that should be present in the snapshot metadata
    :param node: The node that the IXI request will be made on
    """
    arg_list = step.hashes

    options = {}
    api_utils.prepare_options(arg_list, options)

    command = {"command": "LocalSnapshots.getMetaData"}
    request_return = api_utils.send_ixi_request(node, command)
    assert 'ixi' in request_return, "Error: {}".format(request_return['error'])
    node_metadata = request_return['ixi']['metaData']
    hashes = options['hashes']

    for hash_val in hashes:
        assert hash_val in node_metadata, "Provided hash: {} was not found in the snapshot metadata".format(
            hash_val)
    logger.info("Snapshot Metadata contains the provided hashes.")
Пример #13
0
def read_ls_state(step, node):
    """
    Uses an ixi module to check the current snapshot state of the node. It cycles through a provided list of addresses
    to make sure the snapshot state contains them.

    :param step.hashes: A pointer to the list of addresses that should be present in the snapshot state
    :param node: The node that the IXI request will be made on
    """
    arg_list = step.hashes

    options = {}
    api_utils.prepare_options(arg_list, options)

    command = {"command": "LocalSnapshots.getState"}
    request_return = api_utils.send_ixi_request(node, command)
    assert 'ixi' in request_return, "Error: {}".format(request_return['error'])
    node_state = request_return['ixi']['state']
    addresses_with_value = options['address']

    for address in addresses_with_value:
        assert address in node_state, "Provided address: {} was not found in the snapshot state".format(
            address)
    logger.info("Snapshot State contains the provided addresses.")
Пример #14
0
def fetch_transaction_from_list(args, node):
    """
    Fetches a reference transaction from either a static value list in the ../staticValues.py file, or from the response
    for a previous "findTransactions" call.

    :param args: The step argument list
    :param node: The current working node
    :return: The transaction to be used as a reference
    """

    options = {}
    api_utils.prepare_options(args, options)

    if args[0]['type'] == 'responseValue':
        transaction_list = value_fetch.fetch_response(args[0]['values'])
        reference_transaction = transaction_list[node][len(transaction_list) -
                                                       1]
    elif args[0]['type'] == 'staticValue':
        transaction_list = options['transactions']
        reference_transaction = transaction_list[len(transaction_list) - 1]

    assert reference_transaction, "No reference transaction found (Possibly incorrect argument type, check gherkin file"

    return reference_transaction
Пример #15
0
def evaluate_and_send(api, seed, arg_list):
    """
    Prepares a transaction for sending. If the provided seed isn't empty, it changes the bool value to be passed on to
    to the create_and_attach_transaction() function to instruct it to look for an available balance.

    :param api: The api target you would like to make the call to
    :param seed: The seed associated with the given api (This can be an empty string if none is used)
    :param arg_list: The argument list (dictionary) for the transaction
    :return: The transaction object created in the create_and_attach_transaction() function
    """
    is_value_transaction = False

    if seed != "":
        is_value_transaction = True

    options = {}
    api_utils.prepare_options(arg_list, options)
    api_utils.prepare_transaction_arguments(options)

    transaction = create_and_attach_transaction(api, is_value_transaction,
                                                options)
    api.broadcast_and_store(transaction.get('trytes'))

    return transaction