Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
b7e07f9
Implemented Structure For Rest Api Testing
asing177 Aug 22, 2018
b88de72
changes to fixtures
asing177 Sep 3, 2018
b18379d
Added common code for txns and 4 test cases on the same
sandeeplandt Sep 3, 2018
83edfca
Merge pull request #52 from TMPSept/rest_api_testing
sandeeplandt Sep 6, 2018
af6c0eb
Added tests for sprint 19
sandeeplandt Sep 6, 2018
3778dcc
Deleted multi validator tests
sandeeplandt Sep 7, 2018
48036fb
Added tests for sprint 19
sandeeplandt Sep 6, 2018
3d4bf69
Deleted multi validator tests
sandeeplandt Sep 7, 2018
43f4d30
Test files added for Rest Api testing (#30)
lntdev Jun 20, 2018
0a2849c
Head Length - count from 89 to 93
shresthichauhan Aug 14, 2018
1930319
Block content and count
shresthichauhan Aug 16, 2018
931e3e9
Merge branch 'rest_api_testing' of https://github.com/TMPSept/sawtoot…
sandeeplandt Sep 7, 2018
92b0d52
Merge branch 'rest_api_testing' into rest_api_testing
sandeeplandt Sep 7, 2018
8a7c0b0
Merge pull request #54 from TMPSept/rest_api_testing
sandeeplandt Sep 7, 2018
85b5432
Updated utils file
sandeeplandt Sep 7, 2018
23f4d96
Added test to get txns based on signer key
sandeeplandt Sep 11, 2018
6904983
Merge pull request #55 from TMPSept/rest_api_testing
sandeeplandt Sep 12, 2018
24b7c61
Update test_rest_api_get_batch.py
asing177 Oct 5, 2018
c90c9d5
Update test_rest_api_get_batch.py
sandeeplandt Oct 5, 2018
a99a65d
Update test_rest_api_get_batch.py
sandeeplandt Oct 5, 2018
d5ffedb
Update test_rest_api_get_receipts.py
sandeeplandt Oct 5, 2018
cd9d942
Update test_rest_api_get_state.py
sandeeplandt Oct 5, 2018
7119116
Update test_rest_api_post.py
sandeeplandt Oct 5, 2018
d671654
Update test_rest_api_scenario.py
sandeeplandt Oct 5, 2018
b65d4f7
Update test_rest_api_get_batch.py
sandeeplandt Oct 5, 2018
0f9dd51
Update test_rest_api_get_state.py
sandeeplandt Oct 5, 2018
00e8dfe
Update test_rest_api_get_batch.py
asing177 Oct 12, 2018
b54fc99
Update test_rest_api_get_batch.py
asing177 Oct 12, 2018
6e09f1c
Update fixtures.py
asing177 Oct 12, 2018
f573512
Update test_rest_api_get_batch.py
asing177 Oct 12, 2018
f3339e6
Update conftest.py
asing177 Oct 14, 2018
428e06a
Update fixtures.py
asing177 Oct 14, 2018
6a88af5
Update test_rest_api_get_batch.py
asing177 Oct 14, 2018
186b39d
Update test_rest_api_get_batch.py
asing177 Oct 16, 2018
ef25b0b
Update test_rest_api_post.py
asing177 Oct 24, 2018
011d291
Update test_rest_api_get_batch.py
asing177 Oct 24, 2018
4c47c1f
Update test_rest_api_get_block.py
asing177 Oct 24, 2018
5c14ef1
Update test_rest_api_get_peers.py
asing177 Oct 24, 2018
c8aca07
Update test_rest_api_get_receipts.py
asing177 Oct 24, 2018
8d94f9c
Update test_rest_api_get_state.py
asing177 Oct 24, 2018
afa991c
Update test_rest_api_get_transaction.py
asing177 Oct 24, 2018
23f8d92
Update pytest.ini
asing177 Oct 24, 2018
b8c3cd2
Update utils.py
asing177 Oct 24, 2018
c5476a6
Update fixtures.py
asing177 Oct 24, 2018
7e1911c
Create requirements.txt
asing177 Oct 24, 2018
aa6e4ff
Update base.py
asing177 Oct 24, 2018
1aa1d73
Update conftest.py
asing177 Oct 24, 2018
87d7055
Update requirements.txt
asing177 Oct 26, 2018
fe8332c
Update requirements.txt
asing177 Oct 26, 2018
b0a6e43
Update base.py
asing177 Oct 30, 2018
52b1348
Update payload.py
asing177 Nov 12, 2018
204f058
Update conftest.py
asing177 Nov 12, 2018
190e41e
Update test_rest_api_post.py
asing177 Nov 13, 2018
d7aebdb
Added few intkey dep txns test cases
sandeeplandt Dec 3, 2018
bf40a6d
Delete pytest-logs.txt
sandeeplandt Dec 3, 2018
370cab0
Delete report.json
sandeeplandt Dec 3, 2018
e4e3292
Merge pull request #59 from Dep-Txns/rest_api_testing
sandeeplandt Dec 3, 2018
84357fe
Update utils.py
sandeeplandt Dec 3, 2018
73f76fb
Updated with 3 more dep txns test cases
sandeeplandt Dec 5, 2018
70856e8
Updated text_rest_api_dep_txns.py
sandeeplandt Dec 6, 2018
35875b4
Merge pull request #60 from Dep-Txns/rest_api_testing
sandeeplandt Dec 6, 2018
2649b31
Updated test_rest_api_dep_txns.py
sandeeplandt Dec 7, 2018
aa221cb
Merge pull request #61 from Dep-Txns/rest_api_testing
sandeeplandt Dec 7, 2018
77d4bff
Dependent transactions some intkey tcs commit
Jyotsnaranix Dec 14, 2018
e9ee9aa
Merge pull request #62 from FinalMerge14Dec/rest_api_testing
sandeeplandt Dec 14, 2018
c53866f
Modify the trace to make it more verbose
shresthichauhan Dec 18, 2018
852b84c
Merge pull request #64 from sawtoothpython/rest_api_testing
shresthichauhan Dec 18, 2018
c64aee0
Make debug logs verbose to understand
shresthichauhan Dec 18, 2018
f8a5f82
Merge pull request #65 from Restsawtooth/rest_api_testing
shresthichauhan Dec 18, 2018
bcad959
Dependent transactions adding two intkey tcs
Jyotsnaranix Dec 19, 2018
2fec063
Dependent transactions two intkey tcs with modified
Jyotsnaranix Dec 20, 2018
439b004
modified the parameter 40 to variable name
Jyotsnaranix Dec 20, 2018
20b1f67
Merge pull request #68 from Final19DecMerge/rest_api_testing
shresthichauhan Dec 20, 2018
0ed981f
Separate batch dependent transaction
chiranjeevix Dec 21, 2018
6b7084c
Merge pull request #69 from DEC21DependentTransaction/rest_api_testing
chiranjeevix Dec 26, 2018
eb36030
State for deleted block in nodes
shresthichauhan Jan 11, 2019
0c3268c
Raft scenarios
shresthichauhan Feb 25, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Raft scenarios.xlsx
Binary file not shown.
389 changes: 389 additions & 0 deletions rest_api/tests/api_test/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,389 @@
# Copyright 2018 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ------------------------------------------------------------------------------
import aiohttp
import logging
from base64 import b64decode

from utils import _get_node_list


CONSENSUS_ALGO = b'Devmode'
FAMILY_NAME = 'intkey'
FAMILY_VERSION = '1.0'
DEFAULT_LIMIT = 100
TRACE = False
NONCE = ''
TRIES=5

LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.INFO)


class RestApiBaseTest(object):
"""Base class for Rest Api tests that simplifies making assertions
for the test cases
"""

def assert_status(self, response, status):
for data in response['data']:
assert data['status'] == status

def assert_equal(self, response, data):
assert response == data

def assert_check_nonce(self, response):
"""Asserts response has nonce parameter
"""
assert 'nonce' in response['header']
assert response['header']['nonce'] == NONCE

def assert_check_family(self, response):
"""Asserts family name and versions in response
"""
assert 'family_name' in response['header']
assert 'family_version' in response['header']
assert response['header']['family_name'] == FAMILY_NAME
assert response['header']['family_version'] == FAMILY_VERSION

def assert_check_dependency(self, response):
"""Asserts transaction dependencies in response
"""
assert 'dependencies' in response['header']

def assert_content(self, response):
"""Asserts response has inputs and outputs parameter
"""
assert 'inputs' in response['header']
assert 'outputs' in response['header']

def assert_payload_algo(self, response):
"""Asserts payload has been created with
proper algorithm
"""
assert 'payload_sha512' in response['header']

def assert_payload(self, txn, payload):
"""Asserts payload is constructed properly
"""
assert 'payload' in txn
assert payload == txn['payload']
self.assert_payload_algo(txn)

def assert_batcher_public_key(self, response, public_key):
"""Asserts batcher public key in response
"""
assert 'signer_public_key' in response['header']
assert public_key == response['header']['signer_public_key']

def assert_signer_public_key(self, response, public_key):
"""Asserts that signer public key is proper
"""
assert 'signer_public_key' in response['header']
assert public_key == response['header']['signer_public_key']

def assert_trace(self, response):
"""Asserts whether the response has trace parameter
"""
assert 'trace' in response
# assert bool(response['trace'])
assert response['trace'] == TRACE

def assert_check_consensus(self, response):
"""Asserts response has consensus as parameter
"""
assert 'consensus' in response

def assert_state_root_hash(self, response):
"""Asserts the response has state root hash
"""
assert 'state_root_hash' in response

def assert_previous_block_id(self, response):
"""Asserts that response has previous block id
"""
assert 'previous_block_id' in response

def assert_block_num(self, response):
"""Asserts that response has proper block number
"""
assert 'block_num' in response

def assert_items(self, items, cls):
"""Asserts that all items in a collection are instances of a class
"""
for item in items:
assert isinstance(item, cls)

def assert_valid_head(self, response, expected):
"""Asserts a response has a head string with an
expected value
"""
assert 'head' in response
head = response['head']
assert isinstance(head, str)
assert head == expected

def assert_valid_link(self, response, expected_link):
"""Asserts a response has a link url string with an
expected ending
"""
print(response['link'])
print(expected_link)
assert 'link' in response
assert response['link'] == expected_link
self.assert_valid_url(response['link'], expected_link)

def assert_valid_url(self, url, expected_link):
"""Asserts a url is valid, and ends with the expected value
"""
assert isinstance(url, str)
assert url.startswith('http')
assert url.endswith(expected_link)

def assert_transaction_ids(self, response, expected):
"""Asserts a response has a link url string with an
expected ending
"""
assert 'transaction_ids' in response['header']
assert response['header']['transaction_ids'][0] == expected

def assert_valid_paging(self, response, expected_link):
"""Asserts a response has a paging dict with the
expected values.
"""
assert 'paging' in response
paging = response['paging']

if 'next' in paging and expected_link is not None:
assert 'next' in paging
assert 'next_position' in paging
self.assert_valid_url(response['link'], expected_link)
else:
assert 'next' not in paging
assert paging['start'] == None
assert paging['limit'] == None

def assert_valid_error(self, response, expected_code):
"""Asserts a response has only an error dict with an
expected code
"""
assert 'error' in response
assert len(response) == 1

error = response['error']
assert 'code' in error
assert error['code'] == expected_code
assert 'title' in error
assert isinstance(error['title'], str)
assert 'message' in error
assert isinstance(error['message'], str)

def assert_valid_data(self, response):
"""Asserts a response has a data list of dicts
"""
assert 'data' in response
data = response['data']
assert isinstance(data, list)
self.assert_items(data, dict)

def assert_valid_data_length(self, response, expected_length):
"""Asserts a response has a data list of dicts of an
expected length.
"""
LOGGER.info(len(response))
LOGGER.info(expected_length)
assert len(response) == expected_length

def assert_check_block_seq(self, blocks, expected_batches, expected_txns, payload, signer_key):
"""Asserts block is constructed properly after submitting batches
"""
if not isinstance(blocks, list):
blocks = [blocks]

if not isinstance(expected_batches, list):
expected_batches = [expected_batches]

if not isinstance(expected_batches, list):
expected_batches = [expected_batches]

if not isinstance(expected_txns, list):
expected_txns = [expected_txns]

if not isinstance(payload, list):
payload = [payload]


ep = list(zip(blocks, expected_batches, expected_txns, payload))

for block, expected_batch, expected_txn, payload in ep:
assert isinstance(block, dict)
assert isinstance(block['header'], dict)
batches = block['batches']
assert isinstance(batches, list)
assert len(batches) == 1
self.assert_check_batch_seq(batches, expected_batch, expected_txn, payload, signer_key)

def assert_check_batch_seq(self, batches, expected_batches, expected_txns,
payload, signer_key):
"""Asserts batch is constructed properly
"""

if not isinstance(batches, list):
batches = [batches]

if not isinstance(expected_batches, list):
expected_batches = [expected_batches]

if not isinstance(expected_txns, list):
expected_txns = [expected_txns]

if not isinstance(payload, list):
payload = [payload]

for batch, expected_batch , expected_txn, payload in zip(batches, expected_batches , expected_txns, payload):
assert expected_batch == batch['header_signature']
assert isinstance(batch['header'], dict)
txns = batch['transactions']
assert isinstance(txns, list)
assert len(txns) == 1
self.assert_items(txns, dict)
self.assert_transaction_ids(batch, expected_txn)
self.assert_signer_public_key(batch, signer_key)
self.assert_trace(batch)
self.assert_check_transaction_seq(txns, expected_txn,
payload, signer_key)


def assert_check_transaction_seq(self, txns, expected_ids,
payload, signer_key):
"""Asserts transactions are constructed properly
"""
if not isinstance(txns, list):
txns = [txns]

if not isinstance(expected_ids, list):
expected_ids = [expected_ids]

if not isinstance(payload, list):
payload = [payload]


for txn, expected_id, payload in zip(txns, expected_ids, payload):
assert expected_id == txn['header_signature']
assert isinstance(txn['header'], dict)
self.assert_payload(txn, payload)
self.assert_check_family(txn)
self.assert_check_nonce(txn)
self.assert_check_dependency(txn)
self.assert_content(txn)
self.assert_signer_public_key(txn, signer_key)
self.assert_batcher_public_key(txn, signer_key)

def assert_check_state_seq(self, response, expected):
"""Asserts state is updated properly
"""
self.assertEqual(len(proto_entries), len(json_entries))
for pb_leaf, js_leaf in zip(proto_entries, json_entries):
self.assertIn('address', js_leaf)
self.assertIn('data', js_leaf)
self.assertEqual(pb_leaf.address, js_leaf['address'])
self.assertEqual(pb_leaf.data, b64decode(js_leaf['data']))

def wait_until_status(url, status_code=200, tries=5):
"""Pause the program until the given url returns the required status.

Args:
url (str): The url to query.
status_code (int, optional): The required status code. Defaults to 200.
tries (int, optional): The number of attempts to request the url for
the given status. Defaults to 5.
Raises:
AssertionError: If the status is not recieved in the given number of
tries.
"""
attempts = tries
while attempts > 0:
try:
response = urlopen(url)
if response.getcode() == status_code:
return

except HTTPError as err:
if err.code == status_code:
return

LOGGER.debug('failed to read url: %s', str(err))
except URLError as err:
LOGGER.debug('failed to read url: %s', str(err))

sleep_time = (tries - attempts + 1) * 2
LOGGER.debug('Retrying in %s secs', sleep_time)
time.sleep(sleep_time)

attempts -= 1

raise AssertionError(
"{} is not available within {} attempts".format(url, tries))

def wait_for_rest_apis(endpoints, tries=TRIES):
"""Pause the program until all the given REST API endpoints are available.

Args:
endpoints (list of str): A list of host:port strings.
tries (int, optional): The number of attempts to request the url for
availability.
"""
for endpoint in endpoints:
http = 'http://'
url = endpoint if endpoint.startswith(http) else http + endpoint
wait_until_status(
'{}/blocks'.format(url),
status_code=200,
tries=tries)
def assert_check_txn_dependency_commit(self, response):
"""Asserts transaction dependencies in response
and verifying if the txn_id is listed under dependncies
"""
if response['data'][0]['status'] == 'COMMITTED':
assert response['data'][0]['status'] == 'COMMITTED'


def assert_check_txn_dependency_invalid(self, response):
"""Asserts transaction dependencies in response
and verifying if the txn_id is listed under dependncies
"""


if response['data'][0]['status'] == 'INVALID':
assert response['data'][0]['status'] == 'INVALID'

def assert_check_txn_dependency_unknown(self, response):
"""Asserts transaction dependencies in response
and verifying if the txn_id is listed under dependncies
"""


if response['data'][0]['status'] == 'UNKNOWN':
assert response['data'][0]['status'] == 'UNKNOWN'


def assert_check_txn_dependency(self, response, txn_ids):
"""Asserts transaction dependencies in response
and verifying if the txn_id is listed under dependncies
"""

if 'dependencies' in response['data']['header']:
dep_txn = response['data']['header']['dependencies']
return any(txn in dep_txn for txn in txn_ids)
Loading