blob: f4e1714aa4d16df1dcbe520c18451887687c22e0 [file] [log] [blame]
Jon Hall05b2b432014-10-08 19:53:25 -04001#!/usr/bin/env python
andrewonlabe8e56fd2014-10-09 17:12:44 -04002
Jon Hall05b2b432014-10-08 19:53:25 -04003'''
andrewonlabe8e56fd2014-10-09 17:12:44 -04004This driver interacts with ONOS bench, the OSGi platform
5that configures the ONOS nodes. (aka ONOS-next)
6
7Please follow the coding style demonstrated by existing
8functions and document properly.
9
10If you are a contributor to the driver, please
11list your email here for future contact:
12
13jhall@onlab.us
14andrew@onlab.us
15
16OCT 9 2014
17
Jon Hall05b2b432014-10-08 19:53:25 -040018'''
andrewonlabe8e56fd2014-10-09 17:12:44 -040019
andrewonlab7735d852014-10-09 13:02:47 -040020import sys
Jon Hall05b2b432014-10-08 19:53:25 -040021import time
22import pexpect
23import re
24import traceback
andrewonlab7735d852014-10-09 13:02:47 -040025import os.path
andrewonlab6e20c342014-10-10 18:08:48 -040026import pydoc
Jon Hall05b2b432014-10-08 19:53:25 -040027sys.path.append("../")
28from drivers.common.clidriver import CLI
29
30class OnosDriver(CLI):
31
32 def __init__(self):
andrewonlab6e20c342014-10-10 18:08:48 -040033 '''
34 Initialize client
35 '''
Jon Hall05b2b432014-10-08 19:53:25 -040036 super(CLI, self).__init__()
37
38 def connect(self,**connectargs):
39 '''
40 Creates ssh handle for ONOS "bench".
41 '''
42 try:
43 for key in connectargs:
44 vars(self)[key] = connectargs[key]
45 self.home = "~/ONOS"
46 for key in self.options:
47 if key == "home":
48 self.home = self.options['home']
49 break
50
51
52 self.name = self.options['name']
Jon Hallea7818b2014-10-09 14:30:59 -040053 self.handle = super(OnosDriver,self).connect(
54 user_name = self.user_name,
55 ip_address = self.ip_address,
56 port = self.port,
57 pwd = self.pwd,
58 home = self.home)
Jon Hallea7818b2014-10-09 14:30:59 -040059
60 self.handle.sendline("cd "+ self.home)
61 self.handle.expect("\$")
Jon Hall05b2b432014-10-08 19:53:25 -040062 if self.handle:
63 return self.handle
64 else :
65 main.log.info("NO ONOS HANDLE")
66 return main.FALSE
67 except pexpect.EOF:
68 main.log.error(self.name + ": EOF exception found")
69 main.log.error(self.name + ": " + self.handle.before)
70 main.cleanup()
71 main.exit()
72 except:
73 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
74 main.log.error( traceback.print_exc() )
75 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
76 main.cleanup()
77 main.exit()
78
79 def disconnect(self):
80 '''
81 Called when Test is complete to disconnect the ONOS handle.
82 '''
83 response = ''
84 try:
Jon Hallf8d10982014-10-22 12:23:38 -040085 self.handle.sendline("\n")
86 self.handle.expect("\$")
Jon Hall05b2b432014-10-08 19:53:25 -040087 self.handle.sendline("exit")
88 self.handle.expect("closed")
89 except pexpect.EOF:
90 main.log.error(self.name + ": EOF exception found")
91 main.log.error(self.name + ": " + self.handle.before)
92 except:
93 main.log.error(self.name + ": Connection failed to the host")
94 response = main.FALSE
95 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -040096
97 def onos_package(self):
98 '''
99 Produce a self-contained tar.gz file that can be deployed
100 and executed on any platform with Java 7 JRE.
101 '''
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400102
103 try:
104 self.handle.sendline("onos-package")
Jon Hallea7818b2014-10-09 14:30:59 -0400105 self.handle.expect("onos-package")
andrewonlab0748d2a2014-10-09 13:24:17 -0400106 self.handle.expect("tar.gz",timeout=10)
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400107 handle = str(self.handle.before)
108 main.log.info("onos-package command returned: "+
109 handle)
andrewonlab0748d2a2014-10-09 13:24:17 -0400110 #As long as the sendline does not time out,
111 #return true. However, be careful to interpret
112 #the results of the onos-package command return
113 return main.TRUE
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400114
andrewonlab7735d852014-10-09 13:02:47 -0400115 except pexpect.EOF:
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400116 main.log.error(self.name + ": EOF exception found")
117 main.log.error(self.name + ": " + self.handle.before)
118 except:
119 main.log.error("Failed to package ONOS")
120 main.cleanup()
121 main.exit()
122
andrewonlab8790abb2014-11-06 13:51:54 -0500123 def onos_build(self):
124 '''
125 Use the pre defined script to build onos via mvn
126 '''
127
128 try:
129 self.handle.sendline("onos-build")
130 self.handle.expect("onos-build")
131 i = self.handle.expect([
132 "BUILD SUCCESS",
133 "ERROR",
134 "BUILD FAILED"], timeout=120)
135 handle = str(self.handle.before)
136
137 main.log.info("onos-build command returned: "+
138 handle)
139
140 if i == 0:
141 return main.TRUE
142 else:
143 return handle
144
145 except pexpect.EOF:
146 main.log.error(self.name + ": EOF exception found")
147 main.log.error(self.name + ": " + self.handle.before)
148 except:
149 main.log.error("Failed to build ONOS")
150 main.cleanup()
151 main.exit()
152
Jon Hallde9d9aa2014-10-08 20:36:02 -0400153 def clean_install(self):
154 '''
155 Runs mvn clean install in the root of the ONOS directory.
156 This will clean all ONOS artifacts then compile each module
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400157
Jon Hallde9d9aa2014-10-08 20:36:02 -0400158 Returns: main.TRUE on success
159 On Failure, exits the test
160 '''
161 try:
Jon Hallea7818b2014-10-09 14:30:59 -0400162 main.log.info("Running 'mvn clean install' on " + str(self.name) +
163 ". This may take some time.")
164 self.handle.sendline("cd "+ self.home)
165 self.handle.expect("\$")
166
167 self.handle.sendline("\n")
168 self.handle.expect("\$")
Jon Hallde9d9aa2014-10-08 20:36:02 -0400169 self.handle.sendline("mvn clean install")
Jon Hallea7818b2014-10-09 14:30:59 -0400170 self.handle.expect("mvn clean install")
Jon Hallde9d9aa2014-10-08 20:36:02 -0400171 while 1:
172 i=self.handle.expect([
173 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s\
174 Runtime\sEnvironment\sto\scontinue',
175 'BUILD\sFAILURE',
176 'BUILD\sSUCCESS',
177 'ONOS\$',
178 pexpect.TIMEOUT],timeout=600)
179 if i == 0:
180 main.log.error(self.name + ":There is insufficient memory \
181 for the Java Runtime Environment to continue.")
182 #return main.FALSE
183 main.cleanup()
184 main.exit()
185 if i == 1:
186 main.log.error(self.name + ": Build failure!")
187 #return main.FALSE
188 main.cleanup()
189 main.exit()
190 elif i == 2:
191 main.log.info(self.name + ": Build success!")
192 elif i == 3:
193 main.log.info(self.name + ": Build complete")
Jon Hallf8ef52c2014-10-09 19:37:33 -0400194 #Print the build time
195 for line in self.handle.before.splitlines():
196 if "Total time:" in line:
197 main.log.info(line)
Jon Hallea7818b2014-10-09 14:30:59 -0400198 self.handle.sendline("\n")
Jon Hallde9d9aa2014-10-08 20:36:02 -0400199 self.handle.expect("\$", timeout=60)
200 return main.TRUE
201 elif i == 4:
202 main.log.error(self.name + ": mvn clean install TIMEOUT!")
203 #return main.FALSE
204 main.cleanup()
205 main.exit()
206 else:
207 main.log.error(self.name + ": unexpected response from \
208 mvn clean install")
209 #return main.FALSE
210 main.cleanup()
211 main.exit()
212 except pexpect.EOF:
213 main.log.error(self.name + ": EOF exception found")
214 main.log.error(self.name + ": " + self.handle.before)
215 main.cleanup()
216 main.exit()
217 except:
218 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
219 main.log.error( traceback.print_exc() )
220 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
221 main.cleanup()
222 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400223
224 def git_pull(self, comp1=""):
225 '''
226 Assumes that "git pull" works without login
227
228 This function will perform a git pull on the ONOS instance.
229 If used as git_pull("NODE") it will do git pull + NODE. This is
230 for the purpose of pulling from other nodes if necessary.
231
232 Otherwise, this function will perform a git pull in the
233 ONOS repository. If it has any problems, it will return main.ERROR
Shreya Shahee15f6c2014-10-28 18:12:30 -0400234 If it successfully does a git_pull, it will return a 1 (main.TRUE)
235 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400236
237 '''
238 try:
239 # main.log.info(self.name + ": Stopping ONOS")
240 #self.stop()
241 self.handle.sendline("cd " + self.home)
242 self.handle.expect("ONOS\$")
243 if comp1=="":
244 self.handle.sendline("git pull")
245 else:
246 self.handle.sendline("git pull " + comp1)
247
248 uptodate = 0
249 i=self.handle.expect(['fatal',
250 'Username\sfor\s(.*):\s',
251 '\sfile(s*) changed,\s',
252 'Already up-to-date',
253 'Aborting',
254 'You\sare\snot\scurrently\son\sa\sbranch',
255 'You\sasked\sme\sto\spull\swithout\stelling\sme\swhich\sbranch\syou',
256 'Pull\sis\snot\spossible\sbecause\syou\shave\sunmerged\sfiles',
257 pexpect.TIMEOUT],
258 timeout=300)
259 #debug
260 #main.log.report(self.name +": \n"+"git pull response: " + str(self.handle.before) + str(self.handle.after))
261 if i==0:
262 main.log.error(self.name + ": Git pull had some issue...")
263 return main.ERROR
264 elif i==1:
265 main.log.error(self.name + ": Git Pull Asking for username. ")
266 return main.ERROR
267 elif i==2:
268 main.log.info(self.name + ": Git Pull - pulling repository now")
269 self.handle.expect("ONOS\$", 120)
Shreya Shahee15f6c2014-10-28 18:12:30 -0400270 return main.TRUE # So that only when git pull is done, we do mvn clean compile
Jon Hallacabffd2014-10-09 12:36:53 -0400271 elif i==3:
272 main.log.info(self.name + ": Git Pull - Already up to date")
Shreya Shahee15f6c2014-10-28 18:12:30 -0400273 return i
Jon Hallacabffd2014-10-09 12:36:53 -0400274 elif i==4:
275 main.log.info(self.name + ": Git Pull - Aborting... Are there conflicting git files?")
276 return main.ERROR
277 elif i==5:
278 main.log.info(self.name + ": Git Pull - You are not currently on a branch so git pull failed!")
279 return main.ERROR
280 elif i==6:
281 main.log.info(self.name + ": Git Pull - You have not configured an upstream branch to pull from. Git pull failed!")
282 return main.ERROR
283 elif i==7:
284 main.log.info(self.name + ": Git Pull - Pull is not possible because you have unmerged files.")
285 return main.ERROR
286 elif i==8:
287 main.log.error(self.name + ": Git Pull - TIMEOUT")
288 main.log.error(self.name + " Response was: " + str(self.handle.before))
289 return main.ERROR
290 else:
291 main.log.error(self.name + ": Git Pull - Unexpected response, check for pull errors")
292 return main.ERROR
293 except pexpect.EOF:
294 main.log.error(self.name + ": EOF exception found")
295 main.log.error(self.name + ": " + self.handle.before)
296 main.cleanup()
297 main.exit()
298 except:
299 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
300 main.log.error( traceback.print_exc() )
301 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
302 main.cleanup()
303 main.exit()
304
305 def git_checkout(self, branch="master"):
306 '''
307 Assumes that "git pull" works without login
308
309 This function will perform a git git checkout on the ONOS instance.
310 If used as git_checkout("branch") it will do git checkout of the "branch".
311
312 Otherwise, this function will perform a git checkout of the master
313 branch of the ONOS repository. If it has any problems, it will return
314 main.ERROR.
315 If the branch was already the specified branch, or the git checkout was
316 successful then the function will return main.TRUE.
317
318 '''
319 try:
320 # main.log.info(self.name + ": Stopping ONOS")
321 #self.stop()
322 self.handle.sendline("cd " + self.home)
323 self.handle.expect("ONOS\$")
324 if branch != 'master':
325 #self.handle.sendline('git stash')
326 #self.handle.expect('ONOS\$')
327 #print "After issuing git stash cmnd: ", self.handle.before
328 cmd = "git checkout "+branch
329 print "checkout cmd = ", cmd
330 self.handle.sendline(cmd)
331 uptodate = 0
332 i=self.handle.expect(['fatal',
333 'Username\sfor\s(.*):\s',
334 'Already\son\s\'',
335 'Switched\sto\sbranch\s\'',
336 pexpect.TIMEOUT],timeout=60)
337 else:
338 #self.handle.sendline('git stash apply')
339 #self.handle.expect('ONOS\$')
340 #print "After issuing git stash apply cmnd: ", self.handle.before
341 cmd = "git checkout "+branch
342 print "checkout cmd = ", cmd
343 self.handle.sendline(cmd)
344 uptodate = 0
345 switchedToMaster = 0
346 i=self.handle.expect(['fatal',
347 'Username\sfor\s(.*):\s',
348 'Already\son\s\'master\'',
349 'Switched\sto\sbranch\s\'master\'',
350 pexpect.TIMEOUT],timeout=60)
351
352
353 if i==0:
354 main.log.error(self.name + ": Git checkout had some issue...")
355 return main.ERROR
356 elif i==1:
357 main.log.error(self.name + ": Git checkout Asking for username!!! Bad!")
358 return main.ERROR
359 elif i==2:
360 main.log.info(self.name + ": Git Checkout %s : Already on this branch" %branch)
361 self.handle.expect("ONOS\$")
362 print "after checkout cmd = ", self.handle.before
363 switchedToMaster = 1
364 return main.TRUE
365 elif i==3:
366 main.log.info(self.name + ": Git checkout %s - Switched to this branch" %branch)
367 self.handle.expect("ONOS\$")
368 print "after checkout cmd = ", self.handle.before
369 switchedToMaster = 1
370 return main.TRUE
371 elif i==4:
372 main.log.error(self.name + ": Git Checkout- TIMEOUT")
373 main.log.error(self.name + " Response was: " + str(self.handle.before))
374 return main.ERROR
375 else:
376 main.log.error(self.name + ": Git Checkout - Unexpected response, check for pull errors")
377 return main.ERROR
378
379 except pexpect.EOF:
380 main.log.error(self.name + ": EOF exception found")
381 main.log.error(self.name + ": " + self.handle.before)
382 main.cleanup()
383 main.exit()
384 except:
385 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
386 main.log.error( traceback.print_exc() )
387 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
388 main.cleanup()
389 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400390
Jon Hall45ec0922014-10-10 19:33:49 -0400391 def get_version(self):
392 '''
393 Writes the COMMIT number to the report to be parsed by Jenkins data collecter.
394 '''
395 try:
396 self.handle.sendline("export TERM=xterm-256color")
397 self.handle.expect("xterm-256color")
398 self.handle.expect("\$")
Jon Hall42db6dc2014-10-24 19:03:48 -0400399 self.handle.sendline("\n")
400 self.handle.expect("\$")
401 self.handle.sendline("cd " + self.home + "; git log -1 --pretty=fuller --decorate=short | grep -A 6 \"commit\" --color=never")
402 self.handle.expect("--color=never")
Jon Hall45ec0922014-10-10 19:33:49 -0400403 self.handle.expect("\$")
404 response=(self.name +": \n"+ str(self.handle.before + self.handle.after))
Jon Hall42db6dc2014-10-24 19:03:48 -0400405 self.handle.sendline("cd " + self.home)
406 self.handle.expect("\$")
Jon Hall45ec0922014-10-10 19:33:49 -0400407 lines=response.splitlines()
408 for line in lines:
409 print line
410 return lines[2]
411 except pexpect.EOF:
412 main.log.error(self.name + ": EOF exception found")
413 main.log.error(self.name + ": " + self.handle.before)
414 main.cleanup()
415 main.exit()
416 except:
417 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
418 main.log.error( traceback.print_exc() )
419 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
420 main.cleanup()
421 main.exit()
422
andrewonlabba44bcf2014-10-16 16:54:41 -0400423 def create_cell_file(self, bench_ip, file_name, mn_ip_addrs,
andrewonlab3f0a4af2014-10-17 12:25:14 -0400424 extra_feature_string, *onos_ip_addrs):
andrewonlab94282092014-10-10 13:00:11 -0400425 '''
426 Creates a cell file based on arguments
427 Required:
428 * Bench IP address (bench_ip)
429 - Needed to copy the cell file over
430 * File name of the cell file (file_name)
431 * Mininet IP address (mn_ip_addrs)
432 - Note that only 1 ip address is
433 supported currently
434 * ONOS IP addresses (onos_ip_addrs)
435 - Must be passed in as last arguments
436
437 NOTE: Assumes cells are located at:
438 ~/<self.home>/tools/test/cells/
439 '''
440
441 #Variable initialization
442 cell_directory = self.home + "/tools/test/cells/"
443 #We want to create the cell file in the dependencies directory
444 #of TestON first, then copy over to ONOS bench
445 temp_directory = "/tmp/"
446 #Create the cell file in the directory for writing (w+)
447 cell_file = open(temp_directory+file_name , 'w+')
andrewonlabd4940492014-10-24 12:21:27 -0400448
449 comment = ""
450 comment_string = "#"+ comment
andrewonlab7e4d2d32014-10-15 13:23:21 -0400451 #Feature string is hardcoded environment variables
452 #That you may wish to use by default on startup.
453 #Note that you may not want certain features listed
454 #on here.
andrewonlabba44bcf2014-10-16 16:54:41 -0400455 core_feature_string = "export ONOS_FEATURES=webconsole,onos-api,"+\
456 "onos-cli,onos-openflow,onos-app-mobility,onos-app-tvue,"+\
457 "onos-app-proxyarp,"+extra_feature_string
andrewonlab94282092014-10-10 13:00:11 -0400458 mn_string = "export OCN="
459 onos_string = "export OC"
460 temp_count = 1
461
462 #Create ONOS_NIC ip address prefix
463 temp_onos_ip = onos_ip_addrs[0]
464 temp_list = []
465 temp_list = temp_onos_ip.split(".")
andrewonlab7e4d2d32014-10-15 13:23:21 -0400466 #Omit last element of list to format for NIC
andrewonlab94282092014-10-10 13:00:11 -0400467 temp_list = temp_list[:-1]
468 #Structure the nic string ip
andrewonlabd4940492014-10-24 12:21:27 -0400469 nic_addr = ".".join(temp_list) + ".*"
andrewonlab94282092014-10-10 13:00:11 -0400470 onos_nic_string = "export ONOS_NIC="+nic_addr
471
472 try:
473 #Start writing to file
andrewonlabd4940492014-10-24 12:21:27 -0400474 cell_file.write(onos_nic_string + "\n")
andrewonlab94282092014-10-10 13:00:11 -0400475
476 for arg in onos_ip_addrs:
477 #For each argument in onos_ip_addrs, write to file
478 #Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400479 # export OC1="10.128.20.11"
480 # export OC2="10.128.20.12"
andrewonlab94282092014-10-10 13:00:11 -0400481 cell_file.write(onos_string + str(temp_count) +
andrewonlabd4940492014-10-24 12:21:27 -0400482 "=" + "\"" + arg + "\"" + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400483 temp_count = temp_count + 1
484
andrewonlabd4940492014-10-24 12:21:27 -0400485 cell_file.write(mn_string +"\""+ mn_ip_addrs +"\""+ "\n")
486 cell_file.write(core_feature_string + "\n")
andrewonlab94282092014-10-10 13:00:11 -0400487 cell_file.close()
488
489 #We use os.system to send the command to TestON cluster
490 #to account for the case in which TestON is not located
491 #on the same cluster as the ONOS bench
492 #Note that even if TestON is located on the same cluster
493 #as ONOS bench, you must setup passwordless ssh
andrewonlab7e4d2d32014-10-15 13:23:21 -0400494 #between TestON and ONOS bench in order to automate the test.
andrewonlab94282092014-10-10 13:00:11 -0400495 os.system("scp "+temp_directory+file_name+
496 " admin@"+bench_ip+":"+cell_directory)
497
andrewonlab2a6c9342014-10-16 13:40:15 -0400498 return main.TRUE
499
andrewonlab94282092014-10-10 13:00:11 -0400500 except pexpect.EOF:
501 main.log.error(self.name + ": EOF exception found")
502 main.log.error(self.name + ": " + self.handle.before)
503 main.cleanup()
504 main.exit()
505 except:
506 main.log.info(self.name + ":::::::::")
507 main.log.error( traceback.print_exc() )
508 main.log.info(":::::::")
509 main.cleanup()
510 main.exit()
511
andrewonlab95ca1462014-10-09 14:04:24 -0400512 def set_cell(self, cellname):
513 '''
514 Calls 'cell <name>' to set the environment variables on ONOSbench
515 '''
516 try:
517 if not cellname:
518 main.log.error("Must define cellname")
519 main.cleanup()
520 main.exit()
521 else:
522 self.handle.sendline("cell "+str(cellname))
523 #Expect the cellname in the ONOS_CELL variable.
524 #Note that this variable name is subject to change
525 # and that this driver will have to change accordingly
526 self.handle.expect("ONOS_CELL="+str(cellname))
527 handle_before = self.handle.before
528 handle_after = self.handle.after
andrewonlabc03bf6c2014-10-09 14:56:18 -0400529 #Get the rest of the handle
530 self.handle.sendline("")
531 self.handle.expect("\$")
532 handle_more = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400533
534 main.log.info("Cell call returned: "+handle_before+
andrewonlabc03bf6c2014-10-09 14:56:18 -0400535 handle_after + handle_more)
andrewonlab95ca1462014-10-09 14:04:24 -0400536
537 return main.TRUE
538
539 except pexpect.EOF:
540 main.log.error(self.name + ": EOF exception found")
541 main.log.error(self.name + ": " + self.handle.before)
542 main.cleanup()
543 main.exit()
544 except:
545 main.log.info(self.name+" ::::::")
546 main.log.error( traceback.print_exc())
547 main.log.info(self.name+" ::::::")
548 main.cleanup()
549 main.exit()
550
andrewonlabc03bf6c2014-10-09 14:56:18 -0400551 def verify_cell(self):
552 '''
553 Calls 'onos-verify-cell' to check for cell installation
554 '''
andrewonlab8d0d7d72014-10-09 16:33:15 -0400555 #TODO: Add meaningful expect value
556
andrewonlabc03bf6c2014-10-09 14:56:18 -0400557 try:
558 #Clean handle by sending empty and expecting $
559 self.handle.sendline("")
560 self.handle.expect("\$")
561 self.handle.sendline("onos-verify-cell")
562 self.handle.expect("\$")
563 handle_before = self.handle.before
564 handle_after = self.handle.after
565 #Get the rest of the handle
566 self.handle.sendline("")
567 self.handle.expect("\$")
568 handle_more = self.handle.before
569
570 main.log.info("Verify cell returned: "+handle_before+
571 handle_after + handle_more)
572
573 return main.TRUE
Jon Hall7993bfc2014-10-09 16:30:14 -0400574 except pexpect.EOF:
575 main.log.error(self.name + ": EOF exception found")
576 main.log.error(self.name + ": " + self.handle.before)
577 main.cleanup()
578 main.exit()
579 except:
580 main.log.info(self.name+" ::::::")
581 main.log.error( traceback.print_exc())
582 main.log.info(self.name+" ::::::")
583 main.cleanup()
584 main.exit()
585
andrewonlab05e362f2014-10-10 00:40:57 -0400586 def onos_cli(self, ONOS_ip, cmdstr):
587 '''
588 Uses 'onos' command to send various ONOS CLI arguments.
589 Required:
590 * ONOS_ip: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400591 * cmdstr: specify the command string to send
andrewonlab6e20c342014-10-10 18:08:48 -0400592
593 This function is intended to expose the entire karaf
594 CLI commands for ONOS. Try to use this function first
595 before attempting to write a ONOS CLI specific driver
596 function.
597 You can see a list of available 'cmdstr' arguments
598 by starting onos, and typing in 'onos' to enter the
599 onos> CLI. Then, type 'help' to see the list of
600 available commands.
andrewonlab05e362f2014-10-10 00:40:57 -0400601 '''
602 try:
603 if not ONOS_ip:
604 main.log.error("You must specify the IP address")
605 return main.FALSE
606 if not cmdstr:
607 main.log.error("You must specify the command string")
608 return main.FALSE
609
610 cmdstr = str(cmdstr)
611 self.handle.sendline("")
612 self.handle.expect("\$")
613
614 self.handle.sendline("onos -w " + ONOS_ip + " " + cmdstr)
615 self.handle.expect("\$")
616
Shreya Shaha73aaad2014-10-27 18:03:09 -0400617 handle_before = self.handle.before
618 print "handle_before = ", self.handle.before
andrewonlab05e362f2014-10-10 00:40:57 -0400619 handle_after = str(self.handle.after)
620
Shreya Shaha73aaad2014-10-27 18:03:09 -0400621 #self.handle.sendline("")
622 #self.handle.expect("\$")
623 #handle_more = str(self.handle.before)
andrewonlab05e362f2014-10-10 00:40:57 -0400624
625 main.log.info("Command sent successfully")
626
andrewonlab94282092014-10-10 13:00:11 -0400627 #Obtain return handle that consists of result from
628 #the onos command. The string may need to be
629 #configured further.
Shreya Shaha73aaad2014-10-27 18:03:09 -0400630 #return_string = handle_before + handle_after
631 return_string = handle_before
632 print "return_string = ", return_string
andrewonlab05e362f2014-10-10 00:40:57 -0400633 return return_string
634
635 except pexpect.EOF:
636 main.log.error(self.name + ": EOF exception found")
637 main.log.error(self.name + ": " + self.handle.before)
638 main.cleanup()
639 main.exit()
640 except:
641 main.log.info(self.name+" ::::::")
642 main.log.error( traceback.print_exc())
643 main.log.info(self.name+" ::::::")
644 main.cleanup()
645 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400646
647 def onos_install(self, options="-f", node = ""):
648 '''
649 Installs ONOS bits on the designated cell machine.
650 If -f option is provided, it also forces an uninstall.
651 Presently, install also includes onos-push-bits and
652 onos-config within.
653 The node option allows you to selectively only push the jar
654 files to certain onos nodes
655
656 Returns: main.TRUE on success and main.FALSE on failure
657 '''
658 try:
659 self.handle.sendline("onos-install " + options + " " + node)
660 self.handle.expect("onos-install ")
661 #NOTE: this timeout may need to change depending on the network and size of ONOS
662 i=self.handle.expect(["Network\sis\sunreachable",
663 "onos\sstart/running,\sprocess",
664 pexpect.TIMEOUT],timeout=60)
665
Jon Hall7993bfc2014-10-09 16:30:14 -0400666 if i == 0:
667 main.log.warn("Network is unreachable")
668 return main.FALSE
669 elif i == 1:
Jon Hall42db6dc2014-10-24 19:03:48 -0400670 main.log.info("ONOS was installed on " + node + " and started")
Jon Hall7993bfc2014-10-09 16:30:14 -0400671 return main.TRUE
672 elif i == 2:
Jon Hall42db6dc2014-10-24 19:03:48 -0400673 main.log.info("Installation of ONOS on " + node + " timed out")
Jon Hall7993bfc2014-10-09 16:30:14 -0400674 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400675
676 except pexpect.EOF:
677 main.log.error(self.name + ": EOF exception found")
678 main.log.error(self.name + ": " + self.handle.before)
679 main.cleanup()
680 main.exit()
681 except:
682 main.log.info(self.name+" ::::::")
683 main.log.error( traceback.print_exc())
684 main.log.info(self.name+" ::::::")
685 main.cleanup()
686 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400687
andrewonlab8d0d7d72014-10-09 16:33:15 -0400688 def onos_start(self, node_ip):
689 '''
690 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400691 This command is a remote management of the ONOS upstart daemon
andrewonlab8d0d7d72014-10-09 16:33:15 -0400692 '''
693
694 try:
695 self.handle.sendline("")
696 self.handle.expect("\$")
697 self.handle.sendline("onos-service "+str(node_ip)+
698 " start")
699 i = self.handle.expect([
700 "Job\sis\salready\srunning",
701 "start/running",
702 "Unknown\sinstance",
Shreya Shahd01153d2014-10-23 15:08:56 -0400703 pexpect.TIMEOUT],timeout=120)
andrewonlab8d0d7d72014-10-09 16:33:15 -0400704
705 if i == 0:
706 main.log.info("Service is already running")
707 return main.TRUE
708 elif i == 1:
709 main.log.info("ONOS service started")
710 return main.TRUE
711 else:
712 main.log.error("ONOS service failed to start")
713 main.cleanup()
714 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400715 except pexpect.EOF:
716 main.log.error(self.name + ": EOF exception found")
717 main.log.error(self.name + ": " + self.handle.before)
718 main.cleanup()
719 main.exit()
720 except:
721 main.log.info(self.name+" ::::::")
722 main.log.error( traceback.print_exc())
723 main.log.info(self.name+" ::::::")
724 main.cleanup()
725 main.exit()
726
andrewonlab2b30bd32014-10-09 16:48:55 -0400727 def onos_stop(self, node_ip):
728 '''
729 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400730 This command is a remote management of the ONOS upstart daemon
andrewonlab2b30bd32014-10-09 16:48:55 -0400731 '''
732 try:
733 self.handle.sendline("")
734 self.handle.expect("\$")
735 self.handle.sendline("onos-service "+str(node_ip)+
736 " stop")
737 i = self.handle.expect([
738 "stop/waiting",
739 "Unknown\sinstance",
740 pexpect.TIMEOUT],timeout=60)
741
742 if i == 0:
743 main.log.info("ONOS service stopped")
744 return main.TRUE
745 elif i == 1:
746 main.log.info("Unknown ONOS instance specified: "+
747 str(node_ip))
748 return main.FALSE
749 else:
750 main.log.error("ONOS service failed to stop")
751 return main.FALSE
752
753 except pexpect.EOF:
754 main.log.error(self.name + ": EOF exception found")
755 main.log.error(self.name + ": " + self.handle.before)
756 main.cleanup()
757 main.exit()
758 except:
759 main.log.info(self.name+" ::::::")
760 main.log.error( traceback.print_exc())
761 main.log.info(self.name+" ::::::")
762 main.cleanup()
763 main.exit()
764
andrewonlabc8d47972014-10-09 16:52:36 -0400765 def onos_uninstall(self):
766 '''
767 Calls the command: 'onos-uninstall'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400768 Uninstalls ONOS from the designated cell machine, stopping
769 if needed
andrewonlabc8d47972014-10-09 16:52:36 -0400770 '''
771 try:
772 self.handle.sendline("")
773 self.handle.expect("\$")
774 self.handle.sendline("onos-uninstall")
775 self.handle.expect("\$")
776
andrewonlab84727452014-10-09 18:15:36 -0400777 main.log.info("ONOS cell machine was uninstalled")
andrewonlabc8d47972014-10-09 16:52:36 -0400778 #onos-uninstall command does not return any text
779 return main.TRUE
780
781 except pexpect.EOF:
782 main.log.error(self.name + ": EOF exception found")
783 main.log.error(self.name + ": " + self.handle.before)
784 main.cleanup()
785 main.exit()
786 except:
787 main.log.info(self.name+" ::::::")
788 main.log.error( traceback.print_exc())
789 main.log.info(self.name+" ::::::")
790 main.cleanup()
791 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -0400792
andrewonlabe8e56fd2014-10-09 17:12:44 -0400793 def onos_kill(self, node_ip):
794 '''
795 Calls the command: 'onos-kill [<node-ip>]'
796 "Remotely, and unceremoniously kills the ONOS instance running on
797 the specified cell machine" - Tom V
798 '''
799
800 try:
801 self.handle.sendline("")
802 self.handle.expect("\$")
803 self.handle.sendline("onos-kill " + str(node_ip))
804 i = self.handle.expect([
805 "\$",
806 "No\sroute\sto\shost",
807 "password:",
808 pexpect.TIMEOUT], timeout=20)
809
810 if i == 0:
811 main.log.info("ONOS instance "+str(node_ip)+" was killed")
812 return main.TRUE
813 elif i == 1:
814 main.log.info("No route to host")
815 return main.FALSE
816 elif i == 2:
817 main.log.info("Passwordless login for host: "+str(node_ip)+
818 " not configured")
819 return main.FALSE
820 else:
821 main.log.info("ONOS instasnce was not killed")
822 return main.FALSE
823
824 except pexpect.EOF:
825 main.log.error(self.name + ": EOF exception found")
826 main.log.error(self.name + ": " + self.handle.before)
827 main.cleanup()
828 main.exit()
829 except:
830 main.log.info(self.name+" ::::::")
831 main.log.error( traceback.print_exc())
832 main.log.info(self.name+" ::::::")
833 main.cleanup()
834 main.exit()
835
andrewonlab94282092014-10-10 13:00:11 -0400836 def onos_start_network(self, mntopo):
837 '''
838 Calls the command 'onos-start-network [<mininet-topo>]
839 "remotely starts the specified topology on the cell's
840 mininet machine against all controllers configured in the
841 cell."
842 * Specify mininet topology file name for mntopo
843 * Topo files should be placed at:
844 ~/<your-onos-directory>/tools/test/topos
845
846 NOTE: This function will take you to the mininet prompt
847 '''
848 try:
849 if not mntopo:
850 main.log.error("You must specify a topo file to execute")
851 return main.FALSE
852
853 mntopo = str(mntopo)
854 self.handle.sendline("")
855 self.handle.expect("\$")
856
857 self.handle.sendline("onos-start-network " + mntopo)
858 self.handle.expect("mininet>")
859 main.log.info("Network started, entered mininet prompt")
860
861 #TODO: Think about whether return is necessary or not
862
863 except pexpect.EOF:
864 main.log.error(self.name + ": EOF exception found")
865 main.log.error(self.name + ": " + self.handle.before)
866 main.cleanup()
867 main.exit()
868 except:
869 main.log.info(self.name+" ::::::")
870 main.log.error( traceback.print_exc())
871 main.log.info(self.name+" ::::::")
872 main.cleanup()
873 main.exit()
874
875
Jon Hall7993bfc2014-10-09 16:30:14 -0400876 def isup(self, node = ""):
877 '''
Jon Hall77f53ce2014-10-13 18:02:06 -0400878 Run's onos-wait-for-start which only returns once ONOS is at run
879 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -0400880
Jon Hall7993bfc2014-10-09 16:30:14 -0400881 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
882 '''
883 try:
884 self.handle.sendline("onos-wait-for-start " + node )
885 self.handle.expect("onos-wait-for-start")
886 #NOTE: this timeout is arbitrary"
887 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout = 120)
888 if i == 0:
889 main.log.info(self.name + ": " + node + " is up")
890 return main.TRUE
891 elif i == 1:
892 #NOTE: since this function won't return until ONOS is ready,
893 # we will kill it on timeout
894 self.handle.sendline("\003") #Control-C
895 self.handle.expect("\$")
896 return main.FALSE
897 except pexpect.EOF:
898 main.log.error(self.name + ": EOF exception found")
899 main.log.error(self.name + ": " + self.handle.before)
900 main.cleanup()
901 main.exit()
902 except:
903 main.log.info(self.name+" ::::::")
904 main.log.error( traceback.print_exc())
905 main.log.info(self.name+" ::::::")
906 main.cleanup()
907 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -0400908
909
Shreya Shaha73aaad2014-10-27 18:03:09 -0400910 def get_topology(self,topology_output):
Jon Hall77f53ce2014-10-13 18:02:06 -0400911 '''
912 parses the onos:topology output
913 Returns: a topology dict populated by the key values found in
914 the cli command.
915 '''
916
917 try:
918 #call the cli to get the topology summary
Shreya Shaha73aaad2014-10-27 18:03:09 -0400919 #cmdstr = "onos:topology"
920 #cli_result = self.onos_cli(ip, cmdstr)
921 #print "cli_result = ", cli_result
Jon Hall77f53ce2014-10-13 18:02:06 -0400922
923 #Parse the output
924 topology = {}
925 #for line in cli_result.split("\n"):
Shreya Shaha73aaad2014-10-27 18:03:09 -0400926 for line in topology_output.splitlines():
Jon Hall77f53ce2014-10-13 18:02:06 -0400927 if not line.startswith("time="):
928 continue
929 #else
930 print line
931 for var in line.split(","):
Shreya Shaha73aaad2014-10-27 18:03:09 -0400932 #print "'"+var+"'"
933 #print "'"+var.strip()+"'"
Jon Hall77f53ce2014-10-13 18:02:06 -0400934 key, value = var.strip().split("=")
935 topology[key] = value
Shreya Shaha73aaad2014-10-27 18:03:09 -0400936 print "topology = ", topology
Jon Hall77f53ce2014-10-13 18:02:06 -0400937 devices = topology.get('devices', False)
Shreya Shaha73aaad2014-10-27 18:03:09 -0400938 print "devices = ", devices
Jon Hall77f53ce2014-10-13 18:02:06 -0400939 links = topology.get('links', False)
Shreya Shaha73aaad2014-10-27 18:03:09 -0400940 print "links = ", links
Jon Hall77f53ce2014-10-13 18:02:06 -0400941 clusters = topology.get('clusters', False)
Shreya Shaha73aaad2014-10-27 18:03:09 -0400942 print "clusters = ", clusters
Jon Hall77f53ce2014-10-13 18:02:06 -0400943 paths = topology.get('paths', False)
Shreya Shaha73aaad2014-10-27 18:03:09 -0400944 print "paths = ", paths
Jon Hall77f53ce2014-10-13 18:02:06 -0400945
946 return topology
947 except pexpect.EOF:
948 main.log.error(self.name + ": EOF exception found")
949 main.log.error(self.name + ": " + self.handle.before)
950 main.cleanup()
951 main.exit()
952 except:
953 main.log.info(self.name+" ::::::")
954 main.log.error( traceback.print_exc())
955 main.log.info(self.name+" ::::::")
956 main.cleanup()
957 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -0400958
959
Jon Hall77f53ce2014-10-13 18:02:06 -0400960
Shreya Shaha73aaad2014-10-27 18:03:09 -0400961 def check_status(self, topology_result, numoswitch, numolink, log_level="info"):
Jon Hall77f53ce2014-10-13 18:02:06 -0400962 '''
963 Checks the number of swithes & links that ONOS sees against the
964 supplied values. By default this will report to main.log, but the
965 log level can be specifid.
966
967 Params: ip = ip used for the onos cli
968 numoswitch = expected number of switches
969 numlink = expected number of links
970 log_level = level to log to. Currently accepts 'info', 'warn' and 'report'
971
972
973 log_level can
974
975 Returns: main.TRUE if the number of switchs and links are correct,
976 main.FALSE if the numer of switches and links is incorrect,
977 and main.ERROR otherwise
978 '''
979
980 try:
Shreya Shaha73aaad2014-10-27 18:03:09 -0400981 topology = self.get_topology(topology_result)
Jon Hall77f53ce2014-10-13 18:02:06 -0400982 if topology == {}:
983 return main.ERROR
984 output = ""
985 #Is the number of switches is what we expected
986 devices = topology.get('devices',False)
987 links = topology.get('links',False)
988 if devices == False or links == False:
989 return main.ERROR
990 switch_check = ( int(devices) == int(numoswitch) )
991 #Is the number of links is what we expected
992 link_check = ( int(links) == int(numolink) )
993 if (switch_check and link_check):
994 #We expected the correct numbers
995 output = output + "The number of links and switches match "\
996 + "what was expected"
997 result = main.TRUE
998 else:
999 output = output + \
1000 "The number of links and switches does not match what was expected"
1001 result = main.FALSE
1002 output = output + "\n ONOS sees %i devices (%i expected) and %i links (%i expected)"\
1003 % ( int(devices), int(numoswitch), int(links), int(numolink) )
1004 if log_level == "report":
1005 main.log.report(output)
1006 elif log_level == "warn":
1007 main.log.warn(output)
1008 else:
1009 main.log.info(output)
1010 return result
1011 except pexpect.EOF:
1012 main.log.error(self.name + ": EOF exception found")
1013 main.log.error(self.name + ": " + self.handle.before)
1014 main.cleanup()
1015 main.exit()
1016 except:
1017 main.log.info(self.name+" ::::::")
1018 main.log.error( traceback.print_exc())
1019 main.log.info(self.name+" ::::::")
1020 main.cleanup()
1021 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001022
Shreya Shaha73aaad2014-10-27 18:03:09 -04001023
andrewonlabba44bcf2014-10-16 16:54:41 -04001024 def tshark_grep(self, grep, directory, interface='eth0'):
1025 '''
1026 Required:
1027 * grep string
1028 * directory to store results
1029 Optional:
1030 * interface - default: eth0
1031 Description:
1032 Uses tshark command to grep specific group of packets
1033 and stores the results to specified directory.
1034 The timestamp is hardcoded to be in epoch
1035 '''
1036 self.handle.sendline("")
1037 self.handle.expect("\$")
andrewonlabefd7f3d2014-10-21 16:02:31 -04001038 self.handle.sendline("")
andrewonlabba44bcf2014-10-16 16:54:41 -04001039 self.handle.sendline("tshark -i "+str(interface)+
andrewonlabd4940492014-10-24 12:21:27 -04001040 " -t e | grep --line-buffered \""+str(grep)+"\" >"+directory+" &")
andrewonlabba44bcf2014-10-16 16:54:41 -04001041 self.handle.sendline("\r")
1042 self.handle.expect("Capturing on")
1043 self.handle.sendline("\r")
1044 self.handle.expect("\$")
1045
1046 def tshark_stop(self):
1047 '''
1048 Removes wireshark files from /tmp and kills all tshark processes
1049 '''
andrewonlab5ba0d9e2014-10-24 13:32:23 -04001050 #Remove all pcap from previous captures
1051 self.execute(cmd="sudo rm /tmp/wireshark*")
andrewonlabba44bcf2014-10-16 16:54:41 -04001052 self.handle.sendline("")
1053 self.handle.sendline("sudo kill -9 `ps -ef | grep \"tshark -i\" |"+
1054 " grep -v grep | awk '{print $2}'`")
1055 self.handle.sendline("")
1056 main.log.info("Tshark stopped")
1057
andrewonlab0c38a4a2014-10-28 18:35:35 -04001058 def ptpd(self, args):
1059 '''
1060 Initiate ptp with user-specified args.
1061 Required:
1062 * args: specify string of args after command
1063 'sudo ptpd'
1064 '''
1065 try:
1066 self.handle.sendline("sudo ptpd "+str(args))
andrewonlab978dff62014-10-29 16:53:35 -04001067 i = self.handle.expect([
andrewonlab0c38a4a2014-10-28 18:35:35 -04001068 "Multiple",
1069 "Error",
1070 "\$"])
1071 self.handle.expect("\$")
andrewonlabba44bcf2014-10-16 16:54:41 -04001072
andrewonlab0c38a4a2014-10-28 18:35:35 -04001073 if i == 0:
1074 handle = self.handle.before
1075 main.log.info("ptpd returned an error: "+
1076 str(handle))
1077 return handle
1078 elif i == 1:
1079 handle = self.handle.before
1080 main.log.error("ptpd returned an error: "+
1081 str(handle))
1082 return handle
1083 else:
1084 return main.TRUE
1085
1086 except pexpect.EOF:
1087 main.log.error(self.name + ": EOF exception found")
1088 main.log.error(self.name + ": " + self.handle.before)
1089 main.cleanup()
1090 main.exit()
1091 except:
1092 main.log.info(self.name+" ::::::")
1093 main.log.error( traceback.print_exc())
1094 main.log.info(self.name+" ::::::")
1095 main.cleanup()
1096 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001097
1098