-
Notifications
You must be signed in to change notification settings - Fork 0
/
testbase.py
executable file
·174 lines (136 loc) · 6.13 KB
/
testbase.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
#!/usr/bin/env python3
import os
import json
import jsondiff
from pathlib import Path
TEST_NODE_IS_HIVE = True
REFERENCE_NODE_IS_HIVE = True
# ignore this tags when comparing results from test and reference nodes
TAGS_TO_REMOVE = [
"timestamp",
"post_id",
"id"
]
TAGS_TO_RENAME = {
"STEEM_":"HIVE_",
"SBD_":"HBD_"
}
def rename_tags(data):
for k, v in TAGS_TO_RENAME.items():
data = rename_tag(data, k, v)
return data
def rename_tag(data, old, new):
if not isinstance(data, (dict, list)):
return data
if isinstance(data, list):
return [rename_tag(v, old, new) for v in data]
return {k.replace(old, new): rename_tag(v, old, new) for k, v in data.items()}
def remove_tag(data):
if not isinstance(data, (dict, list)):
return data
if isinstance(data, list):
return [remove_tag(v) for v in data]
return {k: remove_tag(v) for k, v in data.items() if k not in TAGS_TO_REMOVE}
class SimpleJsonTest(object):
def __init__(self, test_node, ref_node, work_dir):
self._test_node = test_node
self._ref_node = ref_node
self._work_dir = Path(work_dir)
self.create_work_dir()
def create_work_dir(self):
if self._work_dir.exists():
if self._work_dir.is_file():
os.remove(self._work_dir)
if not self._work_dir.exists():
self._work_dir.mkdir(parents = True)
def create_file_name(self, file_name):
return self._work_dir / Path(file_name)
def write_to_file(self, dest_file, data, label):
try:
f = dest_file.open( "a" )
f.write("{} Response:\n".format(label))
json.dump(data, f, indent=2, sort_keys=True)
f.close()
return True
except:
print( "Cannot open file:", dest_file )
return False
def json_pretty_string(self, json_obj):
return json.dumps(json_obj, sort_keys=True, indent=4)
def compare_results(self, args, print_response = False, test_node_is_hive = TEST_NODE_IS_HIVE, reference_node_is_hive = REFERENCE_NODE_IS_HIVE):
try:
from requests import post
print("Sending query:\n{}".format(self.json_pretty_string(args)))
resp1 = post(self._test_node, data=json.dumps(args))
resp2 = post(self._ref_node, data=json.dumps(args))
filename1 = self.create_file_name("ref.log")
filename2 = self.create_file_name("tested.log")
# we will treat codes != 200 as test failed
if resp1.status_code != 200 or resp2.status_code != 200:
print("One of the nodes returned non 200 return codes. Test node: {}, reference node: {}".format(resp1.status_code, resp2.status_code))
self.write_to_file(filename1, resp1, self._test_node)
self.write_to_file(filename2, resp2, self._ref_node)
return False
json1 = resp1.json()
json1 = remove_tag(json1)
if reference_node_is_hive and not test_node_is_hive:
json1 = rename_tags(json1)
json2 = resp2.json()
json2 = remove_tag(json2)
if test_node_is_hive and not reference_node_is_hive:
json2 = rename_tags(json2)
if print_response:
print("Response from test node at {}:\n{}".format(self._test_node, self.json_pretty_string(json1)))
print("Response from ref node at {}:\n{}".format(self._ref_node, self.json_pretty_string(json2)))
json1_error = json1.get("error", None)
json2_error = json2.get("error", None)
if json1_error is not None:
print("Test node {} returned error code".format(self._test_node))
self.write_to_file(filename1, json1, self._test_node)
if json2_error is not None:
print("Reference node {} returned error code".format(self._ref_node))
self.write_to_file(filename2, json2, self._ref_node)
if resp1.status_code != resp2.status_code or json1 != json2:
print("Difference detected")
# if print_response flag is not set print responses to compare, avoid double printing if flag is set to true
if not print_response:
print("Response from test node at {}:\n{}".format(self._test_node, self.json_pretty_string(json1)))
print("Response from ref node at {}:\n{}".format(self._ref_node, self.json_pretty_string(json2)))
json_diff = jsondiff.diff(json1, json2)
if json_diff:
print("Differences detected in jsons: {}".format(self.json_pretty_string(json_diff)))
# avoid dobuble write in case of error detected and differences detected.
if json1_error is None:
self.write_to_file(filename1, json1, self._test_node)
if json2_error is None:
self.write_to_file(filename2, json2, self._ref_node)
print( "Compare break with error")
return False
print( "Compare finished")
return True
except Exception as ex:
# treat exception as test failed
print("Exception during sending request: {}".format(ex))
return False
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("api", type = str, help = "Full api name. i.e: database_api.get_block")
parser.add_argument("params", type = str, help = "JSON with parameters")
parser.add_argument("--test-node", dest = "test_node", type = str, default = "https://api.steem.house", help = "IP address of test node")
parser.add_argument("--test-node-is-hive", dest = "test_node_is_hive", type = bool, default = True, help = "Test node is hive node?")
parser.add_argument("--ref-node", dest = "ref_node", type = str, default = "https://api.steemit.com", help = "IP address of reference node")
parser.add_argument("--ref-node-is-hive", dest = "ref_node_is_hive", type = bool, default = False, help = "Reference node is hive?")
parser.add_argument("--work-dir", dest = "work_dir", type = str, default = "./", help = "Work dir")
parser.add_argument("--print-response", dest = "print_response", type = bool, default = False, help = "Print response from nodes")
args = parser.parse_args()
tester = SimpleJsonTest(args.test_node, args.ref_node, args.work_dir)
test_args = {
"jsonrpc": "2.0",
"id": 1,
"method": args.api,
"params": json.loads(args.params)
}
if tester.compare_results(test_args, args.print_response, args.test_node_is_hive, args.ref_node_is_hive):
exit(0)
exit(1)