Package TestON :: Package drivers :: Package common :: Package cli :: Module onosdriver
[hide private]
[frames] | no frames]

Source Code for Module TestON.drivers.common.cli.onosdriver

   1  #!/usr/bin/env python 
   2   
   3  """ 
   4  This driver interacts with ONOS bench, the OSGi platform 
   5  that configures the ONOS nodes. ( aka ONOS-next ) 
   6   
   7  Please follow the coding style demonstrated by existing 
   8  functions and document properly. 
   9   
  10  If you are a contributor to the driver, please 
  11  list your email here for future contact: 
  12   
  13  jhall@onlab.us 
  14  andrew@onlab.us 
  15   
  16  OCT 9 2014 
  17   
  18  """ 
  19  import time 
  20  import types 
  21  import pexpect 
  22  import os 
  23  import os.path 
  24  from requests.models import Response 
  25  from drivers.common.clidriver import CLI 
  26   
  27   
28 -class OnosDriver( CLI ):
29
30 - def __init__( self ):
31 """ 32 Initialize client 33 """ 34 self.name = None 35 self.home = None 36 self.handle = None 37 super( CLI, self ).__init__()
38
39 - def connect( self, **connectargs ):
40 """ 41 Creates ssh handle for ONOS "bench". 42 NOTE: 43 The ip_address would come from the topo file using the host tag, the 44 value can be an environment variable as well as a "localhost" to get 45 the ip address needed to ssh to the "bench" 46 """ 47 try: 48 for key in connectargs: 49 vars( self )[ key ] = connectargs[ key ] 50 self.home = "~/onos" 51 for key in self.options: 52 if key == "home": 53 self.home = self.options[ 'home' ] 54 break 55 if self.home is None or self.home == "": 56 self.home = "~/onos" 57 58 self.name = self.options[ 'name' ] 59 60 # The 'nodes' tag is optional and it is not required in .topo file 61 for key in self.options: 62 if key == "nodes": 63 # Maximum number of ONOS nodes to run, if there is any 64 self.maxNodes = int( self.options[ 'nodes' ] ) 65 break 66 self.maxNodes = None 67 68 if self.maxNodes == None or self.maxNodes == "": 69 self.maxNodes = 100 70 71 72 # Grabs all OC environment variables based on max number of nodes 73 self.onosIps = {} # Dictionary of all possible ONOS ip 74 75 try: 76 if self.maxNodes: 77 for i in range( self.maxNodes ): 78 envString = "OC" + str( i + 1 ) 79 # If there is no more OC# then break the loop 80 if os.getenv( envString ): 81 self.onosIps[ envString ] = os.getenv( envString ) 82 else: 83 self.maxNodes = len( self.onosIps ) 84 main.log.info( self.name + 85 ": Created cluster data with " + 86 str( self.maxNodes ) + 87 " maximum number" + 88 " of nodes" ) 89 break 90 91 if not self.onosIps: 92 main.log.info( "Could not read any environment variable" 93 + " please load a cell file with all" + 94 " onos IP" ) 95 self.maxNodes = None 96 else: 97 main.log.info( self.name + ": Found " + 98 str( self.onosIps.values() ) + 99 " ONOS IPs" ) 100 except KeyError: 101 main.log.info( "Invalid environment variable" ) 102 except Exception as inst: 103 main.log.error( "Uncaught exception: " + str( inst ) ) 104 105 try: 106 if os.getenv( str( self.ip_address ) ) != None: 107 self.ip_address = os.getenv( str( self.ip_address ) ) 108 else: 109 main.log.info( self.name + 110 ": Trying to connect to " + 111 self.ip_address ) 112 except KeyError: 113 main.log.info( "Invalid host name," + 114 " connecting to local host instead" ) 115 self.ip_address = 'localhost' 116 except Exception as inst: 117 main.log.error( "Uncaught exception: " + str( inst ) ) 118 119 self.handle = super( OnosDriver, self ).connect( 120 user_name=self.user_name, 121 ip_address=self.ip_address, 122 port=self.port, 123 pwd=self.pwd, 124 home=self.home ) 125 126 if self.handle: 127 self.handle.sendline( "cd " + self.home ) 128 self.handle.expect( "\$" ) 129 return self.handle 130 else: 131 main.log.info( "Failed to create ONOS handle" ) 132 return main.FALSE 133 except pexpect.EOF: 134 main.log.error( self.name + ": EOF exception found" ) 135 main.log.error( self.name + ": " + self.handle.before ) 136 main.cleanup() 137 main.exit() 138 except Exception: 139 main.log.exception( self.name + ": Uncaught exception!" ) 140 main.cleanup() 141 main.exit()
142
143 - def disconnect( self ):
144 """ 145 Called when Test is complete to disconnect the ONOS handle. 146 """ 147 response = main.TRUE 148 try: 149 if self.handle: 150 self.handle.sendline( "" ) 151 self.handle.expect( "\$" ) 152 self.handle.sendline( "exit" ) 153 self.handle.expect( "closed" ) 154 except pexpect.EOF: 155 main.log.error( self.name + ": EOF exception found" ) 156 main.log.error( self.name + ": " + self.handle.before ) 157 except ValueError: 158 main.log.exception( "Exception in disconnect of " + self.name ) 159 response = main.TRUE 160 except Exception: 161 main.log.exception( self.name + ": Connection failed to the host" ) 162 response = main.FALSE 163 return response
164
165 - def getEpochMs( self ):
166 """ 167 Returns milliseconds since epoch 168 169 When checking multiple nodes in a for loop, 170 around a hundred milliseconds of difference (ascending) is 171 generally acceptable due to calltime of the function. 172 Few seconds, however, is not and it means clocks 173 are off sync. 174 """ 175 try: 176 self.handle.sendline( 'date +%s.%N' ) 177 self.handle.expect( 'date \+\%s\.\%N' ) 178 self.handle.expect( '\$' ) 179 epochMs = self.handle.before 180 return epochMs 181 except Exception: 182 main.log.exception( 'Uncaught exception getting epoch time' ) 183 main.cleanup() 184 main.exit()
185
186 - def onosPackage( self, opTimeout=30 ):
187 """ 188 Produce a self-contained tar.gz file that can be deployed 189 and executed on any platform with Java 7 JRE. 190 """ 191 try: 192 self.handle.sendline( "onos-package" ) 193 self.handle.expect( "onos-package" ) 194 self.handle.expect( "tar.gz", opTimeout ) 195 handle = str( self.handle.before ) 196 main.log.info( "onos-package command returned: " + 197 handle ) 198 # As long as the sendline does not time out, 199 # return true. However, be careful to interpret 200 # the results of the onos-package command return 201 return main.TRUE 202 203 except pexpect.EOF: 204 main.log.error( self.name + ": EOF exception found" ) 205 main.log.error( self.name + ": " + self.handle.before ) 206 except Exception: 207 main.log.exception( "Failed to package ONOS" ) 208 main.cleanup() 209 main.exit()
210
211 - def onosBuild( self ):
212 """ 213 Use the pre defined script to build onos via mvn 214 """ 215 try: 216 self.handle.sendline( "onos-build" ) 217 self.handle.expect( "onos-build" ) 218 i = self.handle.expect( [ 219 "BUILD SUCCESS", 220 "ERROR", 221 "BUILD FAILED" ], 222 timeout=120 ) 223 handle = str( self.handle.before ) 224 225 main.log.info( "onos-build command returned: " + 226 handle ) 227 228 if i == 0: 229 return main.TRUE 230 else: 231 return handle 232 233 except pexpect.EOF: 234 main.log.error( self.name + ": EOF exception found" ) 235 main.log.error( self.name + ": " + self.handle.before ) 236 except Exception: 237 main.log.exception( "Failed to build ONOS" ) 238 main.cleanup() 239 main.exit()
240
241 - def cleanInstall( self, skipTest=False, mciTimeout=600 ):
242 """ 243 Runs mvn clean install in the root of the ONOS directory. 244 This will clean all ONOS artifacts then compile each module 245 Optional: 246 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which 247 skip the test. This will make the building faster. 248 Disregarding the credibility of the build 249 Returns: main.TRUE on success 250 On Failure, exits the test 251 """ 252 try: 253 main.log.info( "Running 'mvn clean install' on " + 254 str( self.name ) + 255 ". This may take some time." ) 256 self.handle.sendline( "cd " + self.home ) 257 self.handle.expect( "\$" ) 258 259 self.handle.sendline( "" ) 260 self.handle.expect( "\$" ) 261 262 if not skipTest: 263 self.handle.sendline( "mvn clean install" ) 264 self.handle.expect( "mvn clean install" ) 265 else: 266 self.handle.sendline( "mvn clean install -DskipTests" + 267 " -Dcheckstyle.skip -U -T 1C" ) 268 self.handle.expect( "mvn clean install -DskipTests" + 269 " -Dcheckstyle.skip -U -T 1C" ) 270 while True: 271 i = self.handle.expect( [ 272 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' + 273 'Runtime\sEnvironment\sto\scontinue', 274 'BUILD\sFAILURE', 275 'BUILD\sSUCCESS', 276 'onos\$', #TODO: fix this to be more generic? 277 'ONOS\$', 278 pexpect.TIMEOUT ], mciTimeout ) 279 if i == 0: 280 main.log.error( self.name + ":There is insufficient memory \ 281 for the Java Runtime Environment to continue." ) 282 # return main.FALSE 283 main.cleanup() 284 main.exit() 285 if i == 1: 286 main.log.error( self.name + ": Build failure!" ) 287 # return main.FALSE 288 main.cleanup() 289 main.exit() 290 elif i == 2: 291 main.log.info( self.name + ": Build success!" ) 292 elif i == 3 or i == 4: 293 main.log.info( self.name + ": Build complete" ) 294 # Print the build time 295 for line in self.handle.before.splitlines(): 296 if "Total time:" in line: 297 main.log.info( line ) 298 self.handle.sendline( "" ) 299 self.handle.expect( "\$", timeout=60 ) 300 return main.TRUE 301 elif i == 5: 302 main.log.error( 303 self.name + 304 ": mvn clean install TIMEOUT!" ) 305 # return main.FALSE 306 main.cleanup() 307 main.exit() 308 else: 309 main.log.error( self.name + ": unexpected response from " + 310 "mvn clean install" ) 311 # return main.FALSE 312 main.cleanup() 313 main.exit() 314 except pexpect.EOF: 315 main.log.error( self.name + ": EOF exception found" ) 316 main.log.error( self.name + ": " + self.handle.before ) 317 main.cleanup() 318 main.exit() 319 except Exception: 320 main.log.exception( self.name + ": Uncaught exception!" ) 321 main.cleanup() 322 main.exit()
323
324 - def gitPull( self, comp1="", fastForward=True ):
325 """ 326 Assumes that "git pull" works without login 327 328 If the fastForward boolean is set to true, only git pulls that can 329 be fast forwarded will be performed. IE if you have not local commits 330 in your branch. 331 332 This function will perform a git pull on the ONOS instance. 333 If used as gitPull( "NODE" ) it will do git pull + NODE. This is 334 for the purpose of pulling from other nodes if necessary. 335 336 Otherwise, this function will perform a git pull in the 337 ONOS repository. If it has any problems, it will return main.ERROR 338 If it successfully does a gitPull, it will return a 1 ( main.TRUE ) 339 If it has no updates, it will return 3. 340 341 """ 342 try: 343 # main.log.info( self.name + ": Stopping ONOS" ) 344 # self.stop() 345 self.handle.sendline( "cd " + self.home ) 346 self.handle.expect( self.home + "\$" ) 347 cmd = "git pull" 348 if comp1 != "": 349 cmd += ' ' + comp1 350 if fastForward: 351 cmd += ' ' + " --ff-only" 352 self.handle.sendline( cmd ) 353 i = self.handle.expect( 354 [ 355 'fatal', 356 'Username\sfor\s(.*):\s', 357 '\sfile(s*) changed,\s', 358 'Already up-to-date', 359 'Aborting', 360 'You\sare\snot\scurrently\son\sa\sbranch', 361 'You asked me to pull without telling me which branch you', 362 'Pull is not possible because you have unmerged files', 363 'Please enter a commit message to explain why this merge', 364 'Found a swap file by the name', 365 'Please, commit your changes before you can merge.', 366 pexpect.TIMEOUT ], 367 timeout=300 ) 368 # debug 369 # main.log.report( self.name +": DEBUG: \n"+ 370 # "git pull response: " + 371 # str( self.handle.before ) + str( self.handle.after ) ) 372 if i == 0: 373 main.log.error( self.name + ": Git pull had some issue" ) 374 output = self.handle.after 375 self.handle.expect( '\$' ) 376 output += self.handle.before 377 main.log.warn( output ) 378 return main.ERROR 379 elif i == 1: 380 main.log.error( 381 self.name + 382 ": Git Pull Asking for username. " ) 383 return main.ERROR 384 elif i == 2: 385 main.log.info( 386 self.name + 387 ": Git Pull - pulling repository now" ) 388 self.handle.expect( self.home + "\$", 120 ) 389 # So that only when git pull is done, we do mvn clean compile 390 return main.TRUE 391 elif i == 3: 392 main.log.info( self.name + ": Git Pull - Already up to date" ) 393 return i 394 elif i == 4: 395 main.log.info( 396 self.name + 397 ": Git Pull - Aborting..." + 398 "Are there conflicting git files?" ) 399 return main.ERROR 400 elif i == 5: 401 main.log.info( 402 self.name + 403 ": Git Pull - You are not currently " + 404 "on a branch so git pull failed!" ) 405 return main.ERROR 406 elif i == 6: 407 main.log.info( 408 self.name + 409 ": Git Pull - You have not configured an upstream " + 410 "branch to pull from. Git pull failed!" ) 411 return main.ERROR 412 elif i == 7: 413 main.log.info( 414 self.name + 415 ": Git Pull - Pull is not possible because " + 416 "you have unmerged files." ) 417 return main.ERROR 418 elif i == 8: 419 # NOTE: abandoning test since we can't reliably handle this 420 # there could be different default text editors and we 421 # also don't know if we actually want to make the commit 422 main.log.error( "Git pull resulted in a merge commit message" + 423 ". Exiting test!" ) 424 main.cleanup() 425 main.exit() 426 elif i == 9: # Merge commit message but swap file exists 427 main.log.error( "Git pull resulted in a merge commit message" + 428 " but a swap file exists." ) 429 try: 430 self.handle.send( 'A' ) # Abort 431 self.handle.expect( "\$" ) 432 return main.ERROR 433 except Exception: 434 main.log.exception( "Couldn't exit editor prompt!") 435 main.cleanup() 436 main.exit() 437 elif i == 10: # In the middle of a merge commit 438 main.log.error( "Git branch is in the middle of a merge. " ) 439 main.log.warn( self.handle.before + self.handle.after ) 440 return main.ERROR 441 elif i == 11: 442 main.log.error( self.name + ": Git Pull - TIMEOUT" ) 443 main.log.error( 444 self.name + " Response was: " + str( 445 self.handle.before ) ) 446 return main.ERROR 447 else: 448 main.log.error( 449 self.name + 450 ": Git Pull - Unexpected response, check for pull errors" ) 451 return main.ERROR 452 except pexpect.EOF: 453 main.log.error( self.name + ": EOF exception found" ) 454 main.log.error( self.name + ": " + self.handle.before ) 455 main.cleanup() 456 main.exit() 457 except Exception: 458 main.log.exception( self.name + ": Uncaught exception!" ) 459 main.cleanup() 460 main.exit()
461
462 - def gitCheckout( self, branch="master" ):
463 """ 464 Assumes that "git pull" works without login 465 466 This function will perform a git git checkout on the ONOS instance. 467 If used as gitCheckout( "branch" ) it will do git checkout 468 of the "branch". 469 470 Otherwise, this function will perform a git checkout of the master 471 branch of the ONOS repository. If it has any problems, it will return 472 main.ERROR. 473 If the branch was already the specified branch, or the git checkout was 474 successful then the function will return main.TRUE. 475 476 """ 477 try: 478 self.handle.sendline( "cd " + self.home ) 479 self.handle.expect( self.home + "\$" ) 480 main.log.info( self.name + 481 ": Checking out git branch/ref: " + branch + "..." ) 482 cmd = "git checkout " + branch 483 self.handle.sendline( cmd ) 484 self.handle.expect( cmd ) 485 i = self.handle.expect( 486 [ 'fatal', 487 'Username for (.*): ', 488 'Already on \'', 489 'Switched to (a new )?branch \'' + str( branch ), 490 pexpect.TIMEOUT, 491 'error: Your local changes to the following files' + 492 'would be overwritten by checkout:', 493 'error: you need to resolve your current index first', 494 "You are in 'detached HEAD' state.", 495 "HEAD is now at " ], 496 timeout=60 ) 497 if i == 0: 498 main.log.error( 499 self.name + 500 ": Git checkout had some issue..." ) 501 main.log.error( self.name + ": " + self.handle.before ) 502 return main.ERROR 503 elif i == 1: 504 main.log.error( 505 self.name + 506 ": Git checkout asking for username." + 507 " Please configure your local git repository to be able " + 508 "to access your remote repository passwordlessly" ) 509 # TODO add support for authenticating 510 return main.ERROR 511 elif i == 2: 512 main.log.info( 513 self.name + 514 ": Git Checkout %s : Already on this branch" % branch ) 515 self.handle.expect( self.home + "\$" ) 516 # main.log.info( "DEBUG: after checkout cmd = "+ 517 # self.handle.before ) 518 return main.TRUE 519 elif i == 3: 520 main.log.info( 521 self.name + 522 ": Git checkout %s - Switched to this branch" % branch ) 523 self.handle.expect( self.home + "\$" ) 524 # main.log.info( "DEBUG: after checkout cmd = "+ 525 # self.handle.before ) 526 return main.TRUE 527 elif i == 4: 528 main.log.error( self.name + ": Git Checkout- TIMEOUT" ) 529 main.log.error( 530 self.name + " Response was: " + str( self.handle.before ) ) 531 return main.ERROR 532 elif i == 5: 533 self.handle.expect( "Aborting" ) 534 main.log.error( 535 self.name + 536 ": Git checkout error: \n" + 537 "Your local changes to the following files would" + 538 " be overwritten by checkout:" + 539 str( self.handle.before ) ) 540 self.handle.expect( self.home + "\$" ) 541 return main.ERROR 542 elif i == 6: 543 main.log.error( 544 self.name + 545 ": Git checkout error: \n" + 546 "You need to resolve your current index first:" + 547 str( self.handle.before ) ) 548 self.handle.expect( self.home + "\$" ) 549 return main.ERROR 550 elif i == 7: 551 main.log.info( 552 self.name + 553 ": Git checkout " + str( branch ) + 554 " - You are in 'detached HEAD' state. HEAD is now at " + 555 str( branch ) ) 556 self.handle.expect( self.home + "\$" ) 557 return main.TRUE 558 elif i == 8: # Already in detached HEAD on the specified commit 559 main.log.info( 560 self.name + 561 ": Git Checkout %s : Already on commit" % branch ) 562 self.handle.expect( self.home + "\$" ) 563 return main.TRUE 564 else: 565 main.log.error( 566 self.name + 567 ": Git Checkout - Unexpected response, " + 568 "check for pull errors" ) 569 main.log.error( self.name + ": " + self.handle.before ) 570 return main.ERROR 571 572 except pexpect.EOF: 573 main.log.error( self.name + ": EOF exception found" ) 574 main.log.error( self.name + ": " + self.handle.before ) 575 main.cleanup() 576 main.exit() 577 except Exception: 578 main.log.exception( self.name + ": Uncaught exception!" ) 579 main.cleanup() 580 main.exit()
581
582 - def getBranchName( self ):
583 main.log.info( "self.home = " ) 584 main.log.info( self.home ) 585 self.handle.sendline( "cd " + self.home ) 586 self.handle.expect( self.home + "\$" ) 587 self.handle.sendline( "git name-rev --name-only HEAD" ) 588 self.handle.expect( "git name-rev --name-only HEAD" ) 589 self.handle.expect( "\$" ) 590 591 lines = self.handle.before.splitlines() 592 if lines[1] == "master": 593 return "master" 594 elif lines[1] == "onos-1.0": 595 return "onos-1.0" 596 else: 597 main.log.info( lines[1] ) 598 return "unexpected ONOS branch for SDN-IP test"
599
600 - def getVersion( self, report=False ):
601 """ 602 Writes the COMMIT number to the report to be parsed 603 by Jenkins data collector. 604 """ 605 try: 606 self.handle.sendline( "" ) 607 self.handle.expect( "\$" ) 608 self.handle.sendline( 609 "cd " + 610 self.home + 611 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " + 612 " \"commit\" --color=never" ) 613 # NOTE: for some reason there are backspaces inserted in this 614 # phrase when run from Jenkins on some tests 615 self.handle.expect( "never" ) 616 self.handle.expect( "\$" ) 617 response = ( self.name + ": \n" + str( 618 self.handle.before + self.handle.after ) ) 619 self.handle.sendline( "cd " + self.home ) 620 self.handle.expect( "\$" ) 621 lines = response.splitlines() 622 for line in lines: 623 print line 624 if report: 625 main.log.wiki( "<blockquote>" ) 626 for line in lines[ 2:-1 ]: 627 # Bracket replacement is for Wiki-compliant 628 # formatting. '<' or '>' are interpreted 629 # as xml specific tags that cause errors 630 line = line.replace( "<", "[" ) 631 line = line.replace( ">", "]" ) 632 #main.log.wiki( "\t" + line ) 633 main.log.wiki( line + "<br /> " ) 634 main.log.summary( line ) 635 main.log.wiki( "</blockquote>" ) 636 main.log.summary("\n") 637 return lines[ 2 ] 638 except pexpect.EOF: 639 main.log.error( self.name + ": EOF exception found" ) 640 main.log.error( self.name + ": " + self.handle.before ) 641 main.cleanup() 642 main.exit() 643 except pexpect.TIMEOUT: 644 main.log.error( self.name + ": TIMEOUT exception found" ) 645 main.log.error( self.name + ": " + self.handle.before ) 646 main.cleanup() 647 main.exit() 648 except Exception: 649 main.log.exception( self.name + ": Uncaught exception!" ) 650 main.cleanup() 651 main.exit()
652
653 - def createCellFile( self, benchIp, fileName, mnIpAddrs, 654 appString, onosIpAddrs ):
655 """ 656 Creates a cell file based on arguments 657 Required: 658 * Bench IP address ( benchIp ) 659 - Needed to copy the cell file over 660 * File name of the cell file ( fileName ) 661 * Mininet IP address ( mnIpAddrs ) 662 - Note that only 1 ip address is 663 supported currently 664 * ONOS IP addresses ( onosIpAddrs ) 665 - Must be passed in as last arguments 666 667 NOTE: Assumes cells are located at: 668 ~/<self.home>/tools/test/cells/ 669 """ 670 # Variable initialization 671 cellDirectory = self.home + "/tools/test/cells/" 672 # We want to create the cell file in the dependencies directory 673 # of TestON first, then copy over to ONOS bench 674 tempDirectory = "/tmp/" 675 # Create the cell file in the directory for writing ( w+ ) 676 cellFile = open( tempDirectory + fileName, 'w+' ) 677 if isinstance( onosIpAddrs, types.StringType ): 678 onosIpAddrs = [ onosIpAddrs ] 679 680 # App string is hardcoded environment variables 681 # That you may wish to use by default on startup. 682 # Note that you may not want certain apps listed 683 # on here. 684 appString = "export ONOS_APPS=" + appString 685 mnString = "export OCN=" 686 if mnIpAddrs == "": 687 mnString = "" 688 onosString = "export OC" 689 tempCount = 1 690 691 # Create ONOSNIC ip address prefix 692 tempOnosIp = str( onosIpAddrs[ 0 ] ) 693 tempList = [] 694 tempList = tempOnosIp.split( "." ) 695 # Omit last element of list to format for NIC 696 tempList = tempList[ :-1 ] 697 # Structure the nic string ip 698 nicAddr = ".".join( tempList ) + ".*" 699 onosNicString = "export ONOS_NIC=" + nicAddr 700 701 try: 702 # Start writing to file 703 cellFile.write( onosNicString + "\n" ) 704 705 for arg in onosIpAddrs: 706 # For each argument in onosIpAddrs, write to file 707 # Output should look like the following: 708 # export OC1="10.128.20.11" 709 # export OC2="10.128.20.12" 710 cellFile.write( onosString + str( tempCount ) + 711 "=" + "\"" + arg + "\"" + "\n" ) 712 tempCount = tempCount + 1 713 714 cellFile.write( mnString + "\"" + mnIpAddrs + "\"" + "\n" ) 715 cellFile.write( appString + "\n" ) 716 cellFile.close() 717 718 # We use os.system to send the command to TestON cluster 719 # to account for the case in which TestON is not located 720 # on the same cluster as the ONOS bench 721 # Note that even if TestON is located on the same cluster 722 # as ONOS bench, you must setup passwordless ssh 723 # between TestON and ONOS bench in order to automate the test. 724 os.system( "scp " + tempDirectory + fileName + " " + 725 self.user_name + "@" + self.ip_address + ":" + cellDirectory ) 726 727 return main.TRUE 728 729 except pexpect.EOF: 730 main.log.error( self.name + ": EOF exception found" ) 731 main.log.error( self.name + ": " + self.handle.before ) 732 main.cleanup() 733 main.exit() 734 except Exception: 735 main.log.exception( self.name + ": Uncaught exception!" ) 736 main.cleanup() 737 main.exit()
738
739 - def setCell( self, cellname ):
740 """ 741 Calls 'cell <name>' to set the environment variables on ONOSbench 742 """ 743 import re 744 try: 745 if not cellname: 746 main.log.error( "Must define cellname" ) 747 main.cleanup() 748 main.exit() 749 else: 750 self.handle.sendline( "cell " + str( cellname ) ) 751 # Expect the cellname in the ONOSCELL variable. 752 # Note that this variable name is subject to change 753 # and that this driver will have to change accordingly 754 self.handle.expect(str(cellname)) 755 handleBefore = self.handle.before 756 handleAfter = self.handle.after 757 # Get the rest of the handle 758 self.handle.sendline("") 759 self.handle.expect("\$") 760 handleMore = self.handle.before 761 762 cell_result = handleBefore + handleAfter + handleMore 763 print cell_result 764 if( re.search( "No such cell", cell_result ) ): 765 main.log.error( "Cell call returned: " + handleBefore + 766 handleAfter + handleMore ) 767 main.cleanup() 768 main.exit() 769 return main.TRUE 770 771 except pexpect.EOF: 772 main.log.error( self.name + ": EOF exception found" ) 773 main.log.error( self.name + ": " + self.handle.before ) 774 main.cleanup() 775 main.exit() 776 except Exception: 777 main.log.exception( self.name + ": Uncaught exception!" ) 778 main.cleanup() 779 main.exit()
780
781 - def verifyCell( self ):
782 """ 783 Calls 'onos-verify-cell' to check for cell installation 784 """ 785 # TODO: Add meaningful expect value 786 787 try: 788 # Clean handle by sending empty and expecting $ 789 self.handle.sendline( "" ) 790 self.handle.expect( "\$" ) 791 self.handle.sendline( "onos-verify-cell" ) 792 self.handle.expect( "\$" ) 793 handleBefore = self.handle.before 794 handleAfter = self.handle.after 795 # Get the rest of the handle 796 self.handle.sendline( "" ) 797 self.handle.expect( "\$" ) 798 handleMore = self.handle.before 799 800 main.log.info( "Verify cell returned: " + handleBefore + 801 handleAfter + handleMore ) 802 803 return main.TRUE 804 except pexpect.ExceptionPexpect as e: 805 main.log.error( self.name + ": Pexpect exception found of type " + 806 str( type( e ) ) ) 807 main.log.error ( e.get_trace() ) 808 main.log.error( self.name + ": " + self.handle.before ) 809 main.cleanup() 810 main.exit() 811 except Exception: 812 main.log.exception( self.name + ": Uncaught exception!" ) 813 main.cleanup() 814 main.exit()
815
816 - def onosCfgSet( self, ONOSIp, configName, configParam ):
817 """ 818 Uses 'onos <node-ip> cfg set' to change a parameter value of an 819 application. 820 821 ex) 822 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1 823 ONOSIp = '10.0.0.1' 824 configName = 'org.onosproject.myapp' 825 configParam = 'appSetting 1' 826 """ 827 for i in range(5): 828 try: 829 cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+ 830 str(configName) + " " + 831 str(configParam) 832 ) 833 834 self.handle.sendline( "" ) 835 self.handle.expect( ":~" ) 836 self.handle.sendline( cfgStr ) 837 self.handle.expect("cfg set") 838 self.handle.expect( ":~" ) 839 840 paramValue = configParam.split(" ")[1] 841 paramName = configParam.split(" ")[0] 842 843 checkStr = ( "onos " + str(ONOSIp) + """ cfg get " """ + str(configName) + " " + paramName + """ " """) 844 845 self.handle.sendline( checkStr ) 846 self.handle.expect( ":~" ) 847 848 if "value=" + paramValue + "," in self.handle.before: 849 main.log.info("cfg " + configName + " successfully set to " + configParam) 850 return main.TRUE 851 852 except pexpect.ExceptionPexpect as e: 853 main.log.error( self.name + ": Pexpect exception found of type " + 854 str( type( e ) ) ) 855 main.log.error ( e.get_trace() ) 856 main.log.error( self.name + ": " + self.handle.before ) 857 main.cleanup() 858 main.exit() 859 except Exception: 860 main.log.exception( self.name + ": Uncaught exception!" ) 861 main.cleanup() 862 main.exit() 863 864 time.sleep(5) 865 866 main.log.error("CFG SET FAILURE: " + configName + " " + configParam ) 867 main.ONOSbench.handle.sendline("onos $OC1 cfg get") 868 main.ONOSbench.handle.expect("\$") 869 print main.ONOSbench.handle.before 870 main.ONOSbench.logReport( ONOSIp, ["ERROR","WARN","EXCEPT"], "d") 871 return main.FALSE
872 873
874 - def onosCli( self, ONOSIp, cmdstr ):
875 """ 876 Uses 'onos' command to send various ONOS CLI arguments. 877 Required: 878 * ONOSIp: specify the ip of the cell machine 879 * cmdstr: specify the command string to send 880 881 This function is intended to expose the entire karaf 882 CLI commands for ONOS. Try to use this function first 883 before attempting to write a ONOS CLI specific driver 884 function. 885 You can see a list of available 'cmdstr' arguments 886 by starting onos, and typing in 'onos' to enter the 887 onos> CLI. Then, type 'help' to see the list of 888 available commands. 889 """ 890 try: 891 if not ONOSIp: 892 main.log.error( "You must specify the IP address" ) 893 return main.FALSE 894 if not cmdstr: 895 main.log.error( "You must specify the command string" ) 896 return main.FALSE 897 898 cmdstr = str( cmdstr ) 899 self.handle.sendline( "" ) 900 self.handle.expect( "\$" ) 901 902 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr ) 903 self.handle.expect( "\$" ) 904 905 handleBefore = self.handle.before 906 print "handle_before = ", self.handle.before 907 # handleAfter = str( self.handle.after ) 908 909 # self.handle.sendline( "" ) 910 # self.handle.expect( "\$" ) 911 # handleMore = str( self.handle.before ) 912 913 main.log.info( "Command sent successfully" ) 914 915 # Obtain return handle that consists of result from 916 # the onos command. The string may need to be 917 # configured further. 918 # returnString = handleBefore + handleAfter 919 returnString = handleBefore 920 print "return_string = ", returnString 921 return returnString 922 923 except pexpect.EOF: 924 main.log.error( self.name + ": EOF exception found" ) 925 main.log.error( self.name + ": " + self.handle.before ) 926 main.cleanup() 927 main.exit() 928 except Exception: 929 main.log.exception( self.name + ": Uncaught exception!" ) 930 main.cleanup() 931 main.exit()
932
933 - def onosInstall( self, options="-f", node="" ):
934 """ 935 Installs ONOS bits on the designated cell machine. 936 If -f option is provided, it also forces an uninstall. 937 Presently, install also includes onos-push-bits and 938 onos-config within. 939 The node option allows you to selectively only push the jar 940 files to certain onos nodes 941 942 Returns: main.TRUE on success and main.FALSE on failure 943 """ 944 try: 945 if options: 946 self.handle.sendline( "onos-install " + options + " " + node ) 947 else: 948 self.handle.sendline( "onos-install " + node ) 949 self.handle.expect( "onos-install " ) 950 # NOTE: this timeout may need to change depending on the network 951 # and size of ONOS 952 i = self.handle.expect( [ "Network\sis\sunreachable", 953 "onos\sstart/running,\sprocess", 954 "ONOS\sis\salready\sinstalled", 955 pexpect.TIMEOUT ], timeout=60 ) 956 957 if i == 0: 958 main.log.warn( "Network is unreachable" ) 959 return main.FALSE 960 elif i == 1: 961 main.log.info( 962 "ONOS was installed on " + 963 node + 964 " and started" ) 965 return main.TRUE 966 elif i == 2: 967 main.log.info( "ONOS is already installed on " + node ) 968 return main.TRUE 969 elif i == 3: 970 main.log.info( 971 "Installation of ONOS on " + 972 node + 973 " timed out" ) 974 return main.FALSE 975 976 except pexpect.EOF: 977 main.log.error( self.name + ": EOF exception found" ) 978 main.log.error( self.name + ": " + self.handle.before ) 979 main.cleanup() 980 main.exit() 981 except Exception: 982 main.log.exception( self.name + ": Uncaught exception!" ) 983 main.cleanup() 984 main.exit()
985
986 - def onosStart( self, nodeIp ):
987 """ 988 Calls onos command: 'onos-service [<node-ip>] start' 989 This command is a remote management of the ONOS upstart daemon 990 """ 991 try: 992 self.handle.sendline( "" ) 993 self.handle.expect( "\$" ) 994 self.handle.sendline( "onos-service " + str( nodeIp ) + 995 " start" ) 996 i = self.handle.expect( [ 997 "Job\sis\salready\srunning", 998 "start/running", 999 "Unknown\sinstance", 1000 pexpect.TIMEOUT ], timeout=120 ) 1001 1002 if i == 0: 1003 main.log.info( "Service is already running" ) 1004 return main.TRUE 1005 elif i == 1: 1006 main.log.info( "ONOS service started" ) 1007 return main.TRUE 1008 else: 1009 main.log.error( "ONOS service failed to start" ) 1010 main.cleanup() 1011 main.exit() 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 Exception: 1018 main.log.exception( self.name + ": Uncaught exception!" ) 1019 main.cleanup() 1020 main.exit()
1021
1022 - def onosStop( self, nodeIp ):
1023 """ 1024 Calls onos command: 'onos-service [<node-ip>] stop' 1025 This command is a remote management of the ONOS upstart daemon 1026 """ 1027 try: 1028 self.handle.sendline( "" ) 1029 self.handle.expect( "\$" ) 1030 self.handle.sendline( "onos-service " + str( nodeIp ) + 1031 " stop" ) 1032 i = self.handle.expect( [ 1033 "stop/waiting", 1034 "Could not resolve hostname", 1035 "Unknown\sinstance", 1036 pexpect.TIMEOUT ], timeout=60 ) 1037 1038 if i == 0: 1039 main.log.info( "ONOS service stopped" ) 1040 return main.TRUE 1041 elif i == 1: 1042 main.log.info( "onosStop() Unknown ONOS instance specified: " + 1043 str( nodeIp ) ) 1044 return main.FALSE 1045 elif i == 2: 1046 main.log.warn( "ONOS wasn't running" ) 1047 return main.TRUE 1048 else: 1049 main.log.error( "ONOS service failed to stop" ) 1050 return main.FALSE 1051 1052 except pexpect.EOF: 1053 main.log.error( self.name + ": EOF exception found" ) 1054 main.log.error( self.name + ": " + self.handle.before ) 1055 main.cleanup() 1056 main.exit() 1057 except Exception: 1058 main.log.exception( self.name + ": Uncaught exception!" ) 1059 main.cleanup() 1060 main.exit()
1061
1062 - def onosUninstall( self, nodeIp="" ):
1063 """ 1064 Calls the command: 'onos-uninstall' 1065 Uninstalls ONOS from the designated cell machine, stopping 1066 if needed 1067 """ 1068 try: 1069 self.handle.sendline( "" ) 1070 self.handle.expect( "\$", timeout=60 ) 1071 self.handle.sendline( "onos-uninstall " + str( nodeIp ) ) 1072 self.handle.expect( "\$" ) 1073 1074 main.log.info( "ONOS " + nodeIp + " was uninstalled" ) 1075 1076 # onos-uninstall command does not return any text 1077 return main.TRUE 1078 1079 except pexpect.TIMEOUT: 1080 main.log.exception( self.name + ": Timeout in onosUninstall" ) 1081 return main.FALSE 1082 except pexpect.EOF: 1083 main.log.error( self.name + ": EOF exception found" ) 1084 main.log.error( self.name + ": " + self.handle.before ) 1085 main.cleanup() 1086 main.exit() 1087 except Exception: 1088 main.log.exception( self.name + ": Uncaught exception!" ) 1089 main.cleanup() 1090 main.exit()
1091
1092 - def onosDie( self, nodeIp ):
1093 """ 1094 Issues the command 'onos-die <node-ip>' 1095 This command calls onos-kill and also stops the node 1096 """ 1097 try: 1098 self.handle.sendline( "" ) 1099 self.handle.expect( "\$" ) 1100 cmdStr = "onos-kill " + str( nodeIp ) 1101 self.handle.sendline( cmdStr ) 1102 i = self.handle.expect( [ 1103 "Killing\sONOS", 1104 "ONOS\sprocess\sis\snot\srunning", 1105 pexpect.TIMEOUT ], timeout=20 ) 1106 if i == 0: 1107 main.log.info( "ONOS instance " + str( nodeIp ) + 1108 " was killed and stopped" ) 1109 return main.TRUE 1110 elif i == 1: 1111 main.log.info( "ONOS process was not running" ) 1112 return main.FALSE 1113 except pexpect.EOF: 1114 main.log.error( self.name + ": EOF exception found" ) 1115 main.log.error( self.name + ": " + self.handle.before ) 1116 main.cleanup() 1117 main.exit() 1118 except Exception: 1119 main.log.exception( self.name + ": Uncaught exception!" ) 1120 main.cleanup() 1121 main.exit()
1122
1123 - def onosKill( self, nodeIp ):
1124 """ 1125 Calls the command: 'onos-kill [<node-ip>]' 1126 "Remotely, and unceremoniously kills the ONOS instance running on 1127 the specified cell machine" - Tom V 1128 """ 1129 try: 1130 self.handle.sendline( "" ) 1131 self.handle.expect( "\$" ) 1132 self.handle.sendline( "onos-kill " + str( nodeIp ) ) 1133 i = self.handle.expect( [ 1134 "\$", 1135 "No\sroute\sto\shost", 1136 "password:", 1137 pexpect.TIMEOUT ], timeout=20 ) 1138 1139 if i == 0: 1140 main.log.info( 1141 "ONOS instance " + str( 1142 nodeIp ) + " was killed" ) 1143 return main.TRUE 1144 elif i == 1: 1145 main.log.info( "No route to host" ) 1146 return main.FALSE 1147 elif i == 2: 1148 main.log.info( 1149 "Passwordless login for host: " + 1150 str( nodeIp ) + 1151 " not configured" ) 1152 return main.FALSE 1153 else: 1154 main.log.info( "ONOS instance was not killed" ) 1155 return main.FALSE 1156 1157 except pexpect.EOF: 1158 main.log.error( self.name + ": EOF exception found" ) 1159 main.log.error( self.name + ": " + self.handle.before ) 1160 main.cleanup() 1161 main.exit() 1162 except Exception: 1163 main.log.exception( self.name + ": Uncaught exception!" ) 1164 main.cleanup() 1165 main.exit()
1166
1167 - def onosRemoveRaftLogs( self ):
1168 """ 1169 Removes Raft / Copy cat files from ONOS to ensure 1170 a cleaner environment. 1171 1172 Description: 1173 Stops all ONOS defined in the cell, 1174 wipes the raft / copycat log files 1175 """ 1176 try: 1177 self.handle.sendline( "" ) 1178 self.handle.expect( "\$" ) 1179 self.handle.sendline( "onos-remove-raft-logs" ) 1180 # Sometimes this command hangs 1181 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ], 1182 timeout=120 ) 1183 if i == 1: 1184 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ], 1185 timeout=120 ) 1186 if i == 1: 1187 return main.FALSE 1188 #self.handle.sendline( "" ) 1189 #self.handle.expect( "\$" ) 1190 return main.TRUE 1191 1192 except pexpect.EOF: 1193 main.log.error( self.name + ": EOF exception found" ) 1194 main.log.error( self.name + ": " + self.handle.before ) 1195 main.cleanup() 1196 main.exit() 1197 except Exception: 1198 main.log.exception( self.name + ": Uncaught exception!" ) 1199 main.cleanup() 1200 main.exit()
1201
1202 - def onosStartNetwork( self, mntopo ):
1203 """ 1204 Calls the command 'onos-start-network [ <mininet-topo> ] 1205 "remotely starts the specified topology on the cell's 1206 mininet machine against all controllers configured in the 1207 cell." 1208 * Specify mininet topology file name for mntopo 1209 * Topo files should be placed at: 1210 ~/<your-onos-directory>/tools/test/topos 1211 1212 NOTE: This function will take you to the mininet prompt 1213 """ 1214 try: 1215 if not mntopo: 1216 main.log.error( "You must specify a topo file to execute" ) 1217 return main.FALSE 1218 1219 mntopo = str( mntopo ) 1220 self.handle.sendline( "" ) 1221 self.handle.expect( "\$" ) 1222 1223 self.handle.sendline( "onos-start-network " + mntopo ) 1224 self.handle.expect( "mininet>" ) 1225 main.log.info( "Network started, entered mininet prompt" ) 1226 1227 # TODO: Think about whether return is necessary or not 1228 1229 except pexpect.EOF: 1230 main.log.error( self.name + ": EOF exception found" ) 1231 main.log.error( self.name + ": " + self.handle.before ) 1232 main.cleanup() 1233 main.exit() 1234 except Exception: 1235 main.log.exception( self.name + ": Uncaught exception!" ) 1236 main.cleanup() 1237 main.exit()
1238
1239 - def isup(self, node = "", timeout = 120):
1240 """ 1241 Run's onos-wait-for-start which only returns once ONOS is at run 1242 level 100(ready for use) 1243 1244 Returns: main.TRUE if ONOS is running and main.FALSE on timeout 1245 """ 1246 try: 1247 self.handle.sendline("onos-wait-for-start " + node ) 1248 self.handle.expect("onos-wait-for-start") 1249 # NOTE: this timeout is arbitrary" 1250 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout) 1251 if i == 0: 1252 main.log.info( self.name + ": " + node + " is up" ) 1253 return main.TRUE 1254 elif i == 1: 1255 # NOTE: since this function won't return until ONOS is ready, 1256 # we will kill it on timeout 1257 main.log.error( "ONOS has not started yet" ) 1258 self.handle.send( "\x03" ) # Control-C 1259 self.handle.expect( "\$" ) 1260 return main.FALSE 1261 except pexpect.EOF: 1262 main.log.error( self.name + ": EOF exception found" ) 1263 main.log.error( self.name + ": " + self.handle.before ) 1264 main.cleanup() 1265 main.exit() 1266 except Exception: 1267 main.log.exception( self.name + ": Uncaught exception!" ) 1268 main.cleanup() 1269 main.exit()
1270
1271 - def pushTestIntentsShell( 1272 self, 1273 dpidSrc, 1274 dpidDst, 1275 numIntents, 1276 dirFile, 1277 onosIp, 1278 numMult="", 1279 appId="", 1280 report=True, 1281 options="" ):
1282 """ 1283 Description: 1284 Use the linux prompt to push test intents to 1285 better parallelize the results than the CLI 1286 Required: 1287 * dpidSrc: specify source dpid 1288 * dpidDst: specify destination dpid 1289 * numIntents: specify number of intents to push 1290 * dirFile: specify directory and file name to save 1291 results 1292 * onosIp: specify the IP of ONOS to install on 1293 NOTE: 1294 You must invoke this command at linux shell prompt 1295 """ 1296 try: 1297 # Create the string to sendline 1298 if options: 1299 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\ 1300 options + " " 1301 else: 1302 baseCmd = "onos " + str( onosIp ) + " push-test-intents " 1303 1304 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst ) 1305 if not numMult: 1306 addIntents = addDpid + " " + str( numIntents ) 1307 elif numMult: 1308 addIntents = addDpid + " " + str( numIntents ) + " " +\ 1309 str( numMult ) 1310 if appId: 1311 addApp = addIntents + " " + str( appId ) 1312 else: 1313 addApp = addIntents 1314 1315 if report: 1316 sendCmd = addApp + " > " + str( dirFile ) + " &" 1317 else: 1318 sendCmd = addApp + " &" 1319 main.log.info( "Send cmd: " + sendCmd ) 1320 1321 self.handle.sendline( sendCmd ) 1322 1323 except pexpect.EOF: 1324 main.log.error( self.name + ": EOF exception found" ) 1325 main.log.error( self.name + ": " + self.handle.before ) 1326 main.cleanup() 1327 main.exit() 1328 except Exception: 1329 main.log.exception( self.name + ": Uncaught exception!" ) 1330 main.cleanup() 1331 main.exit()
1332
1333 - def getTopology( self, topologyOutput ):
1334 """ 1335 Definition: 1336 Loads a json topology output 1337 Return: 1338 topology = current ONOS topology 1339 """ 1340 import json 1341 try: 1342 # either onos:topology or 'topology' will work in CLI 1343 topology = json.loads(topologyOutput) 1344 print topology 1345 return topology 1346 except pexpect.EOF: 1347 main.log.error( self.name + ": EOF exception found" ) 1348 main.log.error( self.name + ": " + self.handle.before ) 1349 main.cleanup() 1350 main.exit() 1351 except Exception: 1352 main.log.exception( self.name + ": Uncaught exception!" ) 1353 main.cleanup() 1354 main.exit()
1355
1356 - def checkStatus( 1357 self, 1358 topologyResult, 1359 numoswitch, 1360 numolink, 1361 logLevel="info" ):
1362 """ 1363 Checks the number of switches & links that ONOS sees against the 1364 supplied values. By default this will report to main.log, but the 1365 log level can be specific. 1366 1367 Params: ip = ip used for the onos cli 1368 numoswitch = expected number of switches 1369 numolink = expected number of links 1370 logLevel = level to log to. 1371 Currently accepts 'info', 'warn' and 'report' 1372 1373 1374 logLevel can 1375 1376 Returns: main.TRUE if the number of switches and links are correct, 1377 main.FALSE if the number of switches and links is incorrect, 1378 and main.ERROR otherwise 1379 """ 1380 try: 1381 topology = self.getTopology( topologyResult ) 1382 if topology == {}: 1383 return main.ERROR 1384 output = "" 1385 # Is the number of switches is what we expected 1386 devices = topology.get( 'devices', False ) 1387 links = topology.get( 'links', False ) 1388 if not devices or not links: 1389 return main.ERROR 1390 switchCheck = ( int( devices ) == int( numoswitch ) ) 1391 # Is the number of links is what we expected 1392 linkCheck = ( int( links ) == int( numolink ) ) 1393 if switchCheck and linkCheck: 1394 # We expected the correct numbers 1395 output = output + "The number of links and switches match "\ 1396 + "what was expected" 1397 result = main.TRUE 1398 else: 1399 output = output + \ 1400 "The number of links and switches does not match " + \ 1401 "what was expected" 1402 result = main.FALSE 1403 output = output + "\n ONOS sees %i devices" % int( devices ) 1404 output = output + " (%i expected) " % int( numoswitch ) 1405 output = output + "and %i links " % int( links ) 1406 output = output + "(%i expected)" % int( numolink ) 1407 if logLevel == "report": 1408 main.log.report( output ) 1409 elif logLevel == "warn": 1410 main.log.warn( output ) 1411 else: 1412 main.log.info( output ) 1413 return result 1414 except pexpect.EOF: 1415 main.log.error( self.name + ": EOF exception found" ) 1416 main.log.error( self.name + ": " + self.handle.before ) 1417 main.cleanup() 1418 main.exit() 1419 except Exception: 1420 main.log.exception( self.name + ": Uncaught exception!" ) 1421 main.cleanup() 1422 main.exit()
1423
1424 - def tsharkPcap( self, interface, dirFile ):
1425 """ 1426 Capture all packet activity and store in specified 1427 directory/file 1428 1429 Required: 1430 * interface: interface to capture 1431 * dir: directory/filename to store pcap 1432 """ 1433 try: 1434 self.handle.sendline( "" ) 1435 self.handle.expect( "\$" ) 1436 1437 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" ) 1438 self.handle.sendline( "\r" ) 1439 self.handle.expect( "Capturing on" ) 1440 self.handle.sendline( "\r" ) 1441 self.handle.expect( "\$" ) 1442 1443 main.log.info( "Tshark started capturing files on " + 1444 str( interface ) + " and saving to directory: " + 1445 str( dirFile ) ) 1446 except pexpect.EOF: 1447 main.log.error( self.name + ": EOF exception found" ) 1448 main.log.error( self.name + ": " + self.handle.before ) 1449 main.cleanup() 1450 main.exit() 1451 except Exception: 1452 main.log.exception( self.name + ": Uncaught exception!" ) 1453 main.cleanup() 1454 main.exit()
1455
1456 - def runOnosTopoCfg( self, instanceName, jsonFile ):
1457 """ 1458 On ONOS bench, run this command: 1459 {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename 1460 which starts the rest and copies 1461 the json file to the onos instance 1462 """ 1463 try: 1464 self.handle.sendline( "" ) 1465 self.handle.expect( "\$" ) 1466 self.handle.sendline( "cd " + self.home + "/tools/test/bin" ) 1467 self.handle.expect( "/bin$" ) 1468 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile 1469 print "cmd = ", cmd 1470 self.handle.sendline( cmd ) 1471 self.handle.expect( "\$" ) 1472 self.handle.sendline( "cd ~" ) 1473 self.handle.expect( "\$" ) 1474 return main.TRUE 1475 except pexpect.EOF: 1476 main.log.error( self.name + ": EOF exception found" ) 1477 main.log.error( self.name + ": " + self.handle.before ) 1478 main.cleanup() 1479 main.exit() 1480 except Exception: 1481 main.log.exception( self.name + ": Uncaught exception!" ) 1482 main.cleanup() 1483 main.exit()
1484
1485 - def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
1486 """ 1487 Required: 1488 * grep string 1489 * directory to store results 1490 Optional: 1491 * interface - default: eth0 1492 * grepOptions - options for grep 1493 Description: 1494 Uses tshark command to grep specific group of packets 1495 and stores the results to specified directory. 1496 The timestamp is hardcoded to be in epoch 1497 """ 1498 try: 1499 self.handle.sendline( "" ) 1500 self.handle.expect( "\$" ) 1501 self.handle.sendline( "" ) 1502 if grepOptions: 1503 grepStr = "grep "+str(grepOptions) 1504 else: 1505 grepStr = "grep" 1506 1507 cmd = ( 1508 "sudo tshark -i " + 1509 str( interface ) + 1510 " -t e | " + 1511 grepStr + " --line-buffered \"" + 1512 str(grep) + 1513 "\" >" + 1514 directory + 1515 " &" ) 1516 self.handle.sendline(cmd) 1517 main.log.info(cmd) 1518 self.handle.expect( "Capturing on" ) 1519 self.handle.sendline( "\n" ) 1520 self.handle.expect( "\$" ) 1521 except pexpect.EOF: 1522 main.log.error( self.name + ": EOF exception found" ) 1523 main.log.error( self.name + ": " + self.handle.before ) 1524 main.cleanup() 1525 main.exit() 1526 except Exception: 1527 main.log.exception( self.name + ": Uncaught exception!" ) 1528 main.cleanup() 1529 main.exit()
1530
1531 - def tsharkStop( self ):
1532 """ 1533 Removes wireshark files from /tmp and kills all tshark processes 1534 """ 1535 # Remove all pcap from previous captures 1536 try: 1537 self.execute( cmd="sudo rm /tmp/wireshark*" ) 1538 self.handle.sendline( "" ) 1539 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" + 1540 " | grep -v grep | awk '{print $2}'`" ) 1541 self.handle.sendline( "" ) 1542 main.log.info( "Tshark stopped" ) 1543 except pexpect.EOF: 1544 main.log.error( self.name + ": EOF exception found" ) 1545 main.log.error( self.name + ": " + self.handle.before ) 1546 main.cleanup() 1547 main.exit() 1548 except Exception: 1549 main.log.exception( self.name + ": Uncaught exception!" ) 1550 main.cleanup() 1551 main.exit()
1552
1553 - def ptpd( self, args ):
1554 """ 1555 Initiate ptp with user-specified args. 1556 Required: 1557 * args: specify string of args after command 1558 'sudo ptpd' 1559 """ 1560 try: 1561 self.handle.sendline( "sudo ptpd " + str( args ) ) 1562 i = self.handle.expect( [ 1563 "Multiple", 1564 "Error", 1565 "\$" ] ) 1566 self.handle.expect( "\$" ) 1567 1568 if i == 0: 1569 handle = self.handle.before 1570 main.log.info( "ptpd returned an error: " + 1571 str( handle ) ) 1572 return handle 1573 elif i == 1: 1574 handle = self.handle.before 1575 main.log.error( "ptpd returned an error: " + 1576 str( handle ) ) 1577 return handle 1578 else: 1579 return main.TRUE 1580 1581 except pexpect.EOF: 1582 main.log.error( self.name + ": EOF exception found" ) 1583 main.log.error( self.name + ": " + self.handle.before ) 1584 main.cleanup() 1585 main.exit() 1586 except Exception: 1587 main.log.exception( self.name + ": Uncaught exception!" ) 1588 main.cleanup() 1589 main.exit()
1590
1591 - def cpLogsToDir( self, logToCopy, 1592 destDir, copyFileName="" ):
1593 """ 1594 Copies logs to a desired directory. 1595 Current implementation of ONOS deletes its karaf 1596 logs on every iteration. For debugging purposes, 1597 you may want to use this function to capture 1598 certain karaf logs. ( or any other logs if needed ) 1599 Localtime will be attached to the filename 1600 1601 Required: 1602 * logToCopy: specify directory and log name to 1603 copy. 1604 ex ) /opt/onos/log/karaf.log.1 1605 For copying multiple files, leave copyFileName 1606 empty and only specify destDir - 1607 ex ) /opt/onos/log/karaf* 1608 * destDir: specify directory to copy to. 1609 ex ) /tmp/ 1610 Optional: 1611 * copyFileName: If you want to rename the log 1612 file, specify copyFileName. This will not work 1613 with multiple file copying 1614 """ 1615 try: 1616 localtime = time.strftime( '%x %X' ) 1617 localtime = localtime.replace( "/", "" ) 1618 localtime = localtime.replace( " ", "_" ) 1619 localtime = localtime.replace( ":", "" ) 1620 if destDir[ -1: ] != "/": 1621 destDir += "/" 1622 1623 if copyFileName: 1624 self.handle.sendline( "cp " + str( logToCopy ) + " " + 1625 str( destDir ) + str( copyFileName ) + 1626 localtime ) 1627 self.handle.expect( "cp" ) 1628 self.handle.expect( "\$" ) 1629 else: 1630 self.handle.sendline( "cp " + str( logToCopy ) + 1631 " " + str( destDir ) ) 1632 self.handle.expect( "cp" ) 1633 self.handle.expect( "\$" ) 1634 1635 return self.handle.before 1636 1637 except pexpect.EOF: 1638 main.log.error( "Copying files failed" ) 1639 main.log.error( self.name + ": EOF exception found" ) 1640 main.log.error( self.name + ": " + self.handle.before ) 1641 except Exception: 1642 main.log.exception( "Copying files failed" )
1643
1644 - def checkLogs( self, onosIp, restart=False):
1645 """ 1646 runs onos-check-logs on the given onos node 1647 If restart is True, use the old version of onos-check-logs which 1648 does not print the full stacktrace, but shows the entire log file, 1649 including across restarts 1650 returns the response 1651 """ 1652 try: 1653 cmd = "onos-check-logs " + str( onosIp ) 1654 if restart: 1655 cmd += " old" 1656 self.handle.sendline( cmd ) 1657 self.handle.expect( cmd ) 1658 self.handle.expect( "\$" ) 1659 response = self.handle.before 1660 return response 1661 except pexpect.EOF: 1662 main.log.error( "Lost ssh connection" ) 1663 main.log.error( self.name + ": EOF exception found" ) 1664 main.log.error( self.name + ": " + self.handle.before ) 1665 except Exception: 1666 main.log.exception( self.name + ": Uncaught exception!" ) 1667 main.cleanup() 1668 main.exit()
1669
1670 - def onosStatus( self, node="" ):
1671 """ 1672 Calls onos command: 'onos-service [<node-ip>] status' 1673 """ 1674 try: 1675 self.handle.sendline( "" ) 1676 self.handle.expect( "\$" ) 1677 self.handle.sendline( "onos-service " + str( node ) + 1678 " status" ) 1679 i = self.handle.expect( [ 1680 "start/running", 1681 "stop/waiting", 1682 pexpect.TIMEOUT ], timeout=120 ) 1683 1684 if i == 0: 1685 main.log.info( "ONOS is running" ) 1686 return main.TRUE 1687 elif i == 1: 1688 main.log.info( "ONOS is stopped" ) 1689 main.log.error( "ONOS service failed to check the status" ) 1690 main.cleanup() 1691 main.exit() 1692 except pexpect.EOF: 1693 main.log.error( self.name + ": EOF exception found" ) 1694 main.log.error( self.name + ": " + self.handle.before ) 1695 main.cleanup() 1696 main.exit() 1697 except Exception: 1698 main.log.exception( self.name + ": Uncaught exception!" ) 1699 main.cleanup() 1700 main.exit()
1701
1702 - def setIpTables( self, ip, port='', action='add', packet_type='', 1703 direction='INPUT', rule='DROP', states=True ):
1704 """ 1705 Description: 1706 add or remove iptables rule to DROP (default) packets from 1707 specific IP and PORT 1708 Usage: 1709 * specify action ('add' or 'remove') 1710 when removing, pass in the same argument as you would add. It will 1711 delete that specific rule. 1712 * specify the ip to block 1713 * specify the destination port to block (defaults to all ports) 1714 * optional packet type to block (default tcp) 1715 * optional iptables rule (default DROP) 1716 * optional direction to block (default 'INPUT') 1717 * States boolean toggles adding all supported tcp states to the 1718 firewall rule 1719 Returns: 1720 main.TRUE on success or 1721 main.FALSE if given invalid input or 1722 main.ERROR if there is an error in response from iptables 1723 WARNING: 1724 * This function uses root privilege iptables command which may result 1725 in unwanted network errors. USE WITH CAUTION 1726 """ 1727 import time 1728 1729 # NOTE********* 1730 # The strict checking methods of this driver function is intentional 1731 # to discourage any misuse or error of iptables, which can cause 1732 # severe network errors 1733 # ************* 1734 1735 # NOTE: Sleep needed to give some time for rule to be added and 1736 # registered to the instance. If you are calling this function 1737 # multiple times this sleep will prevent any errors. 1738 # DO NOT REMOVE 1739 # time.sleep( 5 ) 1740 try: 1741 # input validation 1742 action_type = action.lower() 1743 rule = rule.upper() 1744 direction = direction.upper() 1745 if action_type != 'add' and action_type != 'remove': 1746 main.log.error( "Invalid action type. Use 'add' or " 1747 "'remove' table rule" ) 1748 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG': 1749 # NOTE Currently only supports rules DROP, ACCEPT, and LOG 1750 main.log.error( "Invalid rule. Valid rules are 'DROP' or " 1751 "'ACCEPT' or 'LOG' only." ) 1752 if direction != 'INPUT' and direction != 'OUTPUT': 1753 # NOTE currently only supports rules INPUT and OUPTUT 1754 main.log.error( "Invalid rule. Valid directions are" 1755 " 'OUTPUT' or 'INPUT'" ) 1756 return main.FALSE 1757 return main.FALSE 1758 return main.FALSE 1759 if action_type == 'add': 1760 # -A is the 'append' action of iptables 1761 actionFlag = '-A' 1762 elif action_type == 'remove': 1763 # -D is the 'delete' rule of iptables 1764 actionFlag = '-D' 1765 self.handle.sendline( "" ) 1766 self.handle.expect( "\$" ) 1767 cmd = "sudo iptables " + actionFlag + " " +\ 1768 direction +\ 1769 " -s " + str( ip ) 1770 # " -p " + str( packet_type ) +\ 1771 if packet_type: 1772 cmd += " -p " + str( packet_type ) 1773 if port: 1774 cmd += " --dport " + str( port ) 1775 if states: 1776 cmd += " -m state --state=" 1777 #FIXME- Allow user to configure which states to block 1778 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED" 1779 cmd += " -j " + str( rule ) 1780 1781 self.handle.sendline( cmd ) 1782 self.handle.expect( "\$" ) 1783 main.log.warn( self.handle.before ) 1784 1785 info_string = "On " + str( self.name ) 1786 info_string += " " + str( action_type ) 1787 info_string += " iptable rule [ " 1788 info_string += " IP: " + str( ip ) 1789 info_string += " Port: " + str( port ) 1790 info_string += " Rule: " + str( rule ) 1791 info_string += " Direction: " + str( direction ) + " ]" 1792 main.log.info( info_string ) 1793 return main.TRUE 1794 except pexpect.TIMEOUT: 1795 main.log.exception( self.name + ": Timeout exception in " 1796 "setIpTables function" ) 1797 return main.ERROR 1798 except pexpect.EOF: 1799 main.log.error( self.name + ": EOF exception found" ) 1800 main.log.error( self.name + ": " + self.handle.before ) 1801 main.cleanup() 1802 main.exit() 1803 except Exception: 1804 main.log.exception( self.name + ": Uncaught exception!" ) 1805 main.cleanup() 1806 main.exit()
1807
1808 - def detailed_status(self, log_filename):
1809 """ 1810 This method is used by STS to check the status of the controller 1811 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason) 1812 """ 1813 import re 1814 try: 1815 self.handle.sendline( "" ) 1816 self.handle.expect( "\$" ) 1817 self.handle.sendline( "cd " + self.home ) 1818 self.handle.expect( "\$" ) 1819 self.handle.sendline( "service onos status" ) 1820 self.handle.expect( "\$" ) 1821 response = self.handle.before 1822 if re.search( "onos start/running", response ): 1823 # onos start/running, process 10457 1824 return 'RUNNING' 1825 # FIXME: Implement this case 1826 # elif re.search( pattern, response ): 1827 # return 'STARTING' 1828 elif re.search( "onos stop/", response ): 1829 # onos stop/waiting 1830 # FIXME handle this differently?: onos stop/pre-stop 1831 return 'STOPPED' 1832 # FIXME: Implement this case 1833 # elif re.search( pattern, response ): 1834 # return 'FROZEN' 1835 else: 1836 main.log.warn( self.name + 1837 " WARNING: status received unknown response" ) 1838 main.log.warn( response ) 1839 return 'ERROR', "Unknown response: %s" % response 1840 except pexpect.TIMEOUT: 1841 main.log.exception( self.name + ": Timeout exception in " 1842 "setIpTables function" ) 1843 return 'ERROR', "Pexpect Timeout" 1844 except pexpect.EOF: 1845 main.log.error( self.name + ": EOF exception found" ) 1846 main.log.error( self.name + ": " + self.handle.before ) 1847 main.cleanup() 1848 main.exit() 1849 except Exception: 1850 main.log.exception( self.name + ": Uncaught exception!" ) 1851 main.cleanup() 1852 main.exit()
1853
1854 - def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1855 ''' 1856 Create/formats the LinkGraph.cfg file based on arguments 1857 -only creates a linear topology and connects islands 1858 -evenly distributes devices 1859 -must be called by ONOSbench 1860 1861 ONOSIpList - list of all of the node IPs to be used 1862 1863 deviceCount - number of switches to be assigned 1864 ''' 1865 main.log.step("Creating link graph configuration file." ) 1866 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg" 1867 tempFile = "/tmp/linkGraph.cfg" 1868 1869 linkGraph = open(tempFile, 'w+') 1870 linkGraph.write("# NullLinkProvider topology description (config file).\n") 1871 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n") 1872 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n") 1873 1874 clusterCount = len(ONOSIpList) 1875 1876 if type(deviceCount) is int or type(deviceCount) is str: 1877 deviceCount = int(deviceCount) 1878 switchList = [0]*(clusterCount+1) 1879 baselineSwitchCount = deviceCount/clusterCount 1880 1881 for node in range(1, clusterCount + 1): 1882 switchList[node] = baselineSwitchCount 1883 1884 for node in range(1, (deviceCount%clusterCount)+1): 1885 switchList[node] += 1 1886 1887 if type(deviceCount) is list: 1888 main.log.info("Using provided device distribution") 1889 switchList = [0] 1890 for i in deviceCount: 1891 switchList.append(int(i)) 1892 1893 tempList = ['0'] 1894 tempList.extend(ONOSIpList) 1895 ONOSIpList = tempList 1896 1897 myPort = 6 1898 lastSwitch = 0 1899 for node in range(1, clusterCount+1): 1900 if switchList[node] == 0: 1901 continue 1902 1903 linkGraph.write("graph " + ONOSIpList[node] + " {\n") 1904 1905 if node > 1: 1906 #connect to last device on previous node 1907 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1] 1908 linkGraph.write(line) 1909 1910 lastSwitch = 0 1911 for switch in range (0, switchList[node]-1): 1912 line = "" 1913 line = ("\t" + str(switch) + ":" + str(myPort)) 1914 line += " -- " 1915 line += (str(switch+1) + ":" + str(myPort-1) + "\n") 1916 linkGraph.write(line) 1917 lastSwitch = switch+1 1918 lastIp = ONOSIpList[node] 1919 1920 #lastSwitch += 1 1921 if node < (clusterCount): 1922 #connect to first device on the next node 1923 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n") 1924 linkGraph.write(line) 1925 1926 linkGraph.write("}\n") 1927 linkGraph.close() 1928 1929 #SCP 1930 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath) 1931 main.log.info("linkGraph.cfg creation complete")
1932
1933 - def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
1934 1935 ''' 1936 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst 1937 deviceCount = number of switches to distribute, or list of values to use as custom distribution 1938 numPorts = number of ports per device. Defaults to 10 both in this function and in ONOS. Optional arg 1939 ''' 1940 1941 main.log.step("Configuring Null Device Provider" ) 1942 clusterCount = len(ONOSIpList) 1943 1944 try: 1945 1946 if type(deviceCount) is int or type(deviceCount) is str: 1947 main.log.step("Creating device distribution") 1948 deviceCount = int(deviceCount) 1949 switchList = [0]*(clusterCount+1) 1950 baselineSwitchCount = deviceCount/clusterCount 1951 1952 for node in range(1, clusterCount + 1): 1953 switchList[node] = baselineSwitchCount 1954 1955 for node in range(1, (deviceCount%clusterCount)+1): 1956 switchList[node] += 1 1957 1958 if type(deviceCount) is list: 1959 main.log.info("Using provided device distribution") 1960 1961 if len(deviceCount) == clusterCount: 1962 switchList = ['0'] 1963 switchList.extend(deviceCount) 1964 1965 if len(deviceCount) == (clusterCount + 1): 1966 if deviceCount[0] == '0' or deviceCount[0] == 0: 1967 switchList = deviceCount 1968 1969 assert len(switchList) == (clusterCount + 1) 1970 1971 except AssertionError: 1972 main.log.error( "Bad device/Ip list match") 1973 except TypeError: 1974 main.log.exception( self.name + ": Object not as expected" ) 1975 return None 1976 except Exception: 1977 main.log.exception( self.name + ": Uncaught exception!" ) 1978 main.cleanup() 1979 main.exit() 1980 1981 1982 ONOSIp = [0] 1983 ONOSIp.extend(ONOSIpList) 1984 1985 devicesString = "devConfigs = " 1986 for node in range(1, len(ONOSIp)): 1987 devicesString += (ONOSIp[node] + ":" + str(switchList[node] )) 1988 if node < clusterCount: 1989 devicesString += (",") 1990 1991 try: 1992 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString ) 1993 self.handle.expect(":~") 1994 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) ) 1995 self.handle.expect(":~") 1996 1997 for i in range(10): 1998 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider") 1999 self.handle.expect(":~") 2000 verification = self.handle.before 2001 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification: 2002 break 2003 else: 2004 time.sleep(1) 2005 2006 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification 2007 2008 except AssertionError: 2009 main.log.error("Incorrect Config settings: " + verification) 2010 except Exception: 2011 main.log.exception( self.name + ": Uncaught exception!" ) 2012 main.cleanup() 2013 main.exit()
2014 2052
2053 - def getOnosIps( self ):
2054 """ 2055 Get all onos IPs stored in 2056 """ 2057 2058 return sorted( self.onosIps.values() )
2059
2060 - def logReport( self, nodeIp, searchTerms, outputMode="s" ):
2061 ''' 2062 - accepts either a list or a string for "searchTerms" these 2063 terms will be searched for in the log and have their 2064 instances counted 2065 2066 - nodeIp is the ip of the node whos log is to be scanned 2067 2068 - output modes: 2069 "s" - Simple. Quiet output mode that just prints 2070 the occurences of each search term 2071 2072 "d" - Detailed. Prints number of occurences as well as the entire 2073 line for each of the last 5 occurences 2074 2075 - returns total of the number of instances of all search terms 2076 ''' 2077 main.log.info("========================== Log Report ===========================\n") 2078 2079 if type(searchTerms) is str: 2080 searchTerms = [searchTerms] 2081 2082 logLines = [ [" "] for i in range(len(searchTerms)) ] 2083 2084 for term in range(len(searchTerms)): 2085 logLines[term][0] = searchTerms[term] 2086 2087 totalHits = 0 2088 for term in range(len(searchTerms)): 2089 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + searchTerms[term] 2090 self.handle.sendline(cmd) 2091 self.handle.expect(":~") 2092 before = (self.handle.before).splitlines() 2093 2094 count = [searchTerms[term],0] 2095 2096 for line in before: 2097 if searchTerms[term] in line and "grep" not in line: 2098 count[1] += 1 2099 if before.index(line) > ( len(before) - 7 ): 2100 logLines[term].append(line) 2101 2102 main.log.info( str(count[0]) + ": " + str(count[1]) ) 2103 if term == len(searchTerms)-1: 2104 print("\n") 2105 totalHits += int(count[1]) 2106 2107 if outputMode != "s" and outputMode != "S": 2108 outputString = "" 2109 for i in logLines: 2110 outputString = i[0] + ": \n" 2111 for x in range(1,len(i)): 2112 outputString += ( i[x] + "\n" ) 2113 2114 if outputString != (i[0] + ": \n"): 2115 main.log.info(outputString) 2116 2117 main.log.info("================================================================\n") 2118 return totalHits
2119
2120 - def copyMininetFile( self, fileName, localPath, userName, ip, 2121 mnPath='~/mininet/custom/', timeout = 60 ):
2122 """ 2123 Description: 2124 Copy mininet topology file from dependency folder in the test folder 2125 and paste it to the mininet machine's mininet/custom folder 2126 Required: 2127 fileName - Name of the topology file to copy 2128 localPath - File path of the mininet topology file 2129 userName - User name of the mininet machine to send the file to 2130 ip - Ip address of the mininet machine 2131 Optional: 2132 mnPath - of the mininet directory to send the file to 2133 Return: 2134 Return main.TRUE if successfully copied the file otherwise 2135 return main.FALSE 2136 """ 2137 2138 try: 2139 cmd = "scp " + localPath + fileName + " " + userName + "@" + \ 2140 str( ip ) + ":" + mnPath + fileName 2141 2142 self.handle.sendline( "" ) 2143 self.handle.expect( "\$" ) 2144 2145 main.log.info( self.name + ": Execute: " + cmd ) 2146 2147 self.handle.sendline( cmd ) 2148 2149 i = self.handle.expect( [ 'No such file', 2150 "100%", 2151 pexpect.TIMEOUT ] ) 2152 2153 if i == 0: 2154 main.log.error( self.name + ": File " + fileName + 2155 " does not exist!" ) 2156 return main.FALSE 2157 2158 if i == 1: 2159 main.log.info( self.name + ": File " + fileName + 2160 " has been copied!" ) 2161 self.handle.sendline( "" ) 2162 self.handle.expect( "\$" ) 2163 return main.TRUE 2164 2165 except pexpect.EOF: 2166 main.log.error( self.name + ": EOF exception found" ) 2167 main.log.error( self.name + ": " + self.handle.before ) 2168 main.cleanup() 2169 main.exit() 2170 except pexpect.TIMEOUT: 2171 main.log.error( self.name + ": TIMEOUT exception found" ) 2172 main.log.error( self.name + ": " + self.handle.before ) 2173 main.cleanup() 2174 main.exit()
2175
2176 - def jvmSet(self, memory=8):
2177 2178 import os 2179 2180 homeDir = os.path.expanduser('~') 2181 filename = "/onos/tools/package/bin/onos-service" 2182 2183 serviceConfig = open(homeDir + filename, 'w+') 2184 serviceConfig.write("#!/bin/bash\n ") 2185 serviceConfig.write("#------------------------------------- \n ") 2186 serviceConfig.write("# Starts ONOS Apache Karaf container\n ") 2187 serviceConfig.write("#------------------------------------- \n ") 2188 serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ") 2189 serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """) 2190 serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n") 2191 serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """) 2192 serviceConfig.close()
2193
2194 - def createDBFile(self, testData):
2195 2196 filename = main.TEST + "DB" 2197 DBString = "" 2198 2199 for item in testData: 2200 if type(item) is string: 2201 item = "'" + item + "'" 2202 if testData.index(item) < len(testData-1): 2203 item += "," 2204 DBString += str(item) 2205 2206 DBFile = open(filename, "a") 2207 DBFile.write(DBString) 2208 DBFile.close()
2209
2210 - def verifySummary(self, ONOSIp,*deviceCount):
2211 2212 self.handle.sendline("onos " + ONOSIp + " summary") 2213 self.handle.expect(":~") 2214 2215 summaryStr = self.handle.before 2216 print "\nSummary\n==============\n" + summaryStr + "\n\n" 2217 2218 #passed = "SCC(s)=1" in summaryStr 2219 #if deviceCount: 2220 # passed = "devices=" + str(deviceCount) + "," not in summaryStr 2221 2222 2223 if "SCC(s)=1," in summaryStr: 2224 passed = True 2225 print("Summary is verifed") 2226 else: 2227 print("Summary failed") 2228 2229 if deviceCount: 2230 print" =============================" 2231 checkStr = "devices=" + str(deviceCount[0]) + "," 2232 print "Checkstr: " + checkStr 2233 if checkStr not in summaryStr: 2234 passed = False 2235 print("Device count failed") 2236 else: 2237 print "device count verified" 2238 2239 return passed
2240