1
2
3 """
4 This driver enters the onos> prompt to issue commands.
5
6 Please follow the coding style demonstrated by existing
7 functions and document properly.
8
9 If you are a contributor to the driver, please
10 list your email here for future contact:
11
12 jhall@onlab.us
13 andrew@onlab.us
14 shreya@onlab.us
15
16 OCT 13 2014
17
18 """
19 import pexpect
20 import re
21 import json
22 import types
23 import time
24 import os
25 from drivers.common.clidriver import CLI
26
27
29
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 cli.
42 """
43 try:
44 for key in connectargs:
45 vars( self )[ key ] = connectargs[ key ]
46 self.home = "~/onos"
47 for key in self.options:
48 if key == "home":
49 self.home = self.options[ 'home' ]
50 break
51 if self.home is None or self.home == "":
52 self.home = "~/onos"
53
54 for key in self.options:
55 if key == 'onosIp':
56 self.onosIp = self.options[ 'onosIp' ]
57 break
58
59 self.name = self.options[ 'name' ]
60
61 try:
62 if os.getenv( str( self.ip_address ) ) != None:
63 self.ip_address = os.getenv( str( self.ip_address ) )
64 else:
65 main.log.info( self.name +
66 ": Trying to connect to " +
67 self.ip_address )
68
69 except KeyError:
70 main.log.info( "Invalid host name," +
71 " connecting to local host instead" )
72 self.ip_address = 'localhost'
73 except Exception as inst:
74 main.log.error( "Uncaught exception: " + str( inst ) )
75
76 self.handle = super( OnosCliDriver, self ).connect(
77 user_name=self.user_name,
78 ip_address=self.ip_address,
79 port=self.port,
80 pwd=self.pwd,
81 home=self.home )
82
83 self.handle.sendline( "cd " + self.home )
84 self.handle.expect( "\$" )
85 if self.handle:
86 return self.handle
87 else:
88 main.log.info( "NO ONOS HANDLE" )
89 return main.FALSE
90 except TypeError:
91 main.log.exception( self.name + ": Object not as expected" )
92 return None
93 except pexpect.EOF:
94 main.log.error( self.name + ": EOF exception found" )
95 main.log.error( self.name + ": " + self.handle.before )
96 main.cleanup()
97 main.exit()
98 except Exception:
99 main.log.exception( self.name + ": Uncaught exception!" )
100 main.cleanup()
101 main.exit()
102
104 """
105 Called when Test is complete to disconnect the ONOS handle.
106 """
107 response = main.TRUE
108 try:
109 if self.handle:
110 i = self.logout()
111 if i == main.TRUE:
112 self.handle.sendline( "" )
113 self.handle.expect( "\$" )
114 self.handle.sendline( "exit" )
115 self.handle.expect( "closed" )
116 except TypeError:
117 main.log.exception( self.name + ": Object not as expected" )
118 response = main.FALSE
119 except pexpect.EOF:
120 main.log.error( self.name + ": EOF exception found" )
121 main.log.error( self.name + ": " + self.handle.before )
122 except ValueError:
123 main.log.exception( "Exception in disconnect of " + self.name )
124 response = main.TRUE
125 except Exception:
126 main.log.exception( self.name + ": Connection failed to the host" )
127 response = main.FALSE
128 return response
129
131 """
132 Sends 'logout' command to ONOS cli
133 Returns main.TRUE if exited CLI and
134 main.FALSE on timeout (not guranteed you are disconnected)
135 None on TypeError
136 Exits test on unknown error or pexpect exits unexpectedly
137 """
138 try:
139 if self.handle:
140 self.handle.sendline( "" )
141 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
142 timeout=10 )
143 if i == 0:
144 self.handle.sendline( "logout" )
145 self.handle.expect( "\$" )
146 return main.TRUE
147 elif i == 1:
148 return main.TRUE
149 elif i == 3:
150 return main.FALSE
151 else:
152 return main.TRUE
153 except TypeError:
154 main.log.exception( self.name + ": Object not as expected" )
155 return None
156 except pexpect.EOF:
157 main.log.error( self.name + ": eof exception found" )
158 main.log.error( self.name + ": " + self.handle.before )
159 main.cleanup()
160 main.exit()
161 except ValueError:
162 main.log.error( self.name +
163 "ValueError exception in logout method" )
164 except Exception:
165 main.log.exception( self.name + ": Uncaught exception!" )
166 main.cleanup()
167 main.exit()
168
170 """
171 Calls 'cell <name>' to set the environment variables on ONOSbench
172
173 Before issuing any cli commands, set the environment variable first.
174 """
175 try:
176 if not cellname:
177 main.log.error( "Must define cellname" )
178 main.cleanup()
179 main.exit()
180 else:
181 self.handle.sendline( "cell " + str( cellname ) )
182
183
184
185 self.handle.expect(str(cellname))
186 handleBefore = self.handle.before
187 handleAfter = self.handle.after
188
189 self.handle.sendline("")
190 self.handle.expect("\$")
191 handleMore = self.handle.before
192
193 main.log.info( "Cell call returned: " + handleBefore +
194 handleAfter + handleMore )
195
196 return main.TRUE
197
198 except TypeError:
199 main.log.exception( self.name + ": Object not as expected" )
200 return None
201 except pexpect.EOF:
202 main.log.error( self.name + ": eof exception found" )
203 main.log.error( self.name + ": " + self.handle.before )
204 main.cleanup()
205 main.exit()
206 except Exception:
207 main.log.exception( self.name + ": Uncaught exception!" )
208 main.cleanup()
209 main.exit()
210
211 - def startOnosCli( self, ONOSIp, karafTimeout="",
212 commandlineTimeout=10, onosStartTimeout=60 ):
213 """
214 karafTimeout is an optional argument. karafTimeout value passed
215 by user would be used to set the current karaf shell idle timeout.
216 Note that when ever this property is modified the shell will exit and
217 the subsequent login would reflect new idle timeout.
218 Below is an example to start a session with 60 seconds idle timeout
219 ( input value is in milliseconds ):
220
221 tValue = "60000"
222 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
223
224 Note: karafTimeout is left as str so that this could be read
225 and passed to startOnosCli from PARAMS file as str.
226 """
227 try:
228 self.handle.sendline( "" )
229 x = self.handle.expect( [
230 "\$", "onos>" ], commandlineTimeout)
231
232 if x == 1:
233 main.log.info( "ONOS cli is already running" )
234 return main.TRUE
235
236
237 self.handle.sendline( "onos -w " + str( ONOSIp ) )
238 i = self.handle.expect( [
239 "onos>",
240 pexpect.TIMEOUT ], onosStartTimeout )
241
242 if i == 0:
243 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
244 if karafTimeout:
245 self.handle.sendline(
246 "config:property-set -p org.apache.karaf.shell\
247 sshIdleTimeout " +
248 karafTimeout )
249 self.handle.expect( "\$" )
250 self.handle.sendline( "onos -w " + str( ONOSIp ) )
251 self.handle.expect( "onos>" )
252 return main.TRUE
253 else:
254
255 main.log.info( "Starting CLI failed. Retrying..." )
256 self.handle.send( "\x03" )
257 self.handle.sendline( "onos -w " + str( ONOSIp ) )
258 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
259 timeout=30 )
260 if i == 0:
261 main.log.info( str( ONOSIp ) + " CLI Started " +
262 "successfully after retry attempt" )
263 if karafTimeout:
264 self.handle.sendline(
265 "config:property-set -p org.apache.karaf.shell\
266 sshIdleTimeout " +
267 karafTimeout )
268 self.handle.expect( "\$" )
269 self.handle.sendline( "onos -w " + str( ONOSIp ) )
270 self.handle.expect( "onos>" )
271 return main.TRUE
272 else:
273 main.log.error( "Connection to CLI " +
274 str( ONOSIp ) + " timeout" )
275 return main.FALSE
276
277 except TypeError:
278 main.log.exception( self.name + ": Object not as expected" )
279 return None
280 except pexpect.EOF:
281 main.log.error( self.name + ": EOF exception found" )
282 main.log.error( self.name + ": " + self.handle.before )
283 main.cleanup()
284 main.exit()
285 except Exception:
286 main.log.exception( self.name + ": Uncaught exception!" )
287 main.cleanup()
288 main.exit()
289
290 - def log( self, cmdStr, level="" ):
291 """
292 log the commands in the onos CLI.
293 returns main.TRUE on success
294 returns main.FALSE if Error occurred
295 Available level: DEBUG, TRACE, INFO, WARN, ERROR
296 Level defaults to INFO
297 """
298 try:
299 lvlStr = ""
300 if level:
301 lvlStr = "--level=" + level
302
303 self.handle.sendline( "" )
304 i = self.handle.expect( [ "onos>","\$", pexpect.TIMEOUT ] )
305 if i == 1:
306 main.log.error( self.name + ": onos cli session closed." )
307 main.cleanup()
308 main.exit()
309 if i == 2:
310 self.handle.sendline( "" )
311 self.handle.expect( "onos>" )
312 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
313 self.handle.expect( "log:log" )
314 self.handle.expect( "onos>" )
315
316 response = self.handle.before
317 if re.search( "Error", response ):
318 return main.FALSE
319 return main.TRUE
320 except pexpect.TIMEOUT:
321 main.log.exception( self.name + ": TIMEOUT exception found" )
322 main.cleanup()
323 main.exit()
324 except pexpect.EOF:
325 main.log.error( self.name + ": EOF exception found" )
326 main.log.error( self.name + ": " + self.handle.before )
327 main.cleanup()
328 main.exit()
329 except Exception:
330 main.log.exception( self.name + ": Uncaught exception!" )
331 main.cleanup()
332 main.exit()
333
334 - def sendline( self, cmdStr, debug=False ):
335 """
336 Send a completely user specified string to
337 the onos> prompt. Use this function if you have
338 a very specific command to send.
339
340 Warning: There are no sanity checking to commands
341 sent using this method.
342 """
343 try:
344 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
345 self.log( logStr )
346 self.handle.sendline( cmdStr )
347 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
348 response = self.handle.before
349 if i == 2:
350 self.handle.sendline()
351 self.handle.expect( ["\$", pexpect.TIMEOUT] )
352 response += self.handle.before
353 print response
354 try:
355 print self.handle.after
356 except TypeError:
357 pass
358
359 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
360 + self.name + "." )
361 if debug:
362 main.log.debug( self.name + ": Raw output" )
363 main.log.debug( self.name + ": " + repr( response ) )
364
365
366 ansiEscape = re.compile( r'\x1b[^m]*m' )
367 response = ansiEscape.sub( '', response )
368 if debug:
369 main.log.debug( self.name + ": ansiEscape output" )
370 main.log.debug( self.name + ": " + repr( response ) )
371
372
373 response = re.sub( r"\s\r", "", response )
374 if debug:
375 main.log.debug( self.name + ": Removed extra returns " +
376 "from output" )
377 main.log.debug( self.name + ": " + repr( response ) )
378
379
380 response = response.strip()
381 if debug:
382 main.log.debug( self.name + ": parsed and stripped output" )
383 main.log.debug( self.name + ": " + repr( response ) )
384
385
386 output = response.split( cmdStr.strip(), 1 )
387 if debug:
388 main.log.debug( self.name + ": split output" )
389 for r in output:
390 main.log.debug( self.name + ": " + repr( r ) )
391 return output[1].strip()
392 except IndexError:
393 main.log.exception( self.name + ": Object not as expected" )
394 return None
395 except TypeError:
396 main.log.exception( self.name + ": Object not as expected" )
397 return None
398 except pexpect.EOF:
399 main.log.error( self.name + ": EOF exception found" )
400 main.log.error( self.name + ": " + self.handle.before )
401 main.cleanup()
402 main.exit()
403 except Exception:
404 main.log.exception( self.name + ": Uncaught exception!" )
405 main.cleanup()
406 main.exit()
407
408
409
410
411
412
413
414
415 - def addNode( self, nodeId, ONOSIp, tcpPort="" ):
416 """
417 Adds a new cluster node by ID and address information.
418 Required:
419 * nodeId
420 * ONOSIp
421 Optional:
422 * tcpPort
423 """
424 try:
425 cmdStr = "add-node " + str( nodeId ) + " " +\
426 str( ONOSIp ) + " " + str( tcpPort )
427 handle = self.sendline( cmdStr )
428 if re.search( "Error", handle ):
429 main.log.error( "Error in adding node" )
430 main.log.error( handle )
431 return main.FALSE
432 else:
433 main.log.info( "Node " + str( ONOSIp ) + " added" )
434 return main.TRUE
435 except TypeError:
436 main.log.exception( self.name + ": Object not as expected" )
437 return None
438 except pexpect.EOF:
439 main.log.error( self.name + ": EOF exception found" )
440 main.log.error( self.name + ": " + self.handle.before )
441 main.cleanup()
442 main.exit()
443 except Exception:
444 main.log.exception( self.name + ": Uncaught exception!" )
445 main.cleanup()
446 main.exit()
447
449 """
450 Removes a cluster by ID
451 Issues command: 'remove-node [<node-id>]'
452 Required:
453 * nodeId
454 """
455 try:
456
457 cmdStr = "remove-node " + str( nodeId )
458 handle = self.sendline( cmdStr )
459 if re.search( "Error", handle ):
460 main.log.error( "Error in removing node" )
461 main.log.error( handle )
462 return main.FALSE
463 else:
464 return main.TRUE
465 except TypeError:
466 main.log.exception( self.name + ": Object not as expected" )
467 return None
468 except pexpect.EOF:
469 main.log.error( self.name + ": EOF exception found" )
470 main.log.error( self.name + ": " + self.handle.before )
471 main.cleanup()
472 main.exit()
473 except Exception:
474 main.log.exception( self.name + ": Uncaught exception!" )
475 main.cleanup()
476 main.exit()
477
478 - def nodes( self, jsonFormat=True):
479 """
480 List the nodes currently visible
481 Issues command: 'nodes'
482 Optional argument:
483 * jsonFormat - boolean indicating if you want output in json
484 """
485 try:
486 cmdStr = "nodes"
487 if jsonFormat:
488 cmdStr += " -j"
489 output = self.sendline( cmdStr )
490 return output
491 except TypeError:
492 main.log.exception( self.name + ": Object not as expected" )
493 return None
494 except pexpect.EOF:
495 main.log.error( self.name + ": EOF exception found" )
496 main.log.error( self.name + ": " + self.handle.before )
497 main.cleanup()
498 main.exit()
499 except Exception:
500 main.log.exception( self.name + ": Uncaught exception!" )
501 main.cleanup()
502 main.exit()
503
505 """
506 Definition:
507 Returns the output of topology command.
508 Return:
509 topology = current ONOS topology
510 """
511 try:
512 cmdStr = "topology -j"
513 handle = self.sendline( cmdStr )
514 main.log.info( cmdStr + " returned: " + str( handle ) )
515 return handle
516 except TypeError:
517 main.log.exception( self.name + ": Object not as expected" )
518 return None
519 except pexpect.EOF:
520 main.log.error( self.name + ": EOF exception found" )
521 main.log.error( self.name + ": " + self.handle.before )
522 main.cleanup()
523 main.exit()
524 except Exception:
525 main.log.exception( self.name + ": Uncaught exception!" )
526 main.cleanup()
527 main.exit()
528
530 """
531 Installs a specified feature by issuing command:
532 'feature:install <feature_str>'
533 NOTE: This is now deprecated, you should use the activateApp method
534 instead
535 """
536 try:
537 cmdStr = "feature:install " + str( featureStr )
538 handle = self.sendline( cmdStr )
539 if re.search( "Error", handle ):
540 main.log.error( "Error in installing feature" )
541 main.log.error( handle )
542 return main.FALSE
543 else:
544 return main.TRUE
545 except TypeError:
546 main.log.exception( self.name + ": Object not as expected" )
547 return None
548 except pexpect.EOF:
549 main.log.error( self.name + ": EOF exception found" )
550 main.log.error( self.name + ": " + self.handle.before )
551 main.log.report( "Failed to install feature" )
552 main.log.report( "Exiting test" )
553 main.cleanup()
554 main.exit()
555 except Exception:
556 main.log.exception( self.name + ": Uncaught exception!" )
557 main.log.report( "Failed to install feature" )
558 main.log.report( "Exiting test" )
559 main.cleanup()
560 main.exit()
561
563 """
564 Uninstalls a specified feature by issuing command:
565 'feature:uninstall <feature_str>'
566 NOTE: This is now deprecated, you should use the deactivateApp method
567 instead
568 """
569 try:
570 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
571 handle = self.sendline( cmdStr )
572 if handle != '':
573 cmdStr = "feature:uninstall " + str( featureStr )
574 output = self.sendline( cmdStr )
575
576 else:
577 main.log.info( "Feature needs to be installed before " +
578 "uninstalling it" )
579 return main.TRUE
580 if re.search( "Error", output ):
581 main.log.error( "Error in uninstalling feature" )
582 main.log.error( output )
583 return main.FALSE
584 else:
585 return main.TRUE
586 except TypeError:
587 main.log.exception( self.name + ": Object not as expected" )
588 return None
589 except pexpect.EOF:
590 main.log.error( self.name + ": EOF exception found" )
591 main.log.error( self.name + ": " + self.handle.before )
592 main.cleanup()
593 main.exit()
594 except Exception:
595 main.log.exception( self.name + ": Uncaught exception!" )
596 main.cleanup()
597 main.exit()
598
600 """
601 Removes particular device from storage
602
603 TODO: refactor this function
604 """
605 try:
606 cmdStr = "device-remove " + str( deviceId )
607 handle = self.sendline( cmdStr )
608 if re.search( "Error", handle ):
609 main.log.error( "Error in removing device" )
610 main.log.error( handle )
611 return main.FALSE
612 else:
613 return main.TRUE
614 except TypeError:
615 main.log.exception( self.name + ": Object not as expected" )
616 return None
617 except pexpect.EOF:
618 main.log.error( self.name + ": EOF exception found" )
619 main.log.error( self.name + ": " + self.handle.before )
620 main.cleanup()
621 main.exit()
622 except Exception:
623 main.log.exception( self.name + ": Uncaught exception!" )
624 main.cleanup()
625 main.exit()
626
627 - def devices( self, jsonFormat=True ):
628 """
629 Lists all infrastructure devices or switches
630 Optional argument:
631 * jsonFormat - boolean indicating if you want output in json
632 """
633 try:
634 cmdStr = "devices"
635 if jsonFormat:
636 cmdStr += " -j"
637 handle = self.sendline( cmdStr )
638 return handle
639 except TypeError:
640 main.log.exception( self.name + ": Object not as expected" )
641 return None
642 except pexpect.EOF:
643 main.log.error( self.name + ": EOF exception found" )
644 main.log.error( self.name + ": " + self.handle.before )
645 main.cleanup()
646 main.exit()
647 except Exception:
648 main.log.exception( self.name + ": Uncaught exception!" )
649 main.cleanup()
650 main.exit()
651
653 """
654 This balances the devices across all controllers
655 by issuing command: 'onos> onos:balance-masters'
656 If required this could be extended to return devices balanced output.
657 """
658 try:
659 cmdStr = "onos:balance-masters"
660 handle = self.sendline( cmdStr )
661 if re.search( "Error", handle ):
662 main.log.error( "Error in balancing masters" )
663 main.log.error( handle )
664 return main.FALSE
665 else:
666 return main.TRUE
667 except TypeError:
668 main.log.exception( self.name + ": Object not as expected" )
669 return None
670 except pexpect.EOF:
671 main.log.error( self.name + ": EOF exception found" )
672 main.log.error( self.name + ": " + self.handle.before )
673 main.cleanup()
674 main.exit()
675 except Exception:
676 main.log.exception( self.name + ": Uncaught exception!" )
677 main.cleanup()
678 main.exit()
679
681 """
682 Returns the output of the masters command.
683 Optional argument:
684 * jsonFormat - boolean indicating if you want output in json
685 """
686 try:
687 cmdStr = "onos:masters"
688 if jsonFormat:
689 cmdStr += " -j"
690 output = self.sendline( cmdStr )
691 return output
692 except TypeError:
693 main.log.exception( self.name + ": Object not as expected" )
694 return None
695 except pexpect.EOF:
696 main.log.error( self.name + ": EOF exception found" )
697 main.log.error( self.name + ": " + self.handle.before )
698 main.cleanup()
699 main.exit()
700 except Exception:
701 main.log.exception( self.name + ": Uncaught exception!" )
702 main.cleanup()
703 main.exit()
704
706 """
707 Uses the master command to check that the devices' leadership
708 is evenly divided
709
710 Dependencies: checkMasters() and summary()
711
712 Returns main.True if the devices are balanced
713 Returns main.False if the devices are unbalanced
714 Exits on Exception
715 Returns None on TypeError
716 """
717 try:
718 totalDevices = json.loads( self.summary() )[ "devices" ]
719 totalOwnedDevices = 0
720 masters = json.loads( self.checkMasters() )
721 first = masters[ 0 ][ "size" ]
722 for master in masters:
723 totalOwnedDevices += master[ "size" ]
724 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
725 main.log.error( "Mastership not balanced" )
726 main.log.info( "\n" + self.checkMasters( False ) )
727 return main.FALSE
728 main.log.info( "Mastership balanced between " \
729 + str( len(masters) ) + " masters" )
730 return main.TRUE
731 except TypeError:
732 main.log.exception( self.name + ": Object not as expected" )
733 return None
734 except pexpect.EOF:
735 main.log.error( self.name + ": EOF exception found" )
736 main.log.error( self.name + ": " + self.handle.before )
737 main.cleanup()
738 main.exit()
739 except Exception:
740 main.log.exception( self.name + ": Uncaught exception!" )
741 main.cleanup()
742 main.exit()
743
744 - def links( self, jsonFormat=True ):
745 """
746 Lists all core links
747 Optional argument:
748 * jsonFormat - boolean indicating if you want output in json
749 """
750 try:
751 cmdStr = "links"
752 if jsonFormat:
753 cmdStr += " -j"
754 handle = self.sendline( cmdStr )
755 return handle
756 except TypeError:
757 main.log.exception( self.name + ": Object not as expected" )
758 return None
759 except pexpect.EOF:
760 main.log.error( self.name + ": EOF exception found" )
761 main.log.error( self.name + ": " + self.handle.before )
762 main.cleanup()
763 main.exit()
764 except Exception:
765 main.log.exception( self.name + ": Uncaught exception!" )
766 main.cleanup()
767 main.exit()
768
769 - def ports( self, jsonFormat=True ):
770 """
771 Lists all ports
772 Optional argument:
773 * jsonFormat - boolean indicating if you want output in json
774 """
775 try:
776 cmdStr = "ports"
777 if jsonFormat:
778 cmdStr += " -j"
779 handle = self.sendline( cmdStr )
780 return handle
781 except TypeError:
782 main.log.exception( self.name + ": Object not as expected" )
783 return None
784 except pexpect.EOF:
785 main.log.error( self.name + ": EOF exception found" )
786 main.log.error( self.name + ": " + self.handle.before )
787 main.cleanup()
788 main.exit()
789 except Exception:
790 main.log.exception( self.name + ": Uncaught exception!" )
791 main.cleanup()
792 main.exit()
793
794 - def roles( self, jsonFormat=True ):
795 """
796 Lists all devices and the controllers with roles assigned to them
797 Optional argument:
798 * jsonFormat - boolean indicating if you want output in json
799 """
800 try:
801 cmdStr = "roles"
802 if jsonFormat:
803 cmdStr += " -j"
804 handle = self.sendline( cmdStr )
805 return handle
806 except TypeError:
807 main.log.exception( self.name + ": Object not as expected" )
808 return None
809 except pexpect.EOF:
810 main.log.error( self.name + ": EOF exception found" )
811 main.log.error( self.name + ": " + self.handle.before )
812 main.cleanup()
813 main.exit()
814 except Exception:
815 main.log.exception( self.name + ": Uncaught exception!" )
816 main.cleanup()
817 main.exit()
818
820 """
821 Given the a string containing the json representation of the "roles"
822 cli command and a partial or whole device id, returns a json object
823 containing the roles output for the first device whose id contains
824 "device_id"
825
826 Returns:
827 A dict of the role assignments for the given device or
828 None if no match
829 """
830 try:
831 if deviceId is None:
832 return None
833 else:
834 rawRoles = self.roles()
835 rolesJson = json.loads( rawRoles )
836
837 for device in rolesJson:
838
839 if str( deviceId ) in device[ 'id' ]:
840 return device
841 return None
842 except TypeError:
843 main.log.exception( self.name + ": Object not as expected" )
844 return None
845 except pexpect.EOF:
846 main.log.error( self.name + ": EOF exception found" )
847 main.log.error( self.name + ": " + self.handle.before )
848 main.cleanup()
849 main.exit()
850 except Exception:
851 main.log.exception( self.name + ": Uncaught exception!" )
852 main.cleanup()
853 main.exit()
854
856 """
857 Iterates through each device and checks if there is a master assigned
858 Returns: main.TRUE if each device has a master
859 main.FALSE any device has no master
860 """
861 try:
862 rawRoles = self.roles()
863 rolesJson = json.loads( rawRoles )
864
865 for device in rolesJson:
866
867 if device[ 'master' ] == "none":
868 main.log.warn( "Device has no master: " + str( device ) )
869 return main.FALSE
870 return main.TRUE
871
872 except TypeError:
873 main.log.exception( self.name + ": Object not as expected" )
874 return None
875 except pexpect.EOF:
876 main.log.error( self.name + ": EOF exception found" )
877 main.log.error( self.name + ": " + self.handle.before )
878 main.cleanup()
879 main.exit()
880 except Exception:
881 main.log.exception( self.name + ": Uncaught exception!" )
882 main.cleanup()
883 main.exit()
884
885 - def paths( self, srcId, dstId ):
886 """
887 Returns string of paths, and the cost.
888 Issues command: onos:paths <src> <dst>
889 """
890 try:
891 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
892 handle = self.sendline( cmdStr )
893 if re.search( "Error", handle ):
894 main.log.error( "Error in getting paths" )
895 return ( handle, "Error" )
896 else:
897 path = handle.split( ";" )[ 0 ]
898 cost = handle.split( ";" )[ 1 ]
899 return ( path, cost )
900 except TypeError:
901 main.log.exception( self.name + ": Object not as expected" )
902 return ( handle, "Error" )
903 except pexpect.EOF:
904 main.log.error( self.name + ": EOF exception found" )
905 main.log.error( self.name + ": " + self.handle.before )
906 main.cleanup()
907 main.exit()
908 except Exception:
909 main.log.exception( self.name + ": Uncaught exception!" )
910 main.cleanup()
911 main.exit()
912
913 - def hosts( self, jsonFormat=True ):
914 """
915 Lists all discovered hosts
916 Optional argument:
917 * jsonFormat - boolean indicating if you want output in json
918 """
919 try:
920 cmdStr = "hosts"
921 if jsonFormat:
922 cmdStr += " -j"
923 handle = self.sendline( cmdStr )
924 return handle
925 except TypeError:
926 main.log.exception( self.name + ": Object not as expected" )
927 return None
928 except pexpect.EOF:
929 main.log.error( self.name + ": EOF exception found" )
930 main.log.error( self.name + ": " + self.handle.before )
931 main.cleanup()
932 main.exit()
933 except Exception:
934 main.log.exception( self.name + ": Uncaught exception!" )
935 main.cleanup()
936 main.exit()
937
939 """
940 Return the first host from the hosts api whose 'id' contains 'mac'
941
942 Note: mac must be a colon separated mac address, but could be a
943 partial mac address
944
945 Return None if there is no match
946 """
947 try:
948 if mac is None:
949 return None
950 else:
951 mac = mac
952 rawHosts = self.hosts()
953 hostsJson = json.loads( rawHosts )
954
955 for host in hostsJson:
956
957 if not host:
958 pass
959 elif mac in host[ 'id' ]:
960 return host
961 return None
962 except TypeError:
963 main.log.exception( self.name + ": Object not as expected" )
964 return None
965 except pexpect.EOF:
966 main.log.error( self.name + ": EOF exception found" )
967 main.log.error( self.name + ": " + self.handle.before )
968 main.cleanup()
969 main.exit()
970 except Exception:
971 main.log.exception( self.name + ": Uncaught exception!" )
972 main.cleanup()
973 main.exit()
974
976 """
977 Obtain list of hosts
978 Issues command: 'onos> hosts'
979
980 Required:
981 * hostList: List of hosts obtained by Mininet
982 IMPORTANT:
983 This function assumes that you started your
984 topology with the option '--mac'.
985 Furthermore, it assumes that value of VLAN is '-1'
986 Description:
987 Converts mininet hosts ( h1, h2, h3... ) into
988 ONOS format ( 00:00:00:00:00:01/-1 , ... )
989 """
990 try:
991 onosHostList = []
992
993 for host in hostList:
994 host = host.replace( "h", "" )
995 hostHex = hex( int( host ) ).zfill( 12 )
996 hostHex = str( hostHex ).replace( 'x', '0' )
997 i = iter( str( hostHex ) )
998 hostHex = ":".join( a + b for a, b in zip( i, i ) )
999 hostHex = hostHex + "/-1"
1000 onosHostList.append( hostHex )
1001
1002 return onosHostList
1003
1004 except TypeError:
1005 main.log.exception( self.name + ": Object not as expected" )
1006 return None
1007 except pexpect.EOF:
1008 main.log.error( self.name + ": EOF exception found" )
1009 main.log.error( self.name + ": " + self.handle.before )
1010 main.cleanup()
1011 main.exit()
1012 except Exception:
1013 main.log.exception( self.name + ": Uncaught exception!" )
1014 main.cleanup()
1015 main.exit()
1016
1018 """
1019 Required:
1020 * hostIdOne: ONOS host id for host1
1021 * hostIdTwo: ONOS host id for host2
1022 Description:
1023 Adds a host-to-host intent ( bidirectional ) by
1024 specifying the two hosts.
1025 Returns:
1026 A string of the intent id or None on Error
1027 """
1028 try:
1029 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1030 " " + str( hostIdTwo )
1031 handle = self.sendline( cmdStr )
1032 if re.search( "Error", handle ):
1033 main.log.error( "Error in adding Host intent" )
1034 main.log.debug( "Response from ONOS was: " + repr( handle ) )
1035 return None
1036 else:
1037 main.log.info( "Host intent installed between " +
1038 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1039 match = re.search('id=0x([\da-f]+),', handle)
1040 if match:
1041 return match.group()[3:-1]
1042 else:
1043 main.log.error( "Error, intent ID not found" )
1044 main.log.debug( "Response from ONOS was: " +
1045 repr( handle ) )
1046 return None
1047 except TypeError:
1048 main.log.exception( self.name + ": Object not as expected" )
1049 return None
1050 except pexpect.EOF:
1051 main.log.error( self.name + ": EOF exception found" )
1052 main.log.error( self.name + ": " + self.handle.before )
1053 main.cleanup()
1054 main.exit()
1055 except Exception:
1056 main.log.exception( self.name + ": Uncaught exception!" )
1057 main.cleanup()
1058 main.exit()
1059
1061 """
1062 Required:
1063 * ingressDevice: device id of ingress device
1064 * egressDevice: device id of egress device
1065 Optional:
1066 TODO: Still needs to be implemented via dev side
1067 Description:
1068 Adds an optical intent by specifying an ingress and egress device
1069 Returns:
1070 A string of the intent id or None on error
1071 """
1072 try:
1073 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1074 " " + str( egressDevice )
1075 handle = self.sendline( cmdStr )
1076
1077 if re.search( "Error", handle ):
1078 main.log.error( "Error in adding Optical intent" )
1079 return None
1080 else:
1081 main.log.info( "Optical intent installed between " +
1082 str( ingressDevice ) + " and " +
1083 str( egressDevice ) )
1084 match = re.search('id=0x([\da-f]+),', handle)
1085 if match:
1086 return match.group()[3:-1]
1087 else:
1088 main.log.error( "Error, intent ID not found" )
1089 return None
1090 except TypeError:
1091 main.log.exception( self.name + ": Object not as expected" )
1092 return None
1093 except pexpect.EOF:
1094 main.log.error( self.name + ": EOF exception found" )
1095 main.log.error( self.name + ": " + self.handle.before )
1096 main.cleanup()
1097 main.exit()
1098 except Exception:
1099 main.log.exception( self.name + ": Uncaught exception!" )
1100 main.cleanup()
1101 main.exit()
1102
1103 - def addPointIntent(
1104 self,
1105 ingressDevice,
1106 egressDevice,
1107 portIngress="",
1108 portEgress="",
1109 ethType="",
1110 ethSrc="",
1111 ethDst="",
1112 bandwidth="",
1113 lambdaAlloc=False,
1114 ipProto="",
1115 ipSrc="",
1116 ipDst="",
1117 tcpSrc="",
1118 tcpDst="" ):
1119 """
1120 Required:
1121 * ingressDevice: device id of ingress device
1122 * egressDevice: device id of egress device
1123 Optional:
1124 * ethType: specify ethType
1125 * ethSrc: specify ethSrc ( i.e. src mac addr )
1126 * ethDst: specify ethDst ( i.e. dst mac addr )
1127 * bandwidth: specify bandwidth capacity of link
1128 * lambdaAlloc: if True, intent will allocate lambda
1129 for the specified intent
1130 * ipProto: specify ip protocol
1131 * ipSrc: specify ip source address
1132 * ipDst: specify ip destination address
1133 * tcpSrc: specify tcp source port
1134 * tcpDst: specify tcp destination port
1135 Description:
1136 Adds a point-to-point intent ( uni-directional ) by
1137 specifying device id's and optional fields
1138 Returns:
1139 A string of the intent id or None on error
1140
1141 NOTE: This function may change depending on the
1142 options developers provide for point-to-point
1143 intent via cli
1144 """
1145 try:
1146
1147 if not ethType and not ethSrc and not ethDst\
1148 and not bandwidth and not lambdaAlloc \
1149 and not ipProto and not ipSrc and not ipDst \
1150 and not tcpSrc and not tcpDst:
1151 cmd = "add-point-intent"
1152
1153 else:
1154 cmd = "add-point-intent"
1155
1156 if ethType:
1157 cmd += " --ethType " + str( ethType )
1158 if ethSrc:
1159 cmd += " --ethSrc " + str( ethSrc )
1160 if ethDst:
1161 cmd += " --ethDst " + str( ethDst )
1162 if bandwidth:
1163 cmd += " --bandwidth " + str( bandwidth )
1164 if lambdaAlloc:
1165 cmd += " --lambda "
1166 if ipProto:
1167 cmd += " --ipProto " + str( ipProto )
1168 if ipSrc:
1169 cmd += " --ipSrc " + str( ipSrc )
1170 if ipDst:
1171 cmd += " --ipDst " + str( ipDst )
1172 if tcpSrc:
1173 cmd += " --tcpSrc " + str( tcpSrc )
1174 if tcpDst:
1175 cmd += " --tcpDst " + str( tcpDst )
1176
1177
1178
1179 if "/" in ingressDevice:
1180 cmd += " " + str( ingressDevice )
1181 else:
1182 if not portIngress:
1183 main.log.error( "You must specify the ingress port" )
1184
1185
1186
1187 return None
1188
1189 cmd += " " + \
1190 str( ingressDevice ) + "/" +\
1191 str( portIngress ) + " "
1192
1193 if "/" in egressDevice:
1194 cmd += " " + str( egressDevice )
1195 else:
1196 if not portEgress:
1197 main.log.error( "You must specify the egress port" )
1198 return None
1199
1200 cmd += " " +\
1201 str( egressDevice ) + "/" +\
1202 str( portEgress )
1203
1204 handle = self.sendline( cmd )
1205
1206 if re.search( "Error", handle ):
1207 main.log.error( "Error in adding point-to-point intent" )
1208 return None
1209 else:
1210
1211 main.log.info( "Point-to-point intent installed between " +
1212 str( ingressDevice ) + " and " +
1213 str( egressDevice ) )
1214 match = re.search('id=0x([\da-f]+),', handle)
1215 if match:
1216 return match.group()[3:-1]
1217 else:
1218 main.log.error( "Error, intent ID not found" )
1219 return None
1220 except TypeError:
1221 main.log.exception( self.name + ": Object not as expected" )
1222 return None
1223 except pexpect.EOF:
1224 main.log.error( self.name + ": EOF exception found" )
1225 main.log.error( self.name + ": " + self.handle.before )
1226 main.cleanup()
1227 main.exit()
1228 except Exception:
1229 main.log.exception( self.name + ": Uncaught exception!" )
1230 main.cleanup()
1231 main.exit()
1232
1233 - def addMultipointToSinglepointIntent(
1234 self,
1235 ingressDeviceList,
1236 egressDevice,
1237 portIngressList=None,
1238 portEgress="",
1239 ethType="",
1240 ethSrc="",
1241 ethDst="",
1242 bandwidth="",
1243 lambdaAlloc=False,
1244 ipProto="",
1245 ipSrc="",
1246 ipDst="",
1247 tcpSrc="",
1248 tcpDst="",
1249 setEthSrc="",
1250 setEthDst="" ):
1251 """
1252 Note:
1253 This function assumes the format of all ingress devices
1254 is same. That is, all ingress devices include port numbers
1255 with a "/" or all ingress devices could specify device
1256 ids and port numbers seperately.
1257 Required:
1258 * ingressDeviceList: List of device ids of ingress device
1259 ( Atleast 2 ingress devices required in the list )
1260 * egressDevice: device id of egress device
1261 Optional:
1262 * ethType: specify ethType
1263 * ethSrc: specify ethSrc ( i.e. src mac addr )
1264 * ethDst: specify ethDst ( i.e. dst mac addr )
1265 * bandwidth: specify bandwidth capacity of link
1266 * lambdaAlloc: if True, intent will allocate lambda
1267 for the specified intent
1268 * ipProto: specify ip protocol
1269 * ipSrc: specify ip source address
1270 * ipDst: specify ip destination address
1271 * tcpSrc: specify tcp source port
1272 * tcpDst: specify tcp destination port
1273 * setEthSrc: action to Rewrite Source MAC Address
1274 * setEthDst: action to Rewrite Destination MAC Address
1275 Description:
1276 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
1277 specifying device id's and optional fields
1278 Returns:
1279 A string of the intent id or None on error
1280
1281 NOTE: This function may change depending on the
1282 options developers provide for multipoint-to-singlepoint
1283 intent via cli
1284 """
1285 try:
1286
1287 if not ethType and not ethSrc and not ethDst\
1288 and not bandwidth and not lambdaAlloc\
1289 and not ipProto and not ipSrc and not ipDst\
1290 and not tcpSrc and not tcpDst and not setEthSrc\
1291 and not setEthDst:
1292 cmd = "add-multi-to-single-intent"
1293
1294 else:
1295 cmd = "add-multi-to-single-intent"
1296
1297 if ethType:
1298 cmd += " --ethType " + str( ethType )
1299 if ethSrc:
1300 cmd += " --ethSrc " + str( ethSrc )
1301 if ethDst:
1302 cmd += " --ethDst " + str( ethDst )
1303 if bandwidth:
1304 cmd += " --bandwidth " + str( bandwidth )
1305 if lambdaAlloc:
1306 cmd += " --lambda "
1307 if ipProto:
1308 cmd += " --ipProto " + str( ipProto )
1309 if ipSrc:
1310 cmd += " --ipSrc " + str( ipSrc )
1311 if ipDst:
1312 cmd += " --ipDst " + str( ipDst )
1313 if tcpSrc:
1314 cmd += " --tcpSrc " + str( tcpSrc )
1315 if tcpDst:
1316 cmd += " --tcpDst " + str( tcpDst )
1317 if setEthSrc:
1318 cmd += " --setEthSrc " + str( setEthSrc )
1319 if setEthDst:
1320 cmd += " --setEthDst " + str( setEthDst )
1321
1322
1323
1324
1325 if portIngressList is None:
1326 for ingressDevice in ingressDeviceList:
1327 if "/" in ingressDevice:
1328 cmd += " " + str( ingressDevice )
1329 else:
1330 main.log.error( "You must specify " +
1331 "the ingress port" )
1332
1333 return main.FALSE
1334 else:
1335 if len( ingressDeviceList ) == len( portIngressList ):
1336 for ingressDevice, portIngress in zip( ingressDeviceList,
1337 portIngressList ):
1338 cmd += " " + \
1339 str( ingressDevice ) + "/" +\
1340 str( portIngress ) + " "
1341 else:
1342 main.log.error( "Device list and port list does not " +
1343 "have the same length" )
1344 return main.FALSE
1345 if "/" in egressDevice:
1346 cmd += " " + str( egressDevice )
1347 else:
1348 if not portEgress:
1349 main.log.error( "You must specify " +
1350 "the egress port" )
1351 return main.FALSE
1352
1353 cmd += " " +\
1354 str( egressDevice ) + "/" +\
1355 str( portEgress )
1356 handle = self.sendline( cmd )
1357
1358 if re.search( "Error", handle ):
1359 main.log.error( "Error in adding multipoint-to-singlepoint " +
1360 "intent" )
1361 return None
1362 else:
1363 match = re.search('id=0x([\da-f]+),', handle)
1364 if match:
1365 return match.group()[3:-1]
1366 else:
1367 main.log.error( "Error, intent ID not found" )
1368 return None
1369 except TypeError:
1370 main.log.exception( self.name + ": Object not as expected" )
1371 return None
1372 except pexpect.EOF:
1373 main.log.error( self.name + ": EOF exception found" )
1374 main.log.error( self.name + ": " + self.handle.before )
1375 main.cleanup()
1376 main.exit()
1377 except Exception:
1378 main.log.exception( self.name + ": Uncaught exception!" )
1379 main.cleanup()
1380 main.exit()
1381
1382 - def addSinglepointToMultipointIntent(
1383 self,
1384 ingressDevice,
1385 egressDeviceList,
1386 portIngress="",
1387 portEgressList=None,
1388 ethType="",
1389 ethSrc="",
1390 ethDst="",
1391 bandwidth="",
1392 lambdaAlloc=False,
1393 ipProto="",
1394 ipSrc="",
1395 ipDst="",
1396 tcpSrc="",
1397 tcpDst="",
1398 setEthSrc="",
1399 setEthDst="" ):
1400 """
1401 Note:
1402 This function assumes the format of all egress devices
1403 is same. That is, all egress devices include port numbers
1404 with a "/" or all egress devices could specify device
1405 ids and port numbers seperately.
1406 Required:
1407 * EgressDeviceList: List of device ids of egress device
1408 ( Atleast 2 eress devices required in the list )
1409 * ingressDevice: device id of ingress device
1410 Optional:
1411 * ethType: specify ethType
1412 * ethSrc: specify ethSrc ( i.e. src mac addr )
1413 * ethDst: specify ethDst ( i.e. dst mac addr )
1414 * bandwidth: specify bandwidth capacity of link
1415 * lambdaAlloc: if True, intent will allocate lambda
1416 for the specified intent
1417 * ipProto: specify ip protocol
1418 * ipSrc: specify ip source address
1419 * ipDst: specify ip destination address
1420 * tcpSrc: specify tcp source port
1421 * tcpDst: specify tcp destination port
1422 * setEthSrc: action to Rewrite Source MAC Address
1423 * setEthDst: action to Rewrite Destination MAC Address
1424 Description:
1425 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1426 specifying device id's and optional fields
1427 Returns:
1428 A string of the intent id or None on error
1429
1430 NOTE: This function may change depending on the
1431 options developers provide for singlepoint-to-multipoint
1432 intent via cli
1433 """
1434 try:
1435
1436 if not ethType and not ethSrc and not ethDst\
1437 and not bandwidth and not lambdaAlloc\
1438 and not ipProto and not ipSrc and not ipDst\
1439 and not tcpSrc and not tcpDst and not setEthSrc\
1440 and not setEthDst:
1441 cmd = "add-single-to-multi-intent"
1442
1443 else:
1444 cmd = "add-single-to-multi-intent"
1445
1446 if ethType:
1447 cmd += " --ethType " + str( ethType )
1448 if ethSrc:
1449 cmd += " --ethSrc " + str( ethSrc )
1450 if ethDst:
1451 cmd += " --ethDst " + str( ethDst )
1452 if bandwidth:
1453 cmd += " --bandwidth " + str( bandwidth )
1454 if lambdaAlloc:
1455 cmd += " --lambda "
1456 if ipProto:
1457 cmd += " --ipProto " + str( ipProto )
1458 if ipSrc:
1459 cmd += " --ipSrc " + str( ipSrc )
1460 if ipDst:
1461 cmd += " --ipDst " + str( ipDst )
1462 if tcpSrc:
1463 cmd += " --tcpSrc " + str( tcpSrc )
1464 if tcpDst:
1465 cmd += " --tcpDst " + str( tcpDst )
1466 if setEthSrc:
1467 cmd += " --setEthSrc " + str( setEthSrc )
1468 if setEthDst:
1469 cmd += " --setEthDst " + str( setEthDst )
1470
1471
1472
1473
1474 if "/" in ingressDevice:
1475 cmd += " " + str( ingressDevice )
1476 else:
1477 if not portIngress:
1478 main.log.error( "You must specify " +
1479 "the Ingress port" )
1480 return main.FALSE
1481
1482 cmd += " " +\
1483 str( ingressDevice ) + "/" +\
1484 str( portIngress )
1485
1486 if portEgressList is None:
1487 for egressDevice in egressDeviceList:
1488 if "/" in egressDevice:
1489 cmd += " " + str( egressDevice )
1490 else:
1491 main.log.error( "You must specify " +
1492 "the egress port" )
1493
1494 return main.FALSE
1495 else:
1496 if len( egressDeviceList ) == len( portEgressList ):
1497 for egressDevice, portEgress in zip( egressDeviceList,
1498 portEgressList ):
1499 cmd += " " + \
1500 str( egressDevice ) + "/" +\
1501 str( portEgress )
1502 else:
1503 main.log.error( "Device list and port list does not " +
1504 "have the same length" )
1505 return main.FALSE
1506 handle = self.sendline( cmd )
1507
1508 if re.search( "Error", handle ):
1509 main.log.error( "Error in adding singlepoint-to-multipoint " +
1510 "intent" )
1511 return None
1512 else:
1513 match = re.search('id=0x([\da-f]+),', handle)
1514 if match:
1515 return match.group()[3:-1]
1516 else:
1517 main.log.error( "Error, intent ID not found" )
1518 return None
1519 except TypeError:
1520 main.log.exception( self.name + ": Object not as expected" )
1521 return None
1522 except pexpect.EOF:
1523 main.log.error( self.name + ": EOF exception found" )
1524 main.log.error( self.name + ": " + self.handle.before )
1525 main.cleanup()
1526 main.exit()
1527 except Exception:
1528 main.log.exception( self.name + ": Uncaught exception!" )
1529 main.cleanup()
1530 main.exit()
1531
1532 - def addMplsIntent(
1533 self,
1534 ingressDevice,
1535 egressDevice,
1536 ingressPort="",
1537 egressPort="",
1538 ethType="",
1539 ethSrc="",
1540 ethDst="",
1541 bandwidth="",
1542 lambdaAlloc=False,
1543 ipProto="",
1544 ipSrc="",
1545 ipDst="",
1546 tcpSrc="",
1547 tcpDst="",
1548 ingressLabel="",
1549 egressLabel="",
1550 priority=""):
1551 """
1552 Required:
1553 * ingressDevice: device id of ingress device
1554 * egressDevice: device id of egress device
1555 Optional:
1556 * ethType: specify ethType
1557 * ethSrc: specify ethSrc ( i.e. src mac addr )
1558 * ethDst: specify ethDst ( i.e. dst mac addr )
1559 * bandwidth: specify bandwidth capacity of link
1560 * lambdaAlloc: if True, intent will allocate lambda
1561 for the specified intent
1562 * ipProto: specify ip protocol
1563 * ipSrc: specify ip source address
1564 * ipDst: specify ip destination address
1565 * tcpSrc: specify tcp source port
1566 * tcpDst: specify tcp destination port
1567 * ingressLabel: Ingress MPLS label
1568 * egressLabel: Egress MPLS label
1569 Description:
1570 Adds MPLS intent by
1571 specifying device id's and optional fields
1572 Returns:
1573 A string of the intent id or None on error
1574
1575 NOTE: This function may change depending on the
1576 options developers provide for MPLS
1577 intent via cli
1578 """
1579 try:
1580
1581 if not ethType and not ethSrc and not ethDst\
1582 and not bandwidth and not lambdaAlloc \
1583 and not ipProto and not ipSrc and not ipDst \
1584 and not tcpSrc and not tcpDst and not ingressLabel \
1585 and not egressLabel:
1586 cmd = "add-mpls-intent"
1587
1588 else:
1589 cmd = "add-mpls-intent"
1590
1591 if ethType:
1592 cmd += " --ethType " + str( ethType )
1593 if ethSrc:
1594 cmd += " --ethSrc " + str( ethSrc )
1595 if ethDst:
1596 cmd += " --ethDst " + str( ethDst )
1597 if bandwidth:
1598 cmd += " --bandwidth " + str( bandwidth )
1599 if lambdaAlloc:
1600 cmd += " --lambda "
1601 if ipProto:
1602 cmd += " --ipProto " + str( ipProto )
1603 if ipSrc:
1604 cmd += " --ipSrc " + str( ipSrc )
1605 if ipDst:
1606 cmd += " --ipDst " + str( ipDst )
1607 if tcpSrc:
1608 cmd += " --tcpSrc " + str( tcpSrc )
1609 if tcpDst:
1610 cmd += " --tcpDst " + str( tcpDst )
1611 if ingressLabel:
1612 cmd += " --ingressLabel " + str( ingressLabel )
1613 if egressLabel:
1614 cmd += " --egressLabel " + str( egressLabel )
1615 if priority:
1616 cmd += " --priority " + str( priority )
1617
1618
1619
1620 if "/" in ingressDevice:
1621 cmd += " " + str( ingressDevice )
1622 else:
1623 if not ingressPort:
1624 main.log.error( "You must specify the ingress port" )
1625 return None
1626
1627 cmd += " " + \
1628 str( ingressDevice ) + "/" +\
1629 str( ingressPort ) + " "
1630
1631 if "/" in egressDevice:
1632 cmd += " " + str( egressDevice )
1633 else:
1634 if not egressPort:
1635 main.log.error( "You must specify the egress port" )
1636 return None
1637
1638 cmd += " " +\
1639 str( egressDevice ) + "/" +\
1640 str( egressPort )
1641
1642 handle = self.sendline( cmd )
1643
1644 if re.search( "Error", handle ):
1645 main.log.error( "Error in adding mpls intent" )
1646 return None
1647 else:
1648
1649 main.log.info( "MPLS intent installed between " +
1650 str( ingressDevice ) + " and " +
1651 str( egressDevice ) )
1652 match = re.search('id=0x([\da-f]+),', handle)
1653 if match:
1654 return match.group()[3:-1]
1655 else:
1656 main.log.error( "Error, intent ID not found" )
1657 return None
1658 except TypeError:
1659 main.log.exception( self.name + ": Object not as expected" )
1660 return None
1661 except pexpect.EOF:
1662 main.log.error( self.name + ": EOF exception found" )
1663 main.log.error( self.name + ": " + self.handle.before )
1664 main.cleanup()
1665 main.exit()
1666 except Exception:
1667 main.log.exception( self.name + ": Uncaught exception!" )
1668 main.cleanup()
1669 main.exit()
1670
1671 - def removeIntent( self, intentId, app='org.onosproject.cli',
1672 purge=False, sync=False ):
1673 """
1674 Remove intent for specified application id and intent id
1675 Optional args:-
1676 -s or --sync: Waits for the removal before returning
1677 -p or --purge: Purge the intent from the store after removal
1678
1679 Returns:
1680 main.False on error and
1681 cli output otherwise
1682 """
1683 try:
1684 cmdStr = "remove-intent"
1685 if purge:
1686 cmdStr += " -p"
1687 if sync:
1688 cmdStr += " -s"
1689
1690 cmdStr += " " + app + " " + str( intentId )
1691 handle = self.sendline( cmdStr )
1692 if re.search( "Error", handle ):
1693 main.log.error( "Error in removing intent" )
1694 return main.FALSE
1695 else:
1696
1697 return handle
1698 except TypeError:
1699 main.log.exception( self.name + ": Object not as expected" )
1700 return None
1701 except pexpect.EOF:
1702 main.log.error( self.name + ": EOF exception found" )
1703 main.log.error( self.name + ": " + self.handle.before )
1704 main.cleanup()
1705 main.exit()
1706 except Exception:
1707 main.log.exception( self.name + ": Uncaught exception!" )
1708 main.cleanup()
1709 main.exit()
1710
1712 """
1713 Purges all WITHDRAWN Intents
1714 """
1715 try:
1716 cmdStr = "purge-intents"
1717 handle = self.sendline( cmdStr )
1718 if re.search( "Error", handle ):
1719 main.log.error( "Error in purging intents" )
1720 return main.FALSE
1721 else:
1722 return main.TRUE
1723 except TypeError:
1724 main.log.exception( self.name + ": Object not as expected" )
1725 return None
1726 except pexpect.EOF:
1727 main.log.error( self.name + ": EOF exception found" )
1728 main.log.error( self.name + ": " + self.handle.before )
1729 main.cleanup()
1730 main.exit()
1731 except Exception:
1732 main.log.exception( self.name + ": Uncaught exception!" )
1733 main.cleanup()
1734 main.exit()
1735
1736 - def routes( self, jsonFormat=False ):
1737 """
1738 NOTE: This method should be used after installing application:
1739 onos-app-sdnip
1740 Optional:
1741 * jsonFormat: enable output formatting in json
1742 Description:
1743 Obtain all routes in the system
1744 """
1745 try:
1746 cmdStr = "routes"
1747 if jsonFormat:
1748 cmdStr += " -j"
1749 handle = self.sendline( cmdStr )
1750 return handle
1751 except TypeError:
1752 main.log.exception( self.name + ": Object not as expected" )
1753 return None
1754 except pexpect.EOF:
1755 main.log.error( self.name + ": EOF exception found" )
1756 main.log.error( self.name + ": " + self.handle.before )
1757 main.cleanup()
1758 main.exit()
1759 except Exception:
1760 main.log.exception( self.name + ": Uncaught exception!" )
1761 main.cleanup()
1762 main.exit()
1763
1764 - def intents( self, jsonFormat=True ):
1765 """
1766 Optional:
1767 * jsonFormat: enable output formatting in json
1768 Description:
1769 Obtain intents currently installed
1770 """
1771 try:
1772 cmdStr = "intents"
1773 if jsonFormat:
1774 cmdStr += " -j"
1775 handle = self.sendline( cmdStr )
1776 return handle
1777 except TypeError:
1778 main.log.exception( self.name + ": Object not as expected" )
1779 return None
1780 except pexpect.EOF:
1781 main.log.error( self.name + ": EOF exception found" )
1782 main.log.error( self.name + ": " + self.handle.before )
1783 main.cleanup()
1784 main.exit()
1785 except Exception:
1786 main.log.exception( self.name + ": Uncaught exception!" )
1787 main.cleanup()
1788 main.exit()
1789
1791 """
1792 Check intent state.
1793 Accepts a single intent ID (string type) or a list of intent IDs.
1794 Returns the state(string type) of the id if a single intent ID is
1795 accepted.
1796 Returns a dictionary with intent IDs as the key and its
1797 corresponding states as the values
1798 Parameters:
1799 intentId: intent ID (string type)
1800 intentsJson: parsed json object from the onos:intents api
1801 Returns:
1802 state = An intent's state- INSTALL,WITHDRAWN etc.
1803 stateDict = Dictionary of intent's state. intent ID as the keys and
1804 state as the values.
1805 """
1806 try:
1807 state = "State is Undefined"
1808 if not intentsJson:
1809 intentsJsonTemp = json.loads( self.intents() )
1810 else:
1811 intentsJsonTemp = json.loads( intentsJson )
1812 if isinstance( intentsId, types.StringType ):
1813 for intent in intentsJsonTemp:
1814 if intentsId == intent[ 'id' ]:
1815 state = intent[ 'state' ]
1816 return state
1817 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1818 " on the list" )
1819 return state
1820 elif isinstance( intentsId, types.ListType ):
1821 dictList = []
1822 for i in xrange( len( intentsId ) ):
1823 stateDict = {}
1824 for intents in intentsJsonTemp:
1825 if intentsId[ i ] == intents[ 'id' ]:
1826 stateDict[ 'state' ] = intents[ 'state' ]
1827 stateDict[ 'id' ] = intentsId[ i ]
1828 dictList.append( stateDict )
1829 break
1830 if len( intentsId ) != len( dictList ):
1831 main.log.info( "Cannot find some of the intent ID state" )
1832 return dictList
1833 else:
1834 main.log.info( "Invalid intents ID entry" )
1835 return None
1836 except TypeError:
1837 main.log.exception( self.name + ": Object not as expected" )
1838 return None
1839 except pexpect.EOF:
1840 main.log.error( self.name + ": EOF exception found" )
1841 main.log.error( self.name + ": " + self.handle.before )
1842 main.cleanup()
1843 main.exit()
1844 except Exception:
1845 main.log.exception( self.name + ": Uncaught exception!" )
1846 main.cleanup()
1847 main.exit()
1848
1850 """
1851 Description:
1852 Check intents state
1853 Required:
1854 intentsId - List of intents ID to be checked
1855 Optional:
1856 expectedState - Check the expected state(s) of each intents
1857 state in the list.
1858 *NOTE: You can pass in a list of expected state,
1859 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
1860 Return:
1861 Returns main.TRUE only if all intent are the same as expected states
1862 , otherwise, returns main.FALSE.
1863 """
1864 try:
1865
1866 returnValue = main.TRUE
1867 intentsDict = self.getIntentState( intentsId )
1868
1869
1870 if len( intentsId ) != len( intentsDict ):
1871 main.log.info( self.name + "There is something wrong " +
1872 "getting intents state" )
1873 return main.FALSE
1874
1875 if isinstance( expectedState, types.StringType ):
1876 for intents in intentsDict:
1877 if intents.get( 'state' ) != expectedState:
1878 main.log.debug( self.name + " : Intent ID - " +
1879 intents.get( 'id' ) +
1880 " actual state = " +
1881 intents.get( 'state' )
1882 + " does not equal expected state = "
1883 + expectedState )
1884 returnValue = main.FALSE
1885
1886 elif isinstance( expectedState, types.ListType ):
1887 for intents in intentsDict:
1888 if not any( state == intents.get( 'state' ) for state in
1889 expectedState ):
1890 main.log.debug( self.name + " : Intent ID - " +
1891 intents.get( 'id' ) +
1892 " actual state = " +
1893 intents.get( 'state' ) +
1894 " does not equal expected states = "
1895 + str( expectedState ) )
1896 returnValue = main.FALSE
1897
1898 if returnValue == main.TRUE:
1899 main.log.info( self.name + ": All " +
1900 str( len( intentsDict ) ) +
1901 " intents are in " + str( expectedState ) +
1902 " state" )
1903 return returnValue
1904 except TypeError:
1905 main.log.exception( self.name + ": Object not as expected" )
1906 return None
1907 except pexpect.EOF:
1908 main.log.error( self.name + ": EOF exception found" )
1909 main.log.error( self.name + ": " + self.handle.before )
1910 main.cleanup()
1911 main.exit()
1912 except Exception:
1913 main.log.exception( self.name + ": Uncaught exception!" )
1914 main.cleanup()
1915 main.exit()
1916
1917 - def flows( self, jsonFormat=True ):
1918 """
1919 Optional:
1920 * jsonFormat: enable output formatting in json
1921 Description:
1922 Obtain flows currently installed
1923 """
1924 try:
1925 cmdStr = "flows"
1926 if jsonFormat:
1927 cmdStr += " -j"
1928 handle = self.sendline( cmdStr )
1929 if re.search( "Error:", handle ):
1930 main.log.error( self.name + ": flows() response: " +
1931 str( handle ) )
1932 return handle
1933 except TypeError:
1934 main.log.exception( self.name + ": Object not as expected" )
1935 return None
1936 except pexpect.EOF:
1937 main.log.error( self.name + ": EOF exception found" )
1938 main.log.error( self.name + ": " + self.handle.before )
1939 main.cleanup()
1940 main.exit()
1941 except Exception:
1942 main.log.exception( self.name + ": Uncaught exception!" )
1943 main.cleanup()
1944 main.exit()
1945
1947 """
1948 Description:
1949 Check the if all the current flows are in ADDED state or
1950 PENDING_ADD state
1951 Return:
1952 returnValue - Returns main.TRUE only if all flows are in
1953 ADDED state or PENDING_ADD, return main.FALSE
1954 otherwise.
1955 """
1956 try:
1957 tempFlows = json.loads( self.flows() )
1958
1959 returnValue = main.TRUE
1960
1961 for device in tempFlows:
1962 for flow in device.get( 'flows' ):
1963 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1964 'PENDING_ADD':
1965
1966 main.log.info( self.name + ": flow Id: " +
1967 str( flow.get( 'groupId' ) ) +
1968 " | state:" +
1969 str( flow.get( 'state' ) ) )
1970 returnValue = main.FALSE
1971
1972 return returnValue
1973 except TypeError:
1974 main.log.exception( self.name + ": Object not as expected" )
1975 return None
1976 except pexpect.EOF:
1977 main.log.error( self.name + ": EOF exception found" )
1978 main.log.error( self.name + ": " + self.handle.before )
1979 main.cleanup()
1980 main.exit()
1981 except Exception:
1982 main.log.exception( self.name + ": Uncaught exception!" )
1983 main.cleanup()
1984 main.exit()
1985
1986 - def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
1987 numMult="", appId="", report=True ):
1988 """
1989 Description:
1990 Push a number of intents in a batch format to
1991 a specific point-to-point intent definition
1992 Required:
1993 * dpidSrc: specify source dpid
1994 * dpidDst: specify destination dpid
1995 * numIntents: specify number of intents to push
1996 Optional:
1997 * numMult: number multiplier for multiplying
1998 the number of intents specified
1999 * appId: specify the application id init to further
2000 modularize the intents
2001 * report: default True, returns latency information
2002 """
2003 try:
2004 cmd = "push-test-intents " +\
2005 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
2006 str( numIntents )
2007 if numMult:
2008 cmd += " " + str( numMult )
2009
2010
2011 if appId:
2012 cmd += " " + str( appId )
2013 handle = self.sendline( cmd )
2014 if report:
2015 latResult = []
2016 main.log.info( handle )
2017
2018 newline = handle.split( "\r\r\n" )
2019
2020 newline = newline[ 1: ]
2021
2022 for result in newline:
2023 result = result.split( ": " )
2024
2025 latResult.append( result[ 1 ].split( " " )[ 0 ] )
2026 main.log.info( latResult )
2027 return latResult
2028 else:
2029 return main.TRUE
2030 except TypeError:
2031 main.log.exception( self.name + ": Object not as expected" )
2032 return None
2033 except pexpect.EOF:
2034 main.log.error( self.name + ": EOF exception found" )
2035 main.log.error( self.name + ": " + self.handle.before )
2036 main.cleanup()
2037 main.exit()
2038 except Exception:
2039 main.log.exception( self.name + ": Uncaught exception!" )
2040 main.cleanup()
2041 main.exit()
2042
2044 """
2045 Description:Returns topology metrics
2046 Optional:
2047 * jsonFormat: enable json formatting of output
2048 """
2049 try:
2050 cmdStr = "intents-events-metrics"
2051 if jsonFormat:
2052 cmdStr += " -j"
2053 handle = self.sendline( cmdStr )
2054 return handle
2055 except TypeError:
2056 main.log.exception( self.name + ": Object not as expected" )
2057 return None
2058 except pexpect.EOF:
2059 main.log.error( self.name + ": EOF exception found" )
2060 main.log.error( self.name + ": " + self.handle.before )
2061 main.cleanup()
2062 main.exit()
2063 except Exception:
2064 main.log.exception( self.name + ": Uncaught exception!" )
2065 main.cleanup()
2066 main.exit()
2067
2069 """
2070 Description:Returns topology metrics
2071 Optional:
2072 * jsonFormat: enable json formatting of output
2073 """
2074 try:
2075 cmdStr = "topology-events-metrics"
2076 if jsonFormat:
2077 cmdStr += " -j"
2078 handle = self.sendline( cmdStr )
2079 if handle:
2080 return handle
2081 elif jsonFormat:
2082
2083 return '{}'
2084 else:
2085 return handle
2086 except TypeError:
2087 main.log.exception( self.name + ": Object not as expected" )
2088 return None
2089 except pexpect.EOF:
2090 main.log.error( self.name + ": EOF exception found" )
2091 main.log.error( self.name + ": " + self.handle.before )
2092 main.cleanup()
2093 main.exit()
2094 except Exception:
2095 main.log.exception( self.name + ": Uncaught exception!" )
2096 main.cleanup()
2097 main.exit()
2098
2099
2100
2101
2102
2103
2104
2105
2107 """
2108 Description:
2109 Obtain all intent id's in a list
2110 """
2111 try:
2112
2113 intentsStr = self.intents(jsonFormat=False)
2114 intentIdList = []
2115
2116
2117 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2118 for intents in intentsList:
2119 match = re.search('id=0x([\da-f]+),', intents)
2120 if match:
2121 tmpId = match.group()[3:-1]
2122 intentIdList.append( tmpId )
2123 return intentIdList
2124
2125 except TypeError:
2126 main.log.exception( self.name + ": Object not as expected" )
2127 return None
2128 except pexpect.EOF:
2129 main.log.error( self.name + ": EOF exception found" )
2130 main.log.error( self.name + ": " + self.handle.before )
2131 main.cleanup()
2132 main.exit()
2133 except Exception:
2134 main.log.exception( self.name + ": Uncaught exception!" )
2135 main.cleanup()
2136 main.exit()
2137
2139 """
2140 Determine the number of flow rules for the given device id that are
2141 in the added state
2142 """
2143 try:
2144 cmdStr = "flows any " + str( deviceId ) + " | " +\
2145 "grep 'state=ADDED' | wc -l"
2146 handle = self.sendline( cmdStr )
2147 return handle
2148 except pexpect.EOF:
2149 main.log.error( self.name + ": EOF exception found" )
2150 main.log.error( self.name + ": " + self.handle.before )
2151 main.cleanup()
2152 main.exit()
2153 except Exception:
2154 main.log.exception( self.name + ": Uncaught exception!" )
2155 main.cleanup()
2156 main.exit()
2157
2159 """
2160 Use 'devices' function to obtain list of all devices
2161 and parse the result to obtain a list of all device
2162 id's. Returns this list. Returns empty list if no
2163 devices exist
2164 List is ordered sequentially
2165
2166 This function may be useful if you are not sure of the
2167 device id, and wish to execute other commands using
2168 the ids. By obtaining the list of device ids on the fly,
2169 you can iterate through the list to get mastership, etc.
2170 """
2171 try:
2172
2173 devicesStr = self.devices( jsonFormat=False )
2174 idList = []
2175
2176 if not devicesStr:
2177 main.log.info( "There are no devices to get id from" )
2178 return idList
2179
2180
2181 deviceList = devicesStr.split( "," )
2182
2183 tempList = [ dev for dev in deviceList if "id=" in dev ]
2184
2185
2186
2187 for arg in tempList:
2188 idList.append( arg.split( "id=" )[ 1 ] )
2189 return idList
2190
2191 except TypeError:
2192 main.log.exception( self.name + ": Object not as expected" )
2193 return None
2194 except pexpect.EOF:
2195 main.log.error( self.name + ": EOF exception found" )
2196 main.log.error( self.name + ": " + self.handle.before )
2197 main.cleanup()
2198 main.exit()
2199 except Exception:
2200 main.log.exception( self.name + ": Uncaught exception!" )
2201 main.cleanup()
2202 main.exit()
2203
2205 """
2206 Uses 'nodes' function to obtain list of all nodes
2207 and parse the result of nodes to obtain just the
2208 node id's.
2209 Returns:
2210 list of node id's
2211 """
2212 try:
2213 nodesStr = self.nodes( jsonFormat=True )
2214 idList = []
2215
2216
2217 if not nodesStr:
2218 main.log.info( "There are no nodes to get id from" )
2219 return idList
2220 nodesJson = json.loads( nodesStr )
2221 idList = [ node.get('id') for node in nodesJson ]
2222 return idList
2223
2224 except TypeError:
2225 main.log.exception( self.name + ": Object not as expected" )
2226 return None
2227 except pexpect.EOF:
2228 main.log.error( self.name + ": EOF exception found" )
2229 main.log.error( self.name + ": " + self.handle.before )
2230 main.cleanup()
2231 main.exit()
2232 except Exception:
2233 main.log.exception( self.name + ": Uncaught exception!" )
2234 main.cleanup()
2235 main.exit()
2236
2238 """
2239 Return the first device from the devices api whose 'id' contains 'dpid'
2240 Return None if there is no match
2241 """
2242 try:
2243 if dpid is None:
2244 return None
2245 else:
2246 dpid = dpid.replace( ':', '' )
2247 rawDevices = self.devices()
2248 devicesJson = json.loads( rawDevices )
2249
2250 for device in devicesJson:
2251
2252 if dpid in device[ 'id' ]:
2253 return device
2254 return None
2255 except TypeError:
2256 main.log.exception( self.name + ": Object not as expected" )
2257 return None
2258 except pexpect.EOF:
2259 main.log.error( self.name + ": EOF exception found" )
2260 main.log.error( self.name + ": " + self.handle.before )
2261 main.cleanup()
2262 main.exit()
2263 except Exception:
2264 main.log.exception( self.name + ": Uncaught exception!" )
2265 main.cleanup()
2266 main.exit()
2267
2268 - def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
2269 """
2270 Checks the number of switches & links that ONOS sees against the
2271 supplied values. By default this will report to main.log, but the
2272 log level can be specified.
2273
2274 Params: ip = ip used for the onos cli
2275 numoswitch = expected number of switches
2276 numolink = expected number of links
2277 logLevel = level to log to. Currently accepts
2278 'info', 'warn' and 'report'
2279
2280
2281 logLevel can
2282
2283 Returns: main.TRUE if the number of switches and links are correct,
2284 main.FALSE if the number of switches and links is incorrect,
2285 and main.ERROR otherwise
2286 """
2287 try:
2288 topology = self.getTopology( ip )
2289 if topology == {}:
2290 return main.ERROR
2291 output = ""
2292
2293 devices = topology.get( 'devices', False )
2294 links = topology.get( 'links', False )
2295 if devices is False or links is False:
2296 return main.ERROR
2297 switchCheck = ( int( devices ) == int( numoswitch ) )
2298
2299 linkCheck = ( int( links ) == int( numolink ) )
2300 if ( switchCheck and linkCheck ):
2301
2302 output += "The number of links and switches match " +\
2303 "what was expected"
2304 result = main.TRUE
2305 else:
2306 output += "The number of links and switches does not match " +\
2307 "what was expected"
2308 result = main.FALSE
2309 output = output + "\n ONOS sees %i devices (%i expected) \
2310 and %i links (%i expected)" % (
2311 int( devices ), int( numoswitch ), int( links ),
2312 int( numolink ) )
2313 if logLevel == "report":
2314 main.log.report( output )
2315 elif logLevel == "warn":
2316 main.log.warn( output )
2317 else:
2318 main.log.info( self.name + ": " + output )
2319 return result
2320 except TypeError:
2321 main.log.exception( self.name + ": Object not as expected" )
2322 return None
2323 except pexpect.EOF:
2324 main.log.error( self.name + ": EOF exception found" )
2325 main.log.error( self.name + ": " + self.handle.before )
2326 main.cleanup()
2327 main.exit()
2328 except Exception:
2329 main.log.exception( self.name + ": Uncaught exception!" )
2330 main.cleanup()
2331 main.exit()
2332
2333 - def deviceRole( self, deviceId, onosNode, role="master" ):
2334 """
2335 Calls the device-role cli command.
2336 deviceId must be the id of a device as seen in the onos devices command
2337 onosNode is the ip of one of the onos nodes in the cluster
2338 role must be either master, standby, or none
2339
2340 Returns:
2341 main.TRUE or main.FALSE based on argument verification and
2342 main.ERROR if command returns and error
2343 """
2344 try:
2345 if role.lower() == "master" or role.lower() == "standby" or\
2346 role.lower() == "none":
2347 cmdStr = "device-role " +\
2348 str( deviceId ) + " " +\
2349 str( onosNode ) + " " +\
2350 str( role )
2351 handle = self.sendline( cmdStr )
2352 if re.search( "Error", handle ):
2353
2354
2355 main.log.error( self.name + ": " +
2356 handle + '\033[0m' )
2357 return main.ERROR
2358 return main.TRUE
2359 else:
2360 main.log.error( "Invalid 'role' given to device_role(). " +
2361 "Value was '" + str(role) + "'." )
2362 return main.FALSE
2363 except TypeError:
2364 main.log.exception( self.name + ": Object not as expected" )
2365 return None
2366 except pexpect.EOF:
2367 main.log.error( self.name + ": EOF exception found" )
2368 main.log.error( self.name + ": " + self.handle.before )
2369 main.cleanup()
2370 main.exit()
2371 except Exception:
2372 main.log.exception( self.name + ": Uncaught exception!" )
2373 main.cleanup()
2374 main.exit()
2375
2376 - def clusters( self, jsonFormat=True ):
2377 """
2378 Lists all clusters
2379 Optional argument:
2380 * jsonFormat - boolean indicating if you want output in json
2381 """
2382 try:
2383 cmdStr = "clusters"
2384 if jsonFormat:
2385 cmdStr += " -j"
2386 handle = self.sendline( cmdStr )
2387 return handle
2388 except TypeError:
2389 main.log.exception( self.name + ": Object not as expected" )
2390 return None
2391 except pexpect.EOF:
2392 main.log.error( self.name + ": EOF exception found" )
2393 main.log.error( self.name + ": " + self.handle.before )
2394 main.cleanup()
2395 main.exit()
2396 except Exception:
2397 main.log.exception( self.name + ": Uncaught exception!" )
2398 main.cleanup()
2399 main.exit()
2400
2402 """
2403 CLI command to get the current leader for the Election test application
2404 NOTE: Requires installation of the onos-app-election feature
2405 Returns: Node IP of the leader if one exists
2406 None if none exists
2407 Main.FALSE on error
2408 """
2409 try:
2410 cmdStr = "election-test-leader"
2411 response = self.sendline( cmdStr )
2412
2413 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
2414 "app\sis\s(?P<node>.+)\."
2415 nodeSearch = re.search( leaderPattern, response )
2416 if nodeSearch:
2417 node = nodeSearch.group( 'node' )
2418 main.log.info( "Election-test-leader on " + str( self.name ) +
2419 " found " + node + " as the leader" )
2420 return node
2421
2422 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
2423 "the\sElection\sapp"
2424 nullSearch = re.search( nullPattern, response )
2425 if nullSearch:
2426 main.log.info( "Election-test-leader found no leader on " +
2427 self.name )
2428 return None
2429
2430 errorPattern = "Command\snot\sfound"
2431 if re.search( errorPattern, response ):
2432 main.log.error( "Election app is not loaded on " + self.name )
2433
2434 return main.FALSE
2435 else:
2436 main.log.error( "Error in electionTestLeader on " + self.name +
2437 ": " + "unexpected response" )
2438 main.log.error( repr( response ) )
2439 return main.FALSE
2440 except TypeError:
2441 main.log.exception( self.name + ": Object not as expected" )
2442 return main.FALSE
2443 except pexpect.EOF:
2444 main.log.error( self.name + ": EOF exception found" )
2445 main.log.error( self.name + ": " + self.handle.before )
2446 main.cleanup()
2447 main.exit()
2448 except Exception:
2449 main.log.exception( self.name + ": Uncaught exception!" )
2450 main.cleanup()
2451 main.exit()
2452
2454 """
2455 CLI command to run for leadership of the Election test application.
2456 NOTE: Requires installation of the onos-app-election feature
2457 Returns: Main.TRUE on success
2458 Main.FALSE on error
2459 """
2460 try:
2461 cmdStr = "election-test-run"
2462 response = self.sendline( cmdStr )
2463
2464 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
2465 "Election\sapp."
2466 search = re.search( successPattern, response )
2467 if search:
2468 main.log.info( self.name + " entering leadership elections " +
2469 "for the Election app." )
2470 return main.TRUE
2471
2472 errorPattern = "Command\snot\sfound"
2473 if re.search( errorPattern, response ):
2474 main.log.error( "Election app is not loaded on " + self.name )
2475 return main.FALSE
2476 else:
2477 main.log.error( "Error in electionTestRun on " + self.name +
2478 ": " + "unexpected response" )
2479 main.log.error( repr( response ) )
2480 return main.FALSE
2481 except TypeError:
2482 main.log.exception( self.name + ": Object not as expected" )
2483 return main.FALSE
2484 except pexpect.EOF:
2485 main.log.error( self.name + ": EOF exception found" )
2486 main.log.error( self.name + ": " + self.handle.before )
2487 main.cleanup()
2488 main.exit()
2489 except Exception:
2490 main.log.exception( self.name + ": Uncaught exception!" )
2491 main.cleanup()
2492 main.exit()
2493
2495 """
2496 * CLI command to withdraw the local node from leadership election for
2497 * the Election test application.
2498 #NOTE: Requires installation of the onos-app-election feature
2499 Returns: Main.TRUE on success
2500 Main.FALSE on error
2501 """
2502 try:
2503 cmdStr = "election-test-withdraw"
2504 response = self.sendline( cmdStr )
2505
2506 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
2507 "\sthe\sElection\sapp."
2508 if re.search( successPattern, response ):
2509 main.log.info( self.name + " withdrawing from leadership " +
2510 "elections for the Election app." )
2511 return main.TRUE
2512
2513 errorPattern = "Command\snot\sfound"
2514 if re.search( errorPattern, response ):
2515 main.log.error( "Election app is not loaded on " + self.name )
2516 return main.FALSE
2517 else:
2518 main.log.error( "Error in electionTestWithdraw on " +
2519 self.name + ": " + "unexpected response" )
2520 main.log.error( repr( response ) )
2521 return main.FALSE
2522 except TypeError:
2523 main.log.exception( self.name + ": Object not as expected" )
2524 return main.FALSE
2525 except pexpect.EOF:
2526 main.log.error( self.name + ": EOF exception found" )
2527 main.log.error( self.name + ": " + self.handle.before )
2528 main.cleanup()
2529 main.exit()
2530 except Exception:
2531 main.log.exception( self.name + ": Uncaught exception!" )
2532 main.cleanup()
2533 main.exit()
2534
2536 """
2537 Get the count of all enabled ports on a particular device/switch
2538 """
2539 try:
2540 dpid = str( dpid )
2541 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2542 output = self.sendline( cmdStr )
2543 if re.search( "No such device", output ):
2544 main.log.error( "Error in getting ports" )
2545 return ( output, "Error" )
2546 else:
2547 return output
2548 except TypeError:
2549 main.log.exception( self.name + ": Object not as expected" )
2550 return ( output, "Error" )
2551 except pexpect.EOF:
2552 main.log.error( self.name + ": EOF exception found" )
2553 main.log.error( self.name + ": " + self.handle.before )
2554 main.cleanup()
2555 main.exit()
2556 except Exception:
2557 main.log.exception( self.name + ": Uncaught exception!" )
2558 main.cleanup()
2559 main.exit()
2560
2562 """
2563 Get the count of all enabled ports on a particular device/switch
2564 """
2565 try:
2566 dpid = str( dpid )
2567 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2568 output = self.sendline( cmdStr )
2569 if re.search( "No such device", output ):
2570 main.log.error( "Error in getting ports " )
2571 return ( output, "Error " )
2572 else:
2573 return output
2574 except TypeError:
2575 main.log.exception( self.name + ": Object not as expected" )
2576 return ( output, "Error " )
2577 except pexpect.EOF:
2578 main.log.error( self.name + ": EOF exception found" )
2579 main.log.error( self.name + ": " + self.handle.before )
2580 main.cleanup()
2581 main.exit()
2582 except Exception:
2583 main.log.exception( self.name + ": Uncaught exception!" )
2584 main.cleanup()
2585 main.exit()
2586
2588 """
2589 Return a list of all Intent IDs
2590 """
2591 try:
2592 cmdStr = "onos:intents | grep id="
2593 output = self.sendline( cmdStr )
2594 if re.search( "Error", output ):
2595 main.log.error( "Error in getting ports" )
2596 return ( output, "Error" )
2597 else:
2598 return output
2599 except TypeError:
2600 main.log.exception( self.name + ": Object not as expected" )
2601 return ( output, "Error" )
2602 except pexpect.EOF:
2603 main.log.error( self.name + ": EOF exception found" )
2604 main.log.error( self.name + ": " + self.handle.before )
2605 main.cleanup()
2606 main.exit()
2607 except Exception:
2608 main.log.exception( self.name + ": Uncaught exception!" )
2609 main.cleanup()
2610 main.exit()
2611
2613 """
2614 Returns a dictionary containing the current intent states and the count
2615 """
2616 try:
2617 intents = self.intents( )
2618 states = []
2619 for intent in json.loads( intents ):
2620 states.append( intent.get( 'state', None ) )
2621 out = [ ( i, states.count( i ) ) for i in set( states ) ]
2622 main.log.info( dict( out ) )
2623 return dict( out )
2624 except TypeError:
2625 main.log.exception( self.name + ": Object not as expected" )
2626 return None
2627 except pexpect.EOF:
2628 main.log.error( self.name + ": EOF exception found" )
2629 main.log.error( self.name + ": " + self.handle.before )
2630 main.cleanup()
2631 main.exit()
2632 except Exception:
2633 main.log.exception( self.name + ": Uncaught exception!" )
2634 main.cleanup()
2635 main.exit()
2636
2637 - def leaders( self, jsonFormat=True ):
2638 """
2639 Returns the output of the leaders command.
2640 Optional argument:
2641 * jsonFormat - boolean indicating if you want output in json
2642 """
2643 try:
2644 cmdStr = "onos:leaders"
2645 if jsonFormat:
2646 cmdStr += " -j"
2647 output = self.sendline( cmdStr )
2648 return output
2649 except TypeError:
2650 main.log.exception( self.name + ": Object not as expected" )
2651 return None
2652 except pexpect.EOF:
2653 main.log.error( self.name + ": EOF exception found" )
2654 main.log.error( self.name + ": " + self.handle.before )
2655 main.cleanup()
2656 main.exit()
2657 except Exception:
2658 main.log.exception( self.name + ": Uncaught exception!" )
2659 main.cleanup()
2660 main.exit()
2661
2663 """
2664 Returns the output of the leaders -c command.
2665 Optional argument:
2666 * jsonFormat - boolean indicating if you want output in json
2667 """
2668 try:
2669 cmdStr = "onos:leaders -c"
2670 if jsonFormat:
2671 cmdStr += " -j"
2672 output = self.sendline( cmdStr )
2673 return output
2674 except TypeError:
2675 main.log.exception( self.name + ": Object not as expected" )
2676 return None
2677 except pexpect.EOF:
2678 main.log.error( self.name + ": EOF exception found" )
2679 main.log.error( self.name + ": " + self.handle.before )
2680 main.cleanup()
2681 main.exit()
2682 except Exception:
2683 main.log.exception( self.name + ": Uncaught exception!" )
2684 main.cleanup()
2685 main.exit()
2686
2688 """
2689 Returns a list in format [leader,candidate1,candidate2,...] for a given
2690 topic parameter and an empty list if the topic doesn't exist
2691 If no leader is elected leader in the returned list will be "none"
2692 Returns None if there is a type error processing the json object
2693 """
2694 try:
2695 cmdStr = "onos:leaders -c -j"
2696 output = self.sendline( cmdStr )
2697 output = json.loads(output)
2698 results = []
2699 for dict in output:
2700 if dict["topic"] == topic:
2701 leader = dict["leader"]
2702 candidates = re.split(", ",dict["candidates"][1:-1])
2703 results.append(leader)
2704 results.extend(candidates)
2705 return results
2706 except TypeError:
2707 main.log.exception( self.name + ": Object not as expected" )
2708 return None
2709 except pexpect.EOF:
2710 main.log.error( self.name + ": EOF exception found" )
2711 main.log.error( self.name + ": " + self.handle.before )
2712 main.cleanup()
2713 main.exit()
2714 except Exception:
2715 main.log.exception( self.name + ": Uncaught exception!" )
2716 main.cleanup()
2717 main.exit()
2718
2720 """
2721 Returns the output of the intent Pending map.
2722 """
2723 try:
2724 cmdStr = "onos:intents -p"
2725 if jsonFormat:
2726 cmdStr += " -j"
2727 output = self.sendline( cmdStr )
2728 return output
2729 except TypeError:
2730 main.log.exception( self.name + ": Object not as expected" )
2731 return None
2732 except pexpect.EOF:
2733 main.log.error( self.name + ": EOF exception found" )
2734 main.log.error( self.name + ": " + self.handle.before )
2735 main.cleanup()
2736 main.exit()
2737 except Exception:
2738 main.log.exception( self.name + ": Uncaught exception!" )
2739 main.cleanup()
2740 main.exit()
2741
2743 """
2744 Returns the output of the raft partitions command for ONOS.
2745 """
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757 try:
2758 cmdStr = "onos:partitions"
2759 if jsonFormat:
2760 cmdStr += " -j"
2761 output = self.sendline( cmdStr )
2762 return output
2763 except TypeError:
2764 main.log.exception( self.name + ": Object not as expected" )
2765 return None
2766 except pexpect.EOF:
2767 main.log.error( self.name + ": EOF exception found" )
2768 main.log.error( self.name + ": " + self.handle.before )
2769 main.cleanup()
2770 main.exit()
2771 except Exception:
2772 main.log.exception( self.name + ": Uncaught exception!" )
2773 main.cleanup()
2774 main.exit()
2775
2776 - def apps( self, jsonFormat=True ):
2777 """
2778 Returns the output of the apps command for ONOS. This command lists
2779 information about installed ONOS applications
2780 """
2781
2782
2783
2784
2785
2786 try:
2787 cmdStr = "onos:apps"
2788 if jsonFormat:
2789 cmdStr += " -j"
2790 output = self.sendline( cmdStr )
2791 assert "Error executing command" not in output
2792 return output
2793
2794 except AssertionError:
2795 main.log.error( "Error in processing onos:app command: " +
2796 str( output ) )
2797 return None
2798 except TypeError:
2799 main.log.exception( self.name + ": Object not as expected" )
2800 return None
2801 except pexpect.EOF:
2802 main.log.error( self.name + ": EOF exception found" )
2803 main.log.error( self.name + ": " + self.handle.before )
2804 main.cleanup()
2805 main.exit()
2806 except Exception:
2807 main.log.exception( self.name + ": Uncaught exception!" )
2808 main.cleanup()
2809 main.exit()
2810
2812 """
2813 Uses the onos:apps cli command to return the status of an application.
2814 Returns:
2815 "ACTIVE" - If app is installed and activated
2816 "INSTALLED" - If app is installed and deactivated
2817 "UNINSTALLED" - If app is not installed
2818 None - on error
2819 """
2820 try:
2821 if not isinstance( appName, types.StringType ):
2822 main.log.error( self.name + ".appStatus(): appName must be" +
2823 " a string" )
2824 return None
2825 output = self.apps( jsonFormat=True )
2826 appsJson = json.loads( output )
2827 state = None
2828 for app in appsJson:
2829 if appName == app.get('name'):
2830 state = app.get('state')
2831 break
2832 if state == "ACTIVE" or state == "INSTALLED":
2833 return state
2834 elif state is None:
2835 return "UNINSTALLED"
2836 elif state:
2837 main.log.error( "Unexpected state from 'onos:apps': " +
2838 str( state ) )
2839 return state
2840 except TypeError:
2841 main.log.exception( self.name + ": Object not as expected" )
2842 return None
2843 except pexpect.EOF:
2844 main.log.error( self.name + ": EOF exception found" )
2845 main.log.error( self.name + ": " + self.handle.before )
2846 main.cleanup()
2847 main.exit()
2848 except Exception:
2849 main.log.exception( self.name + ": Uncaught exception!" )
2850 main.cleanup()
2851 main.exit()
2852
2853 - def app( self, appName, option ):
2854 """
2855 Interacts with the app command for ONOS. This command manages
2856 application inventory.
2857 """
2858 try:
2859
2860 valid = True
2861 if not isinstance( appName, types.StringType ):
2862 main.log.error( self.name + ".app(): appName must be a " +
2863 "string" )
2864 valid = False
2865 if not isinstance( option, types.StringType ):
2866 main.log.error( self.name + ".app(): option must be a string" )
2867 valid = False
2868 if not valid:
2869 return main.FALSE
2870
2871 option = option.lower()
2872
2873 if option == "activate":
2874 pass
2875 elif option == "deactivate":
2876 pass
2877 elif option == "uninstall":
2878 pass
2879 else:
2880
2881 main.log.error( "The ONOS app command argument only takes " +
2882 "the values: (activate|deactivate|uninstall)" +
2883 "; was given '" + option + "'")
2884 return main.FALSE
2885 cmdStr = "onos:app " + option + " " + appName
2886 output = self.sendline( cmdStr )
2887 if "Error executing command" in output:
2888 main.log.error( "Error in processing onos:app command: " +
2889 str( output ) )
2890 return main.FALSE
2891 elif "No such application" in output:
2892 main.log.error( "The application '" + appName +
2893 "' is not installed in ONOS" )
2894 return main.FALSE
2895 elif "Command not found:" in output:
2896 main.log.error( "Error in processing onos:app command: " +
2897 str( output ) )
2898 return main.FALSE
2899 elif "Unsupported command:" in output:
2900 main.log.error( "Incorrect command given to 'app': " +
2901 str( output ) )
2902
2903
2904
2905 return main.TRUE
2906 except TypeError:
2907 main.log.exception( self.name + ": Object not as expected" )
2908 return main.ERROR
2909 except pexpect.EOF:
2910 main.log.error( self.name + ": EOF exception found" )
2911 main.log.error( self.name + ": " + self.handle.before )
2912 main.cleanup()
2913 main.exit()
2914 except Exception:
2915 main.log.exception( self.name + ": Uncaught exception!" )
2916 main.cleanup()
2917 main.exit()
2918
2920 """
2921 Activate an app that is already installed in ONOS
2922 appName is the hierarchical app name, not the feature name
2923 If check is True, method will check the status of the app after the
2924 command is issued
2925 Returns main.TRUE if the command was successfully sent
2926 main.FALSE if the cli responded with an error or given
2927 incorrect input
2928 """
2929 try:
2930 if not isinstance( appName, types.StringType ):
2931 main.log.error( self.name + ".activateApp(): appName must be" +
2932 " a string" )
2933 return main.FALSE
2934 status = self.appStatus( appName )
2935 if status == "INSTALLED":
2936 response = self.app( appName, "activate" )
2937 if check and response == main.TRUE:
2938 for i in range(10):
2939
2940 status = self.appStatus( appName )
2941 if status == "ACTIVE":
2942 return main.TRUE
2943 else:
2944 main.log.debug( "The state of application " +
2945 appName + " is " + status )
2946 time.sleep( 1 )
2947 return main.FALSE
2948 else:
2949 return response
2950 elif status == "ACTIVE":
2951 return main.TRUE
2952 elif status == "UNINSTALLED":
2953 main.log.error( self.name + ": Tried to activate the " +
2954 "application '" + appName + "' which is not " +
2955 "installed." )
2956 else:
2957 main.log.error( "Unexpected return value from appStatus: " +
2958 str( status ) )
2959 return main.ERROR
2960 except TypeError:
2961 main.log.exception( self.name + ": Object not as expected" )
2962 return main.ERROR
2963 except pexpect.EOF:
2964 main.log.error( self.name + ": EOF exception found" )
2965 main.log.error( self.name + ": " + self.handle.before )
2966 main.cleanup()
2967 main.exit()
2968 except Exception:
2969 main.log.exception( self.name + ": Uncaught exception!" )
2970 main.cleanup()
2971 main.exit()
2972
2974 """
2975 Deactivate an app that is already activated in ONOS
2976 appName is the hierarchical app name, not the feature name
2977 If check is True, method will check the status of the app after the
2978 command is issued
2979 Returns main.TRUE if the command was successfully sent
2980 main.FALSE if the cli responded with an error or given
2981 incorrect input
2982 """
2983 try:
2984 if not isinstance( appName, types.StringType ):
2985 main.log.error( self.name + ".deactivateApp(): appName must " +
2986 "be a string" )
2987 return main.FALSE
2988 status = self.appStatus( appName )
2989 if status == "INSTALLED":
2990 return main.TRUE
2991 elif status == "ACTIVE":
2992 response = self.app( appName, "deactivate" )
2993 if check and response == main.TRUE:
2994 for i in range(10):
2995 status = self.appStatus( appName )
2996 if status == "INSTALLED":
2997 return main.TRUE
2998 else:
2999 time.sleep( 1 )
3000 return main.FALSE
3001 else:
3002 return response
3003 elif status == "UNINSTALLED":
3004 main.log.warn( self.name + ": Tried to deactivate the " +
3005 "application '" + appName + "' which is not " +
3006 "installed." )
3007 return main.TRUE
3008 else:
3009 main.log.error( "Unexpected return value from appStatus: " +
3010 str( status ) )
3011 return main.ERROR
3012 except TypeError:
3013 main.log.exception( self.name + ": Object not as expected" )
3014 return main.ERROR
3015 except pexpect.EOF:
3016 main.log.error( self.name + ": EOF exception found" )
3017 main.log.error( self.name + ": " + self.handle.before )
3018 main.cleanup()
3019 main.exit()
3020 except Exception:
3021 main.log.exception( self.name + ": Uncaught exception!" )
3022 main.cleanup()
3023 main.exit()
3024
3026 """
3027 Uninstall an app that is already installed in ONOS
3028 appName is the hierarchical app name, not the feature name
3029 If check is True, method will check the status of the app after the
3030 command is issued
3031 Returns main.TRUE if the command was successfully sent
3032 main.FALSE if the cli responded with an error or given
3033 incorrect input
3034 """
3035
3036 try:
3037 if not isinstance( appName, types.StringType ):
3038 main.log.error( self.name + ".uninstallApp(): appName must " +
3039 "be a string" )
3040 return main.FALSE
3041 status = self.appStatus( appName )
3042 if status == "INSTALLED":
3043 response = self.app( appName, "uninstall" )
3044 if check and response == main.TRUE:
3045 for i in range(10):
3046 status = self.appStatus( appName )
3047 if status == "UNINSTALLED":
3048 return main.TRUE
3049 else:
3050 time.sleep( 1 )
3051 return main.FALSE
3052 else:
3053 return response
3054 elif status == "ACTIVE":
3055 main.log.warn( self.name + ": Tried to uninstall the " +
3056 "application '" + appName + "' which is " +
3057 "currently active." )
3058 response = self.app( appName, "uninstall" )
3059 if check and response == main.TRUE:
3060 for i in range(10):
3061 status = self.appStatus( appName )
3062 if status == "UNINSTALLED":
3063 return main.TRUE
3064 else:
3065 time.sleep( 1 )
3066 return main.FALSE
3067 else:
3068 return response
3069 elif status == "UNINSTALLED":
3070 return main.TRUE
3071 else:
3072 main.log.error( "Unexpected return value from appStatus: " +
3073 str( status ) )
3074 return main.ERROR
3075 except TypeError:
3076 main.log.exception( self.name + ": Object not as expected" )
3077 return main.ERROR
3078 except pexpect.EOF:
3079 main.log.error( self.name + ": EOF exception found" )
3080 main.log.error( self.name + ": " + self.handle.before )
3081 main.cleanup()
3082 main.exit()
3083 except Exception:
3084 main.log.exception( self.name + ": Uncaught exception!" )
3085 main.cleanup()
3086 main.exit()
3087
3088 - def appIDs( self, jsonFormat=True ):
3089 """
3090 Show the mappings between app id and app names given by the 'app-ids'
3091 cli command
3092 """
3093 try:
3094 cmdStr = "app-ids"
3095 if jsonFormat:
3096 cmdStr += " -j"
3097 output = self.sendline( cmdStr )
3098 assert "Error executing command" not in output
3099 return output
3100 except AssertionError:
3101 main.log.error( "Error in processing onos:app-ids command: " +
3102 str( output ) )
3103 return None
3104 except TypeError:
3105 main.log.exception( self.name + ": Object not as expected" )
3106 return None
3107 except pexpect.EOF:
3108 main.log.error( self.name + ": EOF exception found" )
3109 main.log.error( self.name + ": " + self.handle.before )
3110 main.cleanup()
3111 main.exit()
3112 except Exception:
3113 main.log.exception( self.name + ": Uncaught exception!" )
3114 main.cleanup()
3115 main.exit()
3116
3118 """
3119 This method will check that each application's ID listed in 'apps' is
3120 the same as the ID listed in 'app-ids'. The check will also check that
3121 there are no duplicate IDs issued. Note that an app ID should be
3122 a globaly unique numerical identifier for app/app-like features. Once
3123 an ID is registered, the ID is never freed up so that if an app is
3124 reinstalled it will have the same ID.
3125
3126 Returns: main.TRUE if the check passes and
3127 main.FALSE if the check fails or
3128 main.ERROR if there is some error in processing the test
3129 """
3130 try:
3131 bail = False
3132 ids = self.appIDs( jsonFormat=True )
3133 if ids:
3134 ids = json.loads( ids )
3135 else:
3136 main.log.error( "app-ids returned nothing:" + repr( ids ) )
3137 bail = True
3138 apps = self.apps( jsonFormat=True )
3139 if apps:
3140 apps = json.loads( apps )
3141 else:
3142 main.log.error( "apps returned nothing:" + repr( apps ) )
3143 bail = True
3144 if bail:
3145 return main.FALSE
3146 result = main.TRUE
3147 for app in apps:
3148 appID = app.get( 'id' )
3149 if appID is None:
3150 main.log.error( "Error parsing app: " + str( app ) )
3151 result = main.FALSE
3152 appName = app.get( 'name' )
3153 if appName is None:
3154 main.log.error( "Error parsing app: " + str( app ) )
3155 result = main.FALSE
3156
3157 current = filter( lambda item: item[ 'id' ] == appID, ids )
3158
3159
3160 if not current:
3161 result = main.FALSE
3162 main.log.error( "'app-ids' does not have the ID for " +
3163 str( appName ) + " that apps does." )
3164 elif len( current ) > 1:
3165
3166 result = main.FALSE
3167
3168 elif not current[0][ 'name' ] == appName:
3169 currentName = current[0][ 'name' ]
3170 result = main.FALSE
3171 main.log.error( "'app-ids' has " + str( currentName ) +
3172 " registered under id:" + str( appID ) +
3173 " but 'apps' has " + str( appName ) )
3174 else:
3175 pass
3176
3177 idsList = []
3178 namesList = []
3179 for item in ids:
3180 idsList.append( item[ 'id' ] )
3181 namesList.append( item[ 'name' ] )
3182 if len( idsList ) != len( set( idsList ) ) or\
3183 len( namesList ) != len( set( namesList ) ):
3184 main.log.error( "'app-ids' has some duplicate entries: \n"
3185 + json.dumps( ids,
3186 sort_keys=True,
3187 indent=4,
3188 separators=( ',', ': ' ) ) )
3189 result = main.FALSE
3190 return result
3191 except ( ValueError, TypeError ):
3192 main.log.exception( self.name + ": Object not as expected" )
3193 return main.ERROR
3194 except pexpect.EOF:
3195 main.log.error( self.name + ": EOF exception found" )
3196 main.log.error( self.name + ": " + self.handle.before )
3197 main.cleanup()
3198 main.exit()
3199 except Exception:
3200 main.log.exception( self.name + ": Uncaught exception!" )
3201 main.cleanup()
3202 main.exit()
3203
3204 - def getCfg( self, component=None, propName=None, short=False,
3205 jsonFormat=True ):
3206 """
3207 Get configuration settings from onos cli
3208 Optional arguments:
3209 component - Optionally only list configurations for a specific
3210 component. If None, all components with configurations
3211 are displayed. Case Sensitive string.
3212 propName - If component is specified, propName option will show
3213 only this specific configuration from that component.
3214 Case Sensitive string.
3215 jsonFormat - Returns output as json. Note that this will override
3216 the short option
3217 short - Short, less verbose, version of configurations.
3218 This is overridden by the json option
3219 returns:
3220 Output from cli as a string or None on error
3221 """
3222 try:
3223 baseStr = "cfg"
3224 cmdStr = " get"
3225 componentStr = ""
3226 if component:
3227 componentStr += " " + component
3228 if propName:
3229 componentStr += " " + propName
3230 if jsonFormat:
3231 baseStr += " -j"
3232 elif short:
3233 baseStr += " -s"
3234 output = self.sendline( baseStr + cmdStr + componentStr )
3235 assert "Error executing command" not in output
3236 return output
3237 except AssertionError:
3238 main.log.error( "Error in processing 'cfg get' command: " +
3239 str( output ) )
3240 return None
3241 except TypeError:
3242 main.log.exception( self.name + ": Object not as expected" )
3243 return None
3244 except pexpect.EOF:
3245 main.log.error( self.name + ": EOF exception found" )
3246 main.log.error( self.name + ": " + self.handle.before )
3247 main.cleanup()
3248 main.exit()
3249 except Exception:
3250 main.log.exception( self.name + ": Uncaught exception!" )
3251 main.cleanup()
3252 main.exit()
3253
3254 - def setCfg( self, component, propName, value=None, check=True ):
3255 """
3256 Set/Unset configuration settings from ONOS cli
3257 Required arguments:
3258 component - The case sensitive name of the component whose
3259 property is to be set
3260 propName - The case sensitive name of the property to be set/unset
3261 Optional arguments:
3262 value - The value to set the property to. If None, will unset the
3263 property and revert it to it's default value(if applicable)
3264 check - Boolean, Check whether the option was successfully set this
3265 only applies when a value is given.
3266 returns:
3267 main.TRUE on success or main.FALSE on failure. If check is False,
3268 will return main.TRUE unless there is an error
3269 """
3270 try:
3271 baseStr = "cfg"
3272 cmdStr = " set " + str( component ) + " " + str( propName )
3273 if value is not None:
3274 cmdStr += " " + str( value )
3275 output = self.sendline( baseStr + cmdStr )
3276 assert "Error executing command" not in output
3277 if value and check:
3278 results = self.getCfg( component=str( component ),
3279 propName=str( propName ),
3280 jsonFormat=True )
3281
3282 try:
3283 jsonOutput = json.loads( results )
3284 current = jsonOutput[ 'value' ]
3285 except ( ValueError, TypeError ):
3286 main.log.exception( "Error parsing cfg output" )
3287 main.log.error( "output:" + repr( results ) )
3288 return main.FALSE
3289 if current == str( value ):
3290 return main.TRUE
3291 return main.FALSE
3292 return main.TRUE
3293 except AssertionError:
3294 main.log.error( "Error in processing 'cfg set' command: " +
3295 str( output ) )
3296 return main.FALSE
3297 except TypeError:
3298 main.log.exception( self.name + ": Object not as expected" )
3299 return main.FALSE
3300 except pexpect.EOF:
3301 main.log.error( self.name + ": EOF exception found" )
3302 main.log.error( self.name + ": " + self.handle.before )
3303 main.cleanup()
3304 main.exit()
3305 except Exception:
3306 main.log.exception( self.name + ": Uncaught exception!" )
3307 main.cleanup()
3308 main.exit()
3309
3311 """
3312 CLI command to add elements to a distributed set.
3313 Arguments:
3314 setName - The name of the set to add to.
3315 values - The value(s) to add to the set, space seperated.
3316 Example usages:
3317 setTestAdd( "set1", "a b c" )
3318 setTestAdd( "set2", "1" )
3319 returns:
3320 main.TRUE on success OR
3321 main.FALSE if elements were already in the set OR
3322 main.ERROR on error
3323 """
3324 try:
3325 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3326 output = self.sendline( cmdStr )
3327 try:
3328
3329
3330 assert "org.onosproject.store.service" not in output
3331
3332 assert "java.lang.IllegalStateException" not in output
3333 except AssertionError:
3334 main.log.error( "Error in processing '" + cmdStr + "' " +
3335 "command: " + str( output ) )
3336 retryTime = 30
3337 main.log.info( "Waiting " + str( retryTime ) +
3338 "seconds before retrying." )
3339 time.sleep( retryTime )
3340 output = self.sendline( cmdStr )
3341 assert "Error executing command" not in output
3342 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3343 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3344 main.log.info( self.name + ": " + output )
3345 if re.search( positiveMatch, output):
3346 return main.TRUE
3347 elif re.search( negativeMatch, output):
3348 return main.FALSE
3349 else:
3350 main.log.error( self.name + ": setTestAdd did not" +
3351 " match expected output" )
3352 main.log.debug( self.name + " actual: " + repr( output ) )
3353 return main.ERROR
3354 except AssertionError:
3355 main.log.error( "Error in processing '" + cmdStr + "' command: " +
3356 str( output ) )
3357 return main.ERROR
3358 except TypeError:
3359 main.log.exception( self.name + ": Object not as expected" )
3360 return main.ERROR
3361 except pexpect.EOF:
3362 main.log.error( self.name + ": EOF exception found" )
3363 main.log.error( self.name + ": " + self.handle.before )
3364 main.cleanup()
3365 main.exit()
3366 except Exception:
3367 main.log.exception( self.name + ": Uncaught exception!" )
3368 main.cleanup()
3369 main.exit()
3370
3371 - def setTestRemove( self, setName, values, clear=False, retain=False ):
3372 """
3373 CLI command to remove elements from a distributed set.
3374 Required arguments:
3375 setName - The name of the set to remove from.
3376 values - The value(s) to remove from the set, space seperated.
3377 Optional arguments:
3378 clear - Clear all elements from the set
3379 retain - Retain only the given values. (intersection of the
3380 original set and the given set)
3381 returns:
3382 main.TRUE on success OR
3383 main.FALSE if the set was not changed OR
3384 main.ERROR on error
3385 """
3386 try:
3387 cmdStr = "set-test-remove "
3388 if clear:
3389 cmdStr += "-c " + str( setName )
3390 elif retain:
3391 cmdStr += "-r " + str( setName ) + " " + str( values )
3392 else:
3393 cmdStr += str( setName ) + " " + str( values )
3394 output = self.sendline( cmdStr )
3395 try:
3396
3397
3398 assert "org.onosproject.store.service" not in output
3399
3400 assert "java.lang.IllegalStateException" not in output
3401 except AssertionError:
3402 main.log.error( "Error in processing '" + cmdStr + "' " +
3403 "command: " + str( output ) )
3404 retryTime = 30
3405 main.log.info( "Waiting " + str( retryTime ) +
3406 "seconds before retrying." )
3407 time.sleep( retryTime )
3408 output = self.sendline( cmdStr )
3409 assert "Error executing command" not in output
3410 main.log.info( self.name + ": " + output )
3411 if clear:
3412 pattern = "Set " + str( setName ) + " cleared"
3413 if re.search( pattern, output ):
3414 return main.TRUE
3415 elif retain:
3416 positivePattern = str( setName ) + " was pruned to contain " +\
3417 "only elements of set \[(.*)\]"
3418 negativePattern = str( setName ) + " was not changed by " +\
3419 "retaining only elements of the set " +\
3420 "\[(.*)\]"
3421 if re.search( positivePattern, output ):
3422 return main.TRUE
3423 elif re.search( negativePattern, output ):
3424 return main.FALSE
3425 else:
3426 positivePattern = "\[(.*)\] was removed from the set " +\
3427 str( setName )
3428 if ( len( values.split() ) == 1 ):
3429 negativePattern = "\[(.*)\] was not in set " +\
3430 str( setName )
3431 else:
3432 negativePattern = "No element of \[(.*)\] was in set " +\
3433 str( setName )
3434 if re.search( positivePattern, output ):
3435 return main.TRUE
3436 elif re.search( negativePattern, output ):
3437 return main.FALSE
3438 main.log.error( self.name + ": setTestRemove did not" +
3439 " match expected output" )
3440 main.log.debug( self.name + " expected: " + pattern )
3441 main.log.debug( self.name + " actual: " + repr( output ) )
3442 return main.ERROR
3443 except AssertionError:
3444 main.log.error( "Error in processing '" + cmdStr + "' command: " +
3445 str( output ) )
3446 return main.ERROR
3447 except TypeError:
3448 main.log.exception( self.name + ": Object not as expected" )
3449 return main.ERROR
3450 except pexpect.EOF:
3451 main.log.error( self.name + ": EOF exception found" )
3452 main.log.error( self.name + ": " + self.handle.before )
3453 main.cleanup()
3454 main.exit()
3455 except Exception:
3456 main.log.exception( self.name + ": Uncaught exception!" )
3457 main.cleanup()
3458 main.exit()
3459
3461 """
3462 CLI command to get the elements in a distributed set.
3463 Required arguments:
3464 setName - The name of the set to remove from.
3465 Optional arguments:
3466 values - The value(s) to check if in the set, space seperated.
3467 returns:
3468 main.ERROR on error OR
3469 A list of elements in the set if no optional arguments are
3470 supplied OR
3471 A tuple containing the list then:
3472 main.FALSE if the given values are not in the set OR
3473 main.TRUE if the given values are in the set OR
3474 """
3475 try:
3476 values = str( values ).strip()
3477 setName = str( setName ).strip()
3478 length = len( values.split() )
3479 containsCheck = None
3480
3481 setPattern = "\[(.*)\]"
3482 pattern = "Items in set " + setName + ":\n" + setPattern
3483 containsTrue = "Set " + setName + " contains the value " + values
3484 containsFalse = "Set " + setName + " did not contain the value " +\
3485 values
3486 containsAllTrue = "Set " + setName + " contains the the subset " +\
3487 setPattern
3488 containsAllFalse = "Set " + setName + " did not contain the the" +\
3489 " subset " + setPattern
3490
3491 cmdStr = "set-test-get "
3492 cmdStr += setName + " " + values
3493 output = self.sendline( cmdStr )
3494 try:
3495
3496
3497 assert "org.onosproject.store.service" not in output
3498
3499 assert "java.lang.IllegalStateException" not in output
3500 except AssertionError:
3501 main.log.error( "Error in processing '" + cmdStr + "' " +
3502 "command: " + str( output ) )
3503 retryTime = 30
3504 main.log.info( "Waiting " + str( retryTime ) +
3505 "seconds before retrying." )
3506 time.sleep( retryTime )
3507 output = self.sendline( cmdStr )
3508 assert "Error executing command" not in output
3509 main.log.info( self.name + ": " + output )
3510
3511 if length == 0:
3512 match = re.search( pattern, output )
3513 else:
3514 if length == 1:
3515 patternTrue = pattern + "\n" + containsTrue
3516 patternFalse = pattern + "\n" + containsFalse
3517 else:
3518 patternTrue = pattern + "\n" + containsAllTrue
3519 patternFalse = pattern + "\n" + containsAllFalse
3520 matchTrue = re.search( patternTrue, output )
3521 matchFalse = re.search( patternFalse, output )
3522 if matchTrue:
3523 containsCheck = main.TRUE
3524 match = matchTrue
3525 elif matchFalse:
3526 containsCheck = main.FALSE
3527 match = matchFalse
3528 else:
3529 main.log.error( self.name + " setTestGet did not match " +\
3530 "expected output" )
3531 main.log.debug( self.name + " expected: " + pattern )
3532 main.log.debug( self.name + " actual: " + repr( output ) )
3533 match = None
3534 if match:
3535 setMatch = match.group( 1 )
3536 if setMatch == '':
3537 setList = []
3538 else:
3539 setList = setMatch.split( ", " )
3540 if length > 0:
3541 return ( setList, containsCheck )
3542 else:
3543 return setList
3544 else:
3545 main.log.error( self.name + ": setTestGet did not" +
3546 " match expected output" )
3547 main.log.debug( self.name + " expected: " + pattern )
3548 main.log.debug( self.name + " actual: " + repr( output ) )
3549 return main.ERROR
3550 except AssertionError:
3551 main.log.error( "Error in processing '" + cmdStr + "' command: " +
3552 str( output ) )
3553 return main.ERROR
3554 except TypeError:
3555 main.log.exception( self.name + ": Object not as expected" )
3556 return main.ERROR
3557 except pexpect.EOF:
3558 main.log.error( self.name + ": EOF exception found" )
3559 main.log.error( self.name + ": " + self.handle.before )
3560 main.cleanup()
3561 main.exit()
3562 except Exception:
3563 main.log.exception( self.name + ": Uncaught exception!" )
3564 main.cleanup()
3565 main.exit()
3566
3568 """
3569 CLI command to get the elements in a distributed set.
3570 Required arguments:
3571 setName - The name of the set to remove from.
3572 returns:
3573 The integer value of the size returned or
3574 None on error
3575 """
3576 try:
3577
3578
3579 setName = str( setName ).strip()
3580
3581 setPattern = "\[(.*)\]"
3582 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3583 setPattern
3584 cmdStr = "set-test-get -s "
3585 cmdStr += setName
3586 output = self.sendline( cmdStr )
3587 try:
3588
3589
3590 assert "org.onosproject.store.service" not in output
3591
3592 assert "java.lang.IllegalStateException" not in output
3593 except AssertionError:
3594 main.log.error( "Error in processing '" + cmdStr + "' " +
3595 "command: " + str( output ) )
3596 retryTime = 30
3597 main.log.info( "Waiting " + str( retryTime ) +
3598 "seconds before retrying." )
3599 time.sleep( retryTime )
3600 output = self.sendline( cmdStr )
3601 assert "Error executing command" not in output
3602 main.log.info( self.name + ": " + output )
3603 match = re.search( pattern, output )
3604 if match:
3605 setSize = int( match.group( 1 ) )
3606 setMatch = match.group( 2 )
3607 if len( setMatch.split() ) == setSize:
3608 main.log.info( "The size returned by " + self.name +
3609 " matches the number of elements in " +
3610 "the returned set" )
3611 else:
3612 main.log.error( "The size returned by " + self.name +
3613 " does not match the number of " +
3614 "elements in the returned set." )
3615 return setSize
3616 else:
3617 main.log.error( self.name + ": setTestGet did not" +
3618 " match expected output" )
3619 main.log.debug( self.name + " expected: " + pattern )
3620 main.log.debug( self.name + " actual: " + repr( output ) )
3621 return None
3622 except AssertionError:
3623 main.log.error( "Error in processing '" + cmdStr + "' command: " +
3624 str( output ) )
3625 return None
3626 except TypeError:
3627 main.log.exception( self.name + ": Object not as expected" )
3628 return None
3629 except pexpect.EOF:
3630 main.log.error( self.name + ": EOF exception found" )
3631 main.log.error( self.name + ": " + self.handle.before )
3632 main.cleanup()
3633 main.exit()
3634 except Exception:
3635 main.log.exception( self.name + ": Uncaught exception!" )
3636 main.cleanup()
3637 main.exit()
3638
3639 - def counters( self, jsonFormat=True ):
3640 """
3641 Command to list the various counters in the system.
3642 returns:
3643 if jsonFormat, a string of the json object returned by the cli
3644 command
3645 if not jsonFormat, the normal string output of the cli command
3646 None on error
3647 """
3648 try:
3649 counters = {}
3650 cmdStr = "counters"
3651 if jsonFormat:
3652 cmdStr += " -j"
3653 output = self.sendline( cmdStr )
3654 assert "Error executing command" not in output
3655 main.log.info( self.name + ": " + output )
3656 return output
3657 except AssertionError:
3658 main.log.error( "Error in processing 'counters' command: " +
3659 str( output ) )
3660 return None
3661 except TypeError:
3662 main.log.exception( self.name + ": Object not as expected" )
3663 return None
3664 except pexpect.EOF:
3665 main.log.error( self.name + ": EOF exception found" )
3666 main.log.error( self.name + ": " + self.handle.before )
3667 main.cleanup()
3668 main.exit()
3669 except Exception:
3670 main.log.exception( self.name + ": Uncaught exception!" )
3671 main.cleanup()
3672 main.exit()
3673
3675 """
3676 CLI command to add a delta to then get a distributed counter.
3677 Required arguments:
3678 counter - The name of the counter to increment.
3679 Optional arguments:
3680 delta - The long to add to the counter
3681 inMemory - use in memory map for the counter
3682 returns:
3683 integer value of the counter or
3684 None on Error
3685 """
3686 try:
3687 counter = str( counter )
3688 delta = int( delta )
3689 cmdStr = "counter-test-increment "
3690 if inMemory:
3691 cmdStr += "-i "
3692 cmdStr += counter
3693 if delta != 1:
3694 cmdStr += " " + str( delta )
3695 output = self.sendline( cmdStr )
3696 try:
3697
3698
3699 assert "org.onosproject.store.service" not in output
3700
3701 assert "java.lang.IllegalStateException" not in output
3702 except AssertionError:
3703 main.log.error( "Error in processing '" + cmdStr + "' " +
3704 "command: " + str( output ) )
3705 retryTime = 30
3706 main.log.info( "Waiting " + str( retryTime ) +
3707 "seconds before retrying." )
3708 time.sleep( retryTime )
3709 output = self.sendline( cmdStr )
3710 assert "Error executing command" not in output
3711 main.log.info( self.name + ": " + output )
3712 pattern = counter + " was updated to (-?\d+)"
3713 match = re.search( pattern, output )
3714 if match:
3715 return int( match.group( 1 ) )
3716 else:
3717 main.log.error( self.name + ": counterTestAddAndGet did not" +
3718 " match expected output." )
3719 main.log.debug( self.name + " expected: " + pattern )
3720 main.log.debug( self.name + " actual: " + repr( output ) )
3721 return None
3722 except AssertionError:
3723 main.log.error( "Error in processing '" + cmdStr + "'" +
3724 " command: " + str( output ) )
3725 return None
3726 except TypeError:
3727 main.log.exception( self.name + ": Object not as expected" )
3728 return None
3729 except pexpect.EOF:
3730 main.log.error( self.name + ": EOF exception found" )
3731 main.log.error( self.name + ": " + self.handle.before )
3732 main.cleanup()
3733 main.exit()
3734 except Exception:
3735 main.log.exception( self.name + ": Uncaught exception!" )
3736 main.cleanup()
3737 main.exit()
3738
3740 """
3741 CLI command to get a distributed counter then add a delta to it.
3742 Required arguments:
3743 counter - The name of the counter to increment.
3744 Optional arguments:
3745 delta - The long to add to the counter
3746 inMemory - use in memory map for the counter
3747 returns:
3748 integer value of the counter or
3749 None on Error
3750 """
3751 try:
3752 counter = str( counter )
3753 delta = int( delta )
3754 cmdStr = "counter-test-increment -g "
3755 if inMemory:
3756 cmdStr += "-i "
3757 cmdStr += counter
3758 if delta != 1:
3759 cmdStr += " " + str( delta )
3760 output = self.sendline( cmdStr )
3761 try:
3762
3763
3764 assert "org.onosproject.store.service" not in output
3765
3766 assert "java.lang.IllegalStateException" not in output
3767 except AssertionError:
3768 main.log.error( "Error in processing '" + cmdStr + "' " +
3769 "command: " + str( output ) )
3770 retryTime = 30
3771 main.log.info( "Waiting " + str( retryTime ) +
3772 "seconds before retrying." )
3773 time.sleep( retryTime )
3774 output = self.sendline( cmdStr )
3775 assert "Error executing command" not in output
3776 main.log.info( self.name + ": " + output )
3777 pattern = counter + " was updated to (-?\d+)"
3778 match = re.search( pattern, output )
3779 if match:
3780 return int( match.group( 1 ) )
3781 else:
3782 main.log.error( self.name + ": counterTestGetAndAdd did not" +
3783 " match expected output." )
3784 main.log.debug( self.name + " expected: " + pattern )
3785 main.log.debug( self.name + " actual: " + repr( output ) )
3786 return None
3787 except AssertionError:
3788 main.log.error( "Error in processing '" + cmdStr + "'" +
3789 " command: " + str( output ) )
3790 return None
3791 except TypeError:
3792 main.log.exception( self.name + ": Object not as expected" )
3793 return None
3794 except pexpect.EOF:
3795 main.log.error( self.name + ": EOF exception found" )
3796 main.log.error( self.name + ": " + self.handle.before )
3797 main.cleanup()
3798 main.exit()
3799 except Exception:
3800 main.log.exception( self.name + ": Uncaught exception!" )
3801 main.cleanup()
3802 main.exit()
3803
3804
3805 - def summary( self, jsonFormat=True ):
3806 """
3807 Description: Execute summary command in onos
3808 Returns: json object ( summary -j ), returns main.FALSE if there is
3809 no output
3810
3811 """
3812 try:
3813 cmdStr = "summary"
3814 if jsonFormat:
3815 cmdStr += " -j"
3816 handle = self.sendline( cmdStr )
3817
3818 if re.search( "Error:", handle ):
3819 main.log.error( self.name + ": summary() response: " +
3820 str( handle ) )
3821 if not handle:
3822 main.log.error( self.name + ": There is no output in " +
3823 "summary command" )
3824 return main.FALSE
3825 return handle
3826 except TypeError:
3827 main.log.exception( self.name + ": Object not as expected" )
3828 return None
3829 except pexpect.EOF:
3830 main.log.error( self.name + ": EOF exception found" )
3831 main.log.error( self.name + ": " + self.handle.before )
3832 main.cleanup()
3833 main.exit()
3834 except Exception:
3835 main.log.exception( self.name + ": Uncaught exception!" )
3836 main.cleanup()
3837 main.exit()
3838