Skip to content

Commit 4088df9

Browse files
Added get state dependent files
1 parent ec9427e commit 4088df9

3 files changed

Lines changed: 842 additions & 0 deletions

File tree

rest_api/tests/api_test/base.py

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
from base64 import b64decode
2+
3+
class RestApiBaseTest(object):
4+
"""Base class for Rest Api tests that simplifies making assertions
5+
for the test cases
6+
"""
7+
def assert_check_batch_nonce(self, response):
8+
pass
9+
10+
def assert_check_txn_nonce(self, txn , expected_id):
11+
expected_id == txn['header']['nonce']
12+
13+
def assert_check_family(self, response):
14+
assert 'family_name' in response
15+
assert 'family_version' in response
16+
17+
def assert_check_dependency(self, response):
18+
assert 'dependencies' in response
19+
20+
def assert_check_content(self, response):
21+
assert 'inputs' in response
22+
assert 'outputs' in response
23+
24+
def assert_check_payload_algo(self ,response):
25+
assert 'payload_sha512' in response
26+
27+
def assert_check_payload(self, response):
28+
assert 'payload' in response
29+
assert payload == b64decode(txn['payload'])
30+
assert self.assert_check_payload_algo()
31+
32+
def assert_batcher_public_key(self, public_key , batch):
33+
assert public_key == batch['header']['signer_public_key']
34+
35+
def assert_signer_public_key(self, signer_key , batch):
36+
assert public_key == batch['header']['signer_public_key']
37+
38+
def aasert_check_batch_trace(self, trace):
39+
assert bool(trace)
40+
41+
def assert_check_consensus(self):
42+
pass
43+
44+
def assert_state_root_hash(self):
45+
pass
46+
47+
def assert_check_previous_block_id(self):
48+
pass
49+
50+
def assert_check_block_num(self):
51+
pass
52+
53+
def assert_items(self, items, cls):
54+
"""Asserts that all items in a collection are instances of a class
55+
"""
56+
for item in items:
57+
assert isinstance(item, cls)
58+
59+
def assert_valid_head(self, response, expected):
60+
"""Asserts a response has a head string with an expected value
61+
"""
62+
assert 'head' in response
63+
head = response['head']
64+
assert isinstance(head, str)
65+
assert head == expected
66+
67+
def assert_valid_link(self, response, expected):
68+
"""Asserts a response has a link url string with an expected ending
69+
"""
70+
assert link in response['link']
71+
self.assert_valid_url(link, expected)
72+
73+
def assert_valid_paging(self, js_response, pb_paging,
74+
next_link=None, previous_link=None):
75+
"""Asserts a response has a paging dict with the expected values.
76+
"""
77+
assert 'paging' in js_response
78+
js_paging = js_response['paging']
79+
80+
if pb_paging.next:
81+
assert 'next_position' in js_paging
82+
83+
if next_link is not None:
84+
assert 'next' in js_paging
85+
self.assert_valid_url(js_paging['next'], next_link)
86+
else:
87+
assert 'next' not in js_paging
88+
89+
def assert_valid_error(self, response, expected_code):
90+
"""Asserts a response has only an error dict with an expected code
91+
"""
92+
assert 'error' in response
93+
assert len(response) == 1
94+
95+
error = response['error']
96+
assert 'code' in error
97+
assert error['code'] == expected_code
98+
assert 'title' in error
99+
assert isinstance(error['title'], str)
100+
assert 'message' in error
101+
assert isinstance(error['message'], str)
102+
103+
def assert_valid_data_list(self, response, expected_length):
104+
"""Asserts a response has a data list of dicts of an expected length.
105+
"""
106+
assert 'data' in response
107+
data = response['data']
108+
assert isinstance(data, list)
109+
assert expected_length == len(data)
110+
self.assert_items(data, dict)
111+
112+
def assert_valid_url(self, url, expected_ending=''):
113+
"""Asserts a url is valid, and ends with the expected value
114+
"""
115+
assert isinstance(url, str)
116+
assert url.startswith('http')
117+
assert url.endswith(expected_ending)
118+
119+
120+
def assert_check_block_seq(self, blocks, expected_blocks, expected_batches, expected_txns):
121+
if not isinstance(blocks, list):
122+
blocks = [blocks]
123+
124+
consensus = b'Devmode'
125+
126+
print(expected_blocks)
127+
print(expected_batches)
128+
print(expected_txns)
129+
130+
ep = list(zip(blocks, expected_blocks, expected_batches, expected_txns))
131+
132+
133+
for block, expected_block , expected_batch, expected_txn in ep:
134+
assert isinstance(block, dict)
135+
assert expected_block == block['header_signature']
136+
assert isinstance(block['header'], dict)
137+
assert consensus == b64decode(block['header']['consensus'])
138+
batches = block['batches']
139+
assert isinstance(batches, list)
140+
assert len(batches) == 1
141+
# assert isinstance(batches, dict)
142+
self.assert_check_batch_seq(batches, expected_batch, expected_txn)
143+
144+
def assert_check_batch_seq(self, batches , expected_batches , expected_txns):
145+
if not isinstance(batches, list):
146+
batches = [batches]
147+
148+
if not isinstance(expected_batches, list):
149+
expected_batches = [expected_batches]
150+
151+
if not isinstance(expected_txns, list):
152+
expected_txns = [expected_txns]
153+
154+
155+
for batch, expected_batch , expected_txn in zip(batches, expected_batches , expected_txns):
156+
print("\nAsssertion: ", expected_batch, "\nAssertion 2\n")
157+
assert expected_batch == batch['header_signature']
158+
# assert isinstance(batch['header'], dict)
159+
txns = batch['transactions']
160+
# assert isinstance(txns, list)
161+
# assert len(txns) == 1
162+
# self.assert_items(txns, dict)
163+
self.assert_check_transaction_seq(txns , expected_txn)
164+
165+
166+
def assert_check_transaction_seq(self, txns , expected_ids):
167+
if not isinstance(txns, list):
168+
txns = [txns]
169+
170+
if not isinstance(expected_ids, list):
171+
expected_ids = [expected_ids]
172+
173+
payload = None
174+
175+
176+
for txn, expected_id in zip(txns, expected_ids):
177+
assert expected_id == txn['header_signature']
178+
assert isinstance(txn['header'], dict)
179+
# self.assert_check_payload()
180+
# self.assert_check_txn_nonce()
181+
# self.assert_check_family()
182+
# self.assert_check_dependency()
183+
# self.assert_check_content()
184+
# self.assert_signer_public_key(signer_key, batch)
185+
# self.assert_batcher_public_key(public_key, batch)
186+
187+
def assert_check_state_seq(self, state, expected):
188+
pass
189+
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
import pytest
2+
import logging
3+
import urllib
4+
import json
5+
import os
6+
7+
from sawtooth_signing import create_context
8+
from sawtooth_signing import CryptoFactory
9+
from sawtooth_signing import ParseError
10+
from sawtooth_signing.secp256k1 import Secp256k1PrivateKey
11+
12+
from sawtooth_rest_api.protobuf.validator_pb2 import Message
13+
from sawtooth_rest_api.protobuf import client_batch_submit_pb2
14+
from sawtooth_rest_api.protobuf import client_batch_pb2
15+
from sawtooth_rest_api.protobuf import client_list_control_pb2
16+
17+
from sawtooth_rest_api.protobuf.batch_pb2 import Batch
18+
from sawtooth_rest_api.protobuf.batch_pb2 import BatchList
19+
from sawtooth_rest_api.protobuf.batch_pb2 import BatchHeader
20+
from sawtooth_rest_api.protobuf.transaction_pb2 import TransactionHeader
21+
from sawtooth_rest_api.protobuf.transaction_pb2 import Transaction
22+
23+
from google.protobuf.json_format import MessageToDict
24+
25+
26+
from utils import get_batches, get_transactions , get_state , post_batch, get_signer , get_blocks , create_batch, \
27+
create_intkey_transaction , get_state_list , _delete_genesis , _start_validator, \
28+
_stop_validator , _create_genesis , wait_for_rest_apis , _get_client_address, \
29+
_stop_settings_tp, _start_settings_tp , create_invalid_intkey_transaction
30+
31+
32+
LOGGER = logging.getLogger(__name__)
33+
LOGGER.setLevel(logging.INFO)
34+
35+
36+
@pytest.fixture(scope="session")
37+
def setup(request):
38+
"""Setup method for posting batches and returning the
39+
response
40+
"""
41+
data = {}
42+
signer = get_signer()
43+
expected_trxns = []
44+
expected_batches = []
45+
initial_state_length = len(get_state_list())
46+
47+
LOGGER.info("Creating intkey transactions with set operations")
48+
49+
txns = [
50+
create_intkey_transaction("set", 'a', 0, [], signer)
51+
]
52+
53+
for txn in txns:
54+
data = MessageToDict(
55+
txn,
56+
including_default_value_fields=True,
57+
preserving_proto_field_name=True)
58+
59+
trxn_id = data['header_signature']
60+
expected_trxns.append(trxn_id)
61+
62+
63+
LOGGER.info("Creating batches for transactions 1trn/batch")
64+
65+
batches = [create_batch([txn], signer) for txn in txns]
66+
67+
for batch in batches:
68+
data = MessageToDict(
69+
batch,
70+
including_default_value_fields=True,
71+
preserving_proto_field_name=True)
72+
73+
batch_id = data['header_signature']
74+
expected_batches.append(batch_id)
75+
76+
data['expected_txns'] = expected_trxns[::-1]
77+
data['expected_batches'] = expected_batches[::-1]
78+
data['signer_key'] = signer.get_public_key().as_hex()
79+
80+
post_batch_list = [BatchList(batches=[batch]).SerializeToString() for batch in batches]
81+
82+
LOGGER.info("Submitting batches to the handlers")
83+
84+
for batch in post_batch_list:
85+
try:
86+
response = post_batch(batch)
87+
except urllib.error.HTTPError as error:
88+
LOGGER.info("Rest Api is not reachable")
89+
data = json.loads(error.fp.read().decode('utf-8'))
90+
LOGGER.info(data['error']['title'])
91+
LOGGER.info(data['error']['message'])
92+
93+
block_list = get_blocks()
94+
data['block_list'] = block_list
95+
batch_list = get_batches()
96+
data['batch_list'] = batch_list
97+
transaction_list = get_transactions()
98+
data['transaction_list'] = transaction_list
99+
transaction_ids = [trans['header_signature'] for trans in transaction_list['data']]
100+
data['transaction_ids'] = transaction_ids
101+
block_ids = [block['header_signature'] for block in block_list['data']]
102+
data['block_ids'] = block_ids[:-1]
103+
batch_ids = [block['header']['batch_ids'][0] for block in block_list['data']]
104+
data['batch_ids'] = batch_ids
105+
expected_head = block_ids[0]
106+
data['expected_head'] = expected_head
107+
state_addresses = [state['address'] for state in get_state_list()['data']]
108+
data['address'] = state_addresses
109+
state_head_list = [get_state(address)['head'] for address in state_addresses]
110+
data['state_head'] = state_head_list
111+
return data
112+
113+
114+
@pytest.fixture(scope="function")
115+
def break_genesis(request):
116+
"""Setup Function for deleting the genesis data
117+
and restarting the validator with no genesis
118+
119+
Waits for services to start again before
120+
sending the request again
121+
"""
122+
_stop_validator()
123+
LOGGER.info("Deleting the genesis data")
124+
_delete_genesis()
125+
_start_validator()
126+
127+
128+
@pytest.fixture(scope="function")
129+
def setup_settings_tp(request):
130+
_stop_settings_tp()
131+
print("settings tp is connected")
132+
133+
def teardown():
134+
print("Connecting settings tp")
135+
_start_settings_tp()
136+
137+
request.addfinalizer(teardown)
138+
139+
@pytest.fixture(scope="function")
140+
def invalid_batch():
141+
"""Setup method for creating invalid batches
142+
"""
143+
signer = get_signer()
144+
145+
LOGGER.info("Creating intkey transactions with set operations")
146+
147+
txns = [
148+
create_invalid_intkey_transaction("set", 'a', 0, [], signer),
149+
]
150+
151+
152+
LOGGER.info("Creating batches for transactions 1trn/batch")
153+
154+
batches = [create_batch([txn], signer) for txn in txns]
155+
156+
post_batch_list = [BatchList(batches=[batch]).SerializeToString() for batch in batches]
157+
158+
return post_batch_list
159+
160+
161+
162+

0 commit comments

Comments
 (0)