blob: 1b63f8788eca7c2c18eb874dab46c41025c28e7d [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
2'''
3Created on 26-Oct-2012
4
5@author: Anil Kumar (anilkumar.s@paxterrasolutions.com)
6
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
11 (at your option) any later version.
12
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
19 along with TestON. If not, see <http://www.gnu.org/licenses/>.
20
21
22MininetCliDriver is the basic driver which will handle the Mininet functions
23'''
admin2a9548d2014-06-17 14:08:07 -070024import traceback
adminbae64d82013-08-01 10:50:15 -070025import pexpect
26import struct
27import fcntl
28import os
29import signal
30import re
31import sys
32import core.teston
33sys.path.append("../")
34from drivers.common.cli.emulatordriver import Emulator
35from drivers.common.clidriver import CLI
36from time import time
37
38class RemoteMininetDriver(Emulator):
39 '''
adminaeedddd2013-08-02 15:14:15 -070040 RemoteMininetCliDriver is the basic driver which will handle the Mininet functions
41 The main different between this and the MininetCliDriver is that this one does not build the mininet.
42 It assumes that there is already a mininet running on the target.
adminbae64d82013-08-01 10:50:15 -070043 '''
44 def __init__(self):
45 super(Emulator, self).__init__()
46 self.handle = self
47 self.wrapped = sys.modules[__name__]
48 self.flag = 0
49
50 def connect(self, **connectargs):
51 #,user_name, ip_address, pwd,options):
52 # Here the main is the TestON instance after creating all the log handles.
53 for key in connectargs:
54 vars(self)[key] = connectargs[key]
55
56 self.name = self.options['name']
57 self.handle = super(RemoteMininetDriver, self).connect(user_name = self.user_name, ip_address = self.ip_address,port = None, pwd = self.pwd)
58
59 self.ssh_handle = self.handle
60
61 # Copying the readme file to process the
62 if self.handle :
63 return main.TRUE
64
65 else :
66 main.log.error("Connection failed to the host "+self.user_name+"@"+self.ip_address)
67 main.log.error("Failed to connect to the Mininet")
68 return main.FALSE
admin98ad0092014-07-23 16:51:07 -070069
70#*********************************************************************************************
71#*********************************************************************************************
72# checkForLoss will determine if any of the pings had any packets lost during the course of
73# the pingLong.
74#*********************************************************************************************
75#*********************************************************************************************
76
admin2580a0e2014-07-29 11:24:34 -070077 def checkForLoss(self, pingList):
admin98ad0092014-07-23 16:51:07 -070078 import os
admin2580a0e2014-07-29 11:24:34 -070079 self.handle.sendline("")
80 self.handle.expect("\$")
81 self.handle.sendline("cat " + pingList)
82 self.handle.expect(pingList)
83 self.handle.expect("\$")
84 outputs = self.handle.before + self.handle.after
85 if re.search(" 0% packet loss",outputs):
admin98ad0092014-07-23 16:51:07 -070086 return main.FALSE
admin2580a0e2014-07-29 11:24:34 -070087 elif re.search("found multiple mininet",outputs):
88 return main.ERROR
admin98ad0092014-07-23 16:51:07 -070089 return main.TRUE
90
91
adminbae64d82013-08-01 10:50:15 -070092 def pingLong(self,**pingParams):
adminaeedddd2013-08-02 15:14:15 -070093 '''
94 Starts a continuous ping on the mininet host outputing to a file in the /tmp dir.
95 '''
admin98ad0092014-07-23 16:51:07 -070096 args = utilities.parse_args(["SRC","TARGET","PINGTIME"],**pingParams)
admin530b4c92013-08-14 16:54:35 -070097 precmd = "rm /tmp/ping." + args["SRC"]
98 self.execute(cmd=precmd,prompt="(.*)",timeout=10)
admin98ad0092014-07-23 16:51:07 -070099 command = "mininet/util/m " + args["SRC"] + " ping "+args ["TARGET"]+" -i .2 -w " + str(args['PINGTIME']) + " > /tmp/ping." + args["SRC"] + " &"
adminbae64d82013-08-01 10:50:15 -0700100 main.log.info( command )
101 self.execute(cmd=command,prompt="(.*)",timeout=10)
102 return main.TRUE
103
104 def pingstatus(self,**pingParams):
adminaeedddd2013-08-02 15:14:15 -0700105 '''
106 Tails the respective ping output file and check that there is a moving "64 bytes"
107 '''
adminbae64d82013-08-01 10:50:15 -0700108 args = utilities.parse_args(["SRC"],**pingParams)
109 self.handle.sendline("tail /tmp/ping." + args["SRC"])
110 self.handle.expect("tail")
111 self.handle.expect("\$")
112 result = self.handle.before + self.handle.after
113 if re.search('Unreachable', result ):
114 main.log.info("Unreachable found in ping logs...")
115 return main.FALSE
116 elif re.search('64\sbytes', result):
117 main.log.info("Pings look good")
118 return main.TRUE
119 else:
120 main.log.info("No, or faulty ping data...")
121 return main.FALSE
122
123 def pingKill(self):
adminaeedddd2013-08-02 15:14:15 -0700124 '''
125 Kills all continuous ping processes.
126 Then copies all the ping files to the TestStation.
127 '''
128 import time
admin2580a0e2014-07-29 11:24:34 -0700129 command = "sudo kill -SIGINT `pgrep ping`"
adminbae64d82013-08-01 10:50:15 -0700130 main.log.info( command )
131 self.execute(cmd=command,prompt="(.*)",timeout=10)
adminbae64d82013-08-01 10:50:15 -0700132 main.log.info( "Removing old ping data" )
133 command = "rm /tmp/ping.*"
134 os.popen(command)
adminbae64d82013-08-01 10:50:15 -0700135 time.sleep(2)
136 main.log.info( "Transferring ping files to TestStation" )
137 command = "scp /tmp/ping.* admin@10.128.7.7:/tmp/"
138 self.execute(cmd=command,prompt="100%",timeout=20)
admin2580a0e2014-07-29 11:24:34 -0700139 print("finished kill")
140 return main.TRUE
141
142 def pingLongKill(self):
143 import time
144 command = "sudo kill -SIGING `pgrep ping`"
145 main.log.info(command)
146 self.execute(cmd=command,prompt="(.*)",timeout=10)
adminbae64d82013-08-01 10:50:15 -0700147 return main.TRUE
148
149 def pingHost(self,**pingParams):
adminaeedddd2013-08-02 15:14:15 -0700150 '''
151 Pings between two hosts on remote mininet
152 '''
adminbae64d82013-08-01 10:50:15 -0700153 args = utilities.parse_args(["SRC","TARGET"],**pingParams)
154 command = "mininet/util/m " + args["SRC"] + " ping "+args ["TARGET"]+" -c 4 -W 1 -i .2"
155 main.log.info ( command )
156 response = self.execute(cmd=command,prompt="rtt",timeout=10 )
157 if utilities.assert_matches(expect=',\s0\%\spacket\sloss',actual=response,onpass="No Packet loss",onfail="Host is not reachable"):
158 main.log.info("NO PACKET LOSS, HOST IS REACHABLE")
159 main.last_result = main.TRUE
160 return main.TRUE
161 else :
162 main.log.error("PACKET LOST, HOST IS NOT REACHABLE")
163 main.last_result = main.FALSE
164 return main.FALSE
165
166
167 def checknum(self,num):
168 '''
adminaeedddd2013-08-02 15:14:15 -0700169 Verifies the correct number of switches are running
adminbae64d82013-08-01 10:50:15 -0700170 '''
171 if self.handle :
172 self.handle.sendline("")
173 self.handle.expect("\$")
174 self.handle.sendline('ifconfig -a | grep "sw.. " | wc -l')
175 self.handle.expect("wc")
176 self.handle.expect("\$")
177 response = self.handle.before
178 self.handle.sendline('ps -ef | grep "bash -ms mininet:sw" | grep -v color | wc -l')
179 self.handle.expect("color")
180 self.handle.expect("\$")
181 response2 = self.handle.before
182
183 if re.search(num, response):
184 if re.search(num, response2):
185 return main.TRUE
186 else:
187 return main.FALSE
188 else:
189 return main.FALSE
190 else :
191 main.log.error("Connection failed to the host")
192
193 def ctrl_none(self):
adminaeedddd2013-08-02 15:14:15 -0700194 '''
195 Sets all the switches to no controllers.
196 '''
adminbae64d82013-08-01 10:50:15 -0700197 self.execute(cmd="~/ONOS/scripts/test-ctrl-none.sh", prompt="\$",timeout=10)
198
199 def ctrl_one(self, ip):
adminaeedddd2013-08-02 15:14:15 -0700200 '''
201 Sets all the switches to point to the supplied IP
202 '''
adminbae64d82013-08-01 10:50:15 -0700203 self.execute(cmd="~/ONOS/scripts/test-ctrl-one.sh "+ip, prompt="\$",timeout=10)
204
205 def ctrl_local(self):
adminaeedddd2013-08-02 15:14:15 -0700206 '''
207 Sets all the switches to point to the Controller on the same machine that they are running on.
208 '''
adminbae64d82013-08-01 10:50:15 -0700209 self.execute(cmd="~/ONOS/scripts/test-ctrl-local.sh ", prompt="\$",timeout=10)
210
211 # def verifySSH(self,**connectargs):
212 # response = self.execute(cmd="h1 /usr/sbin/sshd -D&",prompt="mininet>",timeout=10)
213 # response = self.execute(cmd="h4 /usr/sbin/sshd -D&",prompt="mininet>",timeout=10)
214 # for key in connectargs:
215 # vars(self)[key] = connectargs[key]
216 # response = self.execute(cmd="xterm h1 h4 ",prompt="mininet>",timeout=10)
217 # import time
218 # time.sleep(20)
219 # if self.flag == 0:
220 # self.flag = 1
221 # return main.FALSE
222 # else :
223 # return main.TRUE
224 #
225 # def getMacAddress(self,host):
226 # '''
227 # Verifies the host's ip configured or not.
228 # '''
229 # if self.handle :
230 # response = self.execute(cmd=host+" ifconfig",prompt="mininet>",timeout=10)
231
232 # pattern = "HWaddr\s(((\d|\w)+:)+(\d|\w))"
233 # mac_address_search = re.search(pattern, response)
234 # main.log.info("Mac-Address of Host "+host +" is "+mac_address_search.group(1))
235 # return mac_address_search.group(1)
236 # else :
237 # main.log.error("Connection failed to the host")
238 # def getIPAddress(self,host):
239 # '''
240 # Verifies the host's ip configured or not.
241 # '''
242 # if self.handle :
243 # response = self.execute(cmd=host+" ifconfig",prompt="mininet>",timeout=10)
244
245 # pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
246 # ip_address_search = re.search(pattern, response)
247 # main.log.info("IP-Address of Host "+host +" is "+ip_address_search.group(1))
248 # return ip_address_search.group(1)
249 # else :
250 # main.log.error("Connection failed to the host")
251 #
252 # def dump(self):
253 # main.log.info("Dump node info")
254 # self.execute(cmd = 'dump',prompt = 'mininet>',timeout = 10)
255 # return main.TRUE
256 #
257 # def intfs(self):
258 # main.log.info("List interfaces")
259 # self.execute(cmd = 'intfs',prompt = 'mininet>',timeout = 10)
260 # return main.TRUE
261 #
262 # def net(self):
263 # main.log.info("List network connections")
264 # self.execute(cmd = 'net',prompt = 'mininet>',timeout = 10)
265 # return main.TRUE
266 #
267 # def iperf(self):
268 # main.log.info("Simple iperf TCP test between two (optionally specified) hosts")
269 # self.execute(cmd = 'iperf',prompt = 'mininet>',timeout = 10)
270 # return main.TRUE
271 #
272 # def iperfudp(self):
273 # main.log.info("Simple iperf TCP test between two (optionally specified) hosts")
274 # self.execute(cmd = 'iperfudp',prompt = 'mininet>',timeout = 10)
275 # return main.TRUE
276 #
277 # def nodes(self):
278 # main.log.info("List all nodes.")
279 # self.execute(cmd = 'nodes',prompt = 'mininet>',timeout = 10)
280 # return main.TRUE
281 #
282 # def pingpair(self):
283 # main.log.infoe("Ping between first two hosts")
284 # self.execute(cmd = 'pingpair',prompt = 'mininet>',timeout = 20)
285 #
286 # if utilities.assert_matches(expect='0% packet loss',actual=response,onpass="No Packet loss",onfail="Hosts not reachable"):
287 # main.log.info("Ping between two hosts SUCCESS")
288 # main.last_result = main.TRUE
289 # return main.TRUE
290 # else :
291 # main.log.error("PACKET LOST, HOSTS NOT REACHABLE")
292 # main.last_result = main.FALSE
293 # return main.FALSE
294 #
295 # def link(self,**linkargs):
296 # '''
297 # Bring link(s) between two nodes up or down
298 # '''
299 # main.log.info('Bring link(s) between two nodes up or down')
300 # args = utilities.parse_args(["END1","END2","OPTION"],**linkargs)
301 # end1 = args["END1"] if args["END1"] != None else ""
302 # end2 = args["END2"] if args["END2"] != None else ""
303 # option = args["OPTION"] if args["OPTION"] != None else ""
304 # command = "link "+str(end1) + " " + str(end2)+ " " + str(option)
305 # response = self.execute(cmd=command,prompt="mininet>",timeout=10)
306 # return main.TRUE
307 #
308
309 # def dpctl(self,**dpctlargs):
310 # '''
311 # Run dpctl command on all switches.
312 # '''
313 # main.log.info('Run dpctl command on all switches')
314 # args = utilities.parse_args(["CMD","ARGS"],**dpctlargs)
315 # cmd = args["CMD"] if args["CMD"] != None else ""
316 # cmdargs = args["ARGS"] if args["ARGS"] != None else ""
317 # command = "dpctl "+cmd + " " + str(cmdargs)
318 # response = self.execute(cmd=command,prompt="mininet>",timeout=10)
319 # return main.TRUE
320 #
321 #
322 # def get_version(self):
323 # file_input = path+'/lib/Mininet/INSTALL'
324 # version = super(Mininet, self).get_version()
325 # pattern = 'Mininet\s\w\.\w\.\w\w*'
326 # for line in open(file_input,'r').readlines():
327 # result = re.match(pattern, line)
328 # if result:
329 # version = result.group(0)
330 #
331 #
332 # return version
admin2a9548d2014-06-17 14:08:07 -0700333 def start_tcpdump(self, filename, intf = "eth0", port = "port 6633"):
334 '''
335 Runs tpdump on an intferface and saves the file
336 intf can be specified, or the default eth0 is used
337 '''
338 try:
339 self.handle.sendline("")
340 self.handle.sendline("sudo tcpdump -n -i "+ intf + " " + port + " -w " + filename.strip() + " &")
341 self.handle.sendline("")
342 self.handle.sendline("")
343 i=self.handle.expect(['No\ssuch\device','listening\son',pexpect.TIMEOUT,"\$"],timeout=10)
344 main.log.warn(self.handle.before + self.handle.after)
345 if i == 0:
346 main.log.error(self.name + ": tcpdump - No such device exists. tcpdump attempted on: " + intf)
347 return main.FALSE
348 elif i == 1:
349 main.log.info(self.name + ": tcpdump started on " + intf)
350 return main.TRUE
351 elif i == 2:
352 main.log.error(self.name + ": tcpdump command timed out! Check interface name, given interface was: " + intf)
353 return main.FALSE
354 elif i ==3:
355 main.log.info(self.name +": " + self.handle.before)
356 return main.TRUE
357 else:
358 main.log.error(self.name + ": tcpdump - unexpected response")
359 return main.FALSE
360 except pexpect.EOF:
361 main.log.error(self.name + ": EOF exception found")
362 main.log.error(self.name + ": " + self.handle.before)
363 main.cleanup()
364 main.exit()
365 except:
366 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
367 main.log.error( traceback.print_exc() )
368 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
369 main.cleanup()
370 main.exit()
371
372 def stop_tcpdump(self):
373 "pkills tcpdump"
374 try:
375 self.handle.sendline("sudo pkill tcpdump")
376 self.handle.sendline("")
377 self.handle.sendline("")
378 self.handle.expect("\$")
379 except pexpect.EOF:
380 main.log.error(self.name + ": EOF exception found")
381 main.log.error(self.name + ": " + self.handle.before)
382 main.cleanup()
383 main.exit()
384 except:
385 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
386 main.log.error( traceback.print_exc() )
387 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
388 main.cleanup()
389 main.exit()
390
admin680b78c2014-08-08 11:46:45 -0700391 def del_switch(self,sw):
392 self.handle.sendline("")
393 self.handle.expect("\$")
394 self.handle.sendline("sudo ovs-vsctl del-br "+sw)
395 self.handle.expect("\$")
396 return main.TRUE
admin2a9548d2014-06-17 14:08:07 -0700397
admin680b78c2014-08-08 11:46:45 -0700398 def add_switch(self,sw):
399 self.handle.sendline("")
400 self.handle.expect("\$")
401 self.handle.sendline("sudo ovs-vsctl add-br "+sw)
402 self.handle.expect("\$")
403 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth1")
404 self.handle.expect("\$")
405 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth2")
406 self.handle.expect("\$")
407 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth3")
408 self.handle.expect("\$")
409 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth4")
410 self.handle.expect("\$")
411 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth5")
412 self.handle.expect("\$")
413 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth6")
414 self.handle.expect("\$")
415 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth7")
416 self.handle.expect("\$")
417 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth8")
418 self.handle.expect("\$")
419 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth9")
420 self.handle.expect("\$")
421 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth10")
422 self.handle.expect("\$")
423 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth11")
424 self.handle.expect("\$")
425 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth12")
426 self.handle.expect("\$")
427 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth13")
428 self.handle.expect("\$")
429 self.handle.sendline("sudo ovs-vsctl add-port "+sw+" " + sw + "-eth14")
430 self.handle.expect("\$")
admin2a9548d2014-06-17 14:08:07 -0700431
adminbae64d82013-08-01 10:50:15 -0700432
433 def disconnect(self):
adminaeedddd2013-08-02 15:14:15 -0700434 '''
435 Called at the end of the test to disconnect the handle.
436 '''
adminbae64d82013-08-01 10:50:15 -0700437 response = ''
438 #print "Disconnecting Mininet"
439 if self.handle:
440 self.handle.sendline("exit")
441 self.handle.expect("exit")
442 self.handle.expect("(.*)")
443 response = self.handle.before
444
445 else :
446 main.log.error("Connection failed to the host")
447 response = main.FALSE
448 return response
449
santhosh19fd8032014-07-29 11:56:17 -0700450 def get_flowTable(self,sw):
santhosh9da93892014-07-28 14:11:19 -0700451 self.handle.sendline("cd")
452 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
453 command = "sudo ovs-ofctl dump-flows " + sw + " | awk '{OFS=\",\" ; print $1 $6 $7 }' |sort -n -k1"
santhosh9da93892014-07-28 14:11:19 -0700454 self.handle.sendline(command)
455 self.handle.expect(["sort -n -k1",pexpect.EOF,pexpect.TIMEOUT])
456 self.handle.expect(["NXST_FLOW",pexpect.EOF,pexpect.TIMEOUT])
santhosh9da93892014-07-28 14:11:19 -0700457 response = self.handle.before
santhosh19fd8032014-07-29 11:56:17 -0700458 return response
459
460
461 def flow_comp(self,flow1,flow2):
462 if flow1==flow2:
463 return main.TRUE
464 else:
465 return main.FALSE
466
adminbae64d82013-08-01 10:50:15 -0700467if __name__ != "__main__":
468 import sys
469 sys.modules[__name__] = RemoteMininetDriver()