blob: a31e946c62fe34b27b2317a1b25500a42760d705 [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
Jon Hallde9d9aa2014-10-08 20:36:02 -0400123 def clean_install(self):
124 '''
125 Runs mvn clean install in the root of the ONOS directory.
126 This will clean all ONOS artifacts then compile each module
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400127
Jon Hallde9d9aa2014-10-08 20:36:02 -0400128 Returns: main.TRUE on success
129 On Failure, exits the test
130 '''
131 try:
Jon Hallea7818b2014-10-09 14:30:59 -0400132 main.log.info("Running 'mvn clean install' on " + str(self.name) +
133 ". This may take some time.")
134 self.handle.sendline("cd "+ self.home)
135 self.handle.expect("\$")
136
137 self.handle.sendline("\n")
138 self.handle.expect("\$")
Jon Hallde9d9aa2014-10-08 20:36:02 -0400139 self.handle.sendline("mvn clean install")
Jon Hallea7818b2014-10-09 14:30:59 -0400140 self.handle.expect("mvn clean install")
Jon Hallde9d9aa2014-10-08 20:36:02 -0400141 while 1:
142 i=self.handle.expect([
143 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s\
144 Runtime\sEnvironment\sto\scontinue',
145 'BUILD\sFAILURE',
146 'BUILD\sSUCCESS',
147 'ONOS\$',
148 pexpect.TIMEOUT],timeout=600)
149 if i == 0:
150 main.log.error(self.name + ":There is insufficient memory \
151 for the Java Runtime Environment to continue.")
152 #return main.FALSE
153 main.cleanup()
154 main.exit()
155 if i == 1:
156 main.log.error(self.name + ": Build failure!")
157 #return main.FALSE
158 main.cleanup()
159 main.exit()
160 elif i == 2:
161 main.log.info(self.name + ": Build success!")
162 elif i == 3:
163 main.log.info(self.name + ": Build complete")
Jon Hallf8ef52c2014-10-09 19:37:33 -0400164 #Print the build time
165 for line in self.handle.before.splitlines():
166 if "Total time:" in line:
167 main.log.info(line)
Jon Hallea7818b2014-10-09 14:30:59 -0400168 self.handle.sendline("\n")
Jon Hallde9d9aa2014-10-08 20:36:02 -0400169 self.handle.expect("\$", timeout=60)
170 return main.TRUE
171 elif i == 4:
172 main.log.error(self.name + ": mvn clean install TIMEOUT!")
173 #return main.FALSE
174 main.cleanup()
175 main.exit()
176 else:
177 main.log.error(self.name + ": unexpected response from \
178 mvn clean install")
179 #return main.FALSE
180 main.cleanup()
181 main.exit()
182 except pexpect.EOF:
183 main.log.error(self.name + ": EOF exception found")
184 main.log.error(self.name + ": " + self.handle.before)
185 main.cleanup()
186 main.exit()
187 except:
188 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
189 main.log.error( traceback.print_exc() )
190 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
191 main.cleanup()
192 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400193
194 def git_pull(self, comp1=""):
195 '''
196 Assumes that "git pull" works without login
197
198 This function will perform a git pull on the ONOS instance.
199 If used as git_pull("NODE") it will do git pull + NODE. This is
200 for the purpose of pulling from other nodes if necessary.
201
202 Otherwise, this function will perform a git pull in the
203 ONOS repository. If it has any problems, it will return main.ERROR
204 If it successfully does a git_pull, it will return a 1.
205 If it has no updates, it will return a 0.
206
207 '''
208 try:
209 # main.log.info(self.name + ": Stopping ONOS")
210 #self.stop()
211 self.handle.sendline("cd " + self.home)
212 self.handle.expect("ONOS\$")
213 if comp1=="":
214 self.handle.sendline("git pull")
215 else:
216 self.handle.sendline("git pull " + comp1)
217
218 uptodate = 0
219 i=self.handle.expect(['fatal',
220 'Username\sfor\s(.*):\s',
221 '\sfile(s*) changed,\s',
222 'Already up-to-date',
223 'Aborting',
224 'You\sare\snot\scurrently\son\sa\sbranch',
225 'You\sasked\sme\sto\spull\swithout\stelling\sme\swhich\sbranch\syou',
226 'Pull\sis\snot\spossible\sbecause\syou\shave\sunmerged\sfiles',
227 pexpect.TIMEOUT],
228 timeout=300)
229 #debug
230 #main.log.report(self.name +": \n"+"git pull response: " + str(self.handle.before) + str(self.handle.after))
231 if i==0:
232 main.log.error(self.name + ": Git pull had some issue...")
233 return main.ERROR
234 elif i==1:
235 main.log.error(self.name + ": Git Pull Asking for username. ")
236 return main.ERROR
237 elif i==2:
238 main.log.info(self.name + ": Git Pull - pulling repository now")
239 self.handle.expect("ONOS\$", 120)
Jon Hall77f53ce2014-10-13 18:02:06 -0400240 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400241 elif i==3:
242 main.log.info(self.name + ": Git Pull - Already up to date")
Jon Hall77f53ce2014-10-13 18:02:06 -0400243 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400244 elif i==4:
245 main.log.info(self.name + ": Git Pull - Aborting... Are there conflicting git files?")
246 return main.ERROR
247 elif i==5:
248 main.log.info(self.name + ": Git Pull - You are not currently on a branch so git pull failed!")
249 return main.ERROR
250 elif i==6:
251 main.log.info(self.name + ": Git Pull - You have not configured an upstream branch to pull from. Git pull failed!")
252 return main.ERROR
253 elif i==7:
254 main.log.info(self.name + ": Git Pull - Pull is not possible because you have unmerged files.")
255 return main.ERROR
256 elif i==8:
257 main.log.error(self.name + ": Git Pull - TIMEOUT")
258 main.log.error(self.name + " Response was: " + str(self.handle.before))
259 return main.ERROR
260 else:
261 main.log.error(self.name + ": Git Pull - Unexpected response, check for pull errors")
262 return main.ERROR
263 except pexpect.EOF:
264 main.log.error(self.name + ": EOF exception found")
265 main.log.error(self.name + ": " + self.handle.before)
266 main.cleanup()
267 main.exit()
268 except:
269 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
270 main.log.error( traceback.print_exc() )
271 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
272 main.cleanup()
273 main.exit()
274
275 def git_checkout(self, branch="master"):
276 '''
277 Assumes that "git pull" works without login
278
279 This function will perform a git git checkout on the ONOS instance.
280 If used as git_checkout("branch") it will do git checkout of the "branch".
281
282 Otherwise, this function will perform a git checkout of the master
283 branch of the ONOS repository. If it has any problems, it will return
284 main.ERROR.
285 If the branch was already the specified branch, or the git checkout was
286 successful then the function will return main.TRUE.
287
288 '''
289 try:
290 # main.log.info(self.name + ": Stopping ONOS")
291 #self.stop()
292 self.handle.sendline("cd " + self.home)
293 self.handle.expect("ONOS\$")
294 if branch != 'master':
295 #self.handle.sendline('git stash')
296 #self.handle.expect('ONOS\$')
297 #print "After issuing git stash cmnd: ", self.handle.before
298 cmd = "git checkout "+branch
299 print "checkout cmd = ", cmd
300 self.handle.sendline(cmd)
301 uptodate = 0
302 i=self.handle.expect(['fatal',
303 'Username\sfor\s(.*):\s',
304 'Already\son\s\'',
305 'Switched\sto\sbranch\s\'',
306 pexpect.TIMEOUT],timeout=60)
307 else:
308 #self.handle.sendline('git stash apply')
309 #self.handle.expect('ONOS\$')
310 #print "After issuing git stash apply cmnd: ", self.handle.before
311 cmd = "git checkout "+branch
312 print "checkout cmd = ", cmd
313 self.handle.sendline(cmd)
314 uptodate = 0
315 switchedToMaster = 0
316 i=self.handle.expect(['fatal',
317 'Username\sfor\s(.*):\s',
318 'Already\son\s\'master\'',
319 'Switched\sto\sbranch\s\'master\'',
320 pexpect.TIMEOUT],timeout=60)
321
322
323 if i==0:
324 main.log.error(self.name + ": Git checkout had some issue...")
325 return main.ERROR
326 elif i==1:
327 main.log.error(self.name + ": Git checkout Asking for username!!! Bad!")
328 return main.ERROR
329 elif i==2:
330 main.log.info(self.name + ": Git Checkout %s : Already on this branch" %branch)
331 self.handle.expect("ONOS\$")
332 print "after checkout cmd = ", self.handle.before
333 switchedToMaster = 1
334 return main.TRUE
335 elif i==3:
336 main.log.info(self.name + ": Git checkout %s - Switched to this branch" %branch)
337 self.handle.expect("ONOS\$")
338 print "after checkout cmd = ", self.handle.before
339 switchedToMaster = 1
340 return main.TRUE
341 elif i==4:
342 main.log.error(self.name + ": Git Checkout- TIMEOUT")
343 main.log.error(self.name + " Response was: " + str(self.handle.before))
344 return main.ERROR
345 else:
346 main.log.error(self.name + ": Git Checkout - Unexpected response, check for pull errors")
347 return main.ERROR
348
349 except pexpect.EOF:
350 main.log.error(self.name + ": EOF exception found")
351 main.log.error(self.name + ": " + self.handle.before)
352 main.cleanup()
353 main.exit()
354 except:
355 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
356 main.log.error( traceback.print_exc() )
357 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
358 main.cleanup()
359 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400360
Jon Hall45ec0922014-10-10 19:33:49 -0400361 def get_version(self):
362 '''
363 Writes the COMMIT number to the report to be parsed by Jenkins data collecter.
364 '''
365 try:
366 self.handle.sendline("export TERM=xterm-256color")
367 self.handle.expect("xterm-256color")
368 self.handle.expect("\$")
Jon Hall42db6dc2014-10-24 19:03:48 -0400369 self.handle.sendline("\n")
370 self.handle.expect("\$")
371 self.handle.sendline("cd " + self.home + "; git log -1 --pretty=fuller --decorate=short | grep -A 6 \"commit\" --color=never")
372 self.handle.expect("--color=never")
Jon Hall45ec0922014-10-10 19:33:49 -0400373 self.handle.expect("\$")
374 response=(self.name +": \n"+ str(self.handle.before + self.handle.after))
Jon Hall42db6dc2014-10-24 19:03:48 -0400375 self.handle.sendline("cd " + self.home)
376 self.handle.expect("\$")
Jon Hall45ec0922014-10-10 19:33:49 -0400377 lines=response.splitlines()
378 for line in lines:
379 print line
380 return lines[2]
381 except pexpect.EOF:
382 main.log.error(self.name + ": EOF exception found")
383 main.log.error(self.name + ": " + self.handle.before)
384 main.cleanup()
385 main.exit()
386 except:
387 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
388 main.log.error( traceback.print_exc() )
389 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
390 main.cleanup()
391 main.exit()
392
andrewonlabba44bcf2014-10-16 16:54:41 -0400393 def create_cell_file(self, bench_ip, file_name, mn_ip_addrs,
andrewonlab3f0a4af2014-10-17 12:25:14 -0400394 extra_feature_string, *onos_ip_addrs):
andrewonlab94282092014-10-10 13:00:11 -0400395 '''
396 Creates a cell file based on arguments
397 Required:
398 * Bench IP address (bench_ip)
399 - Needed to copy the cell file over
400 * File name of the cell file (file_name)
401 * Mininet IP address (mn_ip_addrs)
402 - Note that only 1 ip address is
403 supported currently
404 * ONOS IP addresses (onos_ip_addrs)
405 - Must be passed in as last arguments
406
407 NOTE: Assumes cells are located at:
408 ~/<self.home>/tools/test/cells/
409 '''
410
411 #Variable initialization
412 cell_directory = self.home + "/tools/test/cells/"
413 #We want to create the cell file in the dependencies directory
414 #of TestON first, then copy over to ONOS bench
415 temp_directory = "/tmp/"
416 #Create the cell file in the directory for writing (w+)
417 cell_file = open(temp_directory+file_name , 'w+')
andrewonlabd4940492014-10-24 12:21:27 -0400418
419 comment = ""
420 comment_string = "#"+ comment
andrewonlab7e4d2d32014-10-15 13:23:21 -0400421 #Feature string is hardcoded environment variables
422 #That you may wish to use by default on startup.
423 #Note that you may not want certain features listed
424 #on here.
andrewonlabba44bcf2014-10-16 16:54:41 -0400425 core_feature_string = "export ONOS_FEATURES=webconsole,onos-api,"+\
426 "onos-cli,onos-openflow,onos-app-mobility,onos-app-tvue,"+\
427 "onos-app-proxyarp,"+extra_feature_string
andrewonlab94282092014-10-10 13:00:11 -0400428 mn_string = "export OCN="
429 onos_string = "export OC"
430 temp_count = 1
431
432 #Create ONOS_NIC ip address prefix
433 temp_onos_ip = onos_ip_addrs[0]
434 temp_list = []
435 temp_list = temp_onos_ip.split(".")
andrewonlab7e4d2d32014-10-15 13:23:21 -0400436 #Omit last element of list to format for NIC
andrewonlab94282092014-10-10 13:00:11 -0400437 temp_list = temp_list[:-1]
438 #Structure the nic string ip
andrewonlabd4940492014-10-24 12:21:27 -0400439 nic_addr = ".".join(temp_list) + ".*"
andrewonlab94282092014-10-10 13:00:11 -0400440 onos_nic_string = "export ONOS_NIC="+nic_addr
441
442 try:
443 #Start writing to file
andrewonlabd4940492014-10-24 12:21:27 -0400444 cell_file.write(onos_nic_string + "\n")
andrewonlab94282092014-10-10 13:00:11 -0400445
446 for arg in onos_ip_addrs:
447 #For each argument in onos_ip_addrs, write to file
448 #Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400449 # export OC1="10.128.20.11"
450 # export OC2="10.128.20.12"
andrewonlab94282092014-10-10 13:00:11 -0400451 cell_file.write(onos_string + str(temp_count) +
andrewonlabd4940492014-10-24 12:21:27 -0400452 "=" + "\"" + arg + "\"" + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400453 temp_count = temp_count + 1
454
andrewonlabd4940492014-10-24 12:21:27 -0400455 cell_file.write(mn_string +"\""+ mn_ip_addrs +"\""+ "\n")
456 cell_file.write(core_feature_string + "\n")
andrewonlab94282092014-10-10 13:00:11 -0400457 cell_file.close()
458
459 #We use os.system to send the command to TestON cluster
460 #to account for the case in which TestON is not located
461 #on the same cluster as the ONOS bench
462 #Note that even if TestON is located on the same cluster
463 #as ONOS bench, you must setup passwordless ssh
andrewonlab7e4d2d32014-10-15 13:23:21 -0400464 #between TestON and ONOS bench in order to automate the test.
andrewonlab94282092014-10-10 13:00:11 -0400465 os.system("scp "+temp_directory+file_name+
466 " admin@"+bench_ip+":"+cell_directory)
467
andrewonlab2a6c9342014-10-16 13:40:15 -0400468 return main.TRUE
469
andrewonlab94282092014-10-10 13:00:11 -0400470 except pexpect.EOF:
471 main.log.error(self.name + ": EOF exception found")
472 main.log.error(self.name + ": " + self.handle.before)
473 main.cleanup()
474 main.exit()
475 except:
476 main.log.info(self.name + ":::::::::")
477 main.log.error( traceback.print_exc() )
478 main.log.info(":::::::")
479 main.cleanup()
480 main.exit()
481
andrewonlab95ca1462014-10-09 14:04:24 -0400482 def set_cell(self, cellname):
483 '''
484 Calls 'cell <name>' to set the environment variables on ONOSbench
485 '''
486 try:
487 if not cellname:
488 main.log.error("Must define cellname")
489 main.cleanup()
490 main.exit()
491 else:
492 self.handle.sendline("cell "+str(cellname))
493 #Expect the cellname in the ONOS_CELL variable.
494 #Note that this variable name is subject to change
495 # and that this driver will have to change accordingly
496 self.handle.expect("ONOS_CELL="+str(cellname))
497 handle_before = self.handle.before
498 handle_after = self.handle.after
andrewonlabc03bf6c2014-10-09 14:56:18 -0400499 #Get the rest of the handle
500 self.handle.sendline("")
501 self.handle.expect("\$")
502 handle_more = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400503
504 main.log.info("Cell call returned: "+handle_before+
andrewonlabc03bf6c2014-10-09 14:56:18 -0400505 handle_after + handle_more)
andrewonlab95ca1462014-10-09 14:04:24 -0400506
507 return main.TRUE
508
509 except pexpect.EOF:
510 main.log.error(self.name + ": EOF exception found")
511 main.log.error(self.name + ": " + self.handle.before)
512 main.cleanup()
513 main.exit()
514 except:
515 main.log.info(self.name+" ::::::")
516 main.log.error( traceback.print_exc())
517 main.log.info(self.name+" ::::::")
518 main.cleanup()
519 main.exit()
520
andrewonlabc03bf6c2014-10-09 14:56:18 -0400521 def verify_cell(self):
522 '''
523 Calls 'onos-verify-cell' to check for cell installation
524 '''
andrewonlab8d0d7d72014-10-09 16:33:15 -0400525 #TODO: Add meaningful expect value
526
andrewonlabc03bf6c2014-10-09 14:56:18 -0400527 try:
528 #Clean handle by sending empty and expecting $
529 self.handle.sendline("")
530 self.handle.expect("\$")
531 self.handle.sendline("onos-verify-cell")
532 self.handle.expect("\$")
533 handle_before = self.handle.before
534 handle_after = self.handle.after
535 #Get the rest of the handle
536 self.handle.sendline("")
537 self.handle.expect("\$")
538 handle_more = self.handle.before
539
540 main.log.info("Verify cell returned: "+handle_before+
541 handle_after + handle_more)
542
543 return main.TRUE
Jon Hall7993bfc2014-10-09 16:30:14 -0400544 except pexpect.EOF:
545 main.log.error(self.name + ": EOF exception found")
546 main.log.error(self.name + ": " + self.handle.before)
547 main.cleanup()
548 main.exit()
549 except:
550 main.log.info(self.name+" ::::::")
551 main.log.error( traceback.print_exc())
552 main.log.info(self.name+" ::::::")
553 main.cleanup()
554 main.exit()
555
andrewonlab05e362f2014-10-10 00:40:57 -0400556 def onos_cli(self, ONOS_ip, cmdstr):
557 '''
558 Uses 'onos' command to send various ONOS CLI arguments.
559 Required:
560 * ONOS_ip: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400561 * cmdstr: specify the command string to send
andrewonlab6e20c342014-10-10 18:08:48 -0400562
563 This function is intended to expose the entire karaf
564 CLI commands for ONOS. Try to use this function first
565 before attempting to write a ONOS CLI specific driver
566 function.
567 You can see a list of available 'cmdstr' arguments
568 by starting onos, and typing in 'onos' to enter the
569 onos> CLI. Then, type 'help' to see the list of
570 available commands.
andrewonlab05e362f2014-10-10 00:40:57 -0400571 '''
572 try:
573 if not ONOS_ip:
574 main.log.error("You must specify the IP address")
575 return main.FALSE
576 if not cmdstr:
577 main.log.error("You must specify the command string")
578 return main.FALSE
579
580 cmdstr = str(cmdstr)
581 self.handle.sendline("")
582 self.handle.expect("\$")
583
584 self.handle.sendline("onos -w " + ONOS_ip + " " + cmdstr)
585 self.handle.expect("\$")
586
Shreya Shaha73aaad2014-10-27 18:03:09 -0400587 handle_before = self.handle.before
588 print "handle_before = ", self.handle.before
andrewonlab05e362f2014-10-10 00:40:57 -0400589 handle_after = str(self.handle.after)
590
Shreya Shaha73aaad2014-10-27 18:03:09 -0400591 #self.handle.sendline("")
592 #self.handle.expect("\$")
593 #handle_more = str(self.handle.before)
andrewonlab05e362f2014-10-10 00:40:57 -0400594
595 main.log.info("Command sent successfully")
596
andrewonlab94282092014-10-10 13:00:11 -0400597 #Obtain return handle that consists of result from
598 #the onos command. The string may need to be
599 #configured further.
Shreya Shaha73aaad2014-10-27 18:03:09 -0400600 #return_string = handle_before + handle_after
601 return_string = handle_before
602 print "return_string = ", return_string
andrewonlab05e362f2014-10-10 00:40:57 -0400603 return return_string
604
605 except pexpect.EOF:
606 main.log.error(self.name + ": EOF exception found")
607 main.log.error(self.name + ": " + self.handle.before)
608 main.cleanup()
609 main.exit()
610 except:
611 main.log.info(self.name+" ::::::")
612 main.log.error( traceback.print_exc())
613 main.log.info(self.name+" ::::::")
614 main.cleanup()
615 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400616
617 def onos_install(self, options="-f", node = ""):
618 '''
619 Installs ONOS bits on the designated cell machine.
620 If -f option is provided, it also forces an uninstall.
621 Presently, install also includes onos-push-bits and
622 onos-config within.
623 The node option allows you to selectively only push the jar
624 files to certain onos nodes
625
626 Returns: main.TRUE on success and main.FALSE on failure
627 '''
628 try:
629 self.handle.sendline("onos-install " + options + " " + node)
630 self.handle.expect("onos-install ")
631 #NOTE: this timeout may need to change depending on the network and size of ONOS
632 i=self.handle.expect(["Network\sis\sunreachable",
633 "onos\sstart/running,\sprocess",
634 pexpect.TIMEOUT],timeout=60)
635
Jon Hall7993bfc2014-10-09 16:30:14 -0400636 if i == 0:
637 main.log.warn("Network is unreachable")
638 return main.FALSE
639 elif i == 1:
Jon Hall42db6dc2014-10-24 19:03:48 -0400640 main.log.info("ONOS was installed on " + node + " and started")
Jon Hall7993bfc2014-10-09 16:30:14 -0400641 return main.TRUE
642 elif i == 2:
Jon Hall42db6dc2014-10-24 19:03:48 -0400643 main.log.info("Installation of ONOS on " + node + " timed out")
Jon Hall7993bfc2014-10-09 16:30:14 -0400644 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400645
646 except pexpect.EOF:
647 main.log.error(self.name + ": EOF exception found")
648 main.log.error(self.name + ": " + self.handle.before)
649 main.cleanup()
650 main.exit()
651 except:
652 main.log.info(self.name+" ::::::")
653 main.log.error( traceback.print_exc())
654 main.log.info(self.name+" ::::::")
655 main.cleanup()
656 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400657
andrewonlab8d0d7d72014-10-09 16:33:15 -0400658 def onos_start(self, node_ip):
659 '''
660 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400661 This command is a remote management of the ONOS upstart daemon
andrewonlab8d0d7d72014-10-09 16:33:15 -0400662 '''
663
664 try:
665 self.handle.sendline("")
666 self.handle.expect("\$")
667 self.handle.sendline("onos-service "+str(node_ip)+
668 " start")
669 i = self.handle.expect([
670 "Job\sis\salready\srunning",
671 "start/running",
672 "Unknown\sinstance",
Shreya Shahd01153d2014-10-23 15:08:56 -0400673 pexpect.TIMEOUT],timeout=120)
andrewonlab8d0d7d72014-10-09 16:33:15 -0400674
675 if i == 0:
676 main.log.info("Service is already running")
677 return main.TRUE
678 elif i == 1:
679 main.log.info("ONOS service started")
680 return main.TRUE
681 else:
682 main.log.error("ONOS service failed to start")
683 main.cleanup()
684 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400685 except pexpect.EOF:
686 main.log.error(self.name + ": EOF exception found")
687 main.log.error(self.name + ": " + self.handle.before)
688 main.cleanup()
689 main.exit()
690 except:
691 main.log.info(self.name+" ::::::")
692 main.log.error( traceback.print_exc())
693 main.log.info(self.name+" ::::::")
694 main.cleanup()
695 main.exit()
696
andrewonlab2b30bd32014-10-09 16:48:55 -0400697 def onos_stop(self, node_ip):
698 '''
699 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400700 This command is a remote management of the ONOS upstart daemon
andrewonlab2b30bd32014-10-09 16:48:55 -0400701 '''
702 try:
703 self.handle.sendline("")
704 self.handle.expect("\$")
705 self.handle.sendline("onos-service "+str(node_ip)+
706 " stop")
707 i = self.handle.expect([
708 "stop/waiting",
709 "Unknown\sinstance",
710 pexpect.TIMEOUT],timeout=60)
711
712 if i == 0:
713 main.log.info("ONOS service stopped")
714 return main.TRUE
715 elif i == 1:
716 main.log.info("Unknown ONOS instance specified: "+
717 str(node_ip))
718 return main.FALSE
719 else:
720 main.log.error("ONOS service failed to stop")
721 return main.FALSE
722
723 except pexpect.EOF:
724 main.log.error(self.name + ": EOF exception found")
725 main.log.error(self.name + ": " + self.handle.before)
726 main.cleanup()
727 main.exit()
728 except:
729 main.log.info(self.name+" ::::::")
730 main.log.error( traceback.print_exc())
731 main.log.info(self.name+" ::::::")
732 main.cleanup()
733 main.exit()
734
andrewonlabc8d47972014-10-09 16:52:36 -0400735 def onos_uninstall(self):
736 '''
737 Calls the command: 'onos-uninstall'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400738 Uninstalls ONOS from the designated cell machine, stopping
739 if needed
andrewonlabc8d47972014-10-09 16:52:36 -0400740 '''
741 try:
742 self.handle.sendline("")
743 self.handle.expect("\$")
744 self.handle.sendline("onos-uninstall")
745 self.handle.expect("\$")
746
andrewonlab84727452014-10-09 18:15:36 -0400747 main.log.info("ONOS cell machine was uninstalled")
andrewonlabc8d47972014-10-09 16:52:36 -0400748 #onos-uninstall command does not return any text
749 return main.TRUE
750
751 except pexpect.EOF:
752 main.log.error(self.name + ": EOF exception found")
753 main.log.error(self.name + ": " + self.handle.before)
754 main.cleanup()
755 main.exit()
756 except:
757 main.log.info(self.name+" ::::::")
758 main.log.error( traceback.print_exc())
759 main.log.info(self.name+" ::::::")
760 main.cleanup()
761 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -0400762
andrewonlabe8e56fd2014-10-09 17:12:44 -0400763 def onos_kill(self, node_ip):
764 '''
765 Calls the command: 'onos-kill [<node-ip>]'
766 "Remotely, and unceremoniously kills the ONOS instance running on
767 the specified cell machine" - Tom V
768 '''
769
770 try:
771 self.handle.sendline("")
772 self.handle.expect("\$")
773 self.handle.sendline("onos-kill " + str(node_ip))
774 i = self.handle.expect([
775 "\$",
776 "No\sroute\sto\shost",
777 "password:",
778 pexpect.TIMEOUT], timeout=20)
779
780 if i == 0:
781 main.log.info("ONOS instance "+str(node_ip)+" was killed")
782 return main.TRUE
783 elif i == 1:
784 main.log.info("No route to host")
785 return main.FALSE
786 elif i == 2:
787 main.log.info("Passwordless login for host: "+str(node_ip)+
788 " not configured")
789 return main.FALSE
790 else:
791 main.log.info("ONOS instasnce was not killed")
792 return main.FALSE
793
794 except pexpect.EOF:
795 main.log.error(self.name + ": EOF exception found")
796 main.log.error(self.name + ": " + self.handle.before)
797 main.cleanup()
798 main.exit()
799 except:
800 main.log.info(self.name+" ::::::")
801 main.log.error( traceback.print_exc())
802 main.log.info(self.name+" ::::::")
803 main.cleanup()
804 main.exit()
805
andrewonlab94282092014-10-10 13:00:11 -0400806 def onos_start_network(self, mntopo):
807 '''
808 Calls the command 'onos-start-network [<mininet-topo>]
809 "remotely starts the specified topology on the cell's
810 mininet machine against all controllers configured in the
811 cell."
812 * Specify mininet topology file name for mntopo
813 * Topo files should be placed at:
814 ~/<your-onos-directory>/tools/test/topos
815
816 NOTE: This function will take you to the mininet prompt
817 '''
818 try:
819 if not mntopo:
820 main.log.error("You must specify a topo file to execute")
821 return main.FALSE
822
823 mntopo = str(mntopo)
824 self.handle.sendline("")
825 self.handle.expect("\$")
826
827 self.handle.sendline("onos-start-network " + mntopo)
828 self.handle.expect("mininet>")
829 main.log.info("Network started, entered mininet prompt")
830
831 #TODO: Think about whether return is necessary or not
832
833 except pexpect.EOF:
834 main.log.error(self.name + ": EOF exception found")
835 main.log.error(self.name + ": " + self.handle.before)
836 main.cleanup()
837 main.exit()
838 except:
839 main.log.info(self.name+" ::::::")
840 main.log.error( traceback.print_exc())
841 main.log.info(self.name+" ::::::")
842 main.cleanup()
843 main.exit()
844
845
Jon Hall7993bfc2014-10-09 16:30:14 -0400846 def isup(self, node = ""):
847 '''
Jon Hall77f53ce2014-10-13 18:02:06 -0400848 Run's onos-wait-for-start which only returns once ONOS is at run
849 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -0400850
Jon Hall7993bfc2014-10-09 16:30:14 -0400851 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
852 '''
853 try:
854 self.handle.sendline("onos-wait-for-start " + node )
855 self.handle.expect("onos-wait-for-start")
856 #NOTE: this timeout is arbitrary"
857 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout = 120)
858 if i == 0:
859 main.log.info(self.name + ": " + node + " is up")
860 return main.TRUE
861 elif i == 1:
862 #NOTE: since this function won't return until ONOS is ready,
863 # we will kill it on timeout
864 self.handle.sendline("\003") #Control-C
865 self.handle.expect("\$")
866 return main.FALSE
867 except pexpect.EOF:
868 main.log.error(self.name + ": EOF exception found")
869 main.log.error(self.name + ": " + self.handle.before)
870 main.cleanup()
871 main.exit()
872 except:
873 main.log.info(self.name+" ::::::")
874 main.log.error( traceback.print_exc())
875 main.log.info(self.name+" ::::::")
876 main.cleanup()
877 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -0400878
879
Shreya Shaha73aaad2014-10-27 18:03:09 -0400880 def get_topology(self,topology_output):
Jon Hall77f53ce2014-10-13 18:02:06 -0400881 '''
882 parses the onos:topology output
883 Returns: a topology dict populated by the key values found in
884 the cli command.
885 '''
886
887 try:
888 #call the cli to get the topology summary
Shreya Shaha73aaad2014-10-27 18:03:09 -0400889 #cmdstr = "onos:topology"
890 #cli_result = self.onos_cli(ip, cmdstr)
891 #print "cli_result = ", cli_result
Jon Hall77f53ce2014-10-13 18:02:06 -0400892
893 #Parse the output
894 topology = {}
895 #for line in cli_result.split("\n"):
Shreya Shaha73aaad2014-10-27 18:03:09 -0400896 for line in topology_output.splitlines():
Jon Hall77f53ce2014-10-13 18:02:06 -0400897 if not line.startswith("time="):
898 continue
899 #else
900 print line
901 for var in line.split(","):
Shreya Shaha73aaad2014-10-27 18:03:09 -0400902 #print "'"+var+"'"
903 #print "'"+var.strip()+"'"
Jon Hall77f53ce2014-10-13 18:02:06 -0400904 key, value = var.strip().split("=")
905 topology[key] = value
Shreya Shaha73aaad2014-10-27 18:03:09 -0400906 print "topology = ", topology
Jon Hall77f53ce2014-10-13 18:02:06 -0400907 devices = topology.get('devices', False)
Shreya Shaha73aaad2014-10-27 18:03:09 -0400908 print "devices = ", devices
Jon Hall77f53ce2014-10-13 18:02:06 -0400909 links = topology.get('links', False)
Shreya Shaha73aaad2014-10-27 18:03:09 -0400910 print "links = ", links
Jon Hall77f53ce2014-10-13 18:02:06 -0400911 clusters = topology.get('clusters', False)
Shreya Shaha73aaad2014-10-27 18:03:09 -0400912 print "clusters = ", clusters
Jon Hall77f53ce2014-10-13 18:02:06 -0400913 paths = topology.get('paths', False)
Shreya Shaha73aaad2014-10-27 18:03:09 -0400914 print "paths = ", paths
Jon Hall77f53ce2014-10-13 18:02:06 -0400915
916 return topology
917 except pexpect.EOF:
918 main.log.error(self.name + ": EOF exception found")
919 main.log.error(self.name + ": " + self.handle.before)
920 main.cleanup()
921 main.exit()
922 except:
923 main.log.info(self.name+" ::::::")
924 main.log.error( traceback.print_exc())
925 main.log.info(self.name+" ::::::")
926 main.cleanup()
927 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -0400928
929
Jon Hall77f53ce2014-10-13 18:02:06 -0400930
Shreya Shaha73aaad2014-10-27 18:03:09 -0400931 def check_status(self, topology_result, numoswitch, numolink, log_level="info"):
Jon Hall77f53ce2014-10-13 18:02:06 -0400932 '''
933 Checks the number of swithes & links that ONOS sees against the
934 supplied values. By default this will report to main.log, but the
935 log level can be specifid.
936
937 Params: ip = ip used for the onos cli
938 numoswitch = expected number of switches
939 numlink = expected number of links
940 log_level = level to log to. Currently accepts 'info', 'warn' and 'report'
941
942
943 log_level can
944
945 Returns: main.TRUE if the number of switchs and links are correct,
946 main.FALSE if the numer of switches and links is incorrect,
947 and main.ERROR otherwise
948 '''
949
950 try:
Shreya Shaha73aaad2014-10-27 18:03:09 -0400951 topology = self.get_topology(topology_result)
Jon Hall77f53ce2014-10-13 18:02:06 -0400952 if topology == {}:
953 return main.ERROR
954 output = ""
955 #Is the number of switches is what we expected
956 devices = topology.get('devices',False)
957 links = topology.get('links',False)
958 if devices == False or links == False:
959 return main.ERROR
960 switch_check = ( int(devices) == int(numoswitch) )
961 #Is the number of links is what we expected
962 link_check = ( int(links) == int(numolink) )
963 if (switch_check and link_check):
964 #We expected the correct numbers
965 output = output + "The number of links and switches match "\
966 + "what was expected"
967 result = main.TRUE
968 else:
969 output = output + \
970 "The number of links and switches does not match what was expected"
971 result = main.FALSE
972 output = output + "\n ONOS sees %i devices (%i expected) and %i links (%i expected)"\
973 % ( int(devices), int(numoswitch), int(links), int(numolink) )
974 if log_level == "report":
975 main.log.report(output)
976 elif log_level == "warn":
977 main.log.warn(output)
978 else:
979 main.log.info(output)
980 return result
981 except pexpect.EOF:
982 main.log.error(self.name + ": EOF exception found")
983 main.log.error(self.name + ": " + self.handle.before)
984 main.cleanup()
985 main.exit()
986 except:
987 main.log.info(self.name+" ::::::")
988 main.log.error( traceback.print_exc())
989 main.log.info(self.name+" ::::::")
990 main.cleanup()
991 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -0400992
Shreya Shaha73aaad2014-10-27 18:03:09 -0400993
andrewonlabba44bcf2014-10-16 16:54:41 -0400994 def tshark_grep(self, grep, directory, interface='eth0'):
995 '''
996 Required:
997 * grep string
998 * directory to store results
999 Optional:
1000 * interface - default: eth0
1001 Description:
1002 Uses tshark command to grep specific group of packets
1003 and stores the results to specified directory.
1004 The timestamp is hardcoded to be in epoch
1005 '''
1006 self.handle.sendline("")
1007 self.handle.expect("\$")
andrewonlabefd7f3d2014-10-21 16:02:31 -04001008 self.handle.sendline("")
andrewonlabba44bcf2014-10-16 16:54:41 -04001009 self.handle.sendline("tshark -i "+str(interface)+
andrewonlabd4940492014-10-24 12:21:27 -04001010 " -t e | grep --line-buffered \""+str(grep)+"\" >"+directory+" &")
andrewonlabba44bcf2014-10-16 16:54:41 -04001011 self.handle.sendline("\r")
1012 self.handle.expect("Capturing on")
1013 self.handle.sendline("\r")
1014 self.handle.expect("\$")
1015
1016 def tshark_stop(self):
1017 '''
1018 Removes wireshark files from /tmp and kills all tshark processes
1019 '''
andrewonlab5ba0d9e2014-10-24 13:32:23 -04001020 #Remove all pcap from previous captures
1021 self.execute(cmd="sudo rm /tmp/wireshark*")
andrewonlabba44bcf2014-10-16 16:54:41 -04001022 self.handle.sendline("")
1023 self.handle.sendline("sudo kill -9 `ps -ef | grep \"tshark -i\" |"+
1024 " grep -v grep | awk '{print $2}'`")
1025 self.handle.sendline("")
1026 main.log.info("Tshark stopped")
1027
1028
1029
1030