Skip to content

Commit e9ff71e

Browse files
committed
[FAB-3754]: Add endorser_util for behave tests
This CR contains the changes needed for the implementation of the chaincode and channel functionality. Change-Id: I9f74abc785179e35b465b982c96877d1b5704e06 Signed-off-by: Latitia M Haskins <[email protected]>
1 parent 9802bdf commit e9ff71e

File tree

2 files changed

+270
-55
lines changed

2 files changed

+270
-55
lines changed

test/feature/steps/endorser_impl.py

+108-39
Original file line numberDiff line numberDiff line change
@@ -15,67 +15,136 @@
1515

1616
from behave import *
1717
import json
18-
19-
20-
@when(u'a user deploys chaincode at path {path} with {args} with name {name}')
21-
def deploy_impl(context, path, args, name):
22-
pass
23-
24-
@when(u'a user deploys chaincode at path {path} with {args}')
18+
import time
19+
import endorser_util
20+
import config_util
21+
22+
23+
@when(u'a user deploys chaincode at path "{path}" with {args} with name "{name}" to "{containerName}" on channel "{channel}"')
24+
def deploy_impl(context, path, args, name, containerName, channel):
25+
# Be sure there is a transaction block for this channel
26+
config_util.generateChannelConfig(channel+"-1", config_util.CHANNEL_PROFILE, context.composition.projectName)
27+
28+
chaincode = {
29+
"path": path,
30+
"language": "GOLANG",
31+
"name": name,
32+
"channelID": channel+"-1",
33+
"args": args,
34+
}
35+
context.results = endorser_util.deploy_chaincode(context, chaincode, [containerName], channel+"-1")
36+
# Save chaincode name and path and args
37+
context.chaincode = chaincode
38+
39+
@when(u'a user deploys chaincode at path "{path}" with {args} with name "{name}"')
40+
def step_impl(context, path, args, name):
41+
deploy_impl(context, path, args, name, "peer0.org1.example.com", endorser_util.TEST_CHANNEL_ID)
42+
43+
@when(u'a user deploys chaincode at path "{path}" with {args}')
2544
def step_impl(context, path, args):
26-
deploy_impl(context, path, json.loads(args), "mycc")
45+
deploy_impl(context, path, args, "mycc", "peer0.org1.example.com", endorser_util.TEST_CHANNEL_ID)
2746

2847
@when(u'a user deploys chaincode')
2948
def step_impl(context):
3049
deploy_impl(context,
31-
"github.com/hyperledger/fabric//chaincode_example02",
32-
["init", "a", "100" , "b", "200"],
33-
"mycc")
34-
35-
@when(u'a user queries on the chaincode named {name} with args {args} on {component}')
36-
def query_impl(context, name, args, component):
37-
pass
38-
39-
@when(u'a user queries on the chaincode named {name} with args {args}')
50+
"github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02",
51+
'["init", "a", "100" , "b", "200"]',
52+
"mycc",
53+
"peer0.org1.example.com",
54+
(endorser_util.TEST_CHANNEL_ID))
55+
56+
@when(u'a user queries on the channel "{channel}" using chaincode named "{name}" with args {args} on "{component}"')
57+
def query_impl(context, channel, name, args, component):
58+
# Temporarily sleep for 2 sec. This delay should be able to be removed once we start using the python sdk
59+
time.sleep(2)
60+
chaincode = {"args": args,
61+
"name": name}
62+
context.result = endorser_util.query_chaincode(context, chaincode, component, channel+"-1")
63+
64+
@when(u'a user queries on the chaincode named "{name}" with args {args} on "{component}"')
65+
def step_impl(context, name, args, component):
66+
query_impl(context, endorser_util.TEST_CHANNEL_ID, name, args, component)
67+
68+
@when(u'a user queries on the chaincode named "{name}" with args {args}')
4069
def step_impl(context, name, args):
41-
query_impl(context, name, json.loads(args), "peer0")
70+
query_impl(context, endorser_util.TEST_CHANNEL_ID, name, args, "peer0.org1.example.com")
4271

43-
@when(u'a user queries on the chaincode named {name}')
72+
@when(u'a user queries on the chaincode with args {args}')
73+
def step_impl(context, args):
74+
query_impl(context, endorser_util.TEST_CHANNEL_ID, "mycc", args, "peer0.org1.example.com")
75+
76+
@when(u'a user queries on the chaincode named "{name}"')
4477
def step_impl(context, name):
45-
query_impl(context, name, ["query", "a"], "peer0")
78+
query_impl(context, endorser_util.TEST_CHANNEL_ID, name, '["query","a"]', "peer0.org1.example.com")
4679

4780
@when(u'a user queries on the chaincode')
4881
def step_impl(context):
49-
query_impl(context, "mycc", ["query", "a"], "peer0")
82+
query_impl(context, endorser_util.TEST_CHANNEL_ID, "mycc", '["query","a"]', "peer0.org1.example.com")
83+
84+
@when(u'a user invokes {numInvokes} times on the channel "{channel}" using chaincode named "{name}" with args {args} on "{component}"')
85+
def invokes_impl(context, numInvokes, channel, name, args, component):
86+
chaincode = {"args": args,
87+
"name": name}
88+
orderers = endorser_util.get_orderers(context)
89+
for count in range(int(numInvokes)):
90+
context.result = endorser_util.invoke_chaincode(context, chaincode, orderers, component, channel+"-1")
91+
92+
@when(u'a user invokes {numInvokes} times on the channel "{channel}" using chaincode named "{name}" with args {args}')
93+
def step_impl(context, numInvokes, channel, name, args):
94+
invokes_impl(context, numInvokes, channel, name, args, "peer0.org1.example.com")
5095

51-
@when(u'a user invokes {count} times on the chaincode named {name} with args {args}')
52-
def invokes_impl(context, count, name, args):
53-
pass
96+
@when(u'a user invokes {numInvokes} times using chaincode named "{name}" with args {args}')
97+
def step_impl(context, numInvokes, name, args):
98+
invokes_impl(context, numInvokes, endorser_util.TEST_CHANNEL_ID, name, args, "peer0.org1.example.com")
5499

55-
@when(u'a user invokes on the chaincode named {name} with args {args}')
100+
@when(u'a user invokes on the chaincode named "{name}" with args {args}')
56101
def step_impl(context, name, args):
57-
invokes_impl(context, 1, name, json.loads(args))
102+
invokes_impl(context, 1, endorser_util.TEST_CHANNEL_ID, name, args, "peer0.org1.example.com")
58103

59-
@when(u'a user invokes {count} times on the chaincode')
60-
def step_impl(context, count):
61-
invokes_impl(context, count, "mycc", ["txId1", "invoke", "a", 5])
104+
@when(u'a user invokes {numInvokes} times on the chaincode')
105+
def step_impl(context, numInvokes):
106+
invokes_impl(context, numInvokes, endorser_util.TEST_CHANNEL_ID, "mycc", '["invoke","a","b","5"]', "peer0.org1.example.com")
62107

63-
@when(u'a user invokes on the chaincode named {name}')
108+
@when(u'a user invokes on the chaincode named "{name}"')
64109
def step_impl(context, name):
65-
invokes_impl(context, 1, name, ["txId1", "invoke", "a", 5])
110+
invokes_impl(context, 1, endorser_util.TEST_CHANNEL_ID, name, '["invoke","a","b","5"]', "peer0.org1.example.com")
66111

67112
@when(u'a user invokes on the chaincode')
68113
def step_impl(context):
69-
invokes_impl(context, 1, "mycc", ["txId1", "invoke", "a", 5])
114+
invokes_impl(context, 1, endorser_util.TEST_CHANNEL_ID, "mycc", '["invoke","a","b","5"]', "peer0.org1.example.com")
70115

71116
@then(u'the chaincode is deployed')
72117
def step_impl(context):
73-
pass
118+
# Grab the key/value pair from the deploy
119+
key = value = None
120+
print(context.chaincode['args'])
121+
print(json.loads(context.chaincode['args']))
122+
args = json.loads(context.chaincode['args'])
123+
for arg in args:
124+
if arg == 'init':
125+
keyIndex = args.index(arg)+1
126+
valueIndex = args.index(arg)+2
127+
key = args[keyIndex]
128+
value = args[valueIndex]
129+
assert key is not None, "The last message was not a deploy: {0}".format(context.chaincode['args'])
130+
131+
chaincode = {
132+
"path": context.chaincode['path'],
133+
"language": context.chaincode['language'],
134+
"name": context.chaincode['name'],
135+
"args": r'["query","{0}"]'.format(key),
136+
}
137+
orderers = endorser_util.get_orderers(context)
138+
peers = endorser_util.get_peers(context)
139+
result = endorser_util.query_chaincode(context, chaincode, peers[0], endorser_util.TEST_CHANNEL_ID+'-1')
140+
print(result)
141+
assert result[peers[0]] == "Query Result: {0}\n".format(value), "Expect {0} = {1}, received from the deploy: {2}".format(key, value, result[peers[0]])
142+
143+
@then(u'a user receives expected response of {response} from "{peer}"')
144+
def expected_impl(context, response, peer):
145+
assert peer in context.result, "There is no response from {0}".format(peer)
146+
assert context.result[peer] == "Query Result: {0}\n".format(response), "Expected response was {0}; received {1}".format(response, context.result[peer])
74147

75148
@then(u'a user receives expected response of {response}')
76-
def expected_impl(context, response):
77-
pass
78-
79-
@then(u'a user receives expected response')
80-
def step_impl(context):
81-
expected_impl(context, 1000)
149+
def step_impl(context, response):
150+
expected_impl(context, response, "peer0.org1.example.com")

test/feature/steps/endorser_util.py

+162-16
Original file line numberDiff line numberDiff line change
@@ -16,43 +16,186 @@
1616
import os
1717
import sys
1818
import subprocess
19+
import time
1920

2021
try:
2122
pbFilePath = "../../bddtests"
2223
sys.path.insert(0, pbFilePath)
23-
from common import common_pb2
2424
from peer import chaincode_pb2
25-
from peer import proposal_pb2
26-
from peer import transaction_pb2
2725
except:
2826
print("ERROR! Unable to import the protobuf libraries from the hyperledger/fabric/bddtests directory: {0}".format(sys.exc_info()[0]))
2927
sys.exit(1)
3028

31-
3229
# The default channel ID
3330
TEST_CHANNEL_ID = "behavesystest"
3431

3532

3633
def get_chaincode_deploy_spec(projectDir, ccType, path, name, args):
37-
pass
34+
subprocess.call(["peer", "chaincode", "package",
35+
"-n", name,
36+
"-c", '{"Args":{0}}'.format(args),
37+
"-p", path,
38+
"configs/{0}/test.file".format(projectDir)], shell=True)
39+
ccDeploymentSpec = chaincode_pb2.ChaincodeDeploymentSpec()
40+
with open("test.file", 'rb') as f:
41+
ccDeploymentSpec.ParseFromString(f.read())
42+
return ccDeploymentSpec
43+
44+
45+
def install_chaincode(context, chaincode, peers):
46+
configDir = "/var/hyperledger/configs/{0}".format(context.composition.projectName)
47+
for peer in peers:
48+
peerParts = peer.split('.')
49+
org = '.'.join(peerParts[1:])
50+
command = ["/bin/bash", "-c",
51+
'"CORE_PEER_MSPCONFIGPATH={0}/peerOrganizations/{1}/users/Admin@{1}/msp'.format(configDir, org),
52+
'CORE_PEER_LOCALMSPID={0}'.format(org),
53+
'CORE_PEER_ID={0}'.format(peer),
54+
'CORE_PEER_ADDRESS={0}:7051'.format(peer),
55+
"peer", "chaincode", "install",
56+
#"--lang", chaincode['language'],
57+
"--name", chaincode['name'],
58+
"--version", str(chaincode.get('version', 0)),
59+
"--chainID", str(chaincode.get('channelID', TEST_CHANNEL_ID)),
60+
"--path", chaincode['path']]
61+
if "orderers" in chaincode:
62+
command = command + ["--orderer", '{0}:7050'.format(chaincode["orderers"][0])]
63+
if "user" in chaincode:
64+
command = command + ["--username", chaincode["user"]]
65+
if "policy" in chaincode:
66+
command = command + ["--policy", chaincode["policy"]]
67+
command.append('"')
68+
ret = context.composition.docker_exec(command, ['cli'])
69+
assert "Error occurred" not in str(ret['cli']), str(ret['cli'])
3870

39-
def install_chaincode(context, chaincode, containers):
40-
pass
4171

4272
def instantiate_chaincode(context, chaincode, containers):
43-
pass
73+
configDir = "/var/hyperledger/configs/{0}".format(context.composition.projectName)
74+
args = chaincode.get('args', '[]').replace('"', r'\"')
75+
command = ["/bin/bash", "-c",
76+
'"CORE_PEER_MSPCONFIGPATH={0}/peerOrganizations/org1.example.com/users/[email protected]/msp'.format(configDir),
77+
'CORE_PEER_LOCALMSPID=org1.example.com',
78+
'CORE_PEER_ID=peer0.org1.example.com',
79+
'CORE_PEER_ADDRESS=peer0.org1.example.com:7051',
80+
"peer", "chaincode", "instantiate",
81+
#"--lang", chaincode['language'],
82+
"--name", chaincode['name'],
83+
"--version", str(chaincode.get('version', 0)),
84+
"--chainID", str(chaincode.get('channelID', TEST_CHANNEL_ID)),
85+
"--ctor", r"""'{\"Args\": %s}'""" % (args)]
86+
if "orderers" in chaincode:
87+
command = command + ["--orderer", '{0}:7050'.format(chaincode["orderers"][0])]
88+
if "user" in chaincode:
89+
command = command + ["--username", chaincode["user"]]
90+
if "policy" in chaincode:
91+
command = command + ["--policy", chaincode["policy"]]
92+
command.append('"')
93+
ret = context.composition.docker_exec(command, ['peer0.org1.example.com'])
94+
assert "Error occurred" not in str(ret['peer0.org1.example.com']), str(ret['peer0.org1.example.com'])
95+
4496

4597
def create_channel(context, containers, orderers, channelId=TEST_CHANNEL_ID):
46-
pass
98+
configDir = "/var/hyperledger/configs/{0}".format(context.composition.projectName)
99+
ret = context.composition.docker_exec(["ls", configDir], containers)
100+
101+
command = ["/bin/bash", "-c",
102+
'"CORE_PEER_MSPCONFIGPATH={0}/peerOrganizations/org1.example.com/users/[email protected]/msp'.format(configDir),
103+
'CORE_PEER_LOCALMSPID=org1.example.com',
104+
'CORE_PEER_ID=peer0.org1.example.com',
105+
'CORE_PEER_ADDRESS=peer0.org1.example.com:7051',
106+
"peer", "channel", "create",
107+
"--file", "/var/hyperledger/configs/{0}/{1}.tx".format(context.composition.projectName, channelId),
108+
"--chain", channelId,
109+
"--orderer", '{0}:7050"'.format(orderers[0])]
110+
print("Create command: {0}".format(command))
111+
output = context.composition.docker_exec(command, ['cli'])
112+
113+
for item in output:
114+
assert "Error occurred" not in str(output[item]), str(output[item])
115+
116+
# For now, copy the channel block to the config directory
117+
output = context.composition.docker_exec(["cp",
118+
"{0}.block".format(channelId),
119+
configDir],
120+
['cli'])
121+
output = context.composition.docker_exec(["ls", configDir], ['cli'])
122+
print("Create: {0}".format(output))
123+
124+
125+
def fetch_channel(context, peers, orderers, channelId=TEST_CHANNEL_ID):
126+
configDir = "/var/hyperledger/configs/{0}".format(context.composition.projectName)
127+
for peer in peers:
128+
peerParts = peer.split('.')
129+
org = '.'.join(peerParts[1:])
130+
command = ["/bin/bash", "-c",
131+
'"CORE_PEER_MSPCONFIGPATH={0}/peerOrganizations/{1}/users/Admin@{1}/msp'.format(configDir, org),
132+
"peer", "channel", "fetch", "config",
133+
"/var/hyperledger/configs/{0}/{1}.block".format(context.composition.projectName, channelId),
134+
"--file", "/var/hyperledger/configs/{0}/{1}.tx".format(context.composition.projectName, channelId),
135+
"--chain", channelId,
136+
"--orderer", '{0}:7050"'.format(orderers[0])]
137+
output = context.composition.docker_exec(command, [peer])
138+
print("Fetch: {0}".format(str(output)))
139+
assert "Error occurred" not in str(output[peer]), str(output[peer])
47140

48-
def join_channel(context, peers, orderers, channelId=TEST_CHANNEL_ID):
49-
pass
50141

51-
def invoke_chaincode(context, chaincode, orderers, containers, channelId=TEST_CHANNEL_ID):
52-
pass
142+
def join_channel(context, peers, orderers, channelId=TEST_CHANNEL_ID):
143+
configDir = "/var/hyperledger/configs/{0}".format(context.composition.projectName)
144+
145+
# fetch_channel(context, peers, orderers, channelId)
146+
147+
for peer in peers:
148+
peerParts = peer.split('.')
149+
org = '.'.join(peerParts[1:])
150+
command = ["/bin/bash", "-c",
151+
'"CORE_PEER_MSPCONFIGPATH={0}/peerOrganizations/{1}/users/Admin@{1}/msp'.format(configDir, org),
152+
"peer", "channel", "join",
153+
"--blockpath", '/var/hyperledger/configs/{0}/{1}.block"'.format(context.composition.projectName, channelId)]
154+
count = 0
155+
output = "Error"
156+
while count < 5 and "Error" in output:
157+
output = context.composition.docker_exec(command, [peer])
158+
print("Join: {0}".format(str(output)))
159+
time.sleep(2)
160+
count = count + 1
161+
output = output[peer]
162+
163+
# If the LedgerID doesn't already exist check for other errors
164+
if "due to LedgerID already exists" not in output:
165+
assert "Error occurred" not in str(output), str(output)
166+
167+
168+
def invoke_chaincode(context, chaincode, orderers, peer, channelId=TEST_CHANNEL_ID):
169+
configDir = "/var/hyperledger/configs/{0}".format(context.composition.projectName)
170+
args = chaincode.get('args', '[]').replace('"', r'\"')
171+
peerParts = peer.split('.')
172+
org = '.'.join(peerParts[1:])
173+
command = ["/bin/bash", "-c",
174+
'"CORE_PEER_MSPCONFIGPATH={0}/peerOrganizations/{1}/users/Admin@{1}/msp'.format(configDir, org),
175+
"peer", "chaincode", "invoke",
176+
"--name", chaincode['name'],
177+
"--ctor", r"""'{\"Args\": %s}'""" % (args),
178+
"--chainID", channelId,
179+
"--orderer", '{0}:7050"'.format(orderers[0])]
180+
output = context.composition.docker_exec(command, [peer])
181+
print("Invoke[{0}]: {1}".format(command, str(output)))
182+
assert "Error occurred" not in output[peer], output[peer]
183+
184+
185+
def query_chaincode(context, chaincode, peer, channelId=TEST_CHANNEL_ID):
186+
configDir = "/var/hyperledger/configs/{0}".format(context.composition.projectName)
187+
peerParts = peer.split('.')
188+
org = '.'.join(peerParts[1:])
189+
args = chaincode.get('args', '[]').replace('"', r'\"')
190+
command = ["/bin/bash", "-c",
191+
'"CORE_PEER_MSPCONFIGPATH={0}/peerOrganizations/{1}/users/Admin@{1}/msp'.format(configDir, org),
192+
"peer", "chaincode", "query",
193+
"--name", chaincode['name'],
194+
"--ctor", r"""'{\"Args\": %s}'""" % (args),
195+
"--chainID", channelId, '"']
196+
print("Query Exec command: {0}".format(command))
197+
return context.composition.docker_exec(command, [peer])
53198

54-
def query_chaincode(context, chaincode, containers, channelId=TEST_CHANNEL_ID):
55-
pass
56199

57200
def get_orderers(context):
58201
orderers = []
@@ -78,7 +221,10 @@ def deploy_chaincode(context, chaincode, containers, channelId=TEST_CHANNEL_ID):
78221
peers = get_peers(context)
79222
assert orderers != [], "There are no active orderers in this network"
80223

224+
chaincode.update({"orderers": orderers,
225+
"channelID": channelId,
226+
})
81227
create_channel(context, containers, orderers, channelId)
82228
join_channel(context, peers, orderers, channelId)
83-
install_chaincode(context, chaincode, containers)
229+
install_chaincode(context, chaincode, peers)
84230
instantiate_chaincode(context, chaincode, containers)

0 commit comments

Comments
 (0)