blob: ebc8d6bb2249f52ec8bc341ef4a3c5ea6f772fbc [file] [log] [blame]
suibin zhangfd266fd2015-10-27 17:06:33 -07001
suibin zhangc7635702015-11-03 21:30:20 -08002# This is a basic platform test suite.
3# Additional platform test cases can be added on this test suite where appropriate.
suibin zhangfd266fd2015-10-27 17:06:33 -07004
5class PLATdockertest:
6 """
7 This testsuite performs the following tests:
8 1) checkout onos docker image;
9 2) test image start up in single and clustered mode;
10 3) test onos app activation and deactivation;
11
12 Prerequisites:
13 1) docker-engine installed on test station (localhost);
14 2) python docker client (docker-py) installed on test station
15 """
16
17 def __init__( self ):
18 self.default = ''
19 global DOCKERREPO, DOCKERTAG
20 global IPlist
21 global CTIDlist
22 global NODElist
23
24 DOCKERREPO = "onosproject/onos"
25 DOCKERTAG = "latest"
26
Pratik Parabcc406452017-02-28 15:15:25 -080027 def CASE0( self, main ):
28 """
29 Pull all docker images and get a list of image tags
30 """
31 main.case( "Pull all docker images and get a list of image tags" )
32 main.step( "Pull all ONOS docker images" )
33 import os
34 DOCKERREPO = main.params[ 'DOCKER' ][ 'repo' ]
35 os.system( "docker pull -a " + DOCKERREPO )
36 imageTagList = list()
37 imageTagCounter = 0
38 main.step( "Get a list of image tags" )
39 stepResult = main.FALSE
40 imageTagList = main.ONOSbenchDocker.getListOfImages( DOCKERREPO )
41 if imageTagList is not []:
42 main.log.info( "The Image tag list is: " + str(imageTagList) )
43 stepResult = main.TRUE
44 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
45 onpass = "image tag list pulled successfully",
46 onfail = "image tag list not pulled" )
47
suibin zhangfd266fd2015-10-27 17:06:33 -070048 def CASE1( self, main ):
49 """
50 1) set up test params;
51 """
52 import re
suibin zhang3b067ea2015-11-05 13:55:21 -080053 import time
54 import subprocess
suibin zhangfd266fd2015-10-27 17:06:33 -070055
Pratik Parabcc406452017-02-28 15:15:25 -080056 if imageTagCounter < len( imageTagList ):
57 DOCKERTAG = imageTagList[imageTagCounter]
58 imageTagCounter += 1
59
60 main.case("Set case test params for onos image {}".format( DOCKERTAG ))
suibin zhangfd266fd2015-10-27 17:06:33 -070061 main.step("Initialize test params")
62 NODElist = main.params["SCALE"]["nodelist"].split(',')
63 main.log.info("onos container names are: " + ",".join(NODElist) )
64 IPlist = list()
65 main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
suibin zhangfd266fd2015-10-27 17:06:33 -070066 CTIDlist = list()
suibin zhang3b067ea2015-11-05 13:55:21 -080067
68 main.log.info("Check docker status, it not running, try restart it")
69 iter = 0
70 stepResult = main.TRUE
71 while subprocess.call("sudo service docker status", shell=True) and iter <= 3:
72 subprocess.call("sudo service docker restart", shell=True)
73 time.sleep(5)
74 iter += 1
75 if iter == 3: stepResult = main.FALSE
76
77 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
78 onpass = "docker is running",
79 onfail = "docker is not running")
80 if stepResult == main.FALSE:
81 main.log.warn("docker is not running - exiting test")
82 main.exit()
83 main.cleanup()
Pratik Parabcc406452017-02-28 15:15:25 -080084 if imageTagCounter > len( imageTagList ):
85 main.log.warn("All images have been tested")
86 main.exit()
87 main.cleanup()
suibin zhangfd266fd2015-10-27 17:06:33 -070088
89 def CASE5(self, main):
90 """
Pratik Parabcc406452017-02-28 15:15:25 -080091 Pull the specified image
suibin zhangfd266fd2015-10-27 17:06:33 -070092 """
93
Pratik Parabcc406452017-02-28 15:15:25 -080094 main.case( "Pull onos docker image {} from {} - \
95 it may take sometime if this is a first time pulling.".format( DOCKERTAG, DOCKERREPO ) )
suibin zhangfd266fd2015-10-27 17:06:33 -070096 stepResult = main.FALSE
Pratik Parabcc406452017-02-28 15:15:25 -080097 main.step( "pull image {} from {}".format( DOCKERTAG, DOCKERREPO ) )
suibin zhangfd266fd2015-10-27 17:06:33 -070098 stepResult = main.ONOSbenchDocker.dockerPull( onosRepo = DOCKERREPO, onosTag = DOCKERTAG )
99 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
100 onpass = "Succeeded in pulling " + DOCKERREPO + ":" + DOCKERTAG,
101 onfail = "Failed to pull " + DOCKERREPO + ":" + DOCKERTAG )
suibin zhang3b067ea2015-11-05 13:55:21 -0800102 if stepResult == main.FALSE: main.skipCase()
suibin zhangfd266fd2015-10-27 17:06:33 -0700103
104 def CASE10( self, main ):
105 """
106 Start docker containers for list of onos nodes, only if not already existed
107 """
108 import re
suibin zhang3b067ea2015-11-05 13:55:21 -0800109 createResult = main.TRUE
110 startResult = main.TRUE
Pratik Parabcc406452017-02-28 15:15:25 -0800111 main.case( "Start onos container(s) for onos image {}".format( DOCKERTAG ))
suibin zhangfd266fd2015-10-27 17:06:33 -0700112 image = DOCKERREPO + ":" + DOCKERTAG
113
Pratik Parabcc406452017-02-28 15:15:25 -0800114 main.step( "Create and (re)start docker container(s) for onos image {} if not already exist".format( DOCKERTAG ))
suibin zhangfd266fd2015-10-27 17:06:33 -0700115 #stepResult = main.FALSE
116
117 for ct in xrange(0, len(NODElist)):
118 if not main.ONOSbenchDocker.dockerCheckCTName( ctName = NODElist[ct] ):
119 main.log.info( "Create new container for onos" + str(ct + 1) )
120 createResult, ctid = main.ONOSbenchDocker.dockerCreateCT( onosImage = image, onosNode = NODElist[ct])
121 CTIDlist.append(ctid)
122 startResult = main.ONOSbenchDocker.dockerStartCT( ctID = ctid )
123 else:
Pratik Parabcc406452017-02-28 15:15:25 -0800124 main.log.info("Container exists for node onos" + str(ct + 1) + "; restart container with {} image".format( DOCKERTAG ) )
suibin zhangfd266fd2015-10-27 17:06:33 -0700125 startResult = main.ONOSbenchDocker.dockerRestartCT( ctName = NODElist[ct ] )
126
127 utilities.assert_equals( expect = main.TRUE, actual = createResult and startResult,
128 onpass = "Container successfully created",
129 onfail = "Failed to create the container" )
130
131 main.step( "Get IP address on onos containers" )
132 stepResult = main.FALSE
133
134 for ct in xrange(0,len(NODElist)):
135 IPlist.append(main.ONOSbenchDocker.dockerIP( ctName = NODElist[ct] ))
136 main.log.info("Container IPs are: " + ', '.join( IPlist ))
137
138 if IPlist is not []:stepResult = main.TRUE
139 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
140 onpass = "Container successfully started",
141 onfail = "Failed to start the container" )
142
143 def CASE110(self,main):
144 """
145 Steps:
146 1) check default startup standalone onos applications status;
147 2) form onos cluster with all nodes;
148 3) check onos applications status;
149 4) activate apps per params and check app status;
150 5) deactivate apps and check app status
151
152 """
153 import time
154 import json
155
Pratik Parabcc406452017-02-28 15:15:25 -0800156 main.case( "Form onos cluster and check status of onos apps for onos image {}".format( DOCKERTAG ) )
157
suibin zhangfd266fd2015-10-27 17:06:33 -0700158 startupSleep = int(main.params["SLEEP"]["startup"])
159
160 appToAct = main.params["CASE110"]["apps"]
161 stepResult = main.FALSE
162
163 main.log.info( "Wait for startup, sleep (sec): " + str(startupSleep))
164 time.sleep(startupSleep)
165
Pratik Parabcc406452017-02-28 15:15:25 -0800166 main.step( "Check initial app states from onos1 for onos image {}".format( DOCKERTAG ))
suibin zhangfd266fd2015-10-27 17:06:33 -0700167 stepResult = main.TRUE
168 response = main.ONOSbenchRest.apps( ip=IPlist[0], port = 8181 )
169 main.log.debug("Rest call response is: " + response)
170 if response is not main.FALSE:
171 for item in json.loads(response):
172 if item["state"] not in ["ACTIVE", "INSTALLED"]:
173 main.log.info("Some bundles are not in correct state. ")
174 main.log.info("App states are: " + response)
175 stepResult = main.FALSE
176 break;
177 if (item["description"] == "Builtin device drivers") and (item["state"] != "ACTIVE"):
178 main.log.info("Driver app is not in 'ACTIVE' state, but in: " + item["state"])
179 stepResult = main.FALSE
180 break;
181 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
182 onpass = "ONOS successfully started",
183 onfail = "Failed to start ONOS correctly" )
suibin zhang3b067ea2015-11-05 13:55:21 -0800184 if stepResult is main.FALSE: main.skipCase()
suibin zhangfd266fd2015-10-27 17:06:33 -0700185
Jon Hall53c5e662016-04-13 16:06:56 -0700186 main.step( "Form onos cluster using 'dependencies/onos-form-cluster' util")
suibin zhangfd266fd2015-10-27 17:06:33 -0700187 stepResult = main.FALSE
188 clcmdpath = main.params["CASE110"]["clustercmdpath"]
189 main.log.info("onos-form-cluster cmd path is: " + clcmdpath)
190 dkruser = main.params["DOCKER"]["user"]
191 dkrpasswd = main.params["DOCKER"]["password"]
192 main.ONOSbenchDocker.onosFormCluster(cmdPath = clcmdpath, onosIPs=IPlist, user=dkruser, passwd = dkrpasswd)
193 main.log.info("Wait for cluster to form with sleep time of " + str(startupSleep))
194 time.sleep(startupSleep)
suibin zhang1ab833b2016-05-12 12:10:11 -0700195 status, response = main.ONOSbenchRest.send(ip=IPlist[0], port=8181, url="/cluster")
suibin zhangfd266fd2015-10-27 17:06:33 -0700196 main.log.debug("Rest call response: " + str(status) + " - " + response)
197 if status == 200:
198 jrsp = json.loads(response)
Pratik Parabcc406452017-02-28 15:15:25 -0800199 if DOCKERTAG == "1.2" or DOCKERTAG == "1.3" or DOCKERTAG == "1.4" or DOCKERTAG == "1.5":
200 clusterIP = [item["ip"]for item in jrsp["nodes"] if item["status"]== "ACTIVE"]
201 else:
202 clusterIP = [item["ip"]for item in jrsp["nodes"] if item["status"]== "READY"]
suibin zhang3b067ea2015-11-05 13:55:21 -0800203 main.log.debug(" IPlist is:" + ",".join(IPlist))
Pratik Parabcc406452017-02-28 15:15:25 -0800204 main.log.debug(" cluster IP is" + ",".join(clusterIP))
suibin zhangfd266fd2015-10-27 17:06:33 -0700205 if set(IPlist) == set(clusterIP): stepResult = main.TRUE
206
207 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
208 onpass = "ONOS successfully started",
209 onfail = "Failed to start ONOS correctly" )
suibin zhang3b067ea2015-11-05 13:55:21 -0800210 if stepResult is main.FALSE: main.skipCase()
suibin zhangfd266fd2015-10-27 17:06:33 -0700211
212 main.step( "Check cluster app status")
213 stepResult = main.TRUE
214 response = main.ONOSbenchRest.apps( ip=IPlist[0], port = 8181 )
215 if response is not main.FALSE:
216 for item in json.loads(response):
217 if item["state"] not in ["ACTIVE", "INSTALLED"]:
218 main.log.info("Some bundles are not in correct state. ")
219 main.log.info("App states are: " + response)
220 stepResult = main.FALSE
suibin zhang3b067ea2015-11-05 13:55:21 -0800221 break
suibin zhangfd266fd2015-10-27 17:06:33 -0700222 if (item["description"] == "Builtin device drivers") and (item["state"] != "ACTIVE"):
223 main.log.info("Driver app is not in 'ACTIVE' state, but in: " + item["state"])
224 stepResult = main.FALSE
suibin zhang3b067ea2015-11-05 13:55:21 -0800225 break
suibin zhangfd266fd2015-10-27 17:06:33 -0700226 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
227 onpass = "ONOS successfully started",
228 onfail = "Failed to start ONOS correctly" )
suibin zhang3b067ea2015-11-05 13:55:21 -0800229 if stepResult is main.FALSE: main.skipCase()
suibin zhangfd266fd2015-10-27 17:06:33 -0700230
231 main.step(" Activate an APP from REST and check APP status")
232 appResults = list()
233 stepResult = main.TRUE
234 applist = main.params["CASE110"]["apps"].split(",")
235 main.log.info("List of apps to activate: " + str(applist) )
236 for app in applist:
suibin zhangfd266fd2015-10-27 17:06:33 -0700237 appRslt = main.ONOSbenchRest.activateApp(appName=app, ip=IPlist[0], port=8181, check=True)
suibin zhang5ae25332015-11-04 13:56:28 -0800238 time.sleep(5)
suibin zhangfd266fd2015-10-27 17:06:33 -0700239 appResults.append(appRslt)
240 stepResult = stepResult and appRslt
Pratik Parabcc406452017-02-28 15:15:25 -0800241 main.log.debug("Apps activation result for " + ",".join(applist) + ": " + str(appResults) )
suibin zhangfd266fd2015-10-27 17:06:33 -0700242 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
suibin zhang1a291692015-11-04 12:14:31 -0800243 onpass = "Successfully activated apps",
244 onfail = "Failed to activated apps correctly" )
suibin zhang3b067ea2015-11-05 13:55:21 -0800245 if stepResult is main.FALSE: main.skipCase()
suibin zhangfd266fd2015-10-27 17:06:33 -0700246
247 main.step(" Deactivate an APP from REST and check APP status")
248 appResults = list()
249 stepResult = main.TRUE
250 applist = main.params["CASE110"]["apps"].split(",")
suibin zhang5ae25332015-11-04 13:56:28 -0800251 main.log.info("Apps to deactivate: " + str(applist) )
suibin zhangfd266fd2015-10-27 17:06:33 -0700252 for app in applist:
253 time.sleep(5)
254 appRslt = main.ONOSbenchRest.deactivateApp(appName=app, ip=IPlist[0], port=8181, check=True)
255 appResults.append(appRslt)
256 stepResult = stepResult and appRslt
257 main.log.debug("Apps deactivation result for " + ",".join(applist) + ": " + str(appResults) )
258 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
suibin zhang1a291692015-11-04 12:14:31 -0800259 onpass = "Successfully deactivated apps",
260 onfail = "Failed to deactivated apps correctly" )
suibin zhang3b067ea2015-11-05 13:55:21 -0800261 if stepResult is main.FALSE: main.skipCase()
262
263 def CASE900(self,main):
264 """
265 Check onos logs for exceptions after tests
266 """
267 import pexpect
268 import time
269 import re
270
271 logResult = main.TRUE
272
273 user = main.params["DOCKER"]["user"]
274 pwd = main.params["DOCKER"]["password"]
275
Pratik Parabcc406452017-02-28 15:15:25 -0800276 main.case("onos Exceptions check with onos image {}".format( DOCKERTAG ))
suibin zhang3b067ea2015-11-05 13:55:21 -0800277 main.step("check onos for any exceptions")
278
279 for ip in IPlist:
suibin zhang559218e2015-12-08 14:57:12 -0800280 spawncmd = "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p 8101 " + user + "@" + ip
suibin zhang3b067ea2015-11-05 13:55:21 -0800281 main.log.info("log on node using cmd: " + spawncmd)
282 try:
283 handle = pexpect.spawn(spawncmd)
suibin zhang559218e2015-12-08 14:57:12 -0800284 #handle.expect("yes/no")
285 #handle.sendline("yes")
286 #print("yes is sent")
suibin zhang126282c2015-11-30 14:21:35 -0800287 #this extra statement is sent to get around some
288 #pexpect issue of not seeing the next expected string
suibin zhang3b067ea2015-11-05 13:55:21 -0800289 handle.expect("Password:")
290 handle.sendline(pwd)
291 time.sleep(5)
292 handle.expect("onos>")
293 handle.sendline("log:exception-display")
294 handle.expect("onos>")
295 result = handle.before
296 if re.search("Exception", result):
297 main.log.info("onos: " + ip + " Exceptions:" + result)
298 logResult = logResult and main.FALSE
299 else:
300 main.log.info("onos: " + ip + " Exceptions: None")
301 logResult = logResult and main.TRUE
302 except Exception:
303 main.log.exception("Uncaught exception when getting log from onos:" + ip)
304 logResult = logResult and main.FALSE
305
306 utilities.assert_equals( expect = main.TRUE, actual = logResult,
307 onpass = "onos exception check passed",
308 onfail = "onos exeption check failed" )
suibin zhangfd266fd2015-10-27 17:06:33 -0700309
310 def CASE1000( self, main ):
311
312 """
Pratik Parabcc406452017-02-28 15:15:25 -0800313 Cleanup after tests - stop and delete the containers created; delete the image
suibin zhangfd266fd2015-10-27 17:06:33 -0700314 """
315 import time
316
suibin zhang3b067ea2015-11-05 13:55:21 -0800317 main.case("Clean up images (ex. none:none tagged) and containers")
suibin zhangfd266fd2015-10-27 17:06:33 -0700318 main.step("Stop onos containers")
319 stepResult = main.TRUE
320 for ctname in NODElist:
Pratik Parabcc406452017-02-28 15:15:25 -0800321 if main.ONOSbenchDocker.dockerCheckCTName( ctName="/" + ctname ):
322 main.log.info( "stopping docker container: /" + ctname )
323 stopResult = main.ONOSbenchDocker.dockerStopCT( ctName="/" + ctname )
suibin zhangfd266fd2015-10-27 17:06:33 -0700324 time.sleep(10)
Pratik Parabcc406452017-02-28 15:15:25 -0800325 rmResult = main.ONOSbenchDocker.dockerRemoveCT( ctName="/" + ctname )
suibin zhangfd266fd2015-10-27 17:06:33 -0700326 stepResult = stepResult and stopResult and rmResult
327 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
328 onpass = "Container successfully stopped",
329 onfail = "Failed to stopped the container" )
330
331 #main.step( "remove exiting onosproject/onos images")
332 #stepResult = main.ONOSbenchDocker.dockerRemoveImage( image = DOCKERREPO + ":" + DOCKERTAG )
suibin zhang3b067ea2015-11-05 13:55:21 -0800333 main.step( "remove dangling 'none:none' images")
Pratik Parabcc406452017-02-28 15:15:25 -0800334 stepResult = main.ONOSbenchDocker.dockerRemoveImage()
suibin zhangfd266fd2015-10-27 17:06:33 -0700335 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
suibin zhang3b067ea2015-11-05 13:55:21 -0800336 onpass = "Succeeded in cleaning up images",
337 onfail = "Failed in cleaning up images" )
suibin zhangfd266fd2015-10-27 17:06:33 -0700338
Pratik Parab8d884d12017-03-16 12:14:32 -0700339 def CASE1001( self, main ):
340
341 """
342 Create a file for publishing results on wiki in tabular form
343 """
344
345 main.case( "Create a file for publishing on wiki in tabular form" )
346 import re
347 imageTagCounter = 0
348 testCaseCounter = 0
349 resultCounter = 0
350 resultDictionary = {}
351 testCaseList = []
352 totalNumOfTestCases = 6
353 try:
354 main.tableFileName = main.logdir + "/" + main.TEST + "TableWiki.txt"
355 main.wikiTableFile = open(main.tableFileName, "a+")
356 main.wikiFileHandle = open(main.WikiFileName, "r")
357 for imageTag in imageTagList:
358 resultDictionary[ imageTag ] = []
359 for line in main.wikiFileHandle:
360 matchObj = re.search("(?!.*Case 0).*<h3>(.+?)<\/h3>", line)
361 if testCaseCounter < totalNumOfTestCases:
362 if matchObj:
363 wordsToRemove = re.compile("latest|- PASS|- FAIL|- No Result")
364 testCaseName = wordsToRemove.sub("", matchObj.group(1))
365 testCaseList.append(testCaseName)
366 testCaseCounter += 1
367 if matchObj:
368 if "- PASS" in line:
369 resultDictionary[ imageTagList[ imageTagCounter ] ].append("PASS")
370 if "- FAIL" in line:
371 resultDictionary[ imageTagList[ imageTagCounter ] ].append("FAIL")
372 if "- No Result" in line:
373 resultDictionary[ imageTagList[ imageTagCounter ] ].append("No Result")
374 resultCounter += 1
375 if resultCounter == totalNumOfTestCases:
376 imageTagCounter += 1
377 resultCounter = 0
378 main.wikiTableFile.write( "<table style=\"width:100%\">\n" )
379 main.wikiTableFile.write( "<tr>\n" )
380 main.wikiTableFile.write( "<th>ONOS Version</th>\n" )
381 for testCaseName in testCaseList:
382 main.wikiTableFile.write( "<th>" + testCaseName + "</th>\n" )
383 main.wikiTableFile.write( "</tr>\n" )
384 for imageTag in imageTagList:
385 main.wikiTableFile.write( "<tr>\n" )
386 main.wikiTableFile.write( "<td>" + imageTag + "</td>\n" )
387 for resultValue in resultDictionary[ imageTag ]:
388 if resultValue == "PASS":
389 emoticonValue = "\"tick\""
390 if resultValue == "FAIL":
391 emoticonValue = "\"cross\""
392 if resultValue == "No Result":
393 emoticonValue = "\"warning\""
394 main.wikiTableFile.write( "<td>" + resultValue + " <ac:emoticon ac:name=" + emoticonValue + " /></td>\n" )
395 main.wikiTableFile.write( "</tr>\n" )
396 main.wikiTableFile.write( "</table>\n" )
397 main.wikiTableFile.close()
398 main.wikiFileHandle.close()
399 logResult = main.TRUE
400 except Exception:
401 main.log.exception( "Exception while writing to the table file" )
402 logResult = main.FALSE
403 utilities.assert_equals( expect = main.TRUE, actual = logResult,
404 onpass = "onos exception check passed",
405 onfail = "onos exception check failed" )