blob: 9e42bf9ded2ffefbc5e8f5e01fbd47cb18458c66 [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:
shahshreyaeaea39a2014-11-06 13:37:02 -0800409 print "line = ",line
410 returnValue = lines[2]+lines[4]
411 return returnValue
Jon Hall45ec0922014-10-10 19:33:49 -0400412 except pexpect.EOF:
413 main.log.error(self.name + ": EOF exception found")
414 main.log.error(self.name + ": " + self.handle.before)
415 main.cleanup()
416 main.exit()
417 except:
418 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
419 main.log.error( traceback.print_exc() )
420 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
421 main.cleanup()
422 main.exit()
423
andrewonlabba44bcf2014-10-16 16:54:41 -0400424 def create_cell_file(self, bench_ip, file_name, mn_ip_addrs,
andrewonlab3f0a4af2014-10-17 12:25:14 -0400425 extra_feature_string, *onos_ip_addrs):
andrewonlab94282092014-10-10 13:00:11 -0400426 '''
427 Creates a cell file based on arguments
428 Required:
429 * Bench IP address (bench_ip)
430 - Needed to copy the cell file over
431 * File name of the cell file (file_name)
432 * Mininet IP address (mn_ip_addrs)
433 - Note that only 1 ip address is
434 supported currently
435 * ONOS IP addresses (onos_ip_addrs)
436 - Must be passed in as last arguments
437
438 NOTE: Assumes cells are located at:
439 ~/<self.home>/tools/test/cells/
440 '''
441
442 #Variable initialization
443 cell_directory = self.home + "/tools/test/cells/"
444 #We want to create the cell file in the dependencies directory
445 #of TestON first, then copy over to ONOS bench
446 temp_directory = "/tmp/"
447 #Create the cell file in the directory for writing (w+)
448 cell_file = open(temp_directory+file_name , 'w+')
andrewonlabd4940492014-10-24 12:21:27 -0400449
450 comment = ""
451 comment_string = "#"+ comment
andrewonlab7e4d2d32014-10-15 13:23:21 -0400452 #Feature string is hardcoded environment variables
453 #That you may wish to use by default on startup.
454 #Note that you may not want certain features listed
455 #on here.
andrewonlabba44bcf2014-10-16 16:54:41 -0400456 core_feature_string = "export ONOS_FEATURES=webconsole,onos-api,"+\
457 "onos-cli,onos-openflow,onos-app-mobility,onos-app-tvue,"+\
458 "onos-app-proxyarp,"+extra_feature_string
andrewonlab94282092014-10-10 13:00:11 -0400459 mn_string = "export OCN="
460 onos_string = "export OC"
461 temp_count = 1
462
463 #Create ONOS_NIC ip address prefix
464 temp_onos_ip = onos_ip_addrs[0]
465 temp_list = []
466 temp_list = temp_onos_ip.split(".")
andrewonlab7e4d2d32014-10-15 13:23:21 -0400467 #Omit last element of list to format for NIC
andrewonlab94282092014-10-10 13:00:11 -0400468 temp_list = temp_list[:-1]
469 #Structure the nic string ip
andrewonlabd4940492014-10-24 12:21:27 -0400470 nic_addr = ".".join(temp_list) + ".*"
andrewonlab94282092014-10-10 13:00:11 -0400471 onos_nic_string = "export ONOS_NIC="+nic_addr
472
473 try:
474 #Start writing to file
andrewonlabd4940492014-10-24 12:21:27 -0400475 cell_file.write(onos_nic_string + "\n")
andrewonlab94282092014-10-10 13:00:11 -0400476
477 for arg in onos_ip_addrs:
478 #For each argument in onos_ip_addrs, write to file
479 #Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400480 # export OC1="10.128.20.11"
481 # export OC2="10.128.20.12"
andrewonlab94282092014-10-10 13:00:11 -0400482 cell_file.write(onos_string + str(temp_count) +
andrewonlabd4940492014-10-24 12:21:27 -0400483 "=" + "\"" + arg + "\"" + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400484 temp_count = temp_count + 1
485
andrewonlabd4940492014-10-24 12:21:27 -0400486 cell_file.write(mn_string +"\""+ mn_ip_addrs +"\""+ "\n")
487 cell_file.write(core_feature_string + "\n")
andrewonlab94282092014-10-10 13:00:11 -0400488 cell_file.close()
489
490 #We use os.system to send the command to TestON cluster
491 #to account for the case in which TestON is not located
492 #on the same cluster as the ONOS bench
493 #Note that even if TestON is located on the same cluster
494 #as ONOS bench, you must setup passwordless ssh
andrewonlab7e4d2d32014-10-15 13:23:21 -0400495 #between TestON and ONOS bench in order to automate the test.
andrewonlab94282092014-10-10 13:00:11 -0400496 os.system("scp "+temp_directory+file_name+
497 " admin@"+bench_ip+":"+cell_directory)
498
andrewonlab2a6c9342014-10-16 13:40:15 -0400499 return main.TRUE
500
andrewonlab94282092014-10-10 13:00:11 -0400501 except pexpect.EOF:
502 main.log.error(self.name + ": EOF exception found")
503 main.log.error(self.name + ": " + self.handle.before)
504 main.cleanup()
505 main.exit()
506 except:
507 main.log.info(self.name + ":::::::::")
508 main.log.error( traceback.print_exc() )
509 main.log.info(":::::::")
510 main.cleanup()
511 main.exit()
512
andrewonlab95ca1462014-10-09 14:04:24 -0400513 def set_cell(self, cellname):
514 '''
515 Calls 'cell <name>' to set the environment variables on ONOSbench
516 '''
517 try:
518 if not cellname:
519 main.log.error("Must define cellname")
520 main.cleanup()
521 main.exit()
522 else:
523 self.handle.sendline("cell "+str(cellname))
524 #Expect the cellname in the ONOS_CELL variable.
525 #Note that this variable name is subject to change
526 # and that this driver will have to change accordingly
527 self.handle.expect("ONOS_CELL="+str(cellname))
528 handle_before = self.handle.before
529 handle_after = self.handle.after
andrewonlabc03bf6c2014-10-09 14:56:18 -0400530 #Get the rest of the handle
531 self.handle.sendline("")
532 self.handle.expect("\$")
533 handle_more = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400534
535 main.log.info("Cell call returned: "+handle_before+
andrewonlabc03bf6c2014-10-09 14:56:18 -0400536 handle_after + handle_more)
andrewonlab95ca1462014-10-09 14:04:24 -0400537
538 return main.TRUE
539
540 except pexpect.EOF:
541 main.log.error(self.name + ": EOF exception found")
542 main.log.error(self.name + ": " + self.handle.before)
543 main.cleanup()
544 main.exit()
545 except:
546 main.log.info(self.name+" ::::::")
547 main.log.error( traceback.print_exc())
548 main.log.info(self.name+" ::::::")
549 main.cleanup()
550 main.exit()
551
andrewonlabc03bf6c2014-10-09 14:56:18 -0400552 def verify_cell(self):
553 '''
554 Calls 'onos-verify-cell' to check for cell installation
555 '''
andrewonlab8d0d7d72014-10-09 16:33:15 -0400556 #TODO: Add meaningful expect value
557
andrewonlabc03bf6c2014-10-09 14:56:18 -0400558 try:
559 #Clean handle by sending empty and expecting $
560 self.handle.sendline("")
561 self.handle.expect("\$")
562 self.handle.sendline("onos-verify-cell")
563 self.handle.expect("\$")
564 handle_before = self.handle.before
565 handle_after = self.handle.after
566 #Get the rest of the handle
567 self.handle.sendline("")
568 self.handle.expect("\$")
569 handle_more = self.handle.before
570
571 main.log.info("Verify cell returned: "+handle_before+
572 handle_after + handle_more)
573
574 return main.TRUE
Jon Hall7993bfc2014-10-09 16:30:14 -0400575 except pexpect.EOF:
576 main.log.error(self.name + ": EOF exception found")
577 main.log.error(self.name + ": " + self.handle.before)
578 main.cleanup()
579 main.exit()
580 except:
581 main.log.info(self.name+" ::::::")
582 main.log.error( traceback.print_exc())
583 main.log.info(self.name+" ::::::")
584 main.cleanup()
585 main.exit()
586
andrewonlab05e362f2014-10-10 00:40:57 -0400587 def onos_cli(self, ONOS_ip, cmdstr):
588 '''
589 Uses 'onos' command to send various ONOS CLI arguments.
590 Required:
591 * ONOS_ip: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400592 * cmdstr: specify the command string to send
andrewonlab6e20c342014-10-10 18:08:48 -0400593
594 This function is intended to expose the entire karaf
595 CLI commands for ONOS. Try to use this function first
596 before attempting to write a ONOS CLI specific driver
597 function.
598 You can see a list of available 'cmdstr' arguments
599 by starting onos, and typing in 'onos' to enter the
600 onos> CLI. Then, type 'help' to see the list of
601 available commands.
andrewonlab05e362f2014-10-10 00:40:57 -0400602 '''
603 try:
604 if not ONOS_ip:
605 main.log.error("You must specify the IP address")
606 return main.FALSE
607 if not cmdstr:
608 main.log.error("You must specify the command string")
609 return main.FALSE
610
611 cmdstr = str(cmdstr)
612 self.handle.sendline("")
613 self.handle.expect("\$")
614
615 self.handle.sendline("onos -w " + ONOS_ip + " " + cmdstr)
616 self.handle.expect("\$")
617
Shreya Shaha73aaad2014-10-27 18:03:09 -0400618 handle_before = self.handle.before
619 print "handle_before = ", self.handle.before
andrewonlab05e362f2014-10-10 00:40:57 -0400620 handle_after = str(self.handle.after)
621
Shreya Shaha73aaad2014-10-27 18:03:09 -0400622 #self.handle.sendline("")
623 #self.handle.expect("\$")
624 #handle_more = str(self.handle.before)
andrewonlab05e362f2014-10-10 00:40:57 -0400625
626 main.log.info("Command sent successfully")
627
andrewonlab94282092014-10-10 13:00:11 -0400628 #Obtain return handle that consists of result from
629 #the onos command. The string may need to be
630 #configured further.
Shreya Shaha73aaad2014-10-27 18:03:09 -0400631 #return_string = handle_before + handle_after
632 return_string = handle_before
633 print "return_string = ", return_string
andrewonlab05e362f2014-10-10 00:40:57 -0400634 return return_string
635
636 except pexpect.EOF:
637 main.log.error(self.name + ": EOF exception found")
638 main.log.error(self.name + ": " + self.handle.before)
639 main.cleanup()
640 main.exit()
641 except:
642 main.log.info(self.name+" ::::::")
643 main.log.error( traceback.print_exc())
644 main.log.info(self.name+" ::::::")
645 main.cleanup()
646 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400647
648 def onos_install(self, options="-f", node = ""):
649 '''
650 Installs ONOS bits on the designated cell machine.
651 If -f option is provided, it also forces an uninstall.
652 Presently, install also includes onos-push-bits and
653 onos-config within.
654 The node option allows you to selectively only push the jar
655 files to certain onos nodes
656
657 Returns: main.TRUE on success and main.FALSE on failure
658 '''
659 try:
660 self.handle.sendline("onos-install " + options + " " + node)
661 self.handle.expect("onos-install ")
662 #NOTE: this timeout may need to change depending on the network and size of ONOS
663 i=self.handle.expect(["Network\sis\sunreachable",
664 "onos\sstart/running,\sprocess",
665 pexpect.TIMEOUT],timeout=60)
666
Jon Hall7993bfc2014-10-09 16:30:14 -0400667 if i == 0:
668 main.log.warn("Network is unreachable")
669 return main.FALSE
670 elif i == 1:
Jon Hall42db6dc2014-10-24 19:03:48 -0400671 main.log.info("ONOS was installed on " + node + " and started")
Jon Hall7993bfc2014-10-09 16:30:14 -0400672 return main.TRUE
673 elif i == 2:
Jon Hall42db6dc2014-10-24 19:03:48 -0400674 main.log.info("Installation of ONOS on " + node + " timed out")
Jon Hall7993bfc2014-10-09 16:30:14 -0400675 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400676
677 except pexpect.EOF:
678 main.log.error(self.name + ": EOF exception found")
679 main.log.error(self.name + ": " + self.handle.before)
680 main.cleanup()
681 main.exit()
682 except:
683 main.log.info(self.name+" ::::::")
684 main.log.error( traceback.print_exc())
685 main.log.info(self.name+" ::::::")
686 main.cleanup()
687 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400688
andrewonlab8d0d7d72014-10-09 16:33:15 -0400689 def onos_start(self, node_ip):
690 '''
691 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400692 This command is a remote management of the ONOS upstart daemon
andrewonlab8d0d7d72014-10-09 16:33:15 -0400693 '''
694
695 try:
696 self.handle.sendline("")
697 self.handle.expect("\$")
698 self.handle.sendline("onos-service "+str(node_ip)+
699 " start")
700 i = self.handle.expect([
701 "Job\sis\salready\srunning",
702 "start/running",
703 "Unknown\sinstance",
Shreya Shahd01153d2014-10-23 15:08:56 -0400704 pexpect.TIMEOUT],timeout=120)
andrewonlab8d0d7d72014-10-09 16:33:15 -0400705
706 if i == 0:
707 main.log.info("Service is already running")
708 return main.TRUE
709 elif i == 1:
710 main.log.info("ONOS service started")
711 return main.TRUE
712 else:
713 main.log.error("ONOS service failed to start")
714 main.cleanup()
715 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400716 except pexpect.EOF:
717 main.log.error(self.name + ": EOF exception found")
718 main.log.error(self.name + ": " + self.handle.before)
719 main.cleanup()
720 main.exit()
721 except:
722 main.log.info(self.name+" ::::::")
723 main.log.error( traceback.print_exc())
724 main.log.info(self.name+" ::::::")
725 main.cleanup()
726 main.exit()
727
andrewonlab2b30bd32014-10-09 16:48:55 -0400728 def onos_stop(self, node_ip):
729 '''
730 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400731 This command is a remote management of the ONOS upstart daemon
andrewonlab2b30bd32014-10-09 16:48:55 -0400732 '''
733 try:
734 self.handle.sendline("")
735 self.handle.expect("\$")
736 self.handle.sendline("onos-service "+str(node_ip)+
737 " stop")
738 i = self.handle.expect([
739 "stop/waiting",
740 "Unknown\sinstance",
741 pexpect.TIMEOUT],timeout=60)
742
743 if i == 0:
744 main.log.info("ONOS service stopped")
745 return main.TRUE
746 elif i == 1:
747 main.log.info("Unknown ONOS instance specified: "+
748 str(node_ip))
749 return main.FALSE
750 else:
751 main.log.error("ONOS service failed to stop")
752 return main.FALSE
753
754 except pexpect.EOF:
755 main.log.error(self.name + ": EOF exception found")
756 main.log.error(self.name + ": " + self.handle.before)
757 main.cleanup()
758 main.exit()
759 except:
760 main.log.info(self.name+" ::::::")
761 main.log.error( traceback.print_exc())
762 main.log.info(self.name+" ::::::")
763 main.cleanup()
764 main.exit()
765
andrewonlabc8d47972014-10-09 16:52:36 -0400766 def onos_uninstall(self):
767 '''
768 Calls the command: 'onos-uninstall'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400769 Uninstalls ONOS from the designated cell machine, stopping
770 if needed
andrewonlabc8d47972014-10-09 16:52:36 -0400771 '''
772 try:
773 self.handle.sendline("")
774 self.handle.expect("\$")
775 self.handle.sendline("onos-uninstall")
776 self.handle.expect("\$")
777
andrewonlab84727452014-10-09 18:15:36 -0400778 main.log.info("ONOS cell machine was uninstalled")
andrewonlabc8d47972014-10-09 16:52:36 -0400779 #onos-uninstall command does not return any text
780 return main.TRUE
781
782 except pexpect.EOF:
783 main.log.error(self.name + ": EOF exception found")
784 main.log.error(self.name + ": " + self.handle.before)
785 main.cleanup()
786 main.exit()
787 except:
788 main.log.info(self.name+" ::::::")
789 main.log.error( traceback.print_exc())
790 main.log.info(self.name+" ::::::")
791 main.cleanup()
792 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -0400793
andrewonlabe8e56fd2014-10-09 17:12:44 -0400794 def onos_kill(self, node_ip):
795 '''
796 Calls the command: 'onos-kill [<node-ip>]'
797 "Remotely, and unceremoniously kills the ONOS instance running on
798 the specified cell machine" - Tom V
799 '''
800
801 try:
802 self.handle.sendline("")
803 self.handle.expect("\$")
804 self.handle.sendline("onos-kill " + str(node_ip))
805 i = self.handle.expect([
806 "\$",
807 "No\sroute\sto\shost",
808 "password:",
809 pexpect.TIMEOUT], timeout=20)
810
811 if i == 0:
812 main.log.info("ONOS instance "+str(node_ip)+" was killed")
813 return main.TRUE
814 elif i == 1:
815 main.log.info("No route to host")
816 return main.FALSE
817 elif i == 2:
818 main.log.info("Passwordless login for host: "+str(node_ip)+
819 " not configured")
820 return main.FALSE
821 else:
822 main.log.info("ONOS instasnce was not killed")
823 return main.FALSE
824
825 except pexpect.EOF:
826 main.log.error(self.name + ": EOF exception found")
827 main.log.error(self.name + ": " + self.handle.before)
828 main.cleanup()
829 main.exit()
830 except:
831 main.log.info(self.name+" ::::::")
832 main.log.error( traceback.print_exc())
833 main.log.info(self.name+" ::::::")
834 main.cleanup()
835 main.exit()
836
andrewonlab94282092014-10-10 13:00:11 -0400837 def onos_start_network(self, mntopo):
838 '''
839 Calls the command 'onos-start-network [<mininet-topo>]
840 "remotely starts the specified topology on the cell's
841 mininet machine against all controllers configured in the
842 cell."
843 * Specify mininet topology file name for mntopo
844 * Topo files should be placed at:
845 ~/<your-onos-directory>/tools/test/topos
846
847 NOTE: This function will take you to the mininet prompt
848 '''
849 try:
850 if not mntopo:
851 main.log.error("You must specify a topo file to execute")
852 return main.FALSE
853
854 mntopo = str(mntopo)
855 self.handle.sendline("")
856 self.handle.expect("\$")
857
858 self.handle.sendline("onos-start-network " + mntopo)
859 self.handle.expect("mininet>")
860 main.log.info("Network started, entered mininet prompt")
861
862 #TODO: Think about whether return is necessary or not
863
864 except pexpect.EOF:
865 main.log.error(self.name + ": EOF exception found")
866 main.log.error(self.name + ": " + self.handle.before)
867 main.cleanup()
868 main.exit()
869 except:
870 main.log.info(self.name+" ::::::")
871 main.log.error( traceback.print_exc())
872 main.log.info(self.name+" ::::::")
873 main.cleanup()
874 main.exit()
875
876
Jon Hall7993bfc2014-10-09 16:30:14 -0400877 def isup(self, node = ""):
878 '''
Jon Hall77f53ce2014-10-13 18:02:06 -0400879 Run's onos-wait-for-start which only returns once ONOS is at run
880 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -0400881
Jon Hall7993bfc2014-10-09 16:30:14 -0400882 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
883 '''
884 try:
885 self.handle.sendline("onos-wait-for-start " + node )
886 self.handle.expect("onos-wait-for-start")
887 #NOTE: this timeout is arbitrary"
888 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout = 120)
889 if i == 0:
890 main.log.info(self.name + ": " + node + " is up")
891 return main.TRUE
892 elif i == 1:
893 #NOTE: since this function won't return until ONOS is ready,
894 # we will kill it on timeout
895 self.handle.sendline("\003") #Control-C
896 self.handle.expect("\$")
897 return main.FALSE
898 except pexpect.EOF:
899 main.log.error(self.name + ": EOF exception found")
900 main.log.error(self.name + ": " + self.handle.before)
901 main.cleanup()
902 main.exit()
903 except:
904 main.log.info(self.name+" ::::::")
905 main.log.error( traceback.print_exc())
906 main.log.info(self.name+" ::::::")
907 main.cleanup()
908 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -0400909
910
Shreya Shaha73aaad2014-10-27 18:03:09 -0400911 def get_topology(self,topology_output):
Jon Hall77f53ce2014-10-13 18:02:06 -0400912 '''
913 parses the onos:topology output
914 Returns: a topology dict populated by the key values found in
915 the cli command.
916 '''
917
918 try:
919 #call the cli to get the topology summary
Shreya Shaha73aaad2014-10-27 18:03:09 -0400920 #cmdstr = "onos:topology"
921 #cli_result = self.onos_cli(ip, cmdstr)
922 #print "cli_result = ", cli_result
Jon Hall77f53ce2014-10-13 18:02:06 -0400923
924 #Parse the output
925 topology = {}
926 #for line in cli_result.split("\n"):
Shreya Shaha73aaad2014-10-27 18:03:09 -0400927 for line in topology_output.splitlines():
Jon Hall77f53ce2014-10-13 18:02:06 -0400928 if not line.startswith("time="):
929 continue
930 #else
931 print line
932 for var in line.split(","):
Shreya Shaha73aaad2014-10-27 18:03:09 -0400933 #print "'"+var+"'"
934 #print "'"+var.strip()+"'"
Jon Hall77f53ce2014-10-13 18:02:06 -0400935 key, value = var.strip().split("=")
936 topology[key] = value
Shreya Shaha73aaad2014-10-27 18:03:09 -0400937 print "topology = ", topology
Jon Hall77f53ce2014-10-13 18:02:06 -0400938 devices = topology.get('devices', False)
Shreya Shaha73aaad2014-10-27 18:03:09 -0400939 print "devices = ", devices
Jon Hall77f53ce2014-10-13 18:02:06 -0400940 links = topology.get('links', False)
Shreya Shaha73aaad2014-10-27 18:03:09 -0400941 print "links = ", links
Jon Hall77f53ce2014-10-13 18:02:06 -0400942 clusters = topology.get('clusters', False)
Shreya Shaha73aaad2014-10-27 18:03:09 -0400943 print "clusters = ", clusters
Jon Hall77f53ce2014-10-13 18:02:06 -0400944 paths = topology.get('paths', False)
Shreya Shaha73aaad2014-10-27 18:03:09 -0400945 print "paths = ", paths
Jon Hall77f53ce2014-10-13 18:02:06 -0400946
947 return topology
948 except pexpect.EOF:
949 main.log.error(self.name + ": EOF exception found")
950 main.log.error(self.name + ": " + self.handle.before)
951 main.cleanup()
952 main.exit()
953 except:
954 main.log.info(self.name+" ::::::")
955 main.log.error( traceback.print_exc())
956 main.log.info(self.name+" ::::::")
957 main.cleanup()
958 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -0400959
960
Jon Hall77f53ce2014-10-13 18:02:06 -0400961
Shreya Shaha73aaad2014-10-27 18:03:09 -0400962 def check_status(self, topology_result, numoswitch, numolink, log_level="info"):
Jon Hall77f53ce2014-10-13 18:02:06 -0400963 '''
964 Checks the number of swithes & links that ONOS sees against the
965 supplied values. By default this will report to main.log, but the
966 log level can be specifid.
967
968 Params: ip = ip used for the onos cli
969 numoswitch = expected number of switches
970 numlink = expected number of links
971 log_level = level to log to. Currently accepts 'info', 'warn' and 'report'
972
973
974 log_level can
975
976 Returns: main.TRUE if the number of switchs and links are correct,
977 main.FALSE if the numer of switches and links is incorrect,
978 and main.ERROR otherwise
979 '''
980
981 try:
Shreya Shaha73aaad2014-10-27 18:03:09 -0400982 topology = self.get_topology(topology_result)
Jon Hall77f53ce2014-10-13 18:02:06 -0400983 if topology == {}:
984 return main.ERROR
985 output = ""
986 #Is the number of switches is what we expected
987 devices = topology.get('devices',False)
988 links = topology.get('links',False)
989 if devices == False or links == False:
990 return main.ERROR
991 switch_check = ( int(devices) == int(numoswitch) )
992 #Is the number of links is what we expected
993 link_check = ( int(links) == int(numolink) )
994 if (switch_check and link_check):
995 #We expected the correct numbers
996 output = output + "The number of links and switches match "\
997 + "what was expected"
998 result = main.TRUE
999 else:
1000 output = output + \
1001 "The number of links and switches does not match what was expected"
1002 result = main.FALSE
1003 output = output + "\n ONOS sees %i devices (%i expected) and %i links (%i expected)"\
1004 % ( int(devices), int(numoswitch), int(links), int(numolink) )
1005 if log_level == "report":
1006 main.log.report(output)
1007 elif log_level == "warn":
1008 main.log.warn(output)
1009 else:
1010 main.log.info(output)
1011 return result
1012 except pexpect.EOF:
1013 main.log.error(self.name + ": EOF exception found")
1014 main.log.error(self.name + ": " + self.handle.before)
1015 main.cleanup()
1016 main.exit()
1017 except:
1018 main.log.info(self.name+" ::::::")
1019 main.log.error( traceback.print_exc())
1020 main.log.info(self.name+" ::::::")
1021 main.cleanup()
1022 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001023
andrewonlab970399c2014-11-07 13:09:32 -05001024 def tshark_pcap(self, interface, dir_file):
1025 '''
1026 Capture all packet activity and store in specified
1027 directory/file
1028
1029 Required:
1030 * interface: interface to capture
1031 * dir: directory/filename to store pcap
1032 '''
1033 self.handle.sendline("")
1034 self.handle.expect("\$")
1035
1036 self.handle.sendline("tshark -i "+str(interface)+
1037 " -t e -w "+str(dir_file))
1038 self.handle.expect("Capturing on")
1039
1040 main.log.info("Tshark started capturing files on "+
1041 str(interface)+ " and saving to directory: "+
1042 str(dir_File))
Shreya Shaha73aaad2014-10-27 18:03:09 -04001043
andrewonlabba44bcf2014-10-16 16:54:41 -04001044 def tshark_grep(self, grep, directory, interface='eth0'):
1045 '''
1046 Required:
1047 * grep string
1048 * directory to store results
1049 Optional:
1050 * interface - default: eth0
1051 Description:
1052 Uses tshark command to grep specific group of packets
1053 and stores the results to specified directory.
1054 The timestamp is hardcoded to be in epoch
1055 '''
1056 self.handle.sendline("")
1057 self.handle.expect("\$")
andrewonlabefd7f3d2014-10-21 16:02:31 -04001058 self.handle.sendline("")
andrewonlabba44bcf2014-10-16 16:54:41 -04001059 self.handle.sendline("tshark -i "+str(interface)+
andrewonlabd4940492014-10-24 12:21:27 -04001060 " -t e | grep --line-buffered \""+str(grep)+"\" >"+directory+" &")
andrewonlabba44bcf2014-10-16 16:54:41 -04001061 self.handle.sendline("\r")
1062 self.handle.expect("Capturing on")
1063 self.handle.sendline("\r")
1064 self.handle.expect("\$")
1065
1066 def tshark_stop(self):
1067 '''
1068 Removes wireshark files from /tmp and kills all tshark processes
1069 '''
andrewonlab5ba0d9e2014-10-24 13:32:23 -04001070 #Remove all pcap from previous captures
1071 self.execute(cmd="sudo rm /tmp/wireshark*")
andrewonlabba44bcf2014-10-16 16:54:41 -04001072 self.handle.sendline("")
1073 self.handle.sendline("sudo kill -9 `ps -ef | grep \"tshark -i\" |"+
1074 " grep -v grep | awk '{print $2}'`")
1075 self.handle.sendline("")
1076 main.log.info("Tshark stopped")
1077
andrewonlab0c38a4a2014-10-28 18:35:35 -04001078 def ptpd(self, args):
1079 '''
1080 Initiate ptp with user-specified args.
1081 Required:
1082 * args: specify string of args after command
1083 'sudo ptpd'
1084 '''
1085 try:
1086 self.handle.sendline("sudo ptpd "+str(args))
andrewonlab978dff62014-10-29 16:53:35 -04001087 i = self.handle.expect([
andrewonlab0c38a4a2014-10-28 18:35:35 -04001088 "Multiple",
1089 "Error",
1090 "\$"])
1091 self.handle.expect("\$")
andrewonlabba44bcf2014-10-16 16:54:41 -04001092
andrewonlab0c38a4a2014-10-28 18:35:35 -04001093 if i == 0:
1094 handle = self.handle.before
1095 main.log.info("ptpd returned an error: "+
1096 str(handle))
1097 return handle
1098 elif i == 1:
1099 handle = self.handle.before
1100 main.log.error("ptpd returned an error: "+
1101 str(handle))
1102 return handle
1103 else:
1104 return main.TRUE
1105
1106 except pexpect.EOF:
1107 main.log.error(self.name + ": EOF exception found")
1108 main.log.error(self.name + ": " + self.handle.before)
1109 main.cleanup()
1110 main.exit()
1111 except:
1112 main.log.info(self.name+" ::::::")
1113 main.log.error( traceback.print_exc())
1114 main.log.info(self.name+" ::::::")
1115 main.cleanup()
1116 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001117
1118