blob: 8419489b8fb12f066de2a0b4f25bc7413ab83c6f [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:
kelvin-onlabedcff052015-01-16 12:53:55 -080094 main.log.error( "Error, unexpected output in the ping file" )
Jon Hall2ef1e9e2014-11-18 14:27:05 -050095 main.log.warn( outputs )
shahshreyaf4d4d0c2014-10-10 12:11:10 -070096 return main.TRUE
97
shahshreya3140b1a2015-04-28 14:22:15 -070098 def arping( self, host="", ip="10.128.20.211" ):
99 """
100 Description:
101 Sends arp message from mininet host for hosts discovery
102 Required:
103 host - hosts name
104 Optional:
105 ip - ip address that does not exist in the network so there would
106 be no reply.
107 """
108 cmd = " py " + host + ".cmd(\"arping -c 1 " + ip + "\")"
109 try:
110 main.log.warn( "Sending: " + cmd )
111 self.handle.sendline( cmd )
112 response = self.handle.before
113 self.handle.sendline( "" )
114 self.handle.expect( "mininet>" )
115 return main.TRUE
116
117 except pexpect.EOF:
118 main.log.error( self.name + ": EOF exception found" )
119 main.log.error( self.name + ": " + self.handle.before )
120 main.cleanup()
121 main.exit()
122
kelvin-onlabedcff052015-01-16 12:53:55 -0800123 def pingLong( self, **pingParams ):
124 """
Jon Hallefbd9792015-03-05 16:11:36 -0800125 Starts a continuous ping on the mininet host outputting
kelvin-onlabd3b64892015-01-20 13:26:24 -0800126 to a file in the /tmp dir.
kelvin-onlabedcff052015-01-16 12:53:55 -0800127 """
128 self.handle.sendline( "" )
129 self.handle.expect( "\$" )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800130 args = utilities.parse_args(
kelvin-onlabedcff052015-01-16 12:53:55 -0800131 [ "SRC", "TARGET", "PINGTIME" ], **pingParams )
132 precmd = "sudo rm /tmp/ping." + args[ "SRC" ]
133 self.execute( cmd=precmd, prompt="(.*)", timeout=10 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800134 command = "sudo mininet/util/m " + args[ "SRC" ] + " ping " +\
Jon Hallefbd9792015-03-05 16:11:36 -0800135 args[ "TARGET" ] + " -i .2 -w " +\
136 str( args[ 'PINGTIME' ] ) + " -D > /tmp/ping." +\
137 args[ "SRC" ] + " &"
Jon Hallfbc828e2015-01-06 17:30:19 -0800138 main.log.info( command )
kelvin-onlabedcff052015-01-16 12:53:55 -0800139 self.execute( cmd=command, prompt="(.*)", timeout=10 )
140 self.handle.sendline( "" )
141 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700142 return main.TRUE
143
kelvin-onlabedcff052015-01-16 12:53:55 -0800144 def pingstatus( self, **pingParams ):
145 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800146 Tails the respective ping output file and check that
147 there is a moving "64 bytes"
kelvin-onlabedcff052015-01-16 12:53:55 -0800148 """
149 self.handle.sendline( "" )
150 self.handle.expect( "\$" )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800151 args = utilities.parse_args( [ "SRC" ], **pingParams )
kelvin-onlabedcff052015-01-16 12:53:55 -0800152 self.handle.sendline( "tail /tmp/ping." + args[ "SRC" ] )
153 self.handle.expect( "tail" )
154 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700155 result = self.handle.before + self.handle.after
kelvin-onlabedcff052015-01-16 12:53:55 -0800156 self.handle.sendline( "" )
157 self.handle.expect( "\$" )
158 if re.search( 'Unreachable', result ):
159 main.log.info( "Unreachable found in ping logs..." )
adminbae64d82013-08-01 10:50:15 -0700160 return main.FALSE
kelvin-onlabedcff052015-01-16 12:53:55 -0800161 elif re.search( '64\sbytes', result ):
162 main.log.info( "Pings look good" )
adminbae64d82013-08-01 10:50:15 -0700163 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800164 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800165 main.log.info( "No, or faulty ping data..." )
adminbae64d82013-08-01 10:50:15 -0700166 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800167
kelvin-onlabedcff052015-01-16 12:53:55 -0800168 def pingKill( self, testONUser, testONIP ):
169 """
adminaeedddd2013-08-02 15:14:15 -0700170 Kills all continuous ping processes.
171 Then copies all the ping files to the TestStation.
kelvin-onlabedcff052015-01-16 12:53:55 -0800172 """
173 self.handle.sendline( "" )
174 self.handle.expect( "\$" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800175 command = "sudo kill -SIGINT `pgrep ping`"
176 main.log.info( command )
kelvin-onlabedcff052015-01-16 12:53:55 -0800177 self.execute( cmd=command, prompt="(.*)", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800178
adminbae64d82013-08-01 10:50:15 -0700179 main.log.info( "Transferring ping files to TestStation" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800180 command = "scp /tmp/ping.* " + \
181 str( testONUser ) + "@" + str( testONIP ) + ":/tmp/"
182 self.execute( cmd=command, prompt="100%", timeout=20 )
183 # Make sure the output is cleared
184 self.handle.sendline( "" )
185 self.handle.expect( "\$" )
186 self.handle.sendline( "" )
187 self.handle.expect( "\$" )
188 self.handle.sendline( "" )
189 i = self.handle.expect( [ "password", "\$" ] )
Jon Hall368769f2014-11-19 15:43:35 -0800190 if i == 0:
kelvin-onlabedcff052015-01-16 12:53:55 -0800191 main.log.error( "Error, sudo asking for password" )
192 main.log.error( self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800193 return main.FALSE
194 else:
195 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800196
kelvin-onlabedcff052015-01-16 12:53:55 -0800197 def pingLongKill( self ):
198 self.handle.sendline( "" )
199 self.handle.expect( "\$" )
admin2580a0e2014-07-29 11:24:34 -0700200 command = "sudo kill -SIGING `pgrep ping`"
kelvin-onlabedcff052015-01-16 12:53:55 -0800201 main.log.info( command )
202 self.execute( cmd=command, prompt="(.*)", timeout=10 )
203 self.handle.sendline( "" )
204 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700205 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -0800206
kelvin-onlabedcff052015-01-16 12:53:55 -0800207 def pingHostOptical( self, **pingParams ):
208 """
Jon Hallefbd9792015-03-05 16:11:36 -0800209 This function is only for Packet Optical related ping
kelvin-onlabedcff052015-01-16 12:53:55 -0800210 Use the next pingHost() function for all normal scenarios )
shahshreya28bb18e2014-11-17 10:26:23 -0800211 Ping from one mininet host to another
212 Currently the only supported Params: SRC and TARGET
kelvin-onlabedcff052015-01-16 12:53:55 -0800213 """
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800214 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
kelvin-onlabedcff052015-01-16 12:53:55 -0800215 command = args[ "SRC" ] + " ping " + \
216 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
shahshreya28bb18e2014-11-17 10:26:23 -0800217 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800218 main.log.warn( "Sending: " + command )
kelvin-onlabedcff052015-01-16 12:53:55 -0800219 self.handle.sendline( command )
220 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
shahshreya28bb18e2014-11-17 10:26:23 -0800221 if i == 1:
kelvin-onlabedcff052015-01-16 12:53:55 -0800222 main.log.error(
223 self.name +
224 ": timeout when waiting for response from mininet" )
225 main.log.error( "response: " + str( self.handle.before ) )
226 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
shahshreya28bb18e2014-11-17 10:26:23 -0800227 if i == 1:
kelvin-onlabedcff052015-01-16 12:53:55 -0800228 main.log.error(
229 self.name +
230 ": timeout when waiting for response from mininet" )
231 main.log.error( "response: " + str( self.handle.before ) )
shahshreya28bb18e2014-11-17 10:26:23 -0800232 response = self.handle.before
233 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800234 main.log.error( self.name + ": EOF exception found" )
235 main.log.error( self.name + ": " + self.handle.before )
shahshreya28bb18e2014-11-17 10:26:23 -0800236 main.cleanup()
237 main.exit()
kelvin-onlabedcff052015-01-16 12:53:55 -0800238 main.log.info( self.name + ": Ping Response: " + response )
kelvin-onlabedcff052015-01-16 12:53:55 -0800239 if re.search( ',\s0\%\spacket\sloss', response ):
240 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 main.lastResult = main.TRUE
shahshreya28bb18e2014-11-17 10:26:23 -0800242 return main.TRUE
kelvin-onlabedcff052015-01-16 12:53:55 -0800243 else:
244 main.log.error(
245 self.name +
246 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 main.lastResult = main.FALSE
shahshreya28bb18e2014-11-17 10:26:23 -0800248 return main.FALSE
249
kelvin-onlabedcff052015-01-16 12:53:55 -0800250 def pingHost( self, **pingParams ):
251 """
Jon Hallfbc828e2015-01-06 17:30:19 -0800252 Pings between two hosts on remote mininet
kelvin-onlabedcff052015-01-16 12:53:55 -0800253 """
254 self.handle.sendline( "" )
255 self.handle.expect( "\$" )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800256 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
kelvin-onlabedcff052015-01-16 12:53:55 -0800257 command = "mininet/util/m " + \
258 args[ "SRC" ] + " ping " + args[ "TARGET" ] + " -c 4 -W 1 -i .2"
259 main.log.info( command )
260 response = self.execute( cmd=command, prompt="rtt", timeout=10 )
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800261 if utilities.assert_matches(
kelvin-onlabedcff052015-01-16 12:53:55 -0800262 expect=',\s0\%\spacket\sloss',
263 actual=response,
264 onpass="No Packet loss",
265 onfail="Host is not reachable" ):
266 main.log.info( "NO PACKET LOSS, HOST IS REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700268 return main.TRUE
kelvin-onlabedcff052015-01-16 12:53:55 -0800269 else:
270 main.log.error( "PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800271 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700272 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800273
kelvin-onlabedcff052015-01-16 12:53:55 -0800274 def checknum( self, num ):
275 """
Jon Hallfbc828e2015-01-06 17:30:19 -0800276 Verifies the correct number of switches are running
kelvin-onlabedcff052015-01-16 12:53:55 -0800277 """
278 if self.handle:
279 self.handle.sendline( "" )
280 self.handle.expect( "\$" )
281 self.handle.sendline( 'ifconfig -a | grep "sw.. " | wc -l' )
282 self.handle.expect( "wc" )
283 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700284 response = self.handle.before
kelvin-onlabedcff052015-01-16 12:53:55 -0800285 self.handle.sendline(
286 'ps -ef | grep "bash -ms mininet:sw" | grep -v color | wc -l' )
287 self.handle.expect( "color" )
288 self.handle.expect( "\$" )
adminbae64d82013-08-01 10:50:15 -0700289 response2 = self.handle.before
290
kelvin-onlabedcff052015-01-16 12:53:55 -0800291 if re.search( num, response ):
292 if re.search( num, response2 ):
adminbae64d82013-08-01 10:50:15 -0700293 return main.TRUE
294 else:
295 return main.FALSE
296 else:
297 return main.FALSE
kelvin-onlabedcff052015-01-16 12:53:55 -0800298 else:
299 main.log.error( "Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -0700300
kelvin-onlabd3b64892015-01-20 13:26:24 -0800301 def startTcpdump(
kelvin-onlabedcff052015-01-16 12:53:55 -0800302 self,
303 filename,
304 intf="eth0",
305 port="port 6633",
306 user="admin" ):
307 """
Jon Hallefbd9792015-03-05 16:11:36 -0800308 Runs tcpdump on an interface and saves the file
admin2a9548d2014-06-17 14:08:07 -0700309 intf can be specified, or the default eth0 is used
kelvin-onlabedcff052015-01-16 12:53:55 -0800310 """
admin2a9548d2014-06-17 14:08:07 -0700311 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800312 self.handle.sendline( "" )
313 self.handle.sendline(
314 "sudo tcpdump -n -i " +
315 intf +
316 " " +
317 port +
318 " -w " +
319 filename.strip() +
320 " -Z " +
321 user +
322 " &" )
323 self.handle.sendline( "" )
324 self.handle.sendline( "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800325 i = self.handle.expect( [ 'No\ssuch\device', 'listening\son',
326 pexpect.TIMEOUT, "\$" ], timeout=10 )
Jon Hall61282e32015-03-19 11:34:11 -0700327 main.log.info( self.handle.before + self.handle.after )
admin2a9548d2014-06-17 14:08:07 -0700328 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800329 main.log.error( self.name + ": tcpdump - No such device exists.\
330 tcpdump attempted on: " + intf )
admin2a9548d2014-06-17 14:08:07 -0700331 return main.FALSE
332 elif i == 1:
kelvin-onlabedcff052015-01-16 12:53:55 -0800333 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -0700334 return main.TRUE
335 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800336 main.log.error( self.name + ": tcpdump command timed out!\
337 Check interface name, given interface was: " + intf )
admin2a9548d2014-06-17 14:08:07 -0700338 return main.FALSE
kelvin-onlabedcff052015-01-16 12:53:55 -0800339 elif i == 3:
340 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700341 return main.TRUE
342 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800343 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -0700344 return main.FALSE
345 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800346 main.log.error( self.name + ": EOF exception found" )
347 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700348 main.cleanup()
349 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800350 except Exception:
351 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -0700352 main.cleanup()
353 main.exit()
354
kelvin-onlabd3b64892015-01-20 13:26:24 -0800355 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -0800356 """
357 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -0700358 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800359 self.handle.sendline( "sudo pkill tcpdump" )
360 self.handle.sendline( "" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800361 self.handle.expect( "\$" )
admin2a9548d2014-06-17 14:08:07 -0700362 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800363 main.log.error( self.name + ": EOF exception found" )
364 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700365 main.cleanup()
366 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800367 except Exception:
368 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -0700369 main.cleanup()
370 main.exit()
371
shahshreya1f119da2015-04-21 17:16:46 -0700372 def runOpticalMnScript( self,name = 'onos', ctrllerIP = None ):
shahshreya2c57c902015-04-06 20:40:20 -0700373 import time
shahshreya1f119da2015-04-21 17:16:46 -0700374 import types
kelvin-onlabedcff052015-01-16 12:53:55 -0800375 """
shahshreya1f119da2015-04-21 17:16:46 -0700376 Description:
377 This function is only meant for Packet Optical.
378 It runs python script "opticalTest.py" to create the
379 packet layer( mn ) and optical topology
380 Optional:
381 name - Name of onos directory. (ONOS | onos)
382 Required:
383 ctrllerIP = Controller(s) IP address
384 TODO: If no ctrllerIP is provided, a default
shahshreya2c57c902015-04-06 20:40:20 -0700385 $OC1 can be accepted
kelvin-onlabedcff052015-01-16 12:53:55 -0800386 """
shahshreya28bb18e2014-11-17 10:26:23 -0800387 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800388 self.handle.sendline( "" )
389 self.handle.expect( "\$" )
shahshreya1f119da2015-04-21 17:16:46 -0700390 self.handle.sendline( "cd ~/" + name + "/tools/test/topos" )
shahshreya2c57c902015-04-06 20:40:20 -0700391 self.handle.expect( "topos\$" )
392 if ctrllerIP == None:
393 main.log.info( "You need to specify the IP" )
394 return main.FALSE
395 else:
shahshreya1f119da2015-04-21 17:16:46 -0700396 controller = ''
397 if isinstance( ctrllerIP, types.ListType ):
398 for i in xrange( len( ctrllerIP ) ):
399 controller += ctrllerIP[i] + ' '
400 main.log.info( "Mininet topology is being loaded with " +
401 "controllers: " + controller )
402 elif isinstance( ctrllerIP, types.StringType ):
403 controller = ctrllerIP
404 main.log.info( "Mininet topology is being loaded with " +
405 "controller: " + controller )
406 else:
407 main.log.info( "You need to specify a valid IP" )
408 return main.FALSE
409 cmd = "sudo -E python opticalTest.py " + controller
410 main.log.info( self.name + ": cmd = " + cmd )
shahshreya2c57c902015-04-06 20:40:20 -0700411 self.handle.sendline( cmd )
412 self.handle.expect( "Press ENTER to push Topology.json" )
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( "\$" )
shahshreyadccfbc62015-02-20 11:40:09 -0800451 i = self.handle.expect( [ '\$', 'mininet>', pexpect.TIMEOUT ],
Jon Hallefbd9792015-03-05 16:11:36 -0800452 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" )
463
kelvin-onlabedcff052015-01-16 12:53:55 -0800464 else:
465 main.log.error( "Connection failed to the host" )
Jon Halld61331b2015-02-17 16:35:47 -0800466 return main.TRUE
adminbae64d82013-08-01 10:50:15 -0700467
kelvin-onlabd3b64892015-01-20 13:26:24 -0800468 def getFlowTable( self, protoVersion, sw ):
469 """
470 TODO document usage
Jon Hallefbd9792015-03-05 16:11:36 -0800471 TODO add option to look at cookies. ignoring them for now
kelvin-onlabd3b64892015-01-20 13:26:24 -0800472
473 print "get_flowTable(" + str( protoVersion ) +" " + str( sw ) +")"
474 NOTE: Use format to force consistent flow table output across
475 versions"""
kelvin-onlabedcff052015-01-16 12:53:55 -0800476 self.handle.sendline( "cd" )
477 self.handle.expect( [ "\$", pexpect.EOF, pexpect.TIMEOUT ] )
kelvin-onlabedcff052015-01-16 12:53:55 -0800478 if protoVersion == 1.0:
479 command = "sudo ovs-ofctl dump-flows " + sw + \
kelvin-onlabd3b64892015-01-20 13:26:24 -0800480 " -F OpenFlow10-table_id | awk '{OFS=\",\" ; print $1 $3 $6 \
481 $7 $8}' | cut -d ',' -f 2- | sort -n -k1 -r"
kelvin-onlabedcff052015-01-16 12:53:55 -0800482 self.handle.sendline( command )
483 self.handle.expect( [ "k1 -r", pexpect.EOF, pexpect.TIMEOUT ] )
484 self.handle.expect(
485 [ "OFPST_FLOW", pexpect.EOF, pexpect.TIMEOUT ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700486 response = self.handle.before
kelvin-onlabedcff052015-01-16 12:53:55 -0800487 # print "response=", response
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700488 return response
kelvin-onlabedcff052015-01-16 12:53:55 -0800489 elif protoVersion == 1.3:
490 command = "sudo ovs-ofctl dump-flows " + sw + \
kelvin-onlabd3b64892015-01-20 13:26:24 -0800491 " -O OpenFlow13 | awk '{OFS=\",\" ; print $1 $3 $6 $7}'\
492 | cut -d ',' -f 2- | sort -n -k1 -r"
kelvin-onlabedcff052015-01-16 12:53:55 -0800493 self.handle.sendline( command )
494 self.handle.expect( [ "k1 -r", pexpect.EOF, pexpect.TIMEOUT ] )
495 self.handle.expect(
496 [ "OFPST_FLOW", pexpect.EOF, pexpect.TIMEOUT ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700497 response = self.handle.before
kelvin-onlabedcff052015-01-16 12:53:55 -0800498 # print "response=", response
Jon Hall94fd0472014-12-08 11:52:42 -0800499 return response
500 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800501 main.log.error(
502 "Unknown protoVersion in get_flowTable(). given: (" +
503 str(
504 type( protoVersion ) ) +
505 ") '" +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 str( protoVersion ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800507 "'" )
Jon Hall94fd0472014-12-08 11:52:42 -0800508
kelvin-onlabd3b64892015-01-20 13:26:24 -0800509 def flowComp( self, flow1, flow2 ):
kelvin-onlabedcff052015-01-16 12:53:55 -0800510 if flow1 == flow2:
santhosh19fd8032014-07-29 11:56:17 -0700511 return main.TRUE
512 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800513 main.log.info( "Flow tables do not match, printing tables:" )
514 main.log.info( "Flow Table 1:" )
515 main.log.info( flow1 )
516 main.log.info( "Flow Table 2:" )
517 main.log.info( flow2 )
santhosh19fd8032014-07-29 11:56:17 -0700518 return main.FALSE
519
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 def setIpTablesOUTPUT( self, dstIp, dstPort, action='add',
521 packetType='tcp', rule='DROP' ):
kelvin-onlabedcff052015-01-16 12:53:55 -0800522 """
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700523 Description:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800524 add or remove iptables rule to DROP ( default )
525 packets from specific IP and PORT
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700526 Usage:
kelvin-onlabedcff052015-01-16 12:53:55 -0800527 * specify action ( 'add' or 'remove' )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700528 when removing, pass in the same argument as you would add. It will
Jon Hallfbc828e2015-01-06 17:30:19 -0800529 delete that specific rule.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800530 * specify the destination ip to block with dstIp
531 * specify destination port to block to dstPort
kelvin-onlabedcff052015-01-16 12:53:55 -0800532 * optional packet type to block ( default tcp )
533 * optional iptables rule ( default DROP )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700534 WARNING:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800535 * This function uses root privilege iptables command which may result
536 in unwanted network errors. USE WITH CAUTION
kelvin-onlabedcff052015-01-16 12:53:55 -0800537 """
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700538 import re
539 import time
540
kelvin-onlabedcff052015-01-16 12:53:55 -0800541 # NOTE*********
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700542 # The strict checking methods of this driver function is intentional
543 # to discourage any misuse or error of iptables, which can cause
544 # severe network errors
kelvin-onlabd3b64892015-01-20 13:26:24 -0800545 # *************
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700546
kelvin-onlabd3b64892015-01-20 13:26:24 -0800547 # NOTE: Sleep needed to give some time
548 # for rule to be added and registered
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700549 # to the instance
kelvin-onlabedcff052015-01-16 12:53:55 -0800550 time.sleep( 5 )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700551
kelvin-onlabd3b64892015-01-20 13:26:24 -0800552 actionType = action.lower()
553 if actionType != 'add' and actionType != 'remove':
kelvin-onlabedcff052015-01-16 12:53:55 -0800554 main.log.error(
555 "Invalid action type. 'add' or 'remove' table rule" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700556 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
kelvin-onlabedcff052015-01-16 12:53:55 -0800557 # NOTE: Currently only supports rules DROP, ACCEPT, and LOG
558 main.log.error(
559 "Invalid rule. 'DROP' or 'ACCEPT' or 'LOG' only." )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700560 return
561 return
562 else:
563
kelvin-onlabedcff052015-01-16 12:53:55 -0800564 # If there is no existing rule in the iptables, we will see an
kelvin-onlabd3b64892015-01-20 13:26:24 -0800565 # 'iptables:'... message. We expect to see this message.
kelvin-onlabedcff052015-01-16 12:53:55 -0800566 # Otherwise, if there IS an existing rule, we will get the prompt
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700567 # back, hence why we expect $ for remove type. We want to remove
568 # an already existing rule
569
kelvin-onlabd3b64892015-01-20 13:26:24 -0800570 if actionType == 'add':
571 # NOTE: "iptables:" expect is a result of
572 # return from the command
573 # iptables -C ...
574 # Any changes by the iptables command return string
575 # will result in failure of the function. ( deemed unlikely
576 # at the time of writing this function )
kelvin-onlabedcff052015-01-16 12:53:55 -0800577 # Check for existing rules on current input
578 self.handle.sendline( "" )
579 self.handle.expect( "\$" )
580 self.handle.sendline(
581 "sudo iptables -C OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800583 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800584 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800585 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800586 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800587 " -j " +
588 str( rule ) )
589 i = self.handle.expect( [ "iptables:", "\$" ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700590 print i
591 print self.handle.before
592 print "after: "
593 print self.handle.after
594
kelvin-onlabd3b64892015-01-20 13:26:24 -0800595 elif actionType == 'remove':
kelvin-onlabedcff052015-01-16 12:53:55 -0800596 # Check for existing rules on current input
597 self.handle.sendline( "" )
598 self.handle.expect( "\$" )
599 self.handle.sendline(
600 "sudo iptables -C OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800601 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800602 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800603 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800604 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800605 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800606 " -j " +
607 str( rule ) )
608 self.handle.expect( "\$" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700609 print "before: "
610 print self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800611 actualString = self.handle.after
612 expectString = "iptables:"
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700613 print "Actual String:"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800614 print actualString
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700615
kelvin-onlabd3b64892015-01-20 13:26:24 -0800616 if re.search( expectString, actualString ):
617 matchResult = main.TRUE
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700618 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800619 matchResult = main.FALSE
620 # If matchResult is main.TRUE, it means there is no matching rule.
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700621
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 # If tables does not exist and expected prompt is returned,
623 # go ahead and add iptables rule
624 if matchResult == main.TRUE:
kelvin-onlabedcff052015-01-16 12:53:55 -0800625 # Ensure action type is add
kelvin-onlabd3b64892015-01-20 13:26:24 -0800626 if actionType == 'add':
627 # -A is the 'append' action of iptables
628 actionAdd = '-A'
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700629 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800630 self.handle.sendline( "" )
631 self.handle.sendline(
632 "sudo iptables " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800633 actionAdd +
kelvin-onlabedcff052015-01-16 12:53:55 -0800634 " OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800635 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800636 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800637 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800638 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800639 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800640 " -j " +
641 str( rule ) )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700642
kelvin-onlabd3b64892015-01-20 13:26:24 -0800643 infoString = "Rules added to " + str( self.name )
Jon Hallefbd9792015-03-05 16:11:36 -0800644 infoString += "iptables rule added to block IP: " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -0800645 str( dstIp )
646 infoString += "Port: " + \
647 str( dstPort ) + " Rule: " + str( rule )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700648
kelvin-onlabd3b64892015-01-20 13:26:24 -0800649 main.log.info( infoString )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700650
kelvin-onlabedcff052015-01-16 12:53:55 -0800651 self.handle.expect(
652 [ "\$", pexpect.EOF, pexpect.TIMEOUT ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700653 except pexpect.TIMEOUT:
kelvin-onlabedcff052015-01-16 12:53:55 -0800654 main.log.error(
655 self.name +
656 ": Timeout exception in setIpTables function" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800657 except Exception:
658 main.log.exception( self.name +
659 ": Uncaught exception!" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700660 main.cleanup()
661 main.exit()
662 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800663 main.log.error(
664 "Given rule already exists, but attempted to add it" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800665 # If matchResult is 0, it means there IS a matching rule provided
666 elif matchResult == main.FALSE:
kelvin-onlabedcff052015-01-16 12:53:55 -0800667 # Ensure action type is remove
kelvin-onlabd3b64892015-01-20 13:26:24 -0800668 if actionType == 'remove':
669 # -D is the 'delete' rule of iptables
670 actionRemove = '-D'
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700671 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800672 self.handle.sendline( "" )
673 # Delete a specific rule specified into the function
674 self.handle.sendline(
675 "sudo iptables " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800676 actionRemove +
kelvin-onlabedcff052015-01-16 12:53:55 -0800677 " OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800678 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800679 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800680 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800681 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800683 " -j " +
684 str( rule ) )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700685
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 infoString = "Rules removed from " + str( self.name )
687 infoString += " iptables rule removed \
688 from blocking IP: " + \
689 str( dstIp )
690 infoString += " Port: " + \
691 str( dstPort ) + " Rule: " + str( rule )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700692
kelvin-onlabd3b64892015-01-20 13:26:24 -0800693 main.log.info( infoString )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700694
kelvin-onlabedcff052015-01-16 12:53:55 -0800695 self.handle.expect(
696 [ "\$", pexpect.EOF, pexpect.TIMEOUT ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700697 except pexpect.TIMEOUT:
kelvin-onlabedcff052015-01-16 12:53:55 -0800698 main.log.error(
699 self.name +
700 ": Timeout exception in setIpTables function" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800701 except Exception:
702 main.log.exception( self.name +
703 ": Uncaught exception!" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700704 main.cleanup()
705 main.exit()
706 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800707 main.log.error(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800708 "Given rule does not exist,\
709 but attempted to remove it" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700710 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800711 # NOTE: If a bad usage of this function occurs, exit the entire
712 # test
713 main.log.error( "Bad rule given for iptables. Exiting..." )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700714 main.cleanup()
715 main.exit()
716
717
adminbae64d82013-08-01 10:50:15 -0700718if __name__ != "__main__":
719 import sys
kelvin-onlabedcff052015-01-16 12:53:55 -0800720 sys.modules[ __name__ ] = RemoteMininetDriver()