blob: f4adb81f7c0184d8bed3d2733792c63b8d286ab6 [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
Jeremy Songsterae01bba2016-07-11 15:39:17 -07004Modified 2016 by ON.Lab
adminbae64d82013-08-01 10:50:15 -07005
Jeremy Songsterae01bba2016-07-11 15:39:17 -07006Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
7the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
8or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
adminbae64d82013-08-01 10:50:15 -07009
10 TestON is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 2 of the License, or
kelvin-onlabedcff052015-01-16 12:53:55 -080013 ( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070014
15 TestON is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
Jon Hallfbc828e2015-01-06 17:30:19 -080021 along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070022
23
24MininetCliDriver is the basic driver which will handle the Mininet functions
kelvin-onlabedcff052015-01-16 12:53:55 -080025"""
adminbae64d82013-08-01 10:50:15 -070026import pexpect
adminbae64d82013-08-01 10:50:15 -070027import re
28import sys
kelvin-onlaba4074292015-07-09 15:19:49 -070029import os
adminbae64d82013-08-01 10:50:15 -070030from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070031
kelvin-onlabedcff052015-01-16 12:53:55 -080032
33class RemoteMininetDriver( Emulator ):
34
35 """
kelvin-onlabd3b64892015-01-20 13:26:24 -080036 RemoteMininetCliDriver is the basic driver which will handle the Mininet
37 functions. The main different between this and the MininetCliDriver is that
38 this one does not build the mininet. It assumes that there is already a
39 mininet running on the target.
kelvin-onlabedcff052015-01-16 12:53:55 -080040 """
41 def __init__( self ):
42 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070043 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080044 self.name = None
kelvin-onlabedcff052015-01-16 12:53:55 -080045 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070046 self.flag = 0
47
kelvin-onlabedcff052015-01-16 12:53:55 -080048 def connect( self, **connectargs ):
kelvin-onlab08679eb2015-01-21 16:11:48 -080049 """,user_name, ip_address, pwd,options ):
kelvin-onlabd3b64892015-01-20 13:26:24 -080050 Here the main is the TestON instance after creating all the log
51 handles."""
kelvin-onlaba4074292015-07-09 15:19:49 -070052 try:
Ming Yan Shu404f7e72016-07-22 14:37:03 -070053 for key in connectargs:
54 vars( self )[ key ] = connectargs[ key ]
55
56 self.name = self.options[ 'name' ]
57
58 try:
59 if os.getenv( str( self.ip_address ) ) != None:
60 self.ip_address = os.getenv( str( self.ip_address ) )
61 else:
62 main.log.info( self.name +
63 ": Trying to connect to " +
64 self.ip_address )
65
66 except KeyError:
67 main.log.info( "Invalid host name," +
68 " connecting to local host instead" )
69 self.ip_address = 'localhost'
70 except Exception as inst:
71 main.log.error( "Uncaught exception: " + str( inst ) )
72
73 self.handle = super(
74 RemoteMininetDriver,
75 self ).connect(
76 user_name=self.user_name,
77 ip_address=self.ip_address,
78 port=None,
79 pwd=self.pwd )
80
81 # Copying the readme file to process the
82 if self.handle:
83 return main.TRUE
84
kelvin-onlaba4074292015-07-09 15:19:49 -070085 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -070086 main.log.error(
87 "Connection failed to the host " +
88 self.user_name +
89 "@" +
90 self.ip_address )
91 main.log.error( "Failed to connect to the Mininet" )
92 return main.FALSE
93 except Exception:
94 main.log.exception( self.name + ": Uncaught exception!" )
95 main.cleanup()
96 main.exit()
admin98ad0092014-07-23 16:51:07 -070097
kelvin-onlabedcff052015-01-16 12:53:55 -080098 def checkForLoss( self, pingList ):
99 """
Jon Hall6c794f32014-08-14 13:33:13 -0700100 Returns main.FALSE for 0% packet loss and
101 Returns main.ERROR if "found multiple mininet" is found and
102 Returns main.TRUE else
kelvin-onlabedcff052015-01-16 12:53:55 -0800103 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700104 try:
105 self.handle.sendline( "" )
106 self.handle.expect( "\$" )
107 self.handle.sendline( "" )
108 self.handle.expect( "\$" )
109 self.handle.sendline( "cat " + pingList )
110 self.handle.expect( pingList )
111 self.handle.expect( "\$" )
112 outputs = self.handle.before + self.handle.after
113 if re.search( " 0% packet loss", outputs ):
114 return main.FALSE
115 elif re.search( "found multiple mininet", outputs ):
116 return main.ERROR
117 else:
118 # TODO: Parse for failed pings, give some truncated output
119 main.log.error( "Error, unexpected output in the ping file" )
120 main.log.warn( outputs )
121 return main.TRUE
122 except pexpect.TIMEOUT:
123 main.log.exception( self.name + ": TIMEOUT exception found in checkForLoss" )
124 main.log.error( self.name + ": " + self.handle.before )
admin98ad0092014-07-23 16:51:07 -0700125 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700126 except pexpect.EOF:
127 main.log.error( self.name + ": EOF exception found" )
128 main.log.error( self.name + ": " + self.handle.before )
129 main.cleanup()
130 main.exit()
131 except Exception:
132 main.log.exception( self.name + ": Uncaught exception!" )
133 main.cleanup()
134 main.exit()
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700135
kelvin-onlabedcff052015-01-16 12:53:55 -0800136 def pingLong( self, **pingParams ):
137 """
Jon Hallefbd9792015-03-05 16:11:36 -0800138 Starts a continuous ping on the mininet host outputting
kelvin-onlabd3b64892015-01-20 13:26:24 -0800139 to a file in the /tmp dir.
kelvin-onlabedcff052015-01-16 12:53:55 -0800140 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700141 try:
142 self.handle.sendline( "" )
143 self.handle.expect( "\$" )
144 args = utilities.parse_args(
145 [ "SRC", "TARGET", "PINGTIME" ], **pingParams )
146 precmd = "sudo rm /tmp/ping." + args[ "SRC" ]
147 self.execute( cmd=precmd, prompt="(.*)", timeout=10 )
148 command = "sudo mininet/util/m " + args[ "SRC" ] + " ping " +\
149 args[ "TARGET" ] + " -i .2 -w " +\
150 str( args[ 'PINGTIME' ] ) + " -D > /tmp/ping." +\
151 args[ "SRC" ] + " &"
152 main.log.info( command )
153 self.execute( cmd=command, prompt="(.*)", timeout=10 )
154 self.handle.sendline( "" )
155 self.handle.expect( "\$" )
156 return main.TRUE
157 except TypeError:
158 main.log.exception(self.name + ": Object not as expected")
159 return main.FALSE
160 except pexpect.TIMEOUT:
161 main.log.exception( self.name + ": TIMEOUT exception found in pingLong" )
162 main.log.error( self.name + ": " + self.handle.before )
163 return main.FALSE
164 except pexpect.EOF:
165 main.log.error( self.name + ": EOF exception found" )
166 main.log.error( self.name + ": " + self.handle.before )
167 main.cleanup()
168 main.exit()
169 except Exception:
170 main.log.exception( self.name + ": Uncaught exception!" )
171 main.cleanup()
172 main.exit()
173
adminbae64d82013-08-01 10:50:15 -0700174
kelvin-onlabedcff052015-01-16 12:53:55 -0800175 def pingstatus( self, **pingParams ):
176 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800177 Tails the respective ping output file and check that
178 there is a moving "64 bytes"
kelvin-onlabedcff052015-01-16 12:53:55 -0800179 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700180 try:
181 self.handle.sendline( "" )
182 self.handle.expect( "\$" )
183 args = utilities.parse_args( [ "SRC" ], **pingParams )
184 self.handle.sendline( "tail /tmp/ping." + args[ "SRC" ] )
185 self.handle.expect( "tail" )
186 self.handle.expect( "\$" )
187 result = self.handle.before + self.handle.after
188 self.handle.sendline( "" )
189 self.handle.expect( "\$" )
190 if re.search( 'Unreachable', result ):
191 main.log.info( "Unreachable found in ping logs..." )
192 return main.FALSE
193 elif re.search( '64\sbytes', result ):
194 main.log.info( "Pings look good" )
195 return main.TRUE
196 else:
197 main.log.info( "No, or faulty ping data..." )
198 return main.FALSE
199 except TypeError:
200 main.log.exception( self.name + ": Object not as expected" )
adminbae64d82013-08-01 10:50:15 -0700201 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700202 except pexpect.TIMEOUT:
203 main.log.exception( self.name + ": TIMEOUT exception found in pingstatus" )
204 main.log.error( self.name + ": " + self.handle.before )
adminbae64d82013-08-01 10:50:15 -0700205 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700206 except pexpect.EOF:
207 main.log.error( self.name + ": EOF exception found" )
208 main.log.error( self.name + ": " + self.handle.before )
209 main.cleanup()
210 main.exit()
211 except Exception:
212 main.log.exception(self.name + ": Uncaught exception!")
213 main.cleanup()
214 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800215
kelvin-onlabedcff052015-01-16 12:53:55 -0800216 def pingKill( self, testONUser, testONIP ):
217 """
adminaeedddd2013-08-02 15:14:15 -0700218 Kills all continuous ping processes.
219 Then copies all the ping files to the TestStation.
kelvin-onlabedcff052015-01-16 12:53:55 -0800220 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700221 try:
222 self.handle.sendline( "" )
223 self.handle.expect( "\$" )
224 command = "sudo kill -SIGINT `pgrep ping`"
225 main.log.info( command )
226 self.execute( cmd=command, prompt="(.*)", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800227
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700228 main.log.info( "Transferring ping files to TestStation" )
229 command = "scp /tmp/ping.* " + \
230 str( testONUser ) + "@" + str( testONIP ) + ":/tmp/"
231 self.execute( cmd=command, prompt="100%", timeout=20 )
232 # Make sure the output is cleared
233 self.handle.sendline( "" )
234 self.handle.expect( "\$" )
235 self.handle.sendline( "" )
236 self.handle.expect( "\$" )
237 self.handle.sendline( "" )
238 i = self.handle.expect( [ "password", "\$" ] )
239 if i == 0:
240 main.log.error( "Error, sudo asking for password" )
241 main.log.error( self.handle.before )
242 return main.FALSE
243 else:
244 return main.TRUE
245 except pexpect.TIMEOUT:
246 main.log.error( self.name + ": TIMEOUT exception found in pingKill" )
247 main.log.error( self.name + ": " + self.handle.before )
248 main.cleanup()
249 main.exit()
250 except pexpect.EOF:
251 main.log.error( self.name + ": EOF exception found" )
252 main.log.error( self.name + ": " + self.handle.before )
253 main.cleanup()
254 main.exit()
255 except Exception:
256 main.log.exception( self.name + ": Uncaught exception!" )
257 main.cleanup()
258 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800259
kelvin-onlabedcff052015-01-16 12:53:55 -0800260 def pingLongKill( self ):
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700261 try:
262 self.handle.sendline( "" )
263 self.handle.expect( "\$" )
264 command = "sudo kill -SIGING `pgrep ping`"
265 main.log.info( command )
266 self.execute( cmd=command, prompt="(.*)", timeout=10 )
267 self.handle.sendline( "" )
268 self.handle.expect( "\$" )
269 return main.TRUE
270 except pexpect.TIMEOUT:
271 main.log.exception( self.name + ": TIMEOUT exception found in pingLongKill" )
272 main.log.error( self.name + ": " + self.handle.before )
273 return main.FALSE
274 except pexpect.EOF:
275 main.log.error(self.name + ": EOF exception found")
276 main.log.error(self.name + ": " + self.handle.before)
277 main.cleanup()
278 main.exit()
279 except Exception:
280 main.log.exception(self.name + ": Uncaught exception!")
281 main.cleanup()
282 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800283
kelvin-onlabedcff052015-01-16 12:53:55 -0800284 def pingHostOptical( self, **pingParams ):
285 """
Jon Hallefbd9792015-03-05 16:11:36 -0800286 This function is only for Packet Optical related ping
kelvin-onlabedcff052015-01-16 12:53:55 -0800287 Use the next pingHost() function for all normal scenarios )
shahshreya28bb18e2014-11-17 10:26:23 -0800288 Ping from one mininet host to another
289 Currently the only supported Params: SRC and TARGET
kelvin-onlabedcff052015-01-16 12:53:55 -0800290 """
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800291 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
kelvin-onlabedcff052015-01-16 12:53:55 -0800292 command = args[ "SRC" ] + " ping " + \
293 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
shahshreya28bb18e2014-11-17 10:26:23 -0800294 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800295 main.log.warn( "Sending: " + command )
kelvin-onlabedcff052015-01-16 12:53:55 -0800296 self.handle.sendline( command )
297 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
shahshreya28bb18e2014-11-17 10:26:23 -0800298 if i == 1:
kelvin-onlabedcff052015-01-16 12:53:55 -0800299 main.log.error(
300 self.name +
301 ": timeout when waiting for response from mininet" )
302 main.log.error( "response: " + str( self.handle.before ) )
303 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
shahshreya28bb18e2014-11-17 10:26:23 -0800304 if i == 1:
kelvin-onlabedcff052015-01-16 12:53:55 -0800305 main.log.error(
306 self.name +
307 ": timeout when waiting for response from mininet" )
308 main.log.error( "response: " + str( self.handle.before ) )
shahshreya28bb18e2014-11-17 10:26:23 -0800309 response = self.handle.before
310 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800311 main.log.error( self.name + ": EOF exception found" )
312 main.log.error( self.name + ": " + self.handle.before )
shahshreya28bb18e2014-11-17 10:26:23 -0800313 main.cleanup()
314 main.exit()
kelvin-onlabedcff052015-01-16 12:53:55 -0800315 main.log.info( self.name + ": Ping Response: " + response )
kelvin-onlabedcff052015-01-16 12:53:55 -0800316 if re.search( ',\s0\%\spacket\sloss', response ):
317 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800318 main.lastResult = main.TRUE
shahshreya28bb18e2014-11-17 10:26:23 -0800319 return main.TRUE
kelvin-onlabedcff052015-01-16 12:53:55 -0800320 else:
321 main.log.error(
322 self.name +
323 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800324 main.lastResult = main.FALSE
shahshreya28bb18e2014-11-17 10:26:23 -0800325 return main.FALSE
326
kelvin-onlabedcff052015-01-16 12:53:55 -0800327 def pingHost( self, **pingParams ):
328 """
Jon Hallfbc828e2015-01-06 17:30:19 -0800329 Pings between two hosts on remote mininet
kelvin-onlabedcff052015-01-16 12:53:55 -0800330 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700331 try:
332 self.handle.sendline( "" )
333 self.handle.expect( "\$" )
334 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
335 command = "mininet/util/m " + \
336 args[ "SRC" ] + " ping " + args[ "TARGET" ] + " -c 4 -W 1 -i .2"
337 main.log.info( command )
338 response = self.execute( cmd=command, prompt="rtt", timeout=10 )
339 if utilities.assert_matches(
340 expect=',\s0\%\spacket\sloss',
341 actual=response,
342 onpass="No Packet loss",
343 onfail="Host is not reachable" ):
344 main.log.info( "NO PACKET LOSS, HOST IS REACHABLE" )
345 main.lastResult = main.TRUE
346 return main.TRUE
347 else:
348 main.log.error( "PACKET LOST, HOST IS NOT REACHABLE" )
349 main.lastResult = main.FALSE
350 return main.FALSE
351 except pexpect.EOF:
352 main.log.error(self.name + ": EOF exception found")
353 main.log.error(self.name + ": " + self.handle.before)
354 main.cleanup()
355 main.exit()
356 except Exception:
357 main.log.exception(self.name + ": Uncaught exception!")
358 main.cleanup()
359 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800360
kelvin-onlabedcff052015-01-16 12:53:55 -0800361 def checknum( self, num ):
362 """
Jon Hallfbc828e2015-01-06 17:30:19 -0800363 Verifies the correct number of switches are running
kelvin-onlabedcff052015-01-16 12:53:55 -0800364 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700365 try:
366 if self.handle:
367 self.handle.sendline( "" )
368 self.handle.expect( "\$" )
369 self.handle.sendline( 'ifconfig -a | grep "sw.. " | wc -l' )
370 self.handle.expect( "wc" )
371 self.handle.expect( "\$" )
372 response = self.handle.before
373 self.handle.sendline(
374 'ps -ef | grep "bash -ms mininet:sw" | grep -v color | wc -l' )
375 self.handle.expect( "color" )
376 self.handle.expect( "\$" )
377 response2 = self.handle.before
adminbae64d82013-08-01 10:50:15 -0700378
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700379 if re.search( num, response ):
380 if re.search( num, response2 ):
381 return main.TRUE
382 else:
383 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700384 else:
385 return main.FALSE
386 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700387 main.log.error( "Connection failed to the host" )
388 except pexpect.TIMEOUT:
389 main.log.exception( self.name + ": TIMEOUT exception found in checknum" )
390 main.log.error( self.name + ": " + self.handle.before )
391 return main.FALSE
392 except pexpect.EOF:
393 main.log.error( self.name + ": EOF exception found" )
394 main.log.error( self.name + ": " + self.handle.before )
395 main.cleanup()
396 main.exit()
397 except Exception:
398 main.log.exception( self.name + ": Uncaught exception!" )
399 main.cleanup()
400 main.exit()
adminbae64d82013-08-01 10:50:15 -0700401
kelvin-onlabd3b64892015-01-20 13:26:24 -0800402 def startTcpdump(
kelvin-onlabedcff052015-01-16 12:53:55 -0800403 self,
404 filename,
405 intf="eth0",
Charles Chan029be652015-08-24 01:46:10 +0800406 port="port 6653",
Jon Hall53c5e662016-04-13 16:06:56 -0700407 user="sdn" ):
kelvin-onlabedcff052015-01-16 12:53:55 -0800408 """
Jon Hallefbd9792015-03-05 16:11:36 -0800409 Runs tcpdump on an interface and saves the file
admin2a9548d2014-06-17 14:08:07 -0700410 intf can be specified, or the default eth0 is used
kelvin-onlabedcff052015-01-16 12:53:55 -0800411 """
admin2a9548d2014-06-17 14:08:07 -0700412 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800413 self.handle.sendline( "" )
414 self.handle.sendline(
415 "sudo tcpdump -n -i " +
416 intf +
417 " " +
418 port +
419 " -w " +
420 filename.strip() +
421 " -Z " +
422 user +
423 " &" )
424 self.handle.sendline( "" )
425 self.handle.sendline( "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800426 i = self.handle.expect( [ 'No\ssuch\device', 'listening\son',
427 pexpect.TIMEOUT, "\$" ], timeout=10 )
Jon Hall61282e32015-03-19 11:34:11 -0700428 main.log.info( self.handle.before + self.handle.after )
admin2a9548d2014-06-17 14:08:07 -0700429 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800430 main.log.error( self.name + ": tcpdump - No such device exists.\
431 tcpdump attempted on: " + intf )
admin2a9548d2014-06-17 14:08:07 -0700432 return main.FALSE
433 elif i == 1:
kelvin-onlabedcff052015-01-16 12:53:55 -0800434 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -0700435 return main.TRUE
436 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800437 main.log.error( self.name + ": tcpdump command timed out!\
438 Check interface name, given interface was: " + intf )
admin2a9548d2014-06-17 14:08:07 -0700439 return main.FALSE
kelvin-onlabedcff052015-01-16 12:53:55 -0800440 elif i == 3:
441 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700442 return main.TRUE
443 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800444 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -0700445 return main.FALSE
446 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800447 main.log.error( self.name + ": EOF exception found" )
448 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700449 main.cleanup()
450 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800451 except Exception:
452 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -0700453 main.cleanup()
454 main.exit()
455
kelvin-onlabd3b64892015-01-20 13:26:24 -0800456 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -0800457 """
458 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -0700459 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800460 self.handle.sendline( "sudo pkill tcpdump" )
461 self.handle.sendline( "" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800462 self.handle.expect( "\$" )
admin2a9548d2014-06-17 14:08:07 -0700463 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800464 main.log.error( self.name + ": EOF exception found" )
465 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -0700466 main.cleanup()
467 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800468 except Exception:
469 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -0700470 main.cleanup()
471 main.exit()
472
shahshreya1f119da2015-04-21 17:16:46 -0700473 def runOpticalMnScript( self,name = 'onos', ctrllerIP = None ):
shahshreya2c57c902015-04-06 20:40:20 -0700474 import time
shahshreya1f119da2015-04-21 17:16:46 -0700475 import types
kelvin-onlabedcff052015-01-16 12:53:55 -0800476 """
shahshreya1f119da2015-04-21 17:16:46 -0700477 Description:
478 This function is only meant for Packet Optical.
479 It runs python script "opticalTest.py" to create the
480 packet layer( mn ) and optical topology
481 Optional:
482 name - Name of onos directory. (ONOS | onos)
483 Required:
484 ctrllerIP = Controller(s) IP address
485 TODO: If no ctrllerIP is provided, a default
shahshreya2c57c902015-04-06 20:40:20 -0700486 $OC1 can be accepted
kelvin-onlabedcff052015-01-16 12:53:55 -0800487 """
shahshreya28bb18e2014-11-17 10:26:23 -0800488 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800489 self.handle.sendline( "" )
490 self.handle.expect( "\$" )
shahshreya1f119da2015-04-21 17:16:46 -0700491 self.handle.sendline( "cd ~/" + name + "/tools/test/topos" )
shahshreya2c57c902015-04-06 20:40:20 -0700492 self.handle.expect( "topos\$" )
493 if ctrllerIP == None:
494 main.log.info( "You need to specify the IP" )
495 return main.FALSE
496 else:
shahshreya1f119da2015-04-21 17:16:46 -0700497 controller = ''
498 if isinstance( ctrllerIP, types.ListType ):
499 for i in xrange( len( ctrllerIP ) ):
500 controller += ctrllerIP[i] + ' '
501 main.log.info( "Mininet topology is being loaded with " +
502 "controllers: " + controller )
503 elif isinstance( ctrllerIP, types.StringType ):
504 controller = ctrllerIP
505 main.log.info( "Mininet topology is being loaded with " +
506 "controller: " + controller )
507 else:
508 main.log.info( "You need to specify a valid IP" )
509 return main.FALSE
510 cmd = "sudo -E python opticalTest.py " + controller
511 main.log.info( self.name + ": cmd = " + cmd )
shahshreya2c57c902015-04-06 20:40:20 -0700512 self.handle.sendline( cmd )
shahshreyad524a942015-04-21 09:55:16 -0700513 time.sleep(30)
shahshreya2c57c902015-04-06 20:40:20 -0700514 self.handle.sendline( "" )
shahshreya3140b1a2015-04-28 14:22:15 -0700515 self.handle.sendline( "" )
shahshreya2c57c902015-04-06 20:40:20 -0700516 self.handle.expect("mininet>")
517 return main.TRUE
518 except pexpect.EOF:
519 main.log.error( self.name + ": EOF exception found" )
520 main.log.error( self.name + ": " + self.handle.before )
521 return main.FALSE
522
523 def attachLincOESession( self ):
524 """
525 Since executing opticalTest.py will give you mininet
526 prompt, you would at some point require to get onto
527 console of LincOE ((linc@onosTestBench)1>) to execute
528 commands like bring a optical port up or down on a ROADM
529 You can attach to console of Linc-OE session by a cmd:
530 sudo ~/linc-oe/rel/linc/bin/linc attach
531 """
532 try:
533 self.handle.sendline( "" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800534 self.handle.expect( "\$" )
shahshreya2c57c902015-04-06 20:40:20 -0700535 self.handle.sendline( "sudo ~/linc-oe/rel/linc/bin/linc attach" )
kelvin-onlabedcff052015-01-16 12:53:55 -0800536 self.handle.expect( ">" )
shahshreya28bb18e2014-11-17 10:26:23 -0800537 return main.TRUE
538 except pexpect.EOF:
kelvin-onlabedcff052015-01-16 12:53:55 -0800539 main.log.error( self.name + ": EOF exception found" )
540 main.log.error( self.name + ": " + self.handle.before )
shahshreya28bb18e2014-11-17 10:26:23 -0800541 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700542
kelvin-onlabedcff052015-01-16 12:53:55 -0800543 def disconnect( self ):
544 """
Jon Hallfbc828e2015-01-06 17:30:19 -0800545 Called at the end of the test to disconnect the handle.
kelvin-onlabedcff052015-01-16 12:53:55 -0800546 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700547 try:
548 if self.handle:
549 # Close the ssh connection
550 self.handle.sendline( "" )
551 # self.handle.expect( "\$" )
552 i = self.handle.expect( [ '\$', 'mininet>', pexpect.TIMEOUT,
553 pexpect.EOF ], timeout=2 )
554 if i == 0:
555 self.handle.sendline( "exit" )
556 self.handle.expect( "closed" )
557 elif i == 1:
558 self.handle.sendline( "exit" )
559 self.handle.expect( "exit" )
560 self.handle.expect('\$')
561 self.handle.sendline( "exit" )
562 self.handle.expect( "exit" )
563 self.handle.expect( "closed" )
564 else:
565 main.log.error( "Connection failed to the host" )
566 return main.TRUE
567 except pexpect.TIMEOUT:
568 main.log.exception( self.name + ": TIMEOUT exception found in disconnect" )
569 main.log.error( self.name + ": " + self.handle.before )
570 return main.FALSE
571 except pexpect.EOF:
572 main.log.error(self.name + ": EOF exception found")
573 main.log.error(self.name + ": " + self.handle.before)
574 main.cleanup()
575 main.exit()
576 except Exception:
577 main.log.exception(self.name + ": Uncaught exception!")
578 main.cleanup()
579 main.exit()
adminbae64d82013-08-01 10:50:15 -0700580
kelvin-onlabd3b64892015-01-20 13:26:24 -0800581 def setIpTablesOUTPUT( self, dstIp, dstPort, action='add',
582 packetType='tcp', rule='DROP' ):
kelvin-onlabedcff052015-01-16 12:53:55 -0800583 """
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700584 Description:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800585 add or remove iptables rule to DROP ( default )
586 packets from specific IP and PORT
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700587 Usage:
kelvin-onlabedcff052015-01-16 12:53:55 -0800588 * specify action ( 'add' or 'remove' )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700589 when removing, pass in the same argument as you would add. It will
Jon Hallfbc828e2015-01-06 17:30:19 -0800590 delete that specific rule.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800591 * specify the destination ip to block with dstIp
592 * specify destination port to block to dstPort
kelvin-onlabedcff052015-01-16 12:53:55 -0800593 * optional packet type to block ( default tcp )
594 * optional iptables rule ( default DROP )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700595 WARNING:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 * This function uses root privilege iptables command which may result
597 in unwanted network errors. USE WITH CAUTION
kelvin-onlabedcff052015-01-16 12:53:55 -0800598 """
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700599 import re
600 import time
601
kelvin-onlabedcff052015-01-16 12:53:55 -0800602 # NOTE*********
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700603 # The strict checking methods of this driver function is intentional
604 # to discourage any misuse or error of iptables, which can cause
605 # severe network errors
kelvin-onlabd3b64892015-01-20 13:26:24 -0800606 # *************
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700607
kelvin-onlabd3b64892015-01-20 13:26:24 -0800608 # NOTE: Sleep needed to give some time
609 # for rule to be added and registered
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700610 # to the instance
kelvin-onlabedcff052015-01-16 12:53:55 -0800611 time.sleep( 5 )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700612
kelvin-onlabd3b64892015-01-20 13:26:24 -0800613 actionType = action.lower()
614 if actionType != 'add' and actionType != 'remove':
kelvin-onlabedcff052015-01-16 12:53:55 -0800615 main.log.error(
616 "Invalid action type. 'add' or 'remove' table rule" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700617 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
kelvin-onlabedcff052015-01-16 12:53:55 -0800618 # NOTE: Currently only supports rules DROP, ACCEPT, and LOG
619 main.log.error(
620 "Invalid rule. 'DROP' or 'ACCEPT' or 'LOG' only." )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700621 return
622 return
623 else:
624
kelvin-onlabedcff052015-01-16 12:53:55 -0800625 # If there is no existing rule in the iptables, we will see an
kelvin-onlabd3b64892015-01-20 13:26:24 -0800626 # 'iptables:'... message. We expect to see this message.
kelvin-onlabedcff052015-01-16 12:53:55 -0800627 # Otherwise, if there IS an existing rule, we will get the prompt
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700628 # back, hence why we expect $ for remove type. We want to remove
629 # an already existing rule
630
kelvin-onlabd3b64892015-01-20 13:26:24 -0800631 if actionType == 'add':
632 # NOTE: "iptables:" expect is a result of
633 # return from the command
634 # iptables -C ...
635 # Any changes by the iptables command return string
636 # will result in failure of the function. ( deemed unlikely
637 # at the time of writing this function )
kelvin-onlabedcff052015-01-16 12:53:55 -0800638 # Check for existing rules on current input
639 self.handle.sendline( "" )
640 self.handle.expect( "\$" )
641 self.handle.sendline(
642 "sudo iptables -C OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800643 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800644 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800645 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800646 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800647 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800648 " -j " +
649 str( rule ) )
650 i = self.handle.expect( [ "iptables:", "\$" ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700651 print i
652 print self.handle.before
653 print "after: "
654 print self.handle.after
655
kelvin-onlabd3b64892015-01-20 13:26:24 -0800656 elif actionType == 'remove':
kelvin-onlabedcff052015-01-16 12:53:55 -0800657 # Check for existing rules on current input
658 self.handle.sendline( "" )
659 self.handle.expect( "\$" )
660 self.handle.sendline(
661 "sudo iptables -C OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800662 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800663 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800664 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800665 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800666 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800667 " -j " +
668 str( rule ) )
669 self.handle.expect( "\$" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700670 print "before: "
671 print self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800672 actualString = self.handle.after
673 expectString = "iptables:"
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700674 print "Actual String:"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800675 print actualString
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700676
kelvin-onlabd3b64892015-01-20 13:26:24 -0800677 if re.search( expectString, actualString ):
678 matchResult = main.TRUE
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700679 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800680 matchResult = main.FALSE
681 # If matchResult is main.TRUE, it means there is no matching rule.
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700682
kelvin-onlabd3b64892015-01-20 13:26:24 -0800683 # If tables does not exist and expected prompt is returned,
684 # go ahead and add iptables rule
685 if matchResult == main.TRUE:
kelvin-onlabedcff052015-01-16 12:53:55 -0800686 # Ensure action type is add
kelvin-onlabd3b64892015-01-20 13:26:24 -0800687 if actionType == 'add':
688 # -A is the 'append' action of iptables
689 actionAdd = '-A'
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700690 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800691 self.handle.sendline( "" )
692 self.handle.sendline(
693 "sudo iptables " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800694 actionAdd +
kelvin-onlabedcff052015-01-16 12:53:55 -0800695 " OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800696 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800697 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800698 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800699 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800700 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800701 " -j " +
702 str( rule ) )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700703
kelvin-onlabd3b64892015-01-20 13:26:24 -0800704 infoString = "Rules added to " + str( self.name )
Jon Hallefbd9792015-03-05 16:11:36 -0800705 infoString += "iptables rule added to block IP: " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -0800706 str( dstIp )
707 infoString += "Port: " + \
708 str( dstPort ) + " Rule: " + str( rule )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700709
kelvin-onlabd3b64892015-01-20 13:26:24 -0800710 main.log.info( infoString )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700711
kelvin-onlabedcff052015-01-16 12:53:55 -0800712 self.handle.expect(
713 [ "\$", pexpect.EOF, pexpect.TIMEOUT ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700714 except pexpect.TIMEOUT:
kelvin-onlabedcff052015-01-16 12:53:55 -0800715 main.log.error(
716 self.name +
717 ": Timeout exception in setIpTables function" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800718 except Exception:
719 main.log.exception( self.name +
720 ": Uncaught exception!" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700721 main.cleanup()
722 main.exit()
723 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800724 main.log.error(
725 "Given rule already exists, but attempted to add it" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800726 # If matchResult is 0, it means there IS a matching rule provided
727 elif matchResult == main.FALSE:
kelvin-onlabedcff052015-01-16 12:53:55 -0800728 # Ensure action type is remove
kelvin-onlabd3b64892015-01-20 13:26:24 -0800729 if actionType == 'remove':
730 # -D is the 'delete' rule of iptables
731 actionRemove = '-D'
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700732 try:
kelvin-onlabedcff052015-01-16 12:53:55 -0800733 self.handle.sendline( "" )
734 # Delete a specific rule specified into the function
735 self.handle.sendline(
736 "sudo iptables " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 actionRemove +
kelvin-onlabedcff052015-01-16 12:53:55 -0800738 " OUTPUT -p " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 str( packetType ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800740 " -d " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800741 str( dstIp ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800742 " --dport " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 str( dstPort ) +
kelvin-onlabedcff052015-01-16 12:53:55 -0800744 " -j " +
745 str( rule ) )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700746
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 infoString = "Rules removed from " + str( self.name )
748 infoString += " iptables rule removed \
749 from blocking IP: " + \
750 str( dstIp )
751 infoString += " Port: " + \
752 str( dstPort ) + " Rule: " + str( rule )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700753
kelvin-onlabd3b64892015-01-20 13:26:24 -0800754 main.log.info( infoString )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700755
kelvin-onlabedcff052015-01-16 12:53:55 -0800756 self.handle.expect(
757 [ "\$", pexpect.EOF, pexpect.TIMEOUT ] )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700758 except pexpect.TIMEOUT:
kelvin-onlabedcff052015-01-16 12:53:55 -0800759 main.log.error(
760 self.name +
761 ": Timeout exception in setIpTables function" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800762 except Exception:
763 main.log.exception( self.name +
764 ": Uncaught exception!" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700765 main.cleanup()
766 main.exit()
767 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800768 main.log.error(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 "Given rule does not exist,\
770 but attempted to remove it" )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700771 else:
kelvin-onlabedcff052015-01-16 12:53:55 -0800772 # NOTE: If a bad usage of this function occurs, exit the entire
773 # test
774 main.log.error( "Bad rule given for iptables. Exiting..." )
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700775 main.cleanup()
776 main.exit()
777
778
adminbae64d82013-08-01 10:50:15 -0700779if __name__ != "__main__":
780 import sys
kelvin-onlabedcff052015-01-16 12:53:55 -0800781 sys.modules[ __name__ ] = RemoteMininetDriver()