Skip to content

Commit

Permalink
Refactor BDD REST calls
Browse files Browse the repository at this point in the history
Refactor the duplicated code for calling the peer REST endpoints into
standalone functions that can be reused.

Also refactor the 'Wait for transactions to be committed' BDD steps
to utilize the newly created high level functions.

Remove the msg parameter from the JSON checking function and generate
the message at invoke time.

Reduce some timeouts from 5 or 3 mins to a much more reasonable 1
min.

I have tested all behave tests locally to verify they work in lieu of
them being run on Jenkins while they are stabilised.

Change-Id: I484c1cde677461a885863a492be786bae3be44f3
Signed-off-by: Julian Carrivick <cjulian@au1.ibm.com>
  • Loading branch information
juliancarrivick-ibm committed Sep 9, 2016
1 parent f7f5dc3 commit d7e056e
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 309 deletions.
4 changes: 2 additions & 2 deletions bddtests/java_shim.feature
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Feature: Java chaincode example
| arg1 | arg2 | arg3 | arg4 |
| a | 100 | b | 200 |
Then I should have received a chaincode name
Then I wait up to "300" seconds for transaction to be committed to all peers
Then I wait up to "60" seconds for transaction to be committed to all peers

When requesting "/chain" from "vp0"
Then I should get a JSON response with "height" = "2"
Expand Down Expand Up @@ -72,7 +72,7 @@ Scenario: java RangeExample chaincode single peer
||
||
Then I should have received a chaincode name
Then I wait up to "300" seconds for transaction to be committed to all peers
Then I wait up to "60" seconds for transaction to be committed to all peers

When requesting "/chain" from "vp0"
Then I should get a JSON response with "height" = "2"
Expand Down
5 changes: 2 additions & 3 deletions bddtests/peer_basic.feature
Original file line number Diff line number Diff line change
Expand Up @@ -1077,7 +1077,6 @@ Feature: Network of Peers


@issue_1942
# @doNotDecompose
Scenario: chaincode example02 with 4 peers, stop and start alternates, reverse
Given we compose "docker-compose-4-consensus-batch.yml"
And I register with CA supplying username "binhn" and secret "7avZQLwcUe9q" on peers:
Expand Down Expand Up @@ -1113,7 +1112,7 @@ Scenario: chaincode example02 with 4 peers, stop and start alternates, reverse
|arg1|arg2|arg3|
| a | b | 1 |
Then I should have received a transactionID
Then I wait up to "180" seconds for transaction to be committed to peers:
Then I wait up to "60" seconds for transaction to be committed to peers:
| vp0 | vp1 | vp3 |

When I query chaincode "example2" function name "query" with value "a" on peers:
Expand All @@ -1130,7 +1129,7 @@ Scenario: chaincode example02 with 4 peers, stop and start alternates, reverse
When I invoke chaincode "example2" function name "invoke" on "vp3" "20" times
|arg1|arg2|arg3|
| a | b | 1 |
Then I wait up to "300" seconds for transactions to be committed to peers:
Then I wait up to "60" seconds for transactions to be committed to peers:
| vp0 | vp2 | vp3 |

When I query chaincode "example2" function name "query" with value "a" on peers:
Expand Down
9 changes: 4 additions & 5 deletions bddtests/steps/bdd_compose_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import os, time, re, requests

from bdd_rest_util import buildUrl, CORE_REST_PORT
from bdd_request_util import httpGetToContainer, CORE_REST_PORT
from bdd_json_util import getAttributeFromJSON
from bdd_test_util import cli_call, bdd_log

Expand Down Expand Up @@ -229,13 +229,12 @@ def peerIsReady(context, thisPeer, allPeers):
return numPeers == numConnectedPeers

def getConnectedPeersFromPeer(context, thisPeer):
url = buildUrl(context, thisPeer.ipAddress, "/network/peers")
response = requests.get(url, headers={'Accept': 'application/json'}, verify=False)
response = httpGetToContainer(context, thisPeer, "/network/peers")

if response.status_code != 200:
return None

return getAttributeFromJSON("peers", response.json(), "There should be a peer json attribute")
return getAttributeFromJSON("peers", response.json())

def mapAliasesToContainers(context):
aliasToContainerMap = {}
Expand All @@ -258,4 +257,4 @@ def mapContainerNamesToContainers(context):
name = container.name
nameToContainerMap[name] = container

return nameToContainerMap
return nameToContainerMap
24 changes: 17 additions & 7 deletions bddtests/steps/bdd_json_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,21 @@
# limitations under the License.
#

def getAttributeFromJSON(attribute, jsonObject, msg):
return getHierarchyAttributesFromJSON(attribute.split("."), jsonObject, msg)
def getAttributeFromJSON(attribute, json):
foundJson = getHierarchyAttributesFromJSON(attribute.split("."), json)
assert foundJson is not None, "Unable to locate {} in JSON".format(attribute)

def getHierarchyAttributesFromJSON(attributes, jsonObject, msg):
if len(attributes) > 0:
assert attributes[0] in jsonObject, msg
return getHierarchyAttributesFromJSON(attributes[1:], jsonObject[attributes[0]], msg)
return jsonObject
return foundJson

def getHierarchyAttributesFromJSON(attributes, json):
foundJson = None

currentAttribute = attributes[0]
if currentAttribute in json:
foundJson = json[currentAttribute]

attributesToGo = attributes[1:]
if len(attributesToGo) > 0:
foundJson = getHierarchyAttributesFromJSON(attributesToGo, foundJson)

return foundJson
98 changes: 98 additions & 0 deletions bddtests/steps/bdd_request_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#
# Copyright IBM Corp. 2016 All Rights Reserved.
#
# 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 requests, json
from bdd_test_util import bdd_log

CORE_REST_PORT = "7050"
ACCEPT_JSON_HEADER = {
'Accept': 'application/json'
}

def httpGetToContainerAlias(context, containerAlias, endpoint, \
port=CORE_REST_PORT, expectSuccess=True):
""" Performs a GET to the given container doing a lookup by alias first.
Optional args are port (defaults to the default peer rest port) and the
expectSuccess which validates the response returned a 200 """
container = context.containerAliasMap[containerAlias]
return httpGetToContainer(context, container, endpoint, port, expectSuccess)

def httpGetToContainer(context, container, endpoint, \
port=CORE_REST_PORT, expectSuccess=True):
""" Performs a GET to the given container. Optional args are port (defaults
to the default peer rest port) and the expectSuccess which validates the
response returned a 200 """
request_url = buildContainerUrl(context, container, endpoint, port)
return httpGet(request_url, expectSuccess)

def httpPostToContainerAlias(context, containerAlias, endpoint, body, \
port=CORE_REST_PORT, expectSuccess=True):
""" Performs a POST to the given container doing a lookup by alias first.
Optional args are port (defaults to the default peer rest port) and the
expectSuccess which validates the response returned a 200 """
container = context.containerAliasMap[containerAlias]
return httpPostToContainer(context, container, endpoint, body, port, expectSuccess)

def httpPostToContainer(context, container, endpoint, body, \
port=CORE_REST_PORT, expectSuccess=True):
""" Performs a GET to the given container. Optional args are port (defaults
to the default peer rest port) and the expectSuccess which validates the
response returned a 200 """
request_url = buildContainerUrl(context, container, endpoint, port)
return httpPost(request_url, body, expectSuccess)

def buildContainerAliasUrl(context, containerAlias, endpoint, port=CORE_REST_PORT):
""" Build a URL to do a HTTP request to the given container looking up the
alias first. Optionally provide a port too which defaults to the peer
rest port """
container = context.containerAliasMap[containerAlias]
return buildContainerUrl(context, container, endpoint, port=port)

def buildContainerUrl(context, container, endpoint, port=CORE_REST_PORT):
""" Build a URL to do a HTTP request to the given container. Optionally
provide a port too which defaults to the peer rest port """
return buildUrl(context, container.ipAddress, port, endpoint)

def buildUrl(context, ipAddress, port, endpoint):
schema = "http"
if 'TLS' in context.tags:
schema = "https"
return "{0}://{1}:{2}{3}".format(schema, ipAddress, port, endpoint)

def httpGet(url, expectSuccess=True):
return _request("GET", url, expectSuccess=expectSuccess)

def httpPost(url, body, expectSuccess=True):
return _request("POST", url, json=body, expectSuccess=expectSuccess)

def _request(method, url, expectSuccess=True, **kwargs):
bdd_log("HTTP {} to url = {}".format(method, url))

response = requests.request(method, url, \
headers=ACCEPT_JSON_HEADER, verify=False, **kwargs)

if expectSuccess:
assert response.status_code == 200, \
"Failed to {} to {}: {}".format(method, url, response.text)

bdd_log("Response from {}:".format(url))
bdd_log(formatResponseText(response))

return response

def formatResponseText(response):
# Limit to 300 chars because of the size of the Base64 encoded Certs
return json.dumps(response.json(), indent = 4)[:300]
23 changes: 0 additions & 23 deletions bddtests/steps/bdd_rest_util.py

This file was deleted.

Loading

0 comments on commit d7e056e

Please sign in to comment.