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