blob: f03dc2721b15b2607654da21b11a8b4f9f5e64b8 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
kelvin-onlabedcff052015-01-16 12:53:55 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Oct-2012
4
kelvin-onlabedcff052015-01-16 12:53:55 -08005author:: Anil Kumar ( anilkumar.s@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07006
7
8 TestON is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
kelvin-onlabedcff052015-01-16 12:53:55 -080011 ( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070012
13 TestON is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
Jon Hallfbc828e2015-01-06 17:30:19 -080019 along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070020
21
22MininetCliDriver is the basic driver which will handle the Mininet functions
kelvin-onlabedcff052015-01-16 12:53:55 -080023"""
adminbae64d82013-08-01 10:50:15 -070024import pexpect
adminbae64d82013-08-01 10:50:15 -070025import re
26import sys
kelvin-onlaba4074292015-07-09 15:19:49 -070027import os
adminbae64d82013-08-01 10:50:15 -070028from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070029
kelvin-onlabedcff052015-01-16 12:53:55 -080030
31class RemoteMininetDriver( Emulator ):
32
33 """
kelvin-onlabd3b64892015-01-20 13:26:24 -080034 RemoteMininetCliDriver is the basic driver which will handle the Mininet
35 functions. The main different between this and the MininetCliDriver is that
36 this one does not build the mininet. It assumes that there is already a
37 mininet running on the target.
kelvin-onlabedcff052015-01-16 12:53:55 -080038 """
39 def __init__( self ):
40 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070041 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080042 self.name = None
kelvin-onlabedcff052015-01-16 12:53:55 -080043 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070044 self.flag = 0
45
kelvin-onlabedcff052015-01-16 12:53:55 -080046 def connect( self, **connectargs ):
kelvin-onlab08679eb2015-01-21 16:11:48 -080047 """,user_name, ip_address, pwd,options ):
kelvin-onlabd3b64892015-01-20 13:26:24 -080048 Here the main is the TestON instance after creating all the log
49 handles."""
adminbae64d82013-08-01 10:50:15 -070050 for key in connectargs:
kelvin-onlabedcff052015-01-16 12:53:55 -080051 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080052
kelvin-onlabedcff052015-01-16 12:53:55 -080053 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070054
55 try:
56 if os.getenv( str( self.ip_address ) ) != None:
57 self.ip_address = os.getenv( str( self.ip_address ) )
58 else:
59 main.log.info( self.name +
60 ": Trying to connect to " +
61 self.ip_address )
62
63 except KeyError:
64 main.log.info( "Invalid host name," +
65 " connecting to local host instead" )
66 self.ip_address = 'localhost'
67 except Exception as inst:
68 main.log.error( "Uncaught exception: " + str( inst ) )
69
kelvin-onlabedcff052015-01-16 12:53:55 -080070 self.handle = super(
71 RemoteMininetDriver,
72 self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080073 user_name=self.user_name,
74 ip_address=self.ip_address,
kelvin-onlabedcff052015-01-16 12:53:55 -080075 port=None,
76 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080077
Jon Hallfbc828e2015-01-06 17:30:19 -080078 # Copying the readme file to process the
kelvin-onlabedcff052015-01-16 12:53:55 -080079 if self.handle:
adminbae64d82013-08-01 10:50:15 -070080 return main.TRUE
81
kelvin-onlabedcff052015-01-16 12:53:55 -080082 else:
83 main.log.error(
84 "Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -080085 self.user_name +
kelvin-onlabedcff052015-01-16 12:53:55 -080086 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -080087 self.ip_address )
kelvin-onlabedcff052015-01-16 12:53:55 -080088 main.log.error( "Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -070089 return main.FALSE
admin98ad0092014-07-23 16:51:07 -070090
kelvin-onlabedcff052015-01-16 12:53:55 -080091 def checkForLoss( self, pingList ):
92 """
Jon Hall6c794f32014-08-14 13:33:13 -070093 Returns main.FALSE for 0% packet loss and
94 Returns main.ERROR if "found multiple mininet" is found and
95 Returns main.TRUE else
kelvin-onlabedcff052015-01-16 12:53:55 -080096 """
kelvin-onlabedcff052015-01-16 12:53:55 -080097 self.handle.sendline( "" )
98 self.handle.expect( "\$" )
kelvin-onlabedcff052015-01-16 12:53:55 -080099 self.handle.sendline( "" )
100 self.handle.expect( "\$" )
101 self.handle.sendline( "cat " + pingList )
102 self.handle.expect( pingList )
103 self.handle.expect( "\$" )
admin2580a0e2014-07-29 11:24:34 -0700104 outputs = self.handle.before + self.handle.after
kelvin-onlabedcff052015-01-16 12:53:55 -0800105 if re.search( " 0% packet loss", outputs ):
admin98ad0092014-07-23 16:51:07 -0700106 return main.FALSE
kelvin-onlabedcff052015-01-16 12:53:55 -0800107 elif re.search( "found multiple mininet", outputs ):
admin2580a0e2014-07-29 11:24:34 -0700108 return main.ERROR
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700109 else:
Jon Hall80daded2015-05-27 16:07:00 -0700110 # TODO: Parse for failed pings, give some truncated output
kelvin-onlabedcff052015-01-16 12:53:55 -0800111 main.log.error( "Error, unexpected output in the ping file" )
Jon Hall2ef1e9e2014-11-18 14:27:05 -0500112 main.log.warn( outputs )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700113 return main.TRUE
114
kelvin-onlabedcff052015-01-16 12:53:55 -0800115 def pingLong( self, **pingParams ):
116 """
Jon Hallefbd9792015-03-05 16:11:36 -0800117 Starts a continuous ping on the mininet host outputting
kelvin-onlabd3b64892015-01-20 13:26:24 -0800118 to a file in the /tmp dir.
kelvin-onlabedcff052015-01-16 12:53:55 -0800119 """
120 self.handle.sendline( "" )
121 self.handle.expect( "\$" )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800122 args = utilities.parse_args(
kelvin-onlabedcff052015-01-16 12:53:55 -0800123 [ "SRC", "TARGET", "PINGTIME" ], **pingParams )
124 precmd = "sudo rm /tmp/ping." + args[ "SRC" ]
125 self.execute( cmd=precmd, prompt="(.*)", timeout=10 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800126 command = "sudo mininet/util/m " + args[ "SRC" ] + " ping " +\
Jon Hallefbd9792015-03-05 16:11:36 -0800127 args[ "TARGET" ] + " -i .2 -w " +\
128 str( args[ 'PINGTIME' ] ) + " -D > /tmp/ping." +\
129 args[ "SRC" ] + " &"
Jon Hallfbc828e2015-01-06 17:30:19 -0800130 main.log.info( command )
kelvin-onlabedcff052015-01-16 12:53:55 -0800131 self.execute( cmd=command, prompt="(.*)", timeout=10 )
132 self.handle.sendline( "" )
133 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700134 return main.TRUE
135
kelvin-onlabedcff052015-01-16 12:53:55 -0800136 def pingstatus( self, **pingParams ):
137 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800138 Tails the respective ping output file and check that
139 there is a moving "64 bytes"
kelvin-onlabedcff052015-01-16 12:53:55 -0800140 """
141 self.handle.sendline( "" )
142 self.handle.expect( "\$" )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800143 args = utilities.parse_args( [ "SRC" ], **pingParams )
kelvin-onlabedcff052015-01-16 12:53:55 -0800144 self.handle.sendline( "tail /tmp/ping." + args[ "SRC" ] )
145 self.handle.expect( "tail" )
146 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700147 result = self.handle.before + self.handle.after
kelvin-onlabedcff052015-01-16 12:53:55 -0800148 self.handle.sendline( "" )
149 self.handle.expect( "\$" )
150 if re.search( 'Unreachable', result ):
151 main.log.info( "Unreachable found in ping logs..." )
adminbae64d82013-08-01 10:50:15 -0700152 return main.FALSE
kelvin-onlabedcff052015-01-16 12:53:55 -0800153 elif re.search( '64\sbytes', result ):
154 main.log.info( "Pings look good" )
adminbae64d82013-08-01 10:50:15 -0700155 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800156 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800157 main.log.info( "No, or faulty ping data..." )
adminbae64d82013-08-01 10:50:15 -0700158 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800159
kelvin-onlabedcff052015-01-16 12:53:55 -0800160 def pingKill( self, testONUser, testONIP ):
161 """
adminaeedddd2013-08-02 15:14:15 -0700162 Kills all continuous ping processes.
163 Then copies all the ping files to the TestStation.
kelvin-onlabedcff052015-01-16 12:53:55 -0800164 """
165 self.handle.sendline( "" )
166 self.handle.expect( "\$" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800167 command = "sudo kill -SIGINT `pgrep ping`"
168 main.log.info( command )
kelvin-onlabedcff052015-01-16 12:53:55 -0800169 self.execute( cmd=command, prompt="(.*)", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800170
adminbae64d82013-08-01 10:50:15 -0700171 main.log.info( "Transferring ping files to TestStation" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800172 command = "scp /tmp/ping.* " + \
173 str( testONUser ) + "@" + str( testONIP ) + ":/tmp/"
174 self.execute( cmd=command, prompt="100%", timeout=20 )
175 # Make sure the output is cleared
176 self.handle.sendline( "" )
177 self.handle.expect( "\$" )
178 self.handle.sendline( "" )
179 self.handle.expect( "\$" )
180 self.handle.sendline( "" )
181 i = self.handle.expect( [ "password", "\$" ] )
Jon Hall368769f2014-11-19 15:43:35 -0800182 if i == 0:
kelvin-onlabedcff052015-01-16 12:53:55 -0800183 main.log.error( "Error, sudo asking for password" )
184 main.log.error( self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800185 return main.FALSE
186 else:
187 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800188
kelvin-onlabedcff052015-01-16 12:53:55 -0800189 def pingLongKill( self ):
190 self.handle.sendline( "" )
191 self.handle.expect( "\$" )
admin2580a0e2014-07-29 11:24:34 -0700192 command = "sudo kill -SIGING `pgrep ping`"
kelvin-onlabedcff052015-01-16 12:53:55 -0800193 main.log.info( command )
194 self.execute( cmd=command, prompt="(.*)", timeout=10 )
195 self.handle.sendline( "" )
196 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700197 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800198
kelvin-onlabedcff052015-01-16 12:53:55 -0800199 def pingHostOptical( self, **pingParams ):
200 """
Jon Hallefbd9792015-03-05 16:11:36 -0800201 This function is only for Packet Optical related ping
kelvin-onlabedcff052015-01-16 12:53:55 -0800202 Use the next pingHost() function for all normal scenarios )
shahshreya28bb18e2014-11-17 10:26:23 -0800203 Ping from one mininet host to another
204 Currently the only supported Params: SRC and TARGET
kelvin-onlabedcff052015-01-16 12:53:55 -0800205 """
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800206 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
kelvin-onlabedcff052015-01-16 12:53:55 -0800207 command = args[ "SRC" ] + " ping " + \
208 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
shahshreya28bb18e2014-11-17 10:26:23 -0800209 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800210 main.log.warn( "Sending: " + command )
kelvin-onlabedcff052015-01-16 12:53:55 -0800211 self.handle.sendline( command )
212 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
shahshreya28bb18e2014-11-17 10:26:23 -0800213 if i == 1:
kelvin-onlabedcff052015-01-16 12:53:55 -0800214 main.log.error(
215 self.name +
216 ": timeout when waiting for response from mininet" )
217 main.log.error( "response: " + str( self.handle.before ) )
218 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
shahshreya28bb18e2014-11-17 10:26:23 -0800219 if i == 1:
kelvin-onlabedcff052015-01-16 12:53:55 -0800220 main.log.error(
221 self.name +
222 ": timeout when waiting for response from mininet" )
223 main.log.error( "response: " + str( self.handle.before ) )
shahshreya28bb18e2014-11-17 10:26:23 -0800224 response = self.handle.before
225 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800226 main.log.error( self.name + ": EOF exception found" )
227 main.log.error( self.name + ": " + self.handle.before )
shahshreya28bb18e2014-11-17 10:26:23 -0800228 main.cleanup()
229 main.exit()
kelvin-onlabedcff052015-01-16 12:53:55 -0800230 main.log.info( self.name + ": Ping Response: " + response )
kelvin-onlabedcff052015-01-16 12:53:55 -0800231 if re.search( ',\s0\%\spacket\sloss', response ):
232 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800233 main.lastResult = main.TRUE
shahshreya28bb18e2014-11-17 10:26:23 -0800234 return main.TRUE
kelvin-onlabedcff052015-01-16 12:53:55 -0800235 else:
236 main.log.error(
237 self.name +
238 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 main.lastResult = main.FALSE
shahshreya28bb18e2014-11-17 10:26:23 -0800240 return main.FALSE
241
kelvin-onlabedcff052015-01-16 12:53:55 -0800242 def pingHost( self, **pingParams ):
243 """
Jon Hallfbc828e2015-01-06 17:30:19 -0800244 Pings between two hosts on remote mininet
kelvin-onlabedcff052015-01-16 12:53:55 -0800245 """
246 self.handle.sendline( "" )
247 self.handle.expect( "\$" )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800248 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
kelvin-onlabedcff052015-01-16 12:53:55 -0800249 command = "mininet/util/m " + \
250 args[ "SRC" ] + " ping " + args[ "TARGET" ] + " -c 4 -W 1 -i .2"
251 main.log.info( command )
252 response = self.execute( cmd=command, prompt="rtt", timeout=10 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800253 if utilities.assert_matches(
kelvin-onlabedcff052015-01-16 12:53:55 -0800254 expect=',\s0\%\spacket\sloss',
255 actual=response,
256 onpass="No Packet loss",
257 onfail="Host is not reachable" ):
258 main.log.info( "NO PACKET LOSS, HOST IS REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800259 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700260 return main.TRUE
kelvin-onlabedcff052015-01-16 12:53:55 -0800261 else:
262 main.log.error( "PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800263 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700264 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800265
kelvin-onlabedcff052015-01-16 12:53:55 -0800266 def checknum( self, num ):
267 """
Jon Hallfbc828e2015-01-06 17:30:19 -0800268 Verifies the correct number of switches are running
kelvin-onlabedcff052015-01-16 12:53:55 -0800269 """
270 if self.handle:
271 self.handle.sendline( "" )
272 self.handle.expect( "\$" )
273 self.handle.sendline( 'ifconfig -a | grep "sw.. " | wc -l' )
274 self.handle.expect( "wc" )
275 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700276 response = self.handle.before
kelvin-onlabedcff052015-01-16 12:53:55 -0800277 self.handle.sendline(
278 'ps -ef | grep "bash -ms mininet:sw" | grep -v color | wc -l' )
279 self.handle.expect( "color" )
280 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700281 response2 = self.handle.before
282
kelvin-onlabedcff052015-01-16 12:53:55 -0800283 if re.search( num, response ):
284 if re.search( num, response2 ):
adminbae64d82013-08-01 10:50:15 -0700285 return main.TRUE
286 else:
287 return main.FALSE
288 else:
289 return main.FALSE
kelvin-onlabedcff052015-01-16 12:53:55 -0800290 else:
291 main.log.error( "Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -0700292
kelvin-onlabd3b64892015-01-20 13:26:24 -0800293 def startTcpdump(
kelvin-onlabedcff052015-01-16 12:53:55 -0800294 self,
295 filename,
296 intf="eth0",
Charles Chan029be652015-08-24 01:46:10 +0800297 port="port 6653",
kelvin-onlabedcff052015-01-16 12:53:55 -0800298 user="admin" ):
299 """
Jon Hallefbd9792015-03-05 16:11:36 -0800300 Runs tcpdump on an interface and saves the file
admin2a9548d2014-06-17 14:08:07 -0700301 intf can be specified, or the default eth0 is used
kelvin-onlabedcff052015-01-16 12:53:55 -0800302 """
admin2a9548d2014-06-17 14:08:07 -0700303 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800304 self.handle.sendline( "" )
305 self.handle.sendline(
306 "sudo tcpdump -n -i " +
307 intf +
308 " " +
309 port +
310 " -w " +
311 filename.strip() +
312 " -Z " +
313 user +
314 " &" )
315 self.handle.sendline( "" )
316 self.handle.sendline( "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800317 i = self.handle.expect( [ 'No\ssuch\device', 'listening\son',
318 pexpect.TIMEOUT, "\$" ], timeout=10 )
Jon Hall61282e32015-03-19 11:34:11 -0700319 main.log.info( self.handle.before + self.handle.after )
admin2a9548d2014-06-17 14:08:07 -0700320 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800321 main.log.error( self.name + ": tcpdump - No such device exists.\
322 tcpdump attempted on: " + intf )
admin2a9548d2014-06-17 14:08:07 -0700323 return main.FALSE
324 elif i == 1:
kelvin-onlabedcff052015-01-16 12:53:55 -0800325 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -0700326 return main.TRUE
327 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800328 main.log.error( self.name + ": tcpdump command timed out!\
329 Check interface name, given interface was: " + intf )
admin2a9548d2014-06-17 14:08:07 -0700330 return main.FALSE
kelvin-onlabedcff052015-01-16 12:53:55 -0800331 elif i == 3:
332 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700333 return main.TRUE
334 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800335 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -0700336 return main.FALSE
337 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800338 main.log.error( self.name + ": EOF exception found" )
339 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700340 main.cleanup()
341 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800342 except Exception:
343 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -0700344 main.cleanup()
345 main.exit()
346
kelvin-onlabd3b64892015-01-20 13:26:24 -0800347 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -0800348 """
349 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -0700350 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800351 self.handle.sendline( "sudo pkill tcpdump" )
352 self.handle.sendline( "" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800353 self.handle.expect( "\$" )
admin2a9548d2014-06-17 14:08:07 -0700354 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800355 main.log.error( self.name + ": EOF exception found" )
356 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700357 main.cleanup()
358 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800359 except Exception:
360 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -0700361 main.cleanup()
362 main.exit()
363
shahshreya1f119da2015-04-21 17:16:46 -0700364 def runOpticalMnScript( self,name = 'onos', ctrllerIP = None ):
shahshreya2c57c902015-04-06 20:40:20 -0700365 import time
shahshreya1f119da2015-04-21 17:16:46 -0700366 import types
kelvin-onlabedcff052015-01-16 12:53:55 -0800367 """
shahshreya1f119da2015-04-21 17:16:46 -0700368 Description:
369 This function is only meant for Packet Optical.
370 It runs python script "opticalTest.py" to create the
371 packet layer( mn ) and optical topology
372 Optional:
373 name - Name of onos directory. (ONOS | onos)
374 Required:
375 ctrllerIP = Controller(s) IP address
376 TODO: If no ctrllerIP is provided, a default
shahshreya2c57c902015-04-06 20:40:20 -0700377 $OC1 can be accepted
kelvin-onlabedcff052015-01-16 12:53:55 -0800378 """
shahshreya28bb18e2014-11-17 10:26:23 -0800379 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800380 self.handle.sendline( "" )
381 self.handle.expect( "\$" )
shahshreya1f119da2015-04-21 17:16:46 -0700382 self.handle.sendline( "cd ~/" + name + "/tools/test/topos" )
shahshreya2c57c902015-04-06 20:40:20 -0700383 self.handle.expect( "topos\$" )
384 if ctrllerIP == None:
385 main.log.info( "You need to specify the IP" )
386 return main.FALSE
387 else:
shahshreya1f119da2015-04-21 17:16:46 -0700388 controller = ''
389 if isinstance( ctrllerIP, types.ListType ):
390 for i in xrange( len( ctrllerIP ) ):
391 controller += ctrllerIP[i] + ' '
392 main.log.info( "Mininet topology is being loaded with " +
393 "controllers: " + controller )
394 elif isinstance( ctrllerIP, types.StringType ):
395 controller = ctrllerIP
396 main.log.info( "Mininet topology is being loaded with " +
397 "controller: " + controller )
398 else:
399 main.log.info( "You need to specify a valid IP" )
400 return main.FALSE
401 cmd = "sudo -E python opticalTest.py " + controller
402 main.log.info( self.name + ": cmd = " + cmd )
shahshreya2c57c902015-04-06 20:40:20 -0700403 self.handle.sendline( cmd )
shahshreyad524a942015-04-21 09:55:16 -0700404 time.sleep(30)
shahshreya2c57c902015-04-06 20:40:20 -0700405 self.handle.sendline( "" )
shahshreya3140b1a2015-04-28 14:22:15 -0700406 self.handle.sendline( "" )
shahshreya2c57c902015-04-06 20:40:20 -0700407 self.handle.expect("mininet>")
408 return main.TRUE
409 except pexpect.EOF:
410 main.log.error( self.name + ": EOF exception found" )
411 main.log.error( self.name + ": " + self.handle.before )
412 return main.FALSE
413
414 def attachLincOESession( self ):
415 """
416 Since executing opticalTest.py will give you mininet
417 prompt, you would at some point require to get onto
418 console of LincOE ((linc@onosTestBench)1>) to execute
419 commands like bring a optical port up or down on a ROADM
420 You can attach to console of Linc-OE session by a cmd:
421 sudo ~/linc-oe/rel/linc/bin/linc attach
422 """
423 try:
424 self.handle.sendline( "" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800425 self.handle.expect( "\$" )
shahshreya2c57c902015-04-06 20:40:20 -0700426 self.handle.sendline( "sudo ~/linc-oe/rel/linc/bin/linc attach" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800427 self.handle.expect( ">" )
shahshreya28bb18e2014-11-17 10:26:23 -0800428 return main.TRUE
429 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800430 main.log.error( self.name + ": EOF exception found" )
431 main.log.error( self.name + ": " + self.handle.before )
shahshreya28bb18e2014-11-17 10:26:23 -0800432 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700433
kelvin-onlabedcff052015-01-16 12:53:55 -0800434 def disconnect( self ):
435 """
Jon Hallfbc828e2015-01-06 17:30:19 -0800436 Called at the end of the test to disconnect the handle.
kelvin-onlabedcff052015-01-16 12:53:55 -0800437 """
adminbae64d82013-08-01 10:50:15 -0700438 if self.handle:
shahshreya95dd6f82015-02-05 15:59:16 -0800439 # Close the ssh connection
440 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -0800441 # self.handle.expect( "\$" )
Jon Hall390696c2015-05-05 17:13:41 -0700442 i = self.handle.expect( [ '\$', 'mininet>', pexpect.TIMEOUT,
443 pexpect.EOF ], timeout=2 )
shahshreyadccfbc62015-02-20 11:40:09 -0800444 if i == 0:
445 self.handle.sendline( "exit" )
446 self.handle.expect( "closed" )
447 elif i == 1:
448 self.handle.sendline( "exit" )
449 self.handle.expect( "exit" )
450 self.handle.expect('\$')
451 self.handle.sendline( "exit" )
452 self.handle.expect( "exit" )
453 self.handle.expect( "closed" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800454 else:
455 main.log.error( "Connection failed to the host" )
Jon Halld61331b2015-02-17 16:35:47 -0800456 return main.TRUE
adminbae64d82013-08-01 10:50:15 -0700457
kelvin-onlabd3b64892015-01-20 13:26:24 -0800458 def setIpTablesOUTPUT( self, dstIp, dstPort, action='add',
459 packetType='tcp', rule='DROP' ):
kelvin-onlabedcff052015-01-16 12:53:55 -0800460 """
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700461 Description:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800462 add or remove iptables rule to DROP ( default )
463 packets from specific IP and PORT
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700464 Usage:
kelvin-onlabedcff052015-01-16 12:53:55 -0800465 * specify action ( 'add' or 'remove' )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700466 when removing, pass in the same argument as you would add. It will
Jon Hallfbc828e2015-01-06 17:30:19 -0800467 delete that specific rule.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800468 * specify the destination ip to block with dstIp
469 * specify destination port to block to dstPort
kelvin-onlabedcff052015-01-16 12:53:55 -0800470 * optional packet type to block ( default tcp )
471 * optional iptables rule ( default DROP )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700472 WARNING:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800473 * This function uses root privilege iptables command which may result
474 in unwanted network errors. USE WITH CAUTION
kelvin-onlabedcff052015-01-16 12:53:55 -0800475 """
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700476 import re
477 import time
478
kelvin-onlabedcff052015-01-16 12:53:55 -0800479 # NOTE*********
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700480 # The strict checking methods of this driver function is intentional
481 # to discourage any misuse or error of iptables, which can cause
482 # severe network errors
kelvin-onlabd3b64892015-01-20 13:26:24 -0800483 # *************
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700484
kelvin-onlabd3b64892015-01-20 13:26:24 -0800485 # NOTE: Sleep needed to give some time
486 # for rule to be added and registered
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700487 # to the instance
kelvin-onlabedcff052015-01-16 12:53:55 -0800488 time.sleep( 5 )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700489
kelvin-onlabd3b64892015-01-20 13:26:24 -0800490 actionType = action.lower()
491 if actionType != 'add' and actionType != 'remove':
kelvin-onlabedcff052015-01-16 12:53:55 -0800492 main.log.error(
493 "Invalid action type. 'add' or 'remove' table rule" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700494 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
kelvin-onlabedcff052015-01-16 12:53:55 -0800495 # NOTE: Currently only supports rules DROP, ACCEPT, and LOG
496 main.log.error(
497 "Invalid rule. 'DROP' or 'ACCEPT' or 'LOG' only." )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700498 return
499 return
500 else:
501
kelvin-onlabedcff052015-01-16 12:53:55 -0800502 # If there is no existing rule in the iptables, we will see an
kelvin-onlabd3b64892015-01-20 13:26:24 -0800503 # 'iptables:'... message. We expect to see this message.
kelvin-onlabedcff052015-01-16 12:53:55 -0800504 # Otherwise, if there IS an existing rule, we will get the prompt
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700505 # back, hence why we expect $ for remove type. We want to remove
506 # an already existing rule
507
kelvin-onlabd3b64892015-01-20 13:26:24 -0800508 if actionType == 'add':
509 # NOTE: "iptables:" expect is a result of
510 # return from the command
511 # iptables -C ...
512 # Any changes by the iptables command return string
513 # will result in failure of the function. ( deemed unlikely
514 # at the time of writing this function )
kelvin-onlabedcff052015-01-16 12:53:55 -0800515 # Check for existing rules on current input
516 self.handle.sendline( "" )
517 self.handle.expect( "\$" )
518 self.handle.sendline(
519 "sudo iptables -C OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800521 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800522 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800523 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800524 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800525 " -j " +
526 str( rule ) )
527 i = self.handle.expect( [ "iptables:", "\$" ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700528 print i
529 print self.handle.before
530 print "after: "
531 print self.handle.after
532
kelvin-onlabd3b64892015-01-20 13:26:24 -0800533 elif actionType == 'remove':
kelvin-onlabedcff052015-01-16 12:53:55 -0800534 # Check for existing rules on current input
535 self.handle.sendline( "" )
536 self.handle.expect( "\$" )
537 self.handle.sendline(
538 "sudo iptables -C OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800539 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800540 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800541 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800542 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800543 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800544 " -j " +
545 str( rule ) )
546 self.handle.expect( "\$" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700547 print "before: "
548 print self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800549 actualString = self.handle.after
550 expectString = "iptables:"
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700551 print "Actual String:"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800552 print actualString
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700553
kelvin-onlabd3b64892015-01-20 13:26:24 -0800554 if re.search( expectString, actualString ):
555 matchResult = main.TRUE
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700556 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800557 matchResult = main.FALSE
558 # If matchResult is main.TRUE, it means there is no matching rule.
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700559
kelvin-onlabd3b64892015-01-20 13:26:24 -0800560 # If tables does not exist and expected prompt is returned,
561 # go ahead and add iptables rule
562 if matchResult == main.TRUE:
kelvin-onlabedcff052015-01-16 12:53:55 -0800563 # Ensure action type is add
kelvin-onlabd3b64892015-01-20 13:26:24 -0800564 if actionType == 'add':
565 # -A is the 'append' action of iptables
566 actionAdd = '-A'
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700567 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800568 self.handle.sendline( "" )
569 self.handle.sendline(
570 "sudo iptables " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800571 actionAdd +
kelvin-onlabedcff052015-01-16 12:53:55 -0800572 " OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800573 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800574 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800575 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800576 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800577 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800578 " -j " +
579 str( rule ) )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700580
kelvin-onlabd3b64892015-01-20 13:26:24 -0800581 infoString = "Rules added to " + str( self.name )
Jon Hallefbd9792015-03-05 16:11:36 -0800582 infoString += "iptables rule added to block IP: " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -0800583 str( dstIp )
584 infoString += "Port: " + \
585 str( dstPort ) + " Rule: " + str( rule )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700586
kelvin-onlabd3b64892015-01-20 13:26:24 -0800587 main.log.info( infoString )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700588
kelvin-onlabedcff052015-01-16 12:53:55 -0800589 self.handle.expect(
590 [ "\$", pexpect.EOF, pexpect.TIMEOUT ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700591 except pexpect.TIMEOUT:
kelvin-onlabedcff052015-01-16 12:53:55 -0800592 main.log.error(
593 self.name +
594 ": Timeout exception in setIpTables function" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800595 except Exception:
596 main.log.exception( self.name +
597 ": Uncaught exception!" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700598 main.cleanup()
599 main.exit()
600 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800601 main.log.error(
602 "Given rule already exists, but attempted to add it" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800603 # If matchResult is 0, it means there IS a matching rule provided
604 elif matchResult == main.FALSE:
kelvin-onlabedcff052015-01-16 12:53:55 -0800605 # Ensure action type is remove
kelvin-onlabd3b64892015-01-20 13:26:24 -0800606 if actionType == 'remove':
607 # -D is the 'delete' rule of iptables
608 actionRemove = '-D'
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700609 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800610 self.handle.sendline( "" )
611 # Delete a specific rule specified into the function
612 self.handle.sendline(
613 "sudo iptables " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800614 actionRemove +
kelvin-onlabedcff052015-01-16 12:53:55 -0800615 " OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800616 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800617 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800618 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800619 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800620 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800621 " -j " +
622 str( rule ) )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700623
kelvin-onlabd3b64892015-01-20 13:26:24 -0800624 infoString = "Rules removed from " + str( self.name )
625 infoString += " iptables rule removed \
626 from blocking IP: " + \
627 str( dstIp )
628 infoString += " Port: " + \
629 str( dstPort ) + " Rule: " + str( rule )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700630
kelvin-onlabd3b64892015-01-20 13:26:24 -0800631 main.log.info( infoString )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700632
kelvin-onlabedcff052015-01-16 12:53:55 -0800633 self.handle.expect(
634 [ "\$", pexpect.EOF, pexpect.TIMEOUT ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700635 except pexpect.TIMEOUT:
kelvin-onlabedcff052015-01-16 12:53:55 -0800636 main.log.error(
637 self.name +
638 ": Timeout exception in setIpTables function" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800639 except Exception:
640 main.log.exception( self.name +
641 ": Uncaught exception!" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700642 main.cleanup()
643 main.exit()
644 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800645 main.log.error(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800646 "Given rule does not exist,\
647 but attempted to remove it" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700648 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800649 # NOTE: If a bad usage of this function occurs, exit the entire
650 # test
651 main.log.error( "Bad rule given for iptables. Exiting..." )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700652 main.cleanup()
653 main.exit()
654
655
adminbae64d82013-08-01 10:50:15 -0700656if __name__ != "__main__":
657 import sys
kelvin-onlabedcff052015-01-16 12:53:55 -0800658 sys.modules[ __name__ ] = RemoteMininetDriver()