blob: 1bd070fd79946963be8d929398af145942ba1f0f [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
77 def checkForLoss(self, fileName):
78 import os
79 if os.stat(fileName)[6]==0:
80 return main.TRUE
81 pingFile= open(fileName,'r')
82 pingList = pingFile.read()
83
84 if re.search("0% packet loss",pingList):
85 return main.FALSE
86 return main.TRUE
87
88
adminbae64d82013-08-01 10:50:15 -070089 def pingLong(self,**pingParams):
adminaeedddd2013-08-02 15:14:15 -070090 '''
91 Starts a continuous ping on the mininet host outputing to a file in the /tmp dir.
92 '''
admin98ad0092014-07-23 16:51:07 -070093 args = utilities.parse_args(["SRC","TARGET","PINGTIME"],**pingParams)
admin530b4c92013-08-14 16:54:35 -070094 precmd = "rm /tmp/ping." + args["SRC"]
95 self.execute(cmd=precmd,prompt="(.*)",timeout=10)
admin98ad0092014-07-23 16:51:07 -070096 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 -070097 main.log.info( command )
98 self.execute(cmd=command,prompt="(.*)",timeout=10)
99 return main.TRUE
100
101 def pingstatus(self,**pingParams):
adminaeedddd2013-08-02 15:14:15 -0700102 '''
103 Tails the respective ping output file and check that there is a moving "64 bytes"
104 '''
adminbae64d82013-08-01 10:50:15 -0700105 args = utilities.parse_args(["SRC"],**pingParams)
106 self.handle.sendline("tail /tmp/ping." + args["SRC"])
107 self.handle.expect("tail")
108 self.handle.expect("\$")
109 result = self.handle.before + self.handle.after
110 if re.search('Unreachable', result ):
111 main.log.info("Unreachable found in ping logs...")
112 return main.FALSE
113 elif re.search('64\sbytes', result):
114 main.log.info("Pings look good")
115 return main.TRUE
116 else:
117 main.log.info("No, or faulty ping data...")
118 return main.FALSE
119
120 def pingKill(self):
adminaeedddd2013-08-02 15:14:15 -0700121 '''
122 Kills all continuous ping processes.
123 Then copies all the ping files to the TestStation.
124 '''
125 import time
adminbae64d82013-08-01 10:50:15 -0700126 command = "sudo pkill ping"
127 main.log.info( command )
128 self.execute(cmd=command,prompt="(.*)",timeout=10)
adminbae64d82013-08-01 10:50:15 -0700129 main.log.info( "Removing old ping data" )
130 command = "rm /tmp/ping.*"
131 os.popen(command)
adminbae64d82013-08-01 10:50:15 -0700132 time.sleep(2)
133 main.log.info( "Transferring ping files to TestStation" )
134 command = "scp /tmp/ping.* admin@10.128.7.7:/tmp/"
135 self.execute(cmd=command,prompt="100%",timeout=20)
136 return main.TRUE
137
138 def pingHost(self,**pingParams):
adminaeedddd2013-08-02 15:14:15 -0700139 '''
140 Pings between two hosts on remote mininet
141 '''
adminbae64d82013-08-01 10:50:15 -0700142 args = utilities.parse_args(["SRC","TARGET"],**pingParams)
143 command = "mininet/util/m " + args["SRC"] + " ping "+args ["TARGET"]+" -c 4 -W 1 -i .2"
144 main.log.info ( command )
145 response = self.execute(cmd=command,prompt="rtt",timeout=10 )
146 if utilities.assert_matches(expect=',\s0\%\spacket\sloss',actual=response,onpass="No Packet loss",onfail="Host is not reachable"):
147 main.log.info("NO PACKET LOSS, HOST IS REACHABLE")
148 main.last_result = main.TRUE
149 return main.TRUE
150 else :
151 main.log.error("PACKET LOST, HOST IS NOT REACHABLE")
152 main.last_result = main.FALSE
153 return main.FALSE
154
155
156 def checknum(self,num):
157 '''
adminaeedddd2013-08-02 15:14:15 -0700158 Verifies the correct number of switches are running
adminbae64d82013-08-01 10:50:15 -0700159 '''
160 if self.handle :
161 self.handle.sendline("")
162 self.handle.expect("\$")
163 self.handle.sendline('ifconfig -a | grep "sw.. " | wc -l')
164 self.handle.expect("wc")
165 self.handle.expect("\$")
166 response = self.handle.before
167 self.handle.sendline('ps -ef | grep "bash -ms mininet:sw" | grep -v color | wc -l')
168 self.handle.expect("color")
169 self.handle.expect("\$")
170 response2 = self.handle.before
171
172 if re.search(num, response):
173 if re.search(num, response2):
174 return main.TRUE
175 else:
176 return main.FALSE
177 else:
178 return main.FALSE
179 else :
180 main.log.error("Connection failed to the host")
181
182 def ctrl_none(self):
adminaeedddd2013-08-02 15:14:15 -0700183 '''
184 Sets all the switches to no controllers.
185 '''
adminbae64d82013-08-01 10:50:15 -0700186 self.execute(cmd="~/ONOS/scripts/test-ctrl-none.sh", prompt="\$",timeout=10)
187
188 def ctrl_one(self, ip):
adminaeedddd2013-08-02 15:14:15 -0700189 '''
190 Sets all the switches to point to the supplied IP
191 '''
adminbae64d82013-08-01 10:50:15 -0700192 self.execute(cmd="~/ONOS/scripts/test-ctrl-one.sh "+ip, prompt="\$",timeout=10)
193
194 def ctrl_local(self):
adminaeedddd2013-08-02 15:14:15 -0700195 '''
196 Sets all the switches to point to the Controller on the same machine that they are running on.
197 '''
adminbae64d82013-08-01 10:50:15 -0700198 self.execute(cmd="~/ONOS/scripts/test-ctrl-local.sh ", prompt="\$",timeout=10)
199
200 # def verifySSH(self,**connectargs):
201 # response = self.execute(cmd="h1 /usr/sbin/sshd -D&",prompt="mininet>",timeout=10)
202 # response = self.execute(cmd="h4 /usr/sbin/sshd -D&",prompt="mininet>",timeout=10)
203 # for key in connectargs:
204 # vars(self)[key] = connectargs[key]
205 # response = self.execute(cmd="xterm h1 h4 ",prompt="mininet>",timeout=10)
206 # import time
207 # time.sleep(20)
208 # if self.flag == 0:
209 # self.flag = 1
210 # return main.FALSE
211 # else :
212 # return main.TRUE
213 #
214 # def getMacAddress(self,host):
215 # '''
216 # Verifies the host's ip configured or not.
217 # '''
218 # if self.handle :
219 # response = self.execute(cmd=host+" ifconfig",prompt="mininet>",timeout=10)
220
221 # pattern = "HWaddr\s(((\d|\w)+:)+(\d|\w))"
222 # mac_address_search = re.search(pattern, response)
223 # main.log.info("Mac-Address of Host "+host +" is "+mac_address_search.group(1))
224 # return mac_address_search.group(1)
225 # else :
226 # main.log.error("Connection failed to the host")
227 # def getIPAddress(self,host):
228 # '''
229 # Verifies the host's ip configured or not.
230 # '''
231 # if self.handle :
232 # response = self.execute(cmd=host+" ifconfig",prompt="mininet>",timeout=10)
233
234 # pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
235 # ip_address_search = re.search(pattern, response)
236 # main.log.info("IP-Address of Host "+host +" is "+ip_address_search.group(1))
237 # return ip_address_search.group(1)
238 # else :
239 # main.log.error("Connection failed to the host")
240 #
241 # def dump(self):
242 # main.log.info("Dump node info")
243 # self.execute(cmd = 'dump',prompt = 'mininet>',timeout = 10)
244 # return main.TRUE
245 #
246 # def intfs(self):
247 # main.log.info("List interfaces")
248 # self.execute(cmd = 'intfs',prompt = 'mininet>',timeout = 10)
249 # return main.TRUE
250 #
251 # def net(self):
252 # main.log.info("List network connections")
253 # self.execute(cmd = 'net',prompt = 'mininet>',timeout = 10)
254 # return main.TRUE
255 #
256 # def iperf(self):
257 # main.log.info("Simple iperf TCP test between two (optionally specified) hosts")
258 # self.execute(cmd = 'iperf',prompt = 'mininet>',timeout = 10)
259 # return main.TRUE
260 #
261 # def iperfudp(self):
262 # main.log.info("Simple iperf TCP test between two (optionally specified) hosts")
263 # self.execute(cmd = 'iperfudp',prompt = 'mininet>',timeout = 10)
264 # return main.TRUE
265 #
266 # def nodes(self):
267 # main.log.info("List all nodes.")
268 # self.execute(cmd = 'nodes',prompt = 'mininet>',timeout = 10)
269 # return main.TRUE
270 #
271 # def pingpair(self):
272 # main.log.infoe("Ping between first two hosts")
273 # self.execute(cmd = 'pingpair',prompt = 'mininet>',timeout = 20)
274 #
275 # if utilities.assert_matches(expect='0% packet loss',actual=response,onpass="No Packet loss",onfail="Hosts not reachable"):
276 # main.log.info("Ping between two hosts SUCCESS")
277 # main.last_result = main.TRUE
278 # return main.TRUE
279 # else :
280 # main.log.error("PACKET LOST, HOSTS NOT REACHABLE")
281 # main.last_result = main.FALSE
282 # return main.FALSE
283 #
284 # def link(self,**linkargs):
285 # '''
286 # Bring link(s) between two nodes up or down
287 # '''
288 # main.log.info('Bring link(s) between two nodes up or down')
289 # args = utilities.parse_args(["END1","END2","OPTION"],**linkargs)
290 # end1 = args["END1"] if args["END1"] != None else ""
291 # end2 = args["END2"] if args["END2"] != None else ""
292 # option = args["OPTION"] if args["OPTION"] != None else ""
293 # command = "link "+str(end1) + " " + str(end2)+ " " + str(option)
294 # response = self.execute(cmd=command,prompt="mininet>",timeout=10)
295 # return main.TRUE
296 #
297
298 # def dpctl(self,**dpctlargs):
299 # '''
300 # Run dpctl command on all switches.
301 # '''
302 # main.log.info('Run dpctl command on all switches')
303 # args = utilities.parse_args(["CMD","ARGS"],**dpctlargs)
304 # cmd = args["CMD"] if args["CMD"] != None else ""
305 # cmdargs = args["ARGS"] if args["ARGS"] != None else ""
306 # command = "dpctl "+cmd + " " + str(cmdargs)
307 # response = self.execute(cmd=command,prompt="mininet>",timeout=10)
308 # return main.TRUE
309 #
310 #
311 # def get_version(self):
312 # file_input = path+'/lib/Mininet/INSTALL'
313 # version = super(Mininet, self).get_version()
314 # pattern = 'Mininet\s\w\.\w\.\w\w*'
315 # for line in open(file_input,'r').readlines():
316 # result = re.match(pattern, line)
317 # if result:
318 # version = result.group(0)
319 #
320 #
321 # return version
admin2a9548d2014-06-17 14:08:07 -0700322 def start_tcpdump(self, filename, intf = "eth0", port = "port 6633"):
323 '''
324 Runs tpdump on an intferface and saves the file
325 intf can be specified, or the default eth0 is used
326 '''
327 try:
328 self.handle.sendline("")
329 self.handle.sendline("sudo tcpdump -n -i "+ intf + " " + port + " -w " + filename.strip() + " &")
330 self.handle.sendline("")
331 self.handle.sendline("")
332 i=self.handle.expect(['No\ssuch\device','listening\son',pexpect.TIMEOUT,"\$"],timeout=10)
333 main.log.warn(self.handle.before + self.handle.after)
334 if i == 0:
335 main.log.error(self.name + ": tcpdump - No such device exists. tcpdump attempted on: " + intf)
336 return main.FALSE
337 elif i == 1:
338 main.log.info(self.name + ": tcpdump started on " + intf)
339 return main.TRUE
340 elif i == 2:
341 main.log.error(self.name + ": tcpdump command timed out! Check interface name, given interface was: " + intf)
342 return main.FALSE
343 elif i ==3:
344 main.log.info(self.name +": " + self.handle.before)
345 return main.TRUE
346 else:
347 main.log.error(self.name + ": tcpdump - unexpected response")
348 return main.FALSE
349 except pexpect.EOF:
350 main.log.error(self.name + ": EOF exception found")
351 main.log.error(self.name + ": " + self.handle.before)
352 main.cleanup()
353 main.exit()
354 except:
355 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
356 main.log.error( traceback.print_exc() )
357 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
358 main.cleanup()
359 main.exit()
360
361 def stop_tcpdump(self):
362 "pkills tcpdump"
363 try:
364 self.handle.sendline("sudo pkill tcpdump")
365 self.handle.sendline("")
366 self.handle.sendline("")
367 self.handle.expect("\$")
368 except pexpect.EOF:
369 main.log.error(self.name + ": EOF exception found")
370 main.log.error(self.name + ": " + self.handle.before)
371 main.cleanup()
372 main.exit()
373 except:
374 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
375 main.log.error( traceback.print_exc() )
376 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
377 main.cleanup()
378 main.exit()
379
380
381
adminbae64d82013-08-01 10:50:15 -0700382
383 def disconnect(self):
adminaeedddd2013-08-02 15:14:15 -0700384 '''
385 Called at the end of the test to disconnect the handle.
386 '''
adminbae64d82013-08-01 10:50:15 -0700387 response = ''
388 #print "Disconnecting Mininet"
389 if self.handle:
390 self.handle.sendline("exit")
391 self.handle.expect("exit")
392 self.handle.expect("(.*)")
393 response = self.handle.before
394
395 else :
396 main.log.error("Connection failed to the host")
397 response = main.FALSE
398 return response
399
400if __name__ != "__main__":
401 import sys
402 sys.modules[__name__] = RemoteMininetDriver()