blob: 5dc5655e6d26b74c71596652ffcee22321199c33 [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" )
Pratik Parabcc406452017-02-28 15:15:25 -080032 import os
33 DOCKERREPO = main.params[ 'DOCKER' ][ 'repo' ]
34 os.system( "docker pull -a " + DOCKERREPO )
35 imageTagList = list()
36 imageTagCounter = 0
Pratik Parab50d53d42017-03-24 14:28:22 -070037 duplicateTagDetected = 0
38 imageTagList, duplicateTagDetected = main.ONOSbenchDocker.getListOfImages( DOCKERREPO )
39 stepResult = main.FALSE
40 main.step( "Check for duplicate Tags for a given image" )
41 if not duplicateTagDetected:
42 stepResult = main.TRUE
43 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
44 onpass = "no duplicate image tags",
45 onfail = "duplicate image tags detected!!" )
Pratik Parabcc406452017-02-28 15:15:25 -080046 main.step( "Get a list of image tags" )
47 stepResult = main.FALSE
Pratik Parabcc406452017-02-28 15:15:25 -080048 if imageTagList is not []:
49 main.log.info( "The Image tag list is: " + str(imageTagList) )
50 stepResult = main.TRUE
51 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
52 onpass = "image tag list pulled successfully",
53 onfail = "image tag list not pulled" )
54
suibin zhangfd266fd2015-10-27 17:06:33 -070055 def CASE1( self, main ):
56 """
57 1) set up test params;
58 """
59 import re
suibin zhang3b067ea2015-11-05 13:55:21 -080060 import time
61 import subprocess
suibin zhangfd266fd2015-10-27 17:06:33 -070062
Pratik Parabcc406452017-02-28 15:15:25 -080063 if imageTagCounter < len( imageTagList ):
64 DOCKERTAG = imageTagList[imageTagCounter]
65 imageTagCounter += 1
66
67 main.case("Set case test params for onos image {}".format( DOCKERTAG ))
suibin zhangfd266fd2015-10-27 17:06:33 -070068 main.step("Initialize test params")
69 NODElist = main.params["SCALE"]["nodelist"].split(',')
70 main.log.info("onos container names are: " + ",".join(NODElist) )
71 IPlist = list()
72 main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
suibin zhangfd266fd2015-10-27 17:06:33 -070073 CTIDlist = list()
suibin zhang3b067ea2015-11-05 13:55:21 -080074
75 main.log.info("Check docker status, it not running, try restart it")
76 iter = 0
77 stepResult = main.TRUE
78 while subprocess.call("sudo service docker status", shell=True) and iter <= 3:
79 subprocess.call("sudo service docker restart", shell=True)
80 time.sleep(5)
81 iter += 1
82 if iter == 3: stepResult = main.FALSE
83
84 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
85 onpass = "docker is running",
86 onfail = "docker is not running")
87 if stepResult == main.FALSE:
88 main.log.warn("docker is not running - exiting test")
89 main.exit()
90 main.cleanup()
Pratik Parabcc406452017-02-28 15:15:25 -080091 if imageTagCounter > len( imageTagList ):
Pratik Parab50d53d42017-03-24 14:28:22 -070092 main.log.info("All images have been tested")
Pratik Parabcc406452017-02-28 15:15:25 -080093 main.exit()
94 main.cleanup()
suibin zhangfd266fd2015-10-27 17:06:33 -070095
96 def CASE5(self, main):
97 """
Pratik Parabcc406452017-02-28 15:15:25 -080098 Pull the specified image
suibin zhangfd266fd2015-10-27 17:06:33 -070099 """
100
Pratik Parabcc406452017-02-28 15:15:25 -0800101 main.case( "Pull onos docker image {} from {} - \
102 it may take sometime if this is a first time pulling.".format( DOCKERTAG, DOCKERREPO ) )
suibin zhangfd266fd2015-10-27 17:06:33 -0700103 stepResult = main.FALSE
Pratik Parabcc406452017-02-28 15:15:25 -0800104 main.step( "pull image {} from {}".format( DOCKERTAG, DOCKERREPO ) )
suibin zhangfd266fd2015-10-27 17:06:33 -0700105 stepResult = main.ONOSbenchDocker.dockerPull( onosRepo = DOCKERREPO, onosTag = DOCKERTAG )
106 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
107 onpass = "Succeeded in pulling " + DOCKERREPO + ":" + DOCKERTAG,
108 onfail = "Failed to pull " + DOCKERREPO + ":" + DOCKERTAG )
suibin zhang3b067ea2015-11-05 13:55:21 -0800109 if stepResult == main.FALSE: main.skipCase()
suibin zhangfd266fd2015-10-27 17:06:33 -0700110
111 def CASE10( self, main ):
112 """
113 Start docker containers for list of onos nodes, only if not already existed
114 """
115 import re
suibin zhang3b067ea2015-11-05 13:55:21 -0800116 createResult = main.TRUE
117 startResult = main.TRUE
Pratik Parabcc406452017-02-28 15:15:25 -0800118 main.case( "Start onos container(s) for onos image {}".format( DOCKERTAG ))
suibin zhangfd266fd2015-10-27 17:06:33 -0700119 image = DOCKERREPO + ":" + DOCKERTAG
120
Pratik Parabcc406452017-02-28 15:15:25 -0800121 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 -0700122 #stepResult = main.FALSE
123
124 for ct in xrange(0, len(NODElist)):
125 if not main.ONOSbenchDocker.dockerCheckCTName( ctName = NODElist[ct] ):
126 main.log.info( "Create new container for onos" + str(ct + 1) )
127 createResult, ctid = main.ONOSbenchDocker.dockerCreateCT( onosImage = image, onosNode = NODElist[ct])
128 CTIDlist.append(ctid)
129 startResult = main.ONOSbenchDocker.dockerStartCT( ctID = ctid )
130 else:
Pratik Parabcc406452017-02-28 15:15:25 -0800131 main.log.info("Container exists for node onos" + str(ct + 1) + "; restart container with {} image".format( DOCKERTAG ) )
suibin zhangfd266fd2015-10-27 17:06:33 -0700132 startResult = main.ONOSbenchDocker.dockerRestartCT( ctName = NODElist[ct ] )
133
134 utilities.assert_equals( expect = main.TRUE, actual = createResult and startResult,
135 onpass = "Container successfully created",
136 onfail = "Failed to create the container" )
137
138 main.step( "Get IP address on onos containers" )
139 stepResult = main.FALSE
140
141 for ct in xrange(0,len(NODElist)):
142 IPlist.append(main.ONOSbenchDocker.dockerIP( ctName = NODElist[ct] ))
143 main.log.info("Container IPs are: " + ', '.join( IPlist ))
144
145 if IPlist is not []:stepResult = main.TRUE
146 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
147 onpass = "Container successfully started",
148 onfail = "Failed to start the container" )
149
150 def CASE110(self,main):
151 """
152 Steps:
153 1) check default startup standalone onos applications status;
154 2) form onos cluster with all nodes;
155 3) check onos applications status;
156 4) activate apps per params and check app status;
157 5) deactivate apps and check app status
158
159 """
160 import time
161 import json
162
Pratik Parabcc406452017-02-28 15:15:25 -0800163 main.case( "Form onos cluster and check status of onos apps for onos image {}".format( DOCKERTAG ) )
164
suibin zhangfd266fd2015-10-27 17:06:33 -0700165 startupSleep = int(main.params["SLEEP"]["startup"])
166
167 appToAct = main.params["CASE110"]["apps"]
168 stepResult = main.FALSE
169
170 main.log.info( "Wait for startup, sleep (sec): " + str(startupSleep))
171 time.sleep(startupSleep)
172
Pratik Parabcc406452017-02-28 15:15:25 -0800173 main.step( "Check initial app states from onos1 for onos image {}".format( DOCKERTAG ))
suibin zhangfd266fd2015-10-27 17:06:33 -0700174 stepResult = main.TRUE
175 response = main.ONOSbenchRest.apps( ip=IPlist[0], port = 8181 )
176 main.log.debug("Rest call response is: " + response)
177 if response is not main.FALSE:
178 for item in json.loads(response):
179 if item["state"] not in ["ACTIVE", "INSTALLED"]:
180 main.log.info("Some bundles are not in correct state. ")
181 main.log.info("App states are: " + response)
182 stepResult = main.FALSE
183 break;
184 if (item["description"] == "Builtin device drivers") and (item["state"] != "ACTIVE"):
185 main.log.info("Driver app is not in 'ACTIVE' state, but in: " + item["state"])
186 stepResult = main.FALSE
187 break;
188 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
189 onpass = "ONOS successfully started",
190 onfail = "Failed to start ONOS correctly" )
suibin zhang3b067ea2015-11-05 13:55:21 -0800191 if stepResult is main.FALSE: main.skipCase()
suibin zhangfd266fd2015-10-27 17:06:33 -0700192
Jon Hall53c5e662016-04-13 16:06:56 -0700193 main.step( "Form onos cluster using 'dependencies/onos-form-cluster' util")
suibin zhangfd266fd2015-10-27 17:06:33 -0700194 stepResult = main.FALSE
195 clcmdpath = main.params["CASE110"]["clustercmdpath"]
196 main.log.info("onos-form-cluster cmd path is: " + clcmdpath)
197 dkruser = main.params["DOCKER"]["user"]
198 dkrpasswd = main.params["DOCKER"]["password"]
199 main.ONOSbenchDocker.onosFormCluster(cmdPath = clcmdpath, onosIPs=IPlist, user=dkruser, passwd = dkrpasswd)
200 main.log.info("Wait for cluster to form with sleep time of " + str(startupSleep))
201 time.sleep(startupSleep)
suibin zhang1ab833b2016-05-12 12:10:11 -0700202 status, response = main.ONOSbenchRest.send(ip=IPlist[0], port=8181, url="/cluster")
suibin zhangfd266fd2015-10-27 17:06:33 -0700203 main.log.debug("Rest call response: " + str(status) + " - " + response)
204 if status == 200:
205 jrsp = json.loads(response)
Pratik Parabcc406452017-02-28 15:15:25 -0800206 if DOCKERTAG == "1.2" or DOCKERTAG == "1.3" or DOCKERTAG == "1.4" or DOCKERTAG == "1.5":
207 clusterIP = [item["ip"]for item in jrsp["nodes"] if item["status"]== "ACTIVE"]
208 else:
209 clusterIP = [item["ip"]for item in jrsp["nodes"] if item["status"]== "READY"]
suibin zhang3b067ea2015-11-05 13:55:21 -0800210 main.log.debug(" IPlist is:" + ",".join(IPlist))
Pratik Parabcc406452017-02-28 15:15:25 -0800211 main.log.debug(" cluster IP is" + ",".join(clusterIP))
suibin zhangfd266fd2015-10-27 17:06:33 -0700212 if set(IPlist) == set(clusterIP): stepResult = main.TRUE
213
214 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
215 onpass = "ONOS successfully started",
216 onfail = "Failed to start ONOS correctly" )
suibin zhang3b067ea2015-11-05 13:55:21 -0800217 if stepResult is main.FALSE: main.skipCase()
suibin zhangfd266fd2015-10-27 17:06:33 -0700218
219 main.step( "Check cluster app status")
220 stepResult = main.TRUE
221 response = main.ONOSbenchRest.apps( ip=IPlist[0], port = 8181 )
222 if response is not main.FALSE:
223 for item in json.loads(response):
224 if item["state"] not in ["ACTIVE", "INSTALLED"]:
225 main.log.info("Some bundles are not in correct state. ")
226 main.log.info("App states are: " + response)
227 stepResult = main.FALSE
suibin zhang3b067ea2015-11-05 13:55:21 -0800228 break
suibin zhangfd266fd2015-10-27 17:06:33 -0700229 if (item["description"] == "Builtin device drivers") and (item["state"] != "ACTIVE"):
230 main.log.info("Driver app is not in 'ACTIVE' state, but in: " + item["state"])
231 stepResult = main.FALSE
suibin zhang3b067ea2015-11-05 13:55:21 -0800232 break
suibin zhangfd266fd2015-10-27 17:06:33 -0700233 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
234 onpass = "ONOS successfully started",
235 onfail = "Failed to start ONOS correctly" )
suibin zhang3b067ea2015-11-05 13:55:21 -0800236 if stepResult is main.FALSE: main.skipCase()
suibin zhangfd266fd2015-10-27 17:06:33 -0700237
238 main.step(" Activate an APP from REST and check APP status")
239 appResults = list()
240 stepResult = main.TRUE
241 applist = main.params["CASE110"]["apps"].split(",")
242 main.log.info("List of apps to activate: " + str(applist) )
243 for app in applist:
suibin zhangfd266fd2015-10-27 17:06:33 -0700244 appRslt = main.ONOSbenchRest.activateApp(appName=app, ip=IPlist[0], port=8181, check=True)
suibin zhang5ae25332015-11-04 13:56:28 -0800245 time.sleep(5)
suibin zhangfd266fd2015-10-27 17:06:33 -0700246 appResults.append(appRslt)
247 stepResult = stepResult and appRslt
Pratik Parabcc406452017-02-28 15:15:25 -0800248 main.log.debug("Apps activation result for " + ",".join(applist) + ": " + str(appResults) )
suibin zhangfd266fd2015-10-27 17:06:33 -0700249 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
suibin zhang1a291692015-11-04 12:14:31 -0800250 onpass = "Successfully activated apps",
251 onfail = "Failed to activated apps correctly" )
suibin zhang3b067ea2015-11-05 13:55:21 -0800252 if stepResult is main.FALSE: main.skipCase()
suibin zhangfd266fd2015-10-27 17:06:33 -0700253
254 main.step(" Deactivate an APP from REST and check APP status")
255 appResults = list()
256 stepResult = main.TRUE
257 applist = main.params["CASE110"]["apps"].split(",")
suibin zhang5ae25332015-11-04 13:56:28 -0800258 main.log.info("Apps to deactivate: " + str(applist) )
suibin zhangfd266fd2015-10-27 17:06:33 -0700259 for app in applist:
260 time.sleep(5)
261 appRslt = main.ONOSbenchRest.deactivateApp(appName=app, ip=IPlist[0], port=8181, check=True)
262 appResults.append(appRslt)
263 stepResult = stepResult and appRslt
264 main.log.debug("Apps deactivation result for " + ",".join(applist) + ": " + str(appResults) )
265 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
suibin zhang1a291692015-11-04 12:14:31 -0800266 onpass = "Successfully deactivated apps",
267 onfail = "Failed to deactivated apps correctly" )
suibin zhang3b067ea2015-11-05 13:55:21 -0800268 if stepResult is main.FALSE: main.skipCase()
269
270 def CASE900(self,main):
271 """
272 Check onos logs for exceptions after tests
273 """
274 import pexpect
275 import time
276 import re
277
278 logResult = main.TRUE
279
280 user = main.params["DOCKER"]["user"]
281 pwd = main.params["DOCKER"]["password"]
282
Pratik Parabcc406452017-02-28 15:15:25 -0800283 main.case("onos Exceptions check with onos image {}".format( DOCKERTAG ))
suibin zhang3b067ea2015-11-05 13:55:21 -0800284 main.step("check onos for any exceptions")
285
286 for ip in IPlist:
suibin zhang559218e2015-12-08 14:57:12 -0800287 spawncmd = "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p 8101 " + user + "@" + ip
suibin zhang3b067ea2015-11-05 13:55:21 -0800288 main.log.info("log on node using cmd: " + spawncmd)
289 try:
290 handle = pexpect.spawn(spawncmd)
suibin zhang559218e2015-12-08 14:57:12 -0800291 #handle.expect("yes/no")
292 #handle.sendline("yes")
293 #print("yes is sent")
suibin zhang126282c2015-11-30 14:21:35 -0800294 #this extra statement is sent to get around some
295 #pexpect issue of not seeing the next expected string
suibin zhang3b067ea2015-11-05 13:55:21 -0800296 handle.expect("Password:")
297 handle.sendline(pwd)
298 time.sleep(5)
299 handle.expect("onos>")
300 handle.sendline("log:exception-display")
301 handle.expect("onos>")
302 result = handle.before
303 if re.search("Exception", result):
304 main.log.info("onos: " + ip + " Exceptions:" + result)
305 logResult = logResult and main.FALSE
306 else:
307 main.log.info("onos: " + ip + " Exceptions: None")
308 logResult = logResult and main.TRUE
309 except Exception:
310 main.log.exception("Uncaught exception when getting log from onos:" + ip)
311 logResult = logResult and main.FALSE
312
313 utilities.assert_equals( expect = main.TRUE, actual = logResult,
314 onpass = "onos exception check passed",
315 onfail = "onos exeption check failed" )
suibin zhangfd266fd2015-10-27 17:06:33 -0700316
317 def CASE1000( self, main ):
318
319 """
Pratik Parabcc406452017-02-28 15:15:25 -0800320 Cleanup after tests - stop and delete the containers created; delete the image
suibin zhangfd266fd2015-10-27 17:06:33 -0700321 """
322 import time
323
suibin zhang3b067ea2015-11-05 13:55:21 -0800324 main.case("Clean up images (ex. none:none tagged) and containers")
suibin zhangfd266fd2015-10-27 17:06:33 -0700325 main.step("Stop onos containers")
326 stepResult = main.TRUE
327 for ctname in NODElist:
Pratik Parabcc406452017-02-28 15:15:25 -0800328 if main.ONOSbenchDocker.dockerCheckCTName( ctName="/" + ctname ):
329 main.log.info( "stopping docker container: /" + ctname )
330 stopResult = main.ONOSbenchDocker.dockerStopCT( ctName="/" + ctname )
suibin zhangfd266fd2015-10-27 17:06:33 -0700331 time.sleep(10)
Pratik Parabcc406452017-02-28 15:15:25 -0800332 rmResult = main.ONOSbenchDocker.dockerRemoveCT( ctName="/" + ctname )
suibin zhangfd266fd2015-10-27 17:06:33 -0700333 stepResult = stepResult and stopResult and rmResult
334 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
335 onpass = "Container successfully stopped",
336 onfail = "Failed to stopped the container" )
337
338 #main.step( "remove exiting onosproject/onos images")
339 #stepResult = main.ONOSbenchDocker.dockerRemoveImage( image = DOCKERREPO + ":" + DOCKERTAG )
suibin zhang3b067ea2015-11-05 13:55:21 -0800340 main.step( "remove dangling 'none:none' images")
Pratik Parabcc406452017-02-28 15:15:25 -0800341 stepResult = main.ONOSbenchDocker.dockerRemoveImage()
suibin zhangfd266fd2015-10-27 17:06:33 -0700342 utilities.assert_equals( expect = main.TRUE, actual = stepResult,
suibin zhang3b067ea2015-11-05 13:55:21 -0800343 onpass = "Succeeded in cleaning up images",
344 onfail = "Failed in cleaning up images" )
suibin zhangfd266fd2015-10-27 17:06:33 -0700345
Pratik Parab8d884d12017-03-16 12:14:32 -0700346 def CASE1001( self, main ):
347
348 """
349 Create a file for publishing results on wiki in tabular form
350 """
351
352 main.case( "Create a file for publishing on wiki in tabular form" )
353 import re
354 imageTagCounter = 0
355 testCaseCounter = 0
356 resultCounter = 0
357 resultDictionary = {}
358 testCaseList = []
359 totalNumOfTestCases = 6
360 try:
361 main.tableFileName = main.logdir + "/" + main.TEST + "TableWiki.txt"
362 main.wikiTableFile = open(main.tableFileName, "a+")
363 main.wikiFileHandle = open(main.WikiFileName, "r")
364 for imageTag in imageTagList:
365 resultDictionary[ imageTag ] = []
366 for line in main.wikiFileHandle:
367 matchObj = re.search("(?!.*Case 0).*<h3>(.+?)<\/h3>", line)
368 if testCaseCounter < totalNumOfTestCases:
369 if matchObj:
370 wordsToRemove = re.compile("latest|- PASS|- FAIL|- No Result")
371 testCaseName = wordsToRemove.sub("", matchObj.group(1))
372 testCaseList.append(testCaseName)
373 testCaseCounter += 1
374 if matchObj:
375 if "- PASS" in line:
376 resultDictionary[ imageTagList[ imageTagCounter ] ].append("PASS")
377 if "- FAIL" in line:
378 resultDictionary[ imageTagList[ imageTagCounter ] ].append("FAIL")
379 if "- No Result" in line:
380 resultDictionary[ imageTagList[ imageTagCounter ] ].append("No Result")
381 resultCounter += 1
382 if resultCounter == totalNumOfTestCases:
383 imageTagCounter += 1
384 resultCounter = 0
385 main.wikiTableFile.write( "<table style=\"width:100%\">\n" )
386 main.wikiTableFile.write( "<tr>\n" )
387 main.wikiTableFile.write( "<th>ONOS Version</th>\n" )
388 for testCaseName in testCaseList:
389 main.wikiTableFile.write( "<th>" + testCaseName + "</th>\n" )
390 main.wikiTableFile.write( "</tr>\n" )
391 for imageTag in imageTagList:
392 main.wikiTableFile.write( "<tr>\n" )
393 main.wikiTableFile.write( "<td>" + imageTag + "</td>\n" )
394 for resultValue in resultDictionary[ imageTag ]:
395 if resultValue == "PASS":
396 emoticonValue = "\"tick\""
397 if resultValue == "FAIL":
398 emoticonValue = "\"cross\""
399 if resultValue == "No Result":
400 emoticonValue = "\"warning\""
401 main.wikiTableFile.write( "<td>" + resultValue + " <ac:emoticon ac:name=" + emoticonValue + " /></td>\n" )
402 main.wikiTableFile.write( "</tr>\n" )
403 main.wikiTableFile.write( "</table>\n" )
404 main.wikiTableFile.close()
405 main.wikiFileHandle.close()
406 logResult = main.TRUE
407 except Exception:
408 main.log.exception( "Exception while writing to the table file" )
409 logResult = main.FALSE
410 utilities.assert_equals( expect = main.TRUE, actual = logResult,
411 onpass = "onos exception check passed",
412 onfail = "onos exception check failed" )