Skip to content

Commit 9059fa1

Browse files
Add a container alias map to the bdd context
To simplify the usage of mapping between the docker-compose service to container name mapping add a dictionary mapping the service (or alias) to the container data object. Also add a map of full container name to container data object for convenience. Standardize the naming of a compose service to containerAlias to reduce confusion between the actual containerName and the service defined in docker-compose. e.g. I deploy chaincode "{chaincodePath}" with ctor "{ctor}" to "{containerAlias}" containerAlias could refer to "vp0" when in reality the container is called "bddtests_vp0_1" Rename the ContainerData class to Container and its field: containerName to name to reduce verbosity in the code base. Remove functions that were no longer used afer changing the code to use the map of alias->container. Signed-off-by: Julian Carrivick <[email protected]> Change-Id: I870719f3ff4db9d07f23d61f1d1a411b6e7ad804
1 parent af6d3e8 commit 9059fa1

10 files changed

+148
-175
lines changed

bddtests/environment.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ def after_scenario(context, scenario):
2424
file_suffix = "_" + scenario.name.replace(" ", "_") + ".log"
2525
# get logs from the peer containers
2626
for containerData in context.compose_containers:
27-
with open(containerData.containerName + file_suffix, "w+") as logfile:
28-
sys_rc = subprocess.call(["docker", "logs", containerData.containerName], stdout=logfile, stderr=logfile)
27+
with open(containerData.name + file_suffix, "w+") as logfile:
28+
sys_rc = subprocess.call(["docker", "logs", containerData.name], stdout=logfile, stderr=logfile)
2929
if sys_rc !=0 :
30-
bdd_log("Cannot get logs for {0}. Docker rc = {1}".format(containerData.containerName,sys_rc))
30+
bdd_log("Cannot get logs for {0}. Docker rc = {1}".format(containerData.name,sys_rc))
3131
# get logs from the chaincode containers
3232
cc_output, cc_error, cc_returncode = \
3333
cli_call(["docker", "ps", "-f", "name=dev-", "--format", "{{.Names}}"], expect_success=True)
@@ -52,7 +52,7 @@ def after_scenario(context, scenario):
5252

5353
if coverageEnabled(context):
5454
#Save the coverage files for this scenario before removing containers
55-
containerNames = [containerData.containerName for containerData in context.compose_containers]
55+
containerNames = [containerData.name for containerData in context.compose_containers]
5656
saveCoverageFiles("coverage", scenario.name.replace(" ", "_"), containerNames, "cov")
5757

5858
context.compose_output, context.compose_error, context.compose_returncode = \

bddtests/peer_basic.feature

-1
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,6 @@ Feature: Network of Peers
583583
| docker-compose-4-consensus-batch.yml | 60 |
584584

585585

586-
# @doNotDecompose
587586
@issue_724
588587
Scenario Outline: chaincode example02 with 4 peers and 1 membersrvc, issue #724
589588

bddtests/steps/bdd_compose_util.py

+40-17
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
from bdd_json_util import getAttributeFromJSON
2121
from bdd_test_util import cli_call, bdd_log
2222

23-
class ContainerData:
24-
def __init__(self, containerName, ipAddress, envFromInspect, composeService):
25-
self.containerName = containerName
23+
class Container:
24+
def __init__(self, name, ipAddress, envFromInspect, composeService):
25+
self.name = name
2626
self.ipAddress = ipAddress
2727
self.envFromInspect = envFromInspect
2828
self.composeService = composeService
@@ -34,11 +34,11 @@ def getEnv(self, key):
3434
envValue = val[len(key):]
3535
break
3636
if envValue == None:
37-
raise Exception("ENV key not found ({0}) for container ({1})".format(key, self.containerName))
37+
raise Exception("ENV key not found ({0}) for container ({1})".format(key, self.name))
3838
return envValue
3939

4040
def __str__(self):
41-
return "{} - {}".format(self.containerName, self.ipAddress)
41+
return "{} - {}".format(self.name, self.ipAddress)
4242

4343
def __repr__(self):
4444
return self.__str__()
@@ -87,7 +87,7 @@ def parseComposeOutput(context):
8787
dockerComposeService = [composeService[27:] for composeService in labels if composeService.startswith("com.docker.compose.service:")][0]
8888
bdd_log("dockerComposeService = {0}".format(dockerComposeService))
8989
bdd_log("container {0} has env = {1}".format(containerName, env))
90-
containerDataList.append(ContainerData(containerName, ipAddress, env, dockerComposeService))
90+
containerDataList.append(Container(containerName, ipAddress, env, dockerComposeService))
9191
# Now merge the new containerData info with existing
9292
newContainerDataList = []
9393
if "compose_containers" in context:
@@ -119,13 +119,13 @@ def allContainersAreReadyWithinTimeout(context, timeout):
119119
def containerIsInitializedByTimestamp(container, timeoutTimestamp):
120120
while containerIsNotInitialized(container):
121121
if timestampExceeded(timeoutTimestamp):
122-
bdd_log("Timed out waiting for {} to initialize".format(container.containerName))
122+
bdd_log("Timed out waiting for {} to initialize".format(container.name))
123123
return False
124124

125-
bdd_log("{} not initialized, waiting...".format(container.containerName))
125+
bdd_log("{} not initialized, waiting...".format(container.name))
126126
time.sleep(1)
127127

128-
bdd_log("{} now available".format(container.containerName))
128+
bdd_log("{} now available".format(container.name))
129129
return True
130130

131131
def timestampExceeded(timeoutTimestamp):
@@ -141,13 +141,13 @@ def containerIsInitialized(container):
141141
return isReady
142142

143143
def tcpPortsAreReady(container):
144-
netstatOutput = getContainerNetstatOutput(container.containerName)
144+
netstatOutput = getContainerNetstatOutput(container.name)
145145

146146
for line in netstatOutput.splitlines():
147147
if re.search("ESTABLISHED|LISTEN", line):
148148
return True
149149

150-
bdd_log("No TCP connections are ready in container {}".format(container.containerName))
150+
bdd_log("No TCP connections are ready in container {}".format(container.name))
151151
return False
152152

153153
def getContainerNetstatOutput(containerName):
@@ -157,7 +157,7 @@ def getContainerNetstatOutput(containerName):
157157
return stdout
158158

159159
def restPortRespondsIfContainerIsPeer(container):
160-
containerName = container.containerName
160+
containerName = container.name
161161
command = ["docker", "exec", containerName, "curl", "localhost:{}".format(CORE_REST_PORT)]
162162

163163
if containerIsPeer(container):
@@ -195,18 +195,18 @@ def containerIsPeer(container):
195195
# is to determine if the container is listening on the REST port. However, this method
196196
# may run before the listening port is ready. Hence, as along as the current
197197
# convention of vp[0-9] is adhered to this function will be good enough.
198-
return re.search("vp[0-9]+", container.containerName, re.IGNORECASE)
198+
return re.search("vp[0-9]+", container.name, re.IGNORECASE)
199199

200200
def peerIsReadyByTimestamp(context, peerContainer, allPeerContainers, timeoutTimestamp):
201201
while peerIsNotReady(context, peerContainer, allPeerContainers):
202202
if timestampExceeded(timeoutTimestamp):
203-
bdd_log("Timed out waiting for peer {}".format(peerContainer.containerName))
203+
bdd_log("Timed out waiting for peer {}".format(peerContainer.name))
204204
return False
205205

206-
bdd_log("Peer {} not ready, waiting...".format(peerContainer.containerName))
206+
bdd_log("Peer {} not ready, waiting...".format(peerContainer.name))
207207
time.sleep(1)
208208

209-
bdd_log("Peer {} now available".format(peerContainer.containerName))
209+
bdd_log("Peer {} now available".format(peerContainer.name))
210210
return True
211211

212212
def peerIsNotReady(context, thisPeer, allPeers):
@@ -235,4 +235,27 @@ def getConnectedPeersFromPeer(context, thisPeer):
235235
if response.status_code != 200:
236236
return None
237237

238-
return getAttributeFromJSON("peers", response.json(), "There should be a peer json attribute")
238+
return getAttributeFromJSON("peers", response.json(), "There should be a peer json attribute")
239+
240+
def mapAliasesToContainers(context):
241+
aliasToContainerMap = {}
242+
243+
for container in context.compose_containers:
244+
alias = extractAliasFromContainerName(container.name)
245+
aliasToContainerMap[alias] = container
246+
247+
return aliasToContainerMap
248+
249+
def extractAliasFromContainerName(containerName):
250+
""" Take a compose created container name and extract the alias to which it
251+
will be refered. For example bddtests_vp1_0 will return vp0 """
252+
return containerName.split("_")[1]
253+
254+
def mapContainerNamesToContainers(context):
255+
nameToContainerMap = {}
256+
257+
for container in context.compose_containers:
258+
name = container.name
259+
nameToContainerMap[name] = container
260+
261+
return nameToContainerMap

bddtests/steps/bdd_grpc_util.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def getGRPCChannelAndUser(context, enrollId):
5555
userRegistration = bdd_test_util.getUserRegistration(context, enrollId)
5656

5757
# Get the IP address of the server that the user registered on
58-
ipAddress = bdd_test_util.ipFromContainerNamePart(userRegistration.composeService, context.compose_containers)
58+
ipAddress = context.containerAliasMap[userRegistration.composeService].ipAddress
5959

6060
channel = getGRPCChannel(ipAddress)
6161

bddtests/steps/bdd_test_util.py

-40
Original file line numberDiff line numberDiff line change
@@ -75,46 +75,6 @@ def getUserRegistration(context, enrollId):
7575
raise Exception("User has not been registered: {0}".format(enrollId))
7676
return userRegistration
7777

78-
79-
def ipFromContainerNamePart(namePart, containerDataList):
80-
"""Returns the IPAddress based upon a name part of the full container name"""
81-
containerData = containerDataFromNamePart(namePart, containerDataList)
82-
83-
if containerData == None:
84-
raise Exception("Could not find container with namePart = {0}".format(namePart))
85-
86-
return containerData.ipAddress
87-
88-
def fullNameFromContainerNamePart(namePart, containerDataList):
89-
containerData = containerDataFromNamePart(namePart, containerDataList)
90-
91-
if containerData == None:
92-
raise Exception("Could not find container with namePart = {0}".format(namePart))
93-
94-
return containerData.containerName
95-
96-
def containerDataFromNamePart(namePart, containerDataList):
97-
containerNamePrefix = os.path.basename(os.getcwd()) + "_"
98-
fullContainerName = containerNamePrefix + namePart
99-
100-
for containerData in containerDataList:
101-
if containerData.containerName.startswith(fullContainerName):
102-
return containerData
103-
104-
return None
105-
106-
def getContainerDataValuesFromContext(context, aliases, callback):
107-
"""Returns the IPAddress based upon a name part of the full container name"""
108-
assert 'compose_containers' in context, "compose_containers not found in context"
109-
values = []
110-
containerNamePrefix = os.path.basename(os.getcwd()) + "_"
111-
for namePart in aliases:
112-
for containerData in context.compose_containers:
113-
if containerData.containerName.startswith(containerNamePrefix + namePart):
114-
values.append(callback(containerData))
115-
break
116-
return values
117-
11878
def start_background_process(context, program_name, arg_list):
11979
p = subprocess.Popen(arg_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
12080
setattr(context, program_name, p)

0 commit comments

Comments
 (0)