forked from iotaledger/iri
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresponse_handling_steps.py
217 lines (171 loc) · 9.41 KB
/
response_handling_steps.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
from aloe import world, step
from util.response_logic import response_handling as response_handling
from util.test_logic import api_test_logic as api_utils
from util.test_logic import value_fetch_logic
from util import logger as log
logger = log.getLogger(__name__)
world.test_vars = {}
@step(r'the "([^"]*)" parallel call should return with:')
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']
if 'info' in response_list:
del response_list['info']
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')
@step(r'a response for "([^"]*)" should exist')
def response_exists(step,apiCall):
"""
Determines if a response for a given API call exists in the world environment. If it doesn't, that means that the
call was not completed correctly, and contains no data to be extracted.
:param apiCall: The API call you would like to see exists.
"""
response = world.responses[apiCall][world.config['nodeId']]
empty_values = {}
for key in response:
if key != 'duration':
is_empty = api_utils.check_if_empty(response[key])
if is_empty:
empty_values[key] = response[key]
assert len(empty_values) == 0, "There was an empty value in the response {}".format(empty_values)
@step(r'the response for "([^"]*)" should return with:')
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')
@step(r'the response for "([^"]*)" should return null')
def check_if_null(step, api_call):
response = world.responses[api_call][world.config['nodeId']]
assert response is None, "Response is not null"
@step(r'a response with the following is returned:')
def compare_response(step):
"""
Checks the response value for the latest API call and compares it with a given set of expected keys
:param step.hashes: The list of keys expected to be found in the response
"""
logger.info('Validating response')
keys = step.hashes
node_id = world.config['nodeId']
api_call = world.config['apiCall']
response = world.responses[api_call][node_id]
key_list = []
for key in keys:
key_list.append(key['keys'])
for key in key_list:
response_handling.find_in_response(key, response)
@step(r'the returned GTTA transactions will be compared with the milestones')
def compare_gtta_with_milestones(step):
"""Compares the getTransactionsToApprove response values with the collected milestone issuing address"""
logger.info("Compare GTTA response with milestones")
gtta_responses = value_fetch_logic.fetch_response('getTransactionsToApprove')
find_transactions_responses = value_fetch_logic.fetch_response('findTransactions')
node = world.config['nodeId']
milestones = list(find_transactions_responses[node]['hashes'])
world.config['max'] = len(gtta_responses[node])
transactions = []
transactions_count = []
milestone_transactions = []
milestone_transactions_count = []
world.test_vars['milestone_count'] = 0
for node in gtta_responses:
if isinstance(gtta_responses[node], list):
for response in gtta_responses[node]:
branch_transaction = response['branchTransaction']
trunk_transaction = response['trunkTransaction']
compare_responses(branch_transaction, milestones, transactions, transactions_count,
milestone_transactions, milestone_transactions_count)
compare_responses(trunk_transaction, milestones, transactions, transactions_count,
milestone_transactions, milestone_transactions_count)
logger.info("Milestone count: " + str(world.test_vars['milestone_count']))
f = open('blowball_log.txt', 'w')
for index, transaction in enumerate(transactions):
transaction_string = 'Transaction: ' + str(transaction) + " : " + \
str(transactions_count[index])
logger.debug(transaction_string)
f.write(transaction_string + "\n")
for index, milestone in enumerate(milestone_transactions):
milestone_string = 'Milestone: ' + str(milestone) + \
" : " + str(milestone_transactions_count[index])
logger.debug(milestone_string)
f.write(milestone_string + "\n")
f.close()
logger.info('Transactions logged in /tests/features/machine3/blowball_logs.txt')
@step(r'less than (\d+) percent of the returned transactions should be milestones')
def less_than_max_percent(step, max_percent):
"""
Checks the number of returned milestones and ensures that the total number of milestones returned is below a
given threshold
"""
percentage = (float(world.test_vars['milestone_count'])/(world.config['max'] * 2)) * 100.00
logger.info(str(percentage) + "% milestones")
assert percentage < float(max_percent), "The returned percentage exceeds {}%".format(float(max_percent))
def compare_responses(value, milestone_list, transaction_list, transaction_counter_list,
milestone_transaction_list, milestone_transaction_count):
"""
A comparison method to check a given response value with a list of collected milestones. It checks if the value is
present in the milestone list. If it is present in the milestone list, it then determines if this is the first time
this transaction has been returned, and adjusts the milestone_transaction_list and milestone_transaction_count lists
accordingly. The overall milestone count is incremented each time a value is found in the milestone list. If the
value is not present in the milestone list, then it does the same check for the transaction_list and
transaction_counter_list. These lists will be used later for logging the responses and the number of times a given
response has been returned.
:param value: The value you would like to check against the lists
:param milestone_list: The list of found milestones you will compare the value to
:param transaction_list: A list of recorded transaction values that have been found
:param transaction_counter_list: A list of the number of times a value has been returned
:param milestone_transaction_list: A list of returned milestone values that have been found
:param milestone_transaction_count: A list of the number of times a milestone value has been returned
"""
if value in milestone_list:
if value in milestone_transaction_list:
milestone_transaction_count[milestone_transaction_list.index(value)] += 1
else:
milestone_transaction_list.append(value)
milestone_transaction_count.append(1)
logger.debug('added transaction "{}" to milestone list'.format(value))
world.test_vars['milestone_count'] += 1
logger.debug('"{}" is a milestone'.format(value))
else:
if value in transaction_list:
transaction_counter_list[transaction_list.index(value)] += 1
else:
transaction_list.append(value)
transaction_counter_list.append(1)
logger.debug('added transaction "{}" to transaction list'.format(value))