forked from fabric8-analytics/fabric8-analytics-common
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.py
219 lines (174 loc) · 8.11 KB
/
common.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
217
218
219
"""Common test steps and checks."""
import string
import datetime
import json
import time
import os
import re
from behave import given, then, when
from urllib.parse import urljoin
import jsonschema
import requests
import uuid
import botocore
from botocore.exceptions import ClientError
from src.attribute_checks import *
from src.MockedResponse import *
from src.s3interface import *
from src.utils import *
from src.json_utils import *
from src.parsing import *
from src.authorization_tokens import *
# Do not remove - kept for debugging
import logging
logging.basicConfig(level=logging.INFO)
log = logging.getLogger(__name__)
@given('System is in initial state')
def initial_state(context):
"""Restart the system to the known initial state."""
context.restart_system(context)
@given('System is running')
def running_system(context):
"""Ensure that the system is running, (re)start it if necesarry."""
if not context.is_running(context):
initial_state(context)
@when("I obtain TGT in {service} service")
def get_tgt_in_service(context, service):
"""Obtain TGT in specified container via `docker exec` and returns output of klist."""
context.container = context.run_command_in_service(context, service,
["sleep", "10"])
assert context.container
# just in case
context.exec_command_in_container(context.client, context.container,
'kdestroy')
# this may take ages if you are not on network: I'm currently writing this
# in train and I had no wifi nor ethernet and the command would never
# finish; when I connected to train's wifi it started to work just fine;
# can you imagine?
kinit_command = 'bash -c "echo user | kinit [email protected]"'
context.exec_command_in_container(context.client, context.container,
kinit_command)
klist_out = context.exec_command_in_container(context.client,
context.container, 'klist')
assert "Valid starting" in klist_out
@then('I should receive empty JSON response')
@then('I should see empty analysis')
def check_json_empty_response(context):
"""Check that the JSON response is empty."""
assert is_empty_json_response(context)
@then('I should get {status:d} status code')
def check_status_code(context, status):
"""Check the HTTP status code returned by the REST API."""
assert context.response.status_code == status
@then('I should receive JSON response containing the {key} key')
def check_json_response_contains_key(context, key):
"""Check that the JSON response contains given key."""
assert key in context.response.json()
@then('I should receive JSON response with the {key} key set to {value}')
def check_json_value_under_key(context, key, value):
"""Check that the JSON response contains given value under selected key."""
assert context.response.json().get(key) == value
@then('I should receive JSON response with the correct id')
def check_id_in_json_response(context):
"""Check the ID attribute in the JSON response.
Check if ID is in a format like: '477e85660c504b698beae2b5f2a28b4e'
ie. it is a string with 32 characters containing 32 hexadecimal digits
"""
check_id_value_in_json_response(context, "id")
@then('I should receive JSON response with the correct timestamp in attribute {attribute}')
def check_timestamp_in_json_attribute(context, attribute):
"""Check the timestamp stored in the JSON response.
Check if the attribute in the JSON response object contains
proper timestamp value
"""
check_timestamp_in_json_response(context, attribute)
@then('I should find proper timestamp under the path {path}')
def check_timestamp_under_path(context, path):
"""Check the timestamp stored in selected attribute.
Check if timestamp value can be found in the JSON response object
under the given path.
"""
jsondata = context.response.json()
assert jsondata is not None
timestamp = get_value_using_path(jsondata, path)
check_timestamp(timestamp)
@when('I wait {num:d} seconds')
@then('I wait {num:d} seconds')
def pause_scenario_execution(context, num):
"""Pause the test for provided number of seconds."""
time.sleep(num)
@then('I should see {state} analysis result for {ecosystem}/{package}/{version}')
def check_analysis_result(context, state, ecosystem, package, version):
"""Check the analysis result for given ecosystem, package, and version."""
res = context.response.json()
if state == 'incomplete':
assert res['ecosystem'] == ecosystem
assert res['package'] == package
assert res['version'] == version
assert datetime.datetime.strptime(res["started_at"], "%Y-%m-%dT%H:%M:%S.%f")
elif state == 'complete':
assert datetime.datetime.strptime(res["finished_at"], "%Y-%m-%dT%H:%M:%S.%f")
analyzers_keys = context.get_expected_component_analyses(ecosystem)
actual_keys = set(res["analyses"].keys())
missing, unexpected = context.compare_analysis_sets(actual_keys,
analyzers_keys)
err_str = 'unexpected analyses: {}, missing analyses: {}'
assert not missing and not unexpected, err_str.format(unexpected, missing)
analyzers_with_standard_schema = set(analyzers_keys)
analyzers_with_standard_schema -= context.NONSTANDARD_ANALYSIS_FORMATS
for a in analyzers_with_standard_schema:
a_keys = set(res["analyses"].get(a, {}).keys())
if not a_keys and a in context.UNRELIABLE_ANALYSES:
continue
assert a_keys.issuperset({"details", "status", "summary"}), a_keys
@then('Result of {ecosystem}/{package}/{version} should be valid')
def validate_analysis_result(context, ecosystem, package, version):
"""Validate results of the analysis."""
res = context.response.json()
# make sure analysis has finished
assert res['finished_at'] is not None
# we want to validate top-level analysis and worker results that have "schema" defined
structures_to_validate = [res]
for _, worker_result in res['analyses'].items():
# TODO: in future we want to mandate that all workers have their schemas,
# so we'll remove the condition
if 'schema' in worker_result:
structures_to_validate.append(worker_result)
for struct in structures_to_validate:
schema = requests.get(struct['schema']['url']).json()
jsonschema.validate(struct, schema)
@then('I should find the value {value} under the path {path} in the JSON response')
def find_value_under_the_path(context, value, path):
"""Check if the value (attribute) can be found in the JSON output."""
jsondata = context.response.json()
assert jsondata is not None
v = get_value_using_path(jsondata, path)
assert v is not None
# fallback for int value in the JSON file
if type(v) is int:
assert v == int(value)
else:
assert v == value
@then('I should find the null value under the path {path} in the JSON response')
def find_null_value_under_the_path(context, path):
"""Check if the value (attribute) can be found in the JSON output."""
jsondata = context.response.json()
assert jsondata is not None
v = get_value_using_path(jsondata, path)
assert v is None
@then('I should find the timestamp value under the path {path} in the JSON response')
def find_timestamp_value_under_the_path(context, path):
"""Check if the value (attribute) can be found in the JSON output."""
jsondata = context.response.json()
assert jsondata is not None
v = get_value_using_path(jsondata, path)
assert v is not None
check_timestamp(v)
@when('I mock API response by {filename} file')
def read_json_file(context, filename):
"""Mock the API response by content of given data file."""
context.response = MockedResponse(filename)
@when('I mock S3 data by content of {filename} file')
def read_json_file_for_s3(context, filename):
"""Mock the S3 data by content of given data file."""
context.s3_data = MockedResponse.json_load(filename)