blob: c2c011a4371c398de137241f9da0adb7e727d117 [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-onlabedcff052015-01-16 12:53:55 -080027sys.path.append( "../" )
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' ]
54 self.handle = super(
55 RemoteMininetDriver,
56 self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080057 user_name=self.user_name,
58 ip_address=self.ip_address,
kelvin-onlabedcff052015-01-16 12:53:55 -080059 port=None,
60 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080061
Jon Hallfbc828e2015-01-06 17:30:19 -080062 # Copying the readme file to process the
kelvin-onlabedcff052015-01-16 12:53:55 -080063 if self.handle:
adminbae64d82013-08-01 10:50:15 -070064 return main.TRUE
65
kelvin-onlabedcff052015-01-16 12:53:55 -080066 else:
67 main.log.error(
68 "Connection failed to the host " +
kelvin-onlab08679eb2015-01-21 16:11:48 -080069 self.user_name +
kelvin-onlabedcff052015-01-16 12:53:55 -080070 "@" +
kelvin-onlab08679eb2015-01-21 16:11:48 -080071 self.ip_address )
kelvin-onlabedcff052015-01-16 12:53:55 -080072 main.log.error( "Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -070073 return main.FALSE
admin98ad0092014-07-23 16:51:07 -070074
kelvin-onlabedcff052015-01-16 12:53:55 -080075 def checkForLoss( self, pingList ):
76 """
Jon Hall6c794f32014-08-14 13:33:13 -070077 Returns main.FALSE for 0% packet loss and
78 Returns main.ERROR if "found multiple mininet" is found and
79 Returns main.TRUE else
kelvin-onlabedcff052015-01-16 12:53:55 -080080 """
kelvin-onlabedcff052015-01-16 12:53:55 -080081 self.handle.sendline( "" )
82 self.handle.expect( "\$" )
kelvin-onlabedcff052015-01-16 12:53:55 -080083 self.handle.sendline( "" )
84 self.handle.expect( "\$" )
85 self.handle.sendline( "cat " + pingList )
86 self.handle.expect( pingList )
87 self.handle.expect( "\$" )
admin2580a0e2014-07-29 11:24:34 -070088 outputs = self.handle.before + self.handle.after
kelvin-onlabedcff052015-01-16 12:53:55 -080089 if re.search( " 0% packet loss", outputs ):
admin98ad0092014-07-23 16:51:07 -070090 return main.FALSE
kelvin-onlabedcff052015-01-16 12:53:55 -080091 elif re.search( "found multiple mininet", outputs ):
admin2580a0e2014-07-29 11:24:34 -070092 return main.ERROR
shahshreyaf4d4d0c2014-10-10 12:11:10 -070093 else:
Jon Hall80daded2015-05-27 16:07:00 -070094 # TODO: Parse for failed pings, give some truncated output
kelvin-onlabedcff052015-01-16 12:53:55 -080095 main.log.error( "Error, unexpected output in the ping file" )
Jon Hall2ef1e9e2014-11-18 14:27:05 -050096 main.log.warn( outputs )
shahshreyaf4d4d0c2014-10-10 12:11:10 -070097 return main.TRUE
98
shahshreya3140b1a2015-04-28 14:22:15 -070099 def arping( self, host="", ip="10.128.20.211" ):
100 """
101 Description:
102 Sends arp message from mininet host for hosts discovery
103 Required:
104 host - hosts name
105 Optional:
106 ip - ip address that does not exist in the network so there would
107 be no reply.
108 """
109 cmd = " py " + host + ".cmd(\"arping -c 1 " + ip + "\")"
110 try:
111 main.log.warn( "Sending: " + cmd )
112 self.handle.sendline( cmd )
113 response = self.handle.before
114 self.handle.sendline( "" )
115 self.handle.expect( "mininet>" )
116 return main.TRUE
117
118 except pexpect.EOF:
119 main.log.error( self.name + ": EOF exception found" )
120 main.log.error( self.name + ": " + self.handle.before )
121 main.cleanup()
122 main.exit()
123
kelvin-onlabedcff052015-01-16 12:53:55 -0800124 def pingLong( self, **pingParams ):
125 """
Jon Hallefbd9792015-03-05 16:11:36 -0800126 Starts a continuous ping on the mininet host outputting
kelvin-onlabd3b64892015-01-20 13:26:24 -0800127 to a file in the /tmp dir.
kelvin-onlabedcff052015-01-16 12:53:55 -0800128 """
129 self.handle.sendline( "" )
130 self.handle.expect( "\$" )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800131 args = utilities.parse_args(
kelvin-onlabedcff052015-01-16 12:53:55 -0800132 [ "SRC", "TARGET", "PINGTIME" ], **pingParams )
133 precmd = "sudo rm /tmp/ping." + args[ "SRC" ]
134 self.execute( cmd=precmd, prompt="(.*)", timeout=10 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800135 command = "sudo mininet/util/m " + args[ "SRC" ] + " ping " +\
Jon Hallefbd9792015-03-05 16:11:36 -0800136 args[ "TARGET" ] + " -i .2 -w " +\
137 str( args[ 'PINGTIME' ] ) + " -D > /tmp/ping." +\
138 args[ "SRC" ] + " &"
Jon Hallfbc828e2015-01-06 17:30:19 -0800139 main.log.info( command )
kelvin-onlabedcff052015-01-16 12:53:55 -0800140 self.execute( cmd=command, prompt="(.*)", timeout=10 )
141 self.handle.sendline( "" )
142 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700143 return main.TRUE
144
kelvin-onlabedcff052015-01-16 12:53:55 -0800145 def pingstatus( self, **pingParams ):
146 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800147 Tails the respective ping output file and check that
148 there is a moving "64 bytes"
kelvin-onlabedcff052015-01-16 12:53:55 -0800149 """
150 self.handle.sendline( "" )
151 self.handle.expect( "\$" )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800152 args = utilities.parse_args( [ "SRC" ], **pingParams )
kelvin-onlabedcff052015-01-16 12:53:55 -0800153 self.handle.sendline( "tail /tmp/ping." + args[ "SRC" ] )
154 self.handle.expect( "tail" )
155 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700156 result = self.handle.before + self.handle.after
kelvin-onlabedcff052015-01-16 12:53:55 -0800157 self.handle.sendline( "" )
158 self.handle.expect( "\$" )
159 if re.search( 'Unreachable', result ):
160 main.log.info( "Unreachable found in ping logs..." )
adminbae64d82013-08-01 10:50:15 -0700161 return main.FALSE
kelvin-onlabedcff052015-01-16 12:53:55 -0800162 elif re.search( '64\sbytes', result ):
163 main.log.info( "Pings look good" )
adminbae64d82013-08-01 10:50:15 -0700164 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800165 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800166 main.log.info( "No, or faulty ping data..." )
adminbae64d82013-08-01 10:50:15 -0700167 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800168
kelvin-onlabedcff052015-01-16 12:53:55 -0800169 def pingKill( self, testONUser, testONIP ):
170 """
adminaeedddd2013-08-02 15:14:15 -0700171 Kills all continuous ping processes.
172 Then copies all the ping files to the TestStation.
kelvin-onlabedcff052015-01-16 12:53:55 -0800173 """
174 self.handle.sendline( "" )
175 self.handle.expect( "\$" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800176 command = "sudo kill -SIGINT `pgrep ping`"
177 main.log.info( command )
kelvin-onlabedcff052015-01-16 12:53:55 -0800178 self.execute( cmd=command, prompt="(.*)", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800179
adminbae64d82013-08-01 10:50:15 -0700180 main.log.info( "Transferring ping files to TestStation" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800181 command = "scp /tmp/ping.* " + \
182 str( testONUser ) + "@" + str( testONIP ) + ":/tmp/"
183 self.execute( cmd=command, prompt="100%", timeout=20 )
184 # Make sure the output is cleared
185 self.handle.sendline( "" )
186 self.handle.expect( "\$" )
187 self.handle.sendline( "" )
188 self.handle.expect( "\$" )
189 self.handle.sendline( "" )
190 i = self.handle.expect( [ "password", "\$" ] )
Jon Hall368769f2014-11-19 15:43:35 -0800191 if i == 0:
kelvin-onlabedcff052015-01-16 12:53:55 -0800192 main.log.error( "Error, sudo asking for password" )
193 main.log.error( self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800194 return main.FALSE
195 else:
196 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800197
kelvin-onlabedcff052015-01-16 12:53:55 -0800198 def pingLongKill( self ):
199 self.handle.sendline( "" )
200 self.handle.expect( "\$" )
admin2580a0e2014-07-29 11:24:34 -0700201 command = "sudo kill -SIGING `pgrep ping`"
kelvin-onlabedcff052015-01-16 12:53:55 -0800202 main.log.info( command )
203 self.execute( cmd=command, prompt="(.*)", timeout=10 )
204 self.handle.sendline( "" )
205 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700206 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800207
kelvin-onlabedcff052015-01-16 12:53:55 -0800208 def pingHostOptical( self, **pingParams ):
209 """
Jon Hallefbd9792015-03-05 16:11:36 -0800210 This function is only for Packet Optical related ping
kelvin-onlabedcff052015-01-16 12:53:55 -0800211 Use the next pingHost() function for all normal scenarios )
shahshreya28bb18e2014-11-17 10:26:23 -0800212 Ping from one mininet host to another
213 Currently the only supported Params: SRC and TARGET
kelvin-onlabedcff052015-01-16 12:53:55 -0800214 """
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800215 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
kelvin-onlabedcff052015-01-16 12:53:55 -0800216 command = args[ "SRC" ] + " ping " + \
217 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
shahshreya28bb18e2014-11-17 10:26:23 -0800218 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800219 main.log.warn( "Sending: " + command )
kelvin-onlabedcff052015-01-16 12:53:55 -0800220 self.handle.sendline( command )
221 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
shahshreya28bb18e2014-11-17 10:26:23 -0800222 if i == 1:
kelvin-onlabedcff052015-01-16 12:53:55 -0800223 main.log.error(
224 self.name +
225 ": timeout when waiting for response from mininet" )
226 main.log.error( "response: " + str( self.handle.before ) )
227 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
shahshreya28bb18e2014-11-17 10:26:23 -0800228 if i == 1:
kelvin-onlabedcff052015-01-16 12:53:55 -0800229 main.log.error(
230 self.name +
231 ": timeout when waiting for response from mininet" )
232 main.log.error( "response: " + str( self.handle.before ) )
shahshreya28bb18e2014-11-17 10:26:23 -0800233 response = self.handle.before
234 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800235 main.log.error( self.name + ": EOF exception found" )
236 main.log.error( self.name + ": " + self.handle.before )
shahshreya28bb18e2014-11-17 10:26:23 -0800237 main.cleanup()
238 main.exit()
kelvin-onlabedcff052015-01-16 12:53:55 -0800239 main.log.info( self.name + ": Ping Response: " + response )
kelvin-onlabedcff052015-01-16 12:53:55 -0800240 if re.search( ',\s0\%\spacket\sloss', response ):
241 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800242 main.lastResult = main.TRUE
shahshreya28bb18e2014-11-17 10:26:23 -0800243 return main.TRUE
kelvin-onlabedcff052015-01-16 12:53:55 -0800244 else:
245 main.log.error(
246 self.name +
247 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800248 main.lastResult = main.FALSE
shahshreya28bb18e2014-11-17 10:26:23 -0800249 return main.FALSE
250
kelvin-onlabedcff052015-01-16 12:53:55 -0800251 def pingHost( self, **pingParams ):
252 """
Jon Hallfbc828e2015-01-06 17:30:19 -0800253 Pings between two hosts on remote mininet
kelvin-onlabedcff052015-01-16 12:53:55 -0800254 """
255 self.handle.sendline( "" )
256 self.handle.expect( "\$" )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800257 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
kelvin-onlabedcff052015-01-16 12:53:55 -0800258 command = "mininet/util/m " + \
259 args[ "SRC" ] + " ping " + args[ "TARGET" ] + " -c 4 -W 1 -i .2"
260 main.log.info( command )
261 response = self.execute( cmd=command, prompt="rtt", timeout=10 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800262 if utilities.assert_matches(
kelvin-onlabedcff052015-01-16 12:53:55 -0800263 expect=',\s0\%\spacket\sloss',
264 actual=response,
265 onpass="No Packet loss",
266 onfail="Host is not reachable" ):
267 main.log.info( "NO PACKET LOSS, HOST IS REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800268 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700269 return main.TRUE
kelvin-onlabedcff052015-01-16 12:53:55 -0800270 else:
271 main.log.error( "PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800272 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700273 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800274
kelvin-onlabedcff052015-01-16 12:53:55 -0800275 def checknum( self, num ):
276 """
Jon Hallfbc828e2015-01-06 17:30:19 -0800277 Verifies the correct number of switches are running
kelvin-onlabedcff052015-01-16 12:53:55 -0800278 """
279 if self.handle:
280 self.handle.sendline( "" )
281 self.handle.expect( "\$" )
282 self.handle.sendline( 'ifconfig -a | grep "sw.. " | wc -l' )
283 self.handle.expect( "wc" )
284 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700285 response = self.handle.before
kelvin-onlabedcff052015-01-16 12:53:55 -0800286 self.handle.sendline(
287 'ps -ef | grep "bash -ms mininet:sw" | grep -v color | wc -l' )
288 self.handle.expect( "color" )
289 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700290 response2 = self.handle.before
291
kelvin-onlabedcff052015-01-16 12:53:55 -0800292 if re.search( num, response ):
293 if re.search( num, response2 ):
adminbae64d82013-08-01 10:50:15 -0700294 return main.TRUE
295 else:
296 return main.FALSE
297 else:
298 return main.FALSE
kelvin-onlabedcff052015-01-16 12:53:55 -0800299 else:
300 main.log.error( "Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -0700301
kelvin-onlabd3b64892015-01-20 13:26:24 -0800302 def startTcpdump(
kelvin-onlabedcff052015-01-16 12:53:55 -0800303 self,
304 filename,
305 intf="eth0",
306 port="port 6633",
307 user="admin" ):
308 """
Jon Hallefbd9792015-03-05 16:11:36 -0800309 Runs tcpdump on an interface and saves the file
admin2a9548d2014-06-17 14:08:07 -0700310 intf can be specified, or the default eth0 is used
kelvin-onlabedcff052015-01-16 12:53:55 -0800311 """
admin2a9548d2014-06-17 14:08:07 -0700312 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800313 self.handle.sendline( "" )
314 self.handle.sendline(
315 "sudo tcpdump -n -i " +
316 intf +
317 " " +
318 port +
319 " -w " +
320 filename.strip() +
321 " -Z " +
322 user +
323 " &" )
324 self.handle.sendline( "" )
325 self.handle.sendline( "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800326 i = self.handle.expect( [ 'No\ssuch\device', 'listening\son',
327 pexpect.TIMEOUT, "\$" ], timeout=10 )
Jon Hall61282e32015-03-19 11:34:11 -0700328 main.log.info( self.handle.before + self.handle.after )
admin2a9548d2014-06-17 14:08:07 -0700329 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800330 main.log.error( self.name + ": tcpdump - No such device exists.\
331 tcpdump attempted on: " + intf )
admin2a9548d2014-06-17 14:08:07 -0700332 return main.FALSE
333 elif i == 1:
kelvin-onlabedcff052015-01-16 12:53:55 -0800334 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -0700335 return main.TRUE
336 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800337 main.log.error( self.name + ": tcpdump command timed out!\
338 Check interface name, given interface was: " + intf )
admin2a9548d2014-06-17 14:08:07 -0700339 return main.FALSE
kelvin-onlabedcff052015-01-16 12:53:55 -0800340 elif i == 3:
341 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700342 return main.TRUE
343 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800344 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -0700345 return main.FALSE
346 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800347 main.log.error( self.name + ": EOF exception found" )
348 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700349 main.cleanup()
350 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800351 except Exception:
352 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -0700353 main.cleanup()
354 main.exit()
355
kelvin-onlabd3b64892015-01-20 13:26:24 -0800356 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -0800357 """
358 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -0700359 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800360 self.handle.sendline( "sudo pkill tcpdump" )
361 self.handle.sendline( "" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800362 self.handle.expect( "\$" )
admin2a9548d2014-06-17 14:08:07 -0700363 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800364 main.log.error( self.name + ": EOF exception found" )
365 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700366 main.cleanup()
367 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800368 except Exception:
369 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -0700370 main.cleanup()
371 main.exit()
372
shahshreya1f119da2015-04-21 17:16:46 -0700373 def runOpticalMnScript( self,name = 'onos', ctrllerIP = None ):
shahshreya2c57c902015-04-06 20:40:20 -0700374 import time
shahshreya1f119da2015-04-21 17:16:46 -0700375 import types
kelvin-onlabedcff052015-01-16 12:53:55 -0800376 """
shahshreya1f119da2015-04-21 17:16:46 -0700377 Description:
378 This function is only meant for Packet Optical.
379 It runs python script "opticalTest.py" to create the
380 packet layer( mn ) and optical topology
381 Optional:
382 name - Name of onos directory. (ONOS | onos)
383 Required:
384 ctrllerIP = Controller(s) IP address
385 TODO: If no ctrllerIP is provided, a default
shahshreya2c57c902015-04-06 20:40:20 -0700386 $OC1 can be accepted
kelvin-onlabedcff052015-01-16 12:53:55 -0800387 """
shahshreya28bb18e2014-11-17 10:26:23 -0800388 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800389 self.handle.sendline( "" )
390 self.handle.expect( "\$" )
shahshreya1f119da2015-04-21 17:16:46 -0700391 self.handle.sendline( "cd ~/" + name + "/tools/test/topos" )
shahshreya2c57c902015-04-06 20:40:20 -0700392 self.handle.expect( "topos\$" )
393 if ctrllerIP == None:
394 main.log.info( "You need to specify the IP" )
395 return main.FALSE
396 else:
shahshreya1f119da2015-04-21 17:16:46 -0700397 controller = ''
398 if isinstance( ctrllerIP, types.ListType ):
399 for i in xrange( len( ctrllerIP ) ):
400 controller += ctrllerIP[i] + ' '
401 main.log.info( "Mininet topology is being loaded with " +
402 "controllers: " + controller )
403 elif isinstance( ctrllerIP, types.StringType ):
404 controller = ctrllerIP
405 main.log.info( "Mininet topology is being loaded with " +
406 "controller: " + controller )
407 else:
408 main.log.info( "You need to specify a valid IP" )
409 return main.FALSE
410 cmd = "sudo -E python opticalTest.py " + controller
411 main.log.info( self.name + ": cmd = " + cmd )
shahshreya2c57c902015-04-06 20:40:20 -0700412 self.handle.sendline( cmd )
shahshreyad524a942015-04-21 09:55:16 -0700413 time.sleep(30)
shahshreya2c57c902015-04-06 20:40:20 -0700414 self.handle.sendline( "" )
shahshreya3140b1a2015-04-28 14:22:15 -0700415 self.handle.sendline( "" )
shahshreya2c57c902015-04-06 20:40:20 -0700416 self.handle.expect("mininet>")
417 return main.TRUE
418 except pexpect.EOF:
419 main.log.error( self.name + ": EOF exception found" )
420 main.log.error( self.name + ": " + self.handle.before )
421 return main.FALSE
422
423 def attachLincOESession( self ):
424 """
425 Since executing opticalTest.py will give you mininet
426 prompt, you would at some point require to get onto
427 console of LincOE ((linc@onosTestBench)1>) to execute
428 commands like bring a optical port up or down on a ROADM
429 You can attach to console of Linc-OE session by a cmd:
430 sudo ~/linc-oe/rel/linc/bin/linc attach
431 """
432 try:
433 self.handle.sendline( "" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800434 self.handle.expect( "\$" )
shahshreya2c57c902015-04-06 20:40:20 -0700435 self.handle.sendline( "sudo ~/linc-oe/rel/linc/bin/linc attach" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800436 self.handle.expect( ">" )
shahshreya28bb18e2014-11-17 10:26:23 -0800437 return main.TRUE
438 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800439 main.log.error( self.name + ": EOF exception found" )
440 main.log.error( self.name + ": " + self.handle.before )
shahshreya28bb18e2014-11-17 10:26:23 -0800441 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700442
kelvin-onlabedcff052015-01-16 12:53:55 -0800443 def disconnect( self ):
444 """
Jon Hallfbc828e2015-01-06 17:30:19 -0800445 Called at the end of the test to disconnect the handle.
kelvin-onlabedcff052015-01-16 12:53:55 -0800446 """
adminbae64d82013-08-01 10:50:15 -0700447 if self.handle:
shahshreya95dd6f82015-02-05 15:59:16 -0800448 # Close the ssh connection
449 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -0800450 # self.handle.expect( "\$" )
Jon Hall390696c2015-05-05 17:13:41 -0700451 i = self.handle.expect( [ '\$', 'mininet>', pexpect.TIMEOUT,
452 pexpect.EOF ], timeout=2 )
shahshreyadccfbc62015-02-20 11:40:09 -0800453 if i == 0:
454 self.handle.sendline( "exit" )
455 self.handle.expect( "closed" )
456 elif i == 1:
457 self.handle.sendline( "exit" )
458 self.handle.expect( "exit" )
459 self.handle.expect('\$')
460 self.handle.sendline( "exit" )
461 self.handle.expect( "exit" )
462 self.handle.expect( "closed" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800463 else:
464 main.log.error( "Connection failed to the host" )
Jon Halld61331b2015-02-17 16:35:47 -0800465 return main.TRUE
adminbae64d82013-08-01 10:50:15 -0700466
kelvin-onlabd3b64892015-01-20 13:26:24 -0800467 def getFlowTable( self, protoVersion, sw ):
468 """
469 TODO document usage
Jon Hallefbd9792015-03-05 16:11:36 -0800470 TODO add option to look at cookies. ignoring them for now
kelvin-onlabd3b64892015-01-20 13:26:24 -0800471
472 print "get_flowTable(" + str( protoVersion ) +" " + str( sw ) +")"
473 NOTE: Use format to force consistent flow table output across
474 versions"""
kelvin-onlabedcff052015-01-16 12:53:55 -0800475 self.handle.sendline( "cd" )
476 self.handle.expect( [ "\$", pexpect.EOF, pexpect.TIMEOUT ] )
kelvin-onlabedcff052015-01-16 12:53:55 -0800477 if protoVersion == 1.0:
478 command = "sudo ovs-ofctl dump-flows " + sw + \
kelvin-onlabd3b64892015-01-20 13:26:24 -0800479 " -F OpenFlow10-table_id | awk '{OFS=\",\" ; print $1 $3 $6 \
480 $7 $8}' | cut -d ',' -f 2- | sort -n -k1 -r"
kelvin-onlabedcff052015-01-16 12:53:55 -0800481 self.handle.sendline( command )
482 self.handle.expect( [ "k1 -r", pexpect.EOF, pexpect.TIMEOUT ] )
483 self.handle.expect(
484 [ "OFPST_FLOW", pexpect.EOF, pexpect.TIMEOUT ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700485 response = self.handle.before
kelvin-onlabedcff052015-01-16 12:53:55 -0800486 # print "response=", response
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700487 return response
kelvin-onlabedcff052015-01-16 12:53:55 -0800488 elif protoVersion == 1.3:
489 command = "sudo ovs-ofctl dump-flows " + sw + \
kelvin-onlabd3b64892015-01-20 13:26:24 -0800490 " -O OpenFlow13 | awk '{OFS=\",\" ; print $1 $3 $6 $7}'\
491 | cut -d ',' -f 2- | sort -n -k1 -r"
kelvin-onlabedcff052015-01-16 12:53:55 -0800492 self.handle.sendline( command )
493 self.handle.expect( [ "k1 -r", pexpect.EOF, pexpect.TIMEOUT ] )
494 self.handle.expect(
495 [ "OFPST_FLOW", pexpect.EOF, pexpect.TIMEOUT ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700496 response = self.handle.before
kelvin-onlabedcff052015-01-16 12:53:55 -0800497 # print "response=", response
Jon Hall94fd0472014-12-08 11:52:42 -0800498 return response
499 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800500 main.log.error(
501 "Unknown protoVersion in get_flowTable(). given: (" +
502 str(
503 type( protoVersion ) ) +
504 ") '" +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800505 str( protoVersion ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800506 "'" )
Jon Hall94fd0472014-12-08 11:52:42 -0800507
kelvin-onlabd3b64892015-01-20 13:26:24 -0800508 def flowComp( self, flow1, flow2 ):
kelvin-onlabedcff052015-01-16 12:53:55 -0800509 if flow1 == flow2:
santhosh19fd8032014-07-29 11:56:17 -0700510 return main.TRUE
511 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800512 main.log.info( "Flow tables do not match, printing tables:" )
513 main.log.info( "Flow Table 1:" )
514 main.log.info( flow1 )
515 main.log.info( "Flow Table 2:" )
516 main.log.info( flow2 )
santhosh19fd8032014-07-29 11:56:17 -0700517 return main.FALSE
518
kelvin-onlabd3b64892015-01-20 13:26:24 -0800519 def setIpTablesOUTPUT( self, dstIp, dstPort, action='add',
520 packetType='tcp', rule='DROP' ):
kelvin-onlabedcff052015-01-16 12:53:55 -0800521 """
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700522 Description:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800523 add or remove iptables rule to DROP ( default )
524 packets from specific IP and PORT
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700525 Usage:
kelvin-onlabedcff052015-01-16 12:53:55 -0800526 * specify action ( 'add' or 'remove' )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700527 when removing, pass in the same argument as you would add. It will
Jon Hallfbc828e2015-01-06 17:30:19 -0800528 delete that specific rule.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800529 * specify the destination ip to block with dstIp
530 * specify destination port to block to dstPort
kelvin-onlabedcff052015-01-16 12:53:55 -0800531 * optional packet type to block ( default tcp )
532 * optional iptables rule ( default DROP )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700533 WARNING:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800534 * This function uses root privilege iptables command which may result
535 in unwanted network errors. USE WITH CAUTION
kelvin-onlabedcff052015-01-16 12:53:55 -0800536 """
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700537 import re
538 import time
539
kelvin-onlabedcff052015-01-16 12:53:55 -0800540 # NOTE*********
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700541 # The strict checking methods of this driver function is intentional
542 # to discourage any misuse or error of iptables, which can cause
543 # severe network errors
kelvin-onlabd3b64892015-01-20 13:26:24 -0800544 # *************
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700545
kelvin-onlabd3b64892015-01-20 13:26:24 -0800546 # NOTE: Sleep needed to give some time
547 # for rule to be added and registered
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700548 # to the instance
kelvin-onlabedcff052015-01-16 12:53:55 -0800549 time.sleep( 5 )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700550
kelvin-onlabd3b64892015-01-20 13:26:24 -0800551 actionType = action.lower()
552 if actionType != 'add' and actionType != 'remove':
kelvin-onlabedcff052015-01-16 12:53:55 -0800553 main.log.error(
554 "Invalid action type. 'add' or 'remove' table rule" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700555 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
kelvin-onlabedcff052015-01-16 12:53:55 -0800556 # NOTE: Currently only supports rules DROP, ACCEPT, and LOG
557 main.log.error(
558 "Invalid rule. 'DROP' or 'ACCEPT' or 'LOG' only." )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700559 return
560 return
561 else:
562
kelvin-onlabedcff052015-01-16 12:53:55 -0800563 # If there is no existing rule in the iptables, we will see an
kelvin-onlabd3b64892015-01-20 13:26:24 -0800564 # 'iptables:'... message. We expect to see this message.
kelvin-onlabedcff052015-01-16 12:53:55 -0800565 # Otherwise, if there IS an existing rule, we will get the prompt
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700566 # back, hence why we expect $ for remove type. We want to remove
567 # an already existing rule
568
kelvin-onlabd3b64892015-01-20 13:26:24 -0800569 if actionType == 'add':
570 # NOTE: "iptables:" expect is a result of
571 # return from the command
572 # iptables -C ...
573 # Any changes by the iptables command return string
574 # will result in failure of the function. ( deemed unlikely
575 # at the time of writing this function )
kelvin-onlabedcff052015-01-16 12:53:55 -0800576 # Check for existing rules on current input
577 self.handle.sendline( "" )
578 self.handle.expect( "\$" )
579 self.handle.sendline(
580 "sudo iptables -C OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800581 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800582 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800583 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800584 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800585 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800586 " -j " +
587 str( rule ) )
588 i = self.handle.expect( [ "iptables:", "\$" ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700589 print i
590 print self.handle.before
591 print "after: "
592 print self.handle.after
593
kelvin-onlabd3b64892015-01-20 13:26:24 -0800594 elif actionType == 'remove':
kelvin-onlabedcff052015-01-16 12:53:55 -0800595 # Check for existing rules on current input
596 self.handle.sendline( "" )
597 self.handle.expect( "\$" )
598 self.handle.sendline(
599 "sudo iptables -C OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800600 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800601 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800603 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800604 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800605 " -j " +
606 str( rule ) )
607 self.handle.expect( "\$" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700608 print "before: "
609 print self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800610 actualString = self.handle.after
611 expectString = "iptables:"
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700612 print "Actual String:"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800613 print actualString
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700614
kelvin-onlabd3b64892015-01-20 13:26:24 -0800615 if re.search( expectString, actualString ):
616 matchResult = main.TRUE
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700617 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800618 matchResult = main.FALSE
619 # If matchResult is main.TRUE, it means there is no matching rule.
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700620
kelvin-onlabd3b64892015-01-20 13:26:24 -0800621 # If tables does not exist and expected prompt is returned,
622 # go ahead and add iptables rule
623 if matchResult == main.TRUE:
kelvin-onlabedcff052015-01-16 12:53:55 -0800624 # Ensure action type is add
kelvin-onlabd3b64892015-01-20 13:26:24 -0800625 if actionType == 'add':
626 # -A is the 'append' action of iptables
627 actionAdd = '-A'
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700628 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800629 self.handle.sendline( "" )
630 self.handle.sendline(
631 "sudo iptables " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800632 actionAdd +
kelvin-onlabedcff052015-01-16 12:53:55 -0800633 " OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800634 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800635 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800636 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800637 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800638 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800639 " -j " +
640 str( rule ) )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700641
kelvin-onlabd3b64892015-01-20 13:26:24 -0800642 infoString = "Rules added to " + str( self.name )
Jon Hallefbd9792015-03-05 16:11:36 -0800643 infoString += "iptables rule added to block IP: " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -0800644 str( dstIp )
645 infoString += "Port: " + \
646 str( dstPort ) + " Rule: " + str( rule )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700647
kelvin-onlabd3b64892015-01-20 13:26:24 -0800648 main.log.info( infoString )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700649
kelvin-onlabedcff052015-01-16 12:53:55 -0800650 self.handle.expect(
651 [ "\$", pexpect.EOF, pexpect.TIMEOUT ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700652 except pexpect.TIMEOUT:
kelvin-onlabedcff052015-01-16 12:53:55 -0800653 main.log.error(
654 self.name +
655 ": Timeout exception in setIpTables function" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800656 except Exception:
657 main.log.exception( self.name +
658 ": Uncaught exception!" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700659 main.cleanup()
660 main.exit()
661 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800662 main.log.error(
663 "Given rule already exists, but attempted to add it" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800664 # If matchResult is 0, it means there IS a matching rule provided
665 elif matchResult == main.FALSE:
kelvin-onlabedcff052015-01-16 12:53:55 -0800666 # Ensure action type is remove
kelvin-onlabd3b64892015-01-20 13:26:24 -0800667 if actionType == 'remove':
668 # -D is the 'delete' rule of iptables
669 actionRemove = '-D'
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700670 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800671 self.handle.sendline( "" )
672 # Delete a specific rule specified into the function
673 self.handle.sendline(
674 "sudo iptables " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800675 actionRemove +
kelvin-onlabedcff052015-01-16 12:53:55 -0800676 " OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800677 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800678 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800679 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800680 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800681 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800682 " -j " +
683 str( rule ) )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700684
kelvin-onlabd3b64892015-01-20 13:26:24 -0800685 infoString = "Rules removed from " + str( self.name )
686 infoString += " iptables rule removed \
687 from blocking IP: " + \
688 str( dstIp )
689 infoString += " Port: " + \
690 str( dstPort ) + " Rule: " + str( rule )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700691
kelvin-onlabd3b64892015-01-20 13:26:24 -0800692 main.log.info( infoString )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700693
kelvin-onlabedcff052015-01-16 12:53:55 -0800694 self.handle.expect(
695 [ "\$", pexpect.EOF, pexpect.TIMEOUT ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700696 except pexpect.TIMEOUT:
kelvin-onlabedcff052015-01-16 12:53:55 -0800697 main.log.error(
698 self.name +
699 ": Timeout exception in setIpTables function" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800700 except Exception:
701 main.log.exception( self.name +
702 ": Uncaught exception!" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700703 main.cleanup()
704 main.exit()
705 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800706 main.log.error(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800707 "Given rule does not exist,\
708 but attempted to remove it" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700709 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800710 # NOTE: If a bad usage of this function occurs, exit the entire
711 # test
712 main.log.error( "Bad rule given for iptables. Exiting..." )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700713 main.cleanup()
714 main.exit()
715
716
adminbae64d82013-08-01 10:50:15 -0700717if __name__ != "__main__":
718 import sys
kelvin-onlabedcff052015-01-16 12:53:55 -0800719 sys.modules[ __name__ ] = RemoteMininetDriver()