blob: b43b9f49aba027fb8f78640ab48a6f248c449840 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
2'''
3Created on 31-May-2013
4
5@author: Anil Kumar (anilkumar.s@paxterrasolutions.com)
6
7 TestON is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
11
12 TestON is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with TestON. If not, see <http://www.gnu.org/licenses/>.
19
20
21'''
22import time
23import pexpect
24import struct, fcntl, os, sys, signal
adminbae64d82013-08-01 10:50:15 -070025import re
26import json
Jon Hallf89c8552014-04-02 13:14:06 -070027import traceback
adminbae64d82013-08-01 10:50:15 -070028sys.path.append("../")
29from drivers.common.clidriver import CLI
30
31class OnosCliDriver(CLI):
32
33 def __init__(self):
34 super(CLI, self).__init__()
35
36 def connect(self,**connectargs):
37 '''
38 Creates ssh handle for ONOS.
39 '''
Jon Hallf89c8552014-04-02 13:14:06 -070040 try:
41 for key in connectargs:
42 vars(self)[key] = connectargs[key]
43 self.home = "~/ONOS"
44 for key in self.options:
45 if key == "home":
46 self.home = self.options['home']
47 break
adminbae64d82013-08-01 10:50:15 -070048
Jon Hallf89c8552014-04-02 13:14:06 -070049
50 self.name = self.options['name']
51 self.handle = super(OnosCliDriver,self).connect(user_name = self.user_name, ip_address = self.ip_address,port = self.port, pwd = self.pwd, home = self.home)
adminbae64d82013-08-01 10:50:15 -070052
Jon Hallf89c8552014-04-02 13:14:06 -070053 if self.handle:
54 #self.start()
55 #self.start_rest()
56 return self.handle
57 else :
58 main.log.info("NO ONOS HANDLE")
59 return main.FALSE
60 except:
61 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
62 main.log.error( traceback.print_exc() )
63 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
64 main.cleanup()
65 main.exit()
adminbae64d82013-08-01 10:50:15 -070066
67 def start(self):
68 '''
69 Starts ONOS on remote machine.
70 Returns false if any errors were encountered.
71 '''
Jon Hallf89c8552014-04-02 13:14:06 -070072 try:
73 self.handle.sendline("")
74 self.handle.expect("\$")
75 self.handle.sendline(self.home + "/start-onos.sh start")
76 self.handle.expect("onos.sh start")
77 i=self.handle.expect(["Starting\sONOS\scontroller","Cassandra\sis\snot\srunning"])
78 if i==0:
79 try:
80 self.handle.expect("\$", timeout=60)
81 main.log.info(self.name + ": ONOS Started ")
82 except:
83 main.log.info(self.name + ": ONOS NOT Started, stuck while waiting for it to start ")
84 return main.FALSE
85 return main.TRUE
86 elif i==1:
87 main.log.error(self.name + ": ONOS didn't start because cassandra wasn't running.")
adminbae64d82013-08-01 10:50:15 -070088 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -070089 raise
90 main.log.error(self.name + ": ONOS expect script missed something... ")
adminbae64d82013-08-01 10:50:15 -070091 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -070092 except:
93 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
94 main.log.error( traceback.print_exc() )
95 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
96 main.cleanup()
97 main.exit()
admine0ae8202013-08-28 11:51:43 -070098
99 def start_embedded(self):
Jon Hallf89c8552014-04-02 13:14:06 -0700100 '''
101 Starts ONOS on remote machine with cassandra embedded.
102 Returns false if any errors were encountered.
103 '''
admine0ae8202013-08-28 11:51:43 -0700104 try:
Jon Hallf89c8552014-04-02 13:14:06 -0700105 self.handle.sendline("")
106 self.handle.expect("\$")
107 self.handle.sendline("~/ONOS/start-onos-embedded.sh start")
108 try:
109 self.handle.expect("start...")
110 main.log.info(self.name + ": Embedded ONOS started")
111 except:
112 main.log.info(self.name + ": Embedded ONOS failed to start")
113 return main.FALSE
admine0ae8202013-08-28 11:51:43 -0700114 except:
Jon Hallf89c8552014-04-02 13:14:06 -0700115 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
116 main.log.error( traceback.print_exc() )
117 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
118 main.cleanup()
119 main.exit()
adminbae64d82013-08-01 10:50:15 -0700120
121 def start_rest(self):
122 '''
123 Starts the rest server on ONOS.
Jon Hallf89c8552014-04-02 13:14:06 -0700124 '''
125 try:
126 response = self.execute(cmd= self.home + "/start-rest.sh start",prompt="\$",timeout=10)
127 if re.search("admin",response):
128 main.log.info(self.name + ": Rest Server Started Successfully")
129 time.sleep(5)
130 return main.TRUE
131 else :
132 main.log.warn(self.name + ": Failed to start Rest Server")
133 return main.FALSE
134 except:
135 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
136 main.log.error( traceback.print_exc() )
137 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
138 main.cleanup()
139 main.exit()
140
adminbae64d82013-08-01 10:50:15 -0700141 def status(self):
142 '''
143 Called start-onos.sh status and returns TRUE/FALSE accordingly
144 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700145 try:
146 self.execute(cmd="\n",prompt="\$",timeout=10)
147 response = self.execute(cmd= self.home + "/start-onos.sh status ",prompt="\d+\sinstance\sof\sonos\srunning",timeout=10)
148 self.execute(cmd="\n",prompt="\$",timeout=10)
149 if re.search("1\sinstance\sof\sonos\srunning",response):
150 return main.TRUE
151 elif re.search("0\sinstance\sof\sonos\srunning",response):
152 return main.FALSE
153 else :
154 main.log.info( self.name + " WARNING: status recieved unknown response")
155 return main.FALSE
156 except:
157 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
158 main.log.error( traceback.print_exc() )
159 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
160 main.cleanup()
161 main.exit()
162
adminbae64d82013-08-01 10:50:15 -0700163
164 def isup(self):
165 '''
166 A more complete check to see if ONOS is up and running properly.
167 First, it checks if the process is up.
168 Second, it reads the logs for "Exception: Connection refused"
169 Third, it makes sure the logs are actually moving.
170 returns TRUE/FALSE accordingly.
171 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700172 try:
173 self.execute(cmd="\n",prompt="\$",timeout=10)
174 response = self.execute(cmd= self.home + "/start-onos.sh status ",prompt="running",timeout=10)
175 self.execute(cmd="\n",prompt="\$",timeout=10)
176 tail1 = self.execute(cmd="tail " + self.home + "/onos-logs/onos.*.log",prompt="\$",timeout=10)
177 time.sleep(30)
178 self.execute(cmd="\n",prompt="\$",timeout=10)
179 tail2 = self.execute(cmd="tail " + self.home + "/onos-logs/onos.*.log",prompt="\$",timeout=10)
180 pattern = '(.*)1 instance(.*)'
181 pattern2 = '(.*)Exception: Connection refused(.*)'
182 # if utilities.assert_matches(expect=pattern,actual=response,onpass="ONOS process is running...",onfail="ONOS process not running..."):
183
184 if re.search(pattern, response):
185 main.log.info(self.name + ": ONOS process is running...")
186 if tail1 == tail2:
187 main.log.error(self.name + ": ONOS is frozen...")#logs aren't moving
188 return main.FALSE
189 elif re.search( pattern2,tail1 ):
190 main.log.info(self.name + ": Connection Refused found in onos log")
191 return main.FALSE
192 elif re.search( pattern2,tail2 ):
193 main.log.info(self.name + ": Connection Refused found in onos log")
194 return main.FALSE
195 else:
196 main.log.info(self.name + ": Onos log is moving! It's looking good!")
197 return main.TRUE
adminbae64d82013-08-01 10:50:15 -0700198 else:
Jon Hallf89c8552014-04-02 13:14:06 -0700199 main.log.error(self.name + ": ONOS process not running...")
200 return main.FALSE
201 except:
202 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
203 main.log.error( traceback.print_exc() )
204 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
205 main.cleanup()
206 main.exit()
adminbae64d82013-08-01 10:50:15 -0700207
Jon Hallf89c8552014-04-02 13:14:06 -0700208
209
adminbae64d82013-08-01 10:50:15 -0700210 def rest_status(self):
211 '''
212 Checks if the rest server is running.
213 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700214 try:
215 response = self.execute(cmd= self.home + "/start-rest.sh status ",prompt="running",timeout=10)
216 if re.search("rest\sserver\sis\srunning",response):
217 main.log.info(self.name + ": Rest Server is running")
218 elif re.search("rest\sserver\sis\snot\srunning",response):
219 main.log.warn(self.name + ": Rest Server is not Running")
220 else :
221 main.log.error(self.name + ": No response" +response)
222 self.execute(cmd="\n",prompt="\$",timeout=10)
223
224 return response
225 except:
226 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
227 main.log.error( traceback.print_exc() )
228 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
229 main.cleanup()
230 main.exit()
231
232
adminbae64d82013-08-01 10:50:15 -0700233 def stop(self):
234 '''
235 Runs ./start-onos.sh stop to stop ONOS
236 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700237 try:
238 self.handle.sendline("")
239 self.handle.expect("\$")
240 self.handle.sendline(self.home + "/start-onos.sh stop")
241 self.handle.expect("stop", 2)
242 result = self.handle.before
243 self.handle.expect("\$", 60)
244 if re.search("Killed", result):
245 main.log.info(self.name + ": ONOS Killed Successfully")
246 return main.TRUE
247 else :
248 main.log.warn(self.name + ": ONOS wasn't running")
249 return main.FALSE
250 except:
251 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
252 main.log.error( traceback.print_exc() )
253 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
254 main.cleanup()
255 main.exit()
256
adminbae64d82013-08-01 10:50:15 -0700257
258 def rest_stop(self):
259 '''
260 Runs ./start-rest.sh stop to stop ONOS rest server
261 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700262 try:
263 response = self.execute(cmd= self.home + "/start-rest.sh stop ",prompt="killing",timeout=10)
264 self.execute(cmd="\n",prompt="\$",timeout=10)
265 if re.search("killing", response):
266 main.log.info(self.name + ": Rest Server Stopped")
267 return main.TRUE
268 else :
269 main.log.error(self.name + ": Failed to Stop, Rest Server is not Running")
270 return main.FALSE
271 except:
272 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
273 main.log.error( traceback.print_exc() )
274 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
275 main.cleanup()
276 main.exit()
277
278
adminbae64d82013-08-01 10:50:15 -0700279 def disconnect(self):
280 '''
adminaeedddd2013-08-02 15:14:15 -0700281 Called when Test is complete to disconnect the ONOS handle.
adminbae64d82013-08-01 10:50:15 -0700282 '''
adminaeedddd2013-08-02 15:14:15 -0700283 response = ''
284 try:
adminbae64d82013-08-01 10:50:15 -0700285 self.handle.sendline("exit")
adminaeedddd2013-08-02 15:14:15 -0700286 self.handle.expect("closed")
287 except:
Jon Hallf89c8552014-04-02 13:14:06 -0700288 main.log.error(self.name + ": Connection failed to the host")
adminbae64d82013-08-01 10:50:15 -0700289 response = main.FALSE
adminaeedddd2013-08-02 15:14:15 -0700290 return response
291
adminbae64d82013-08-01 10:50:15 -0700292 def get_version(self):
293 '''
294 Writes the COMMIT number to the report to be parsed by Jenkins data collecter.
admin68453302013-12-16 15:40:04 -0800295 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700296 try:
297 self.handle.sendline("export TERM=xterm-256color")
298 self.handle.expect("xterm-256color")
299 self.handle.expect("\$")
300 self.handle.sendline("cd " + self.home + "; git log -1 --pretty=fuller; cd \.\.")
301 self.handle.expect("cd ..")
302 self.handle.expect("\$")
303 main.log.report(self.name +": \n"+ str(self.handle.before + self.handle.after))
304 except:
305 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
306 main.log.error( traceback.print_exc() )
307 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
308 main.cleanup()
309 main.exit()
adminbae64d82013-08-01 10:50:15 -0700310
Jon Hallf89c8552014-04-02 13:14:06 -0700311 def add_flow(self, testONip, user, password, flowDef):
adminbae64d82013-08-01 10:50:15 -0700312 '''
313 Copies the flowdef file from TestStation -> ONOS machine
314 Then runs ./add_flow.py to add the flows to ONOS
315 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700316 try:
317 main.log.info("Adding Flows...")
318 self.handle.sendline("scp %s@%s:%s /tmp/flowtmp" %(user,testONip,flowDef))
319 i=self.handle.expect(['[pP]assword:', '100%', pexpect.TIMEOUT],30)
320 if(i==0):
321 self.handle.sendline("%s" %(password))
322 self.handle.sendline("")
323 self.handle.expect("100%")
324 self.handle.expect("\$", 30)
325 self.handle.sendline(self.home + "/web/add_flow.py -m onos -f /tmp/flowtmp")
326 self.handle.expect("\$", 1000)
327 main.log.info("Flows added")
328 return main.TRUE
329
330 elif(i==1):
331 self.handle.sendline("")
332 self.handle.expect("\$", 10)
333 self.handle.sendline( self.home + "/web/add_flow.py -m onos -f /tmp/flowtmp")
334 self.handle.expect("\$", 1000)
335 main.log.info("Flows added")
336 return main.TRUE
337
338 elif(i==2):
339 main.log.error("Flow Def file SCP Timed out...")
340 return main.FALSE
341
342 else:
343 main.log.error("Failed to add flows...")
344 return main.FALSE
345 except:
346 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
347 main.log.error( traceback.print_exc() )
348 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
349 main.cleanup()
350 main.exit()
351
adminbae64d82013-08-01 10:50:15 -0700352
353 def delete_flow(self, *delParams):
354 '''
355 Deletes a specific flow, a range of flows, or all flows.
356 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700357 try:
358 if len(delParams)==1:
359 if str(delParams[0])=="all":
360 main.log.info(self.name + ": Deleting ALL flows...")
361 #self.execute(cmd="~/ONOS/scripts/TestON_delete_flow.sh all",prompt="done",timeout=150)
362 self.handle.sendline(self.home + "/web/delete_flow.py all")
363 self.handle.expect("delete_flow")
364 self.handle.expect("\$",1000)
365 main.log.info(self.name + ": Flows deleted")
366 else:
367 main.log.info(self.name + ": Deleting flow "+str(delParams[0])+"...")
368 #self.execute(cmd="~/ONOS/scripts/TestON_delete_flow.sh "+str(delParams[0]),prompt="done",timeout=150)
369 #self.execute(cmd="\n",prompt="\$",timeout=60)
370 self.handle.sendline(self.home +"/web/delete_flow.py %d" % int(delParams[0]))
371 self.handle.expect("delete_flow")
372 self.handle.expect("\$",60)
373 main.log.info(self.name + ": Flow deleted")
374 elif len(delParams)==2:
375 main.log.info(self.name + ": Deleting flows "+str(delParams[0])+" through "+str(delParams[1])+"...")
376 #self.execute(cmd="~/ONOS/scripts/TestON_delete_flow.sh "+str(delParams[0])+" "+str(delParams[1]),prompt="done",timeout=150)
377 #self.execute(cmd="\n",prompt="\$",timeout=60)
378 self.handle.sendline(self.home + "/web/delete_flow.py %d %d" % (int(delParams[0]), int(delParams[1])))
379 self.handle.expect("delete_flow")
380 self.handle.expect("\$",600)
381 main.log.info(self.name + ": Flows deleted")
382 except:
383 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
384 main.log.error( traceback.print_exc() )
385 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
386 main.cleanup()
387 main.exit()
adminbae64d82013-08-01 10:50:15 -0700388
389 def check_flow(self):
390 '''
391 Calls the ./get_flow.py all and checks:
392 - If each FlowPath has at least one FlowEntry
393 - That there are no "NOT"s found
394 returns TRUE/FALSE
395 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700396 try:
397 flowEntryDetect = 1
398 count = 0
399 self.handle.sendline("clear")
400 time.sleep(1)
401 self.handle.sendline(self.home + "/web/get_flow.py all")
402 self.handle.expect("get_flow")
403 while 1:
404 i=self.handle.expect(['FlowPath','FlowEntry','NOT','\$',pexpect.TIMEOUT],timeout=180)
405 if i==0:
406 count = count + 1
407 if flowEntryDetect == 0:
408 main.log.info(self.name + ": FlowPath without FlowEntry")
409 return main.FALSE
410 else:
411 flowEntryDetect = 0
412 elif i==1:
413 flowEntryDetect = 1
414 elif i==2:
415 main.log.error(self.name + ": Found a NOT")
adminbae64d82013-08-01 10:50:15 -0700416 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -0700417 elif i==3:
418 if count == 0:
419 main.log.info(self.name + ": There don't seem to be any flows here...")
420 return main.FALSE
421 else:
422 main.log.info(self.name + ": All flows pass")
423 main.log.info(self.name + ": Number of FlowPaths: "+str(count))
424 return main.TRUE
425 elif i==4:
426 main.log.error(self.name + ":Check_flow() - Command Timeout!")
427 return main.FALSE
428 except:
429 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
430 main.log.error( traceback.print_exc() )
431 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
432 main.cleanup()
433 main.exit()
adminbae64d82013-08-01 10:50:15 -0700434
435 def get_flow(self, *flowParams):
436 '''
437 Returns verbose output of ./get_flow.py
438 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700439 try:
440 if len(flowParams)==1:
441 if str(flowParams[0])=="all":
442 self.execute(cmd="\n",prompt="\$",timeout=60)
443 main.log.info(self.name + ": Getting all flow data...")
444 data = self.execute(cmd=self.home + "/scripts/TestON_get_flow.sh all",prompt="done",timeout=150)
445 self.execute(cmd="\n",prompt="\$",timeout=60)
446 return data
447 else:
448 main.log.info(self.name + ": Retrieving flow "+str(flowParams[0])+" data...")
449 data = self.execute(cmd=self.home +"/scripts/TestON_get_flow.sh "+str(flowParams[0]),prompt="done",timeout=150)
450 self.execute(cmd="\n",prompt="\$",timeout=60)
451 return data
452 elif len(flowParams)==5:
453 main.log.info(self.name + ": Retrieving flow installer data...")
454 data = self.execute(cmd=self.home + "/scripts/TestON_get_flow.sh "+str(flowParams[0])+" "+str(flowParams[1])+" "+str(flowParams[2])+" "+str(flowParams[3])+" "+str(flowParams[4]),prompt="done",timeout=150)
455 self.execute(cmd="\n",prompt="\$",timeout=60)
456 return data
457 elif len(flowParams)==4:
458 main.log.info(self.name + ": Retrieving flow endpoints...")
459 data = self.execute(cmd=self.home + "/scripts/TestON_get_flow.sh "+str(flowParams[0])+" "+str(flowParams[1])+" "+str(flowParams[2])+" "+str(flowParams[3]),prompt="done",timeout=150)
460 self.execute(cmd="\n",prompt="\$",timeout=60)
461 return data
462 except:
463 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
464 main.log.error( traceback.print_exc() )
465 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
466 main.cleanup()
467 main.exit()
adminbae64d82013-08-01 10:50:15 -0700468
469
470# http://localhost:8080/wm/core/topology/switches/all/json
471# http://localhost:8080/wm/core/topology/links/json
472# http://localhost:8080/wm/registry/controllers/json
473# http://localhost:8080/wm/registry/switches/json"
474
475 def get_json(self, url):
476 '''
477 Helper functions used to parse the json output of a rest call
478 '''
479 try:
Jon Hallf89c8552014-04-02 13:14:06 -0700480 try:
481 command = "curl -s %s" % (url)
482 result = os.popen(command).read()
483 parsedResult = json.loads(result)
484 except:
485 print "REST IF %s has issue" % command
486 parsedResult = ""
487
488 if type(parsedResult) == 'dict' and parsedResult.has_key('code'):
489 print "REST %s returned code %s" % (command, parsedResult['code'])
490 parsedResult = ""
491 return parsedResult
adminbae64d82013-08-01 10:50:15 -0700492 except:
Jon Hallf89c8552014-04-02 13:14:06 -0700493 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
494 main.log.error( traceback.print_exc() )
495 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
496 main.cleanup()
497 main.exit()
adminbae64d82013-08-01 10:50:15 -0700498
Jon Hallf89c8552014-04-02 13:14:06 -0700499 def check_switch(self,RestIP,correct_nr_switch, RestPort ="8080" ):
adminbae64d82013-08-01 10:50:15 -0700500 '''
501 Used by check_status
502 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700503 try:
504 buf = ""
505 retcode = 0
506 #RestPort="8080"
507 url="http://%s:%s/wm/onos/topology/switches/all/json" % (RestIP, RestPort)
508 parsedResult = self.get_json(url)
509 if parsedResult == "":
510 retcode = 1
511 return (retcode, "Rest API has an issue")
512 url = "http://%s:%s/wm/onos/registry/switches/json" % (RestIP, RestPort)
513 registry = self.get_json(url)
514
515 if registry == "":
516 retcode = 1
517 return (retcode, "Rest API has an issue")
518
519 cnt = 0
520 active = 0
adminbae64d82013-08-01 10:50:15 -0700521
Jon Hallf89c8552014-04-02 13:14:06 -0700522 for s in parsedResult:
523 cnt += 1
524 if s['state'] == "ACTIVE":
525 active += 1
adminbae64d82013-08-01 10:50:15 -0700526
Jon Hallf89c8552014-04-02 13:14:06 -0700527 buf += "switch: network %d : %d switches %d active\n" % (0+1, cnt, active)
528 if correct_nr_switch != cnt:
529 buf += "switch fail: network %d should have %d switches but has %d\n" % (1, correct_nr_switch, cnt)
530 retcode = 1
adminbae64d82013-08-01 10:50:15 -0700531
Jon Hallf89c8552014-04-02 13:14:06 -0700532 if correct_nr_switch != active:
533 buf += "switch fail: network %d should have %d active switches but has %d\n" % (1, correct_nr_switch, active)
534 retcode = 1
535
536 return (retcode, buf)
537 except:
538 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
539 main.log.error( traceback.print_exc() )
540 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
541 main.cleanup()
542 main.exit()
adminbae64d82013-08-01 10:50:15 -0700543
Jon Hallf89c8552014-04-02 13:14:06 -0700544 def check_link(self,RestIP, nr_links, RestPort = "8080"):
adminbae64d82013-08-01 10:50:15 -0700545 '''
546 Used by check_status
547 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700548 try:
549 buf = ""
550 retcode = 0
551
552 url = "http://%s:%s/wm/onos/topology/links/json" % (RestIP, RestPort)
553 parsedResult = self.get_json(url)
554
555 if parsedResult == "":
556 retcode = 1
557 return (retcode, "Rest API has an issue")
558
559 buf += "link: total %d links (correct : %d)\n" % (len(parsedResult), nr_links)
560 intra = 0
561 interlink=0
562
563 for s in parsedResult:
564 intra = intra + 1
565
566 if intra != nr_links:
567 buf += "link fail\n"
568 retcode = 1
569
570 return (retcode, buf)
571 except:
572 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
573 main.log.error( traceback.print_exc() )
574 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
575 main.cleanup()
576 main.exit()
adminbae64d82013-08-01 10:50:15 -0700577
Jon Hallf89c8552014-04-02 13:14:06 -0700578 def check_status_report(self, ip, numoswitch, numolink, port="8080"):
adminbae64d82013-08-01 10:50:15 -0700579 '''
580 Checks the number of swithes & links that ONOS sees against the supplied values.
581 Writes to the report log.
Jon Hallf89c8552014-04-02 13:14:06 -0700582 '''
583 try:
584 main.log.info(self.name + ": Making some rest calls...")
585 switch = self.check_switch(ip, int(numoswitch), port)
586 link = self.check_link(ip, int(numolink), port)
587 value = switch[0]
588 value += link[0]
589 main.log.report( self.name + ": \n-----\n%s%s-----\n" % ( switch[1], link[1]) )
590 if value != 0:
591 return main.FALSE
592 else:
593 # "PASS"
594 return main.TRUE
595 except:
596 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
597 main.log.error( traceback.print_exc() )
598 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
599 main.cleanup()
600 main.exit()
adminbae64d82013-08-01 10:50:15 -0700601
Jon Hallf89c8552014-04-02 13:14:06 -0700602 def check_status(self, ip, numoswitch, numolink, port = "8080"):
adminbae64d82013-08-01 10:50:15 -0700603 '''
604 Checks the number of swithes & links that ONOS sees against the supplied values.
605 Writes to the main log.
606 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700607 try:
608 main.log.info(self.name + ": Making some rest calls...")
609 switch = self.check_switch(ip, int(numoswitch), port)
610 link = self.check_link(ip, int(numolink), port)
611 value = switch[0]
612 value += link[0]
613 main.log.info(self.name + ": \n-----\n%s%s-----\n" % ( switch[1], link[1]) )
614 if value != 0:
615 return main.FALSE
616 else:
617 # "PASS"
618 return main.TRUE
619 except:
620 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
621 main.log.error( traceback.print_exc() )
622 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
623 main.cleanup()
624 main.exit()
adminbae64d82013-08-01 10:50:15 -0700625
626 def drop_keyspace(self):
627 '''
628 Drops the ONOS keyspace
629 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700630 try:
631 self.handle.sendline(self.home + "/scripts/drop-keyspace.sh")
632 self.handle.expect("keyspace")
633 self.handle.sendline("")
634 self.handle.expect("\$")
635 self.handle.expect("\$")
636 main.log.info(self.name + ": Keyspace dropped")
637 except:
638 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
639 main.log.error( traceback.print_exc() )
640 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
641 main.cleanup()
642 main.exit()
adminbae64d82013-08-01 10:50:15 -0700643
Jon Hallf89c8552014-04-02 13:14:06 -0700644
adminbae64d82013-08-01 10:50:15 -0700645 def check_for_no_exceptions(self):
646 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700647 TODO: Rewrite
adminbae64d82013-08-01 10:50:15 -0700648 Used by CassndraCheck.py to scan ONOS logs for Exceptions
649 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700650 try:
651 self.handle.sendline("dsh 'grep Exception ~/ONOS/onos-logs/onos.*.log'")
652 self.handle.expect("\$ dsh")
653 self.handle.expect("\$")
654 output = self.handle.before
655 main.log.info(self.name + ": " + output )
656 if re.search("Exception",output):
657 return main.FALSE
658 else :
659 return main.TRUE
660 except:
661 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
662 main.log.error( traceback.print_exc() )
663 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
664 main.cleanup()
665 main.exit()
666
667
adminbae64d82013-08-01 10:50:15 -0700668 def git_pull(self):
669 '''
670 Stops the ONOS, pulls the latest code, and builds with mvn.
671 Assumes that "git pull" works without login
672 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700673 try:
674 main.log.info(self.name + ": Stopping ONOS")
675 self.stop()
676 self.handle.sendline("cd " + self.home)
677 self.handle.expect("ONOS\$")
678 self.handle.sendline("git pull")
679
680 uptodate = 0
681 i=self.handle.expect(['fatal','Username\sfor\s(.*):\s','Unpacking\sobjects',pexpect.TIMEOUT,'Already up-to-date','Aborting'],timeout=180)
682 #debug
683 #main.log.report(self.name +": \n"+"git pull response: " + str(self.handle.before) + str(self.handle.after))
684 if i==0:
685 main.log.error(self.name + ": Git pull had some issue...")
686 return main.FALSE
687 elif i==1:
688 main.log.error(self.name + ": Git Pull Asking for username!!! BADD!")
689 return main.FALSE
690 elif i==2:
691 main.log.info(self.name + ": Git Pull - pulling repository now")
692 self.handle.expect("ONOS\$", 120)
693 elif i==3:
694 main.log.error(self.name + ": Git Pull - TIMEOUT")
695 return main.FALSE
696 elif i==4:
697 main.log.info(self.name + ": Git Pull - Already up to date")
698 uptodate = 1
699 elif i==5:
700 main.log.info(self.name + ": Git Pull - Aborting... Are there conflicting git files?")
701 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700702 else:
Jon Hallf89c8552014-04-02 13:14:06 -0700703 main.log.error(self.name + ": Git Pull - Unexpected response, check for pull errors")
adminbae64d82013-08-01 10:50:15 -0700704 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -0700705
706 if uptodate == 0:
707 main.log.info(self.name + ": mvn clean")
708 self.handle.sendline("mvn clean")
709 while 1:
710 i=self.handle.expect(['BUILD\sFAILURE','BUILD\sSUCCESS','ONOS\$',pexpect.TIMEOUT],timeout=30)
711 if i == 0:
712 main.log.error(self.name + ": Build failure!")
713 return main.FALSE
714 elif i == 1:
715 main.log.info(self.name + ": Build success!")
716 elif i == 2:
717 main.log.info(self.name + ": Build complete")
718 break;
719 elif i == 3:
720 main.log.error(self.name + ": mvn clean TIMEOUT!")
721 return main.FALSE
722
723 main.log.info(self.name + ": mvn compile")
724 self.handle.sendline("mvn compile")
725 while 1:
726 i=self.handle.expect(['BUILD\sFAILURE','BUILD\sSUCCESS','ONOS\$',pexpect.TIMEOUT],timeout=60)
727 if i == 0:
728 main.log.error(self.name + ": Build failure!")
729 return main.FALSE
730 elif i == 1:
731 main.log.info(self.name + ": Build success!")
732 return main.TRUE
733 elif i == 2:
734 main.log.info(self.name + ": Build complete")
735 return main.TRUE
736 elif i == 3:
737 main.log.error(self.name + ": mvn compile TIMEOUT!")
738 return main.FALSE
739 else:
740 pass
741 except:
742 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
743 main.log.error( traceback.print_exc() )
744 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
745 main.cleanup()
746 main.exit()
admin4a58db92013-09-30 12:04:54 -0700747
Jon Hallf89c8552014-04-02 13:14:06 -0700748
749 def tcpdump(self, intf = "eth0"):
750 try:
751 self.handle.sendline("")
752 self.handle.expect("\$")
753 self.handle.sendline("sudo tcpdump -n -i "+ intf + " -s0 -w onos-logs/tcpdump &")
754 i=self.handle.expect(['No\ssuch\device','listening\son',pexpect.TIMEOUT],timeout=10)
755 if i == 0:
756 main.log.error(self.name + ": tcpdump - No such device exists. tcpdump attempted on: " + intf)
757 return main.FALSE
758 elif i == 1:
759 main.log.info(self.name + ": tcpdump started on " + intf)
760 return main.TRUE
761 elif i == 2:
762 main.log.error(self.name + ": tcpdump command timed out! Check interface name, given interface was: " + intf)
763 return main.FALSE
764 else:
765 main.log.error(self.name + ": tcpdump - unexpected response")
766 return main.FALSE
767 except:
768 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
769 main.log.error( traceback.print_exc() )
770 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
771 main.cleanup()
772 main.exit()
773
admin4a58db92013-09-30 12:04:54 -0700774 def kill_tcpdump(self):
Jon Hallf89c8552014-04-02 13:14:06 -0700775 try:
776 self.handle.sendline("")
777 self.handle.expect("\$")
778 self.handle.sendline("sudo kill -9 `ps -ef | grep \"tcpdump -n\" | grep -v grep | awk '{print $2}'`")
779 except:
780 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
781 main.log.error( traceback.print_exc() )
782 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
783 main.cleanup()
784 main.exit()
785
786 def find_host(self,RestIP,RestPort,RestAPI,hostIP):
787 retcode = 0
788 retswitch = []
789 retport = []
790 retmac = []
791 foundIP = []
792 try:
793 ##### device rest API is: 'host:8080/wm/core/topology/switches/all/json' ###
794 url ="http://%s:%s%s" %(RestIP,RestPort,RestAPI)
795
796 try:
797 command = "curl -s %s" % (url)
798 result = os.popen(command).read()
799 parsedResult = json.loads(result)
800 # print parsedResult
801 except:
802 print "REST IF %s has issue" % command
803 parsedResult = ""
804
805 if parsedResult == "":
806 return (retcode, "Rest API has an error")
807 else:
808 for switch in enumerate(parsedResult):
809 for port in enumerate(switch[1]['ports']):
810 if ( port[1]['devices'] != [] ):
811 try:
812 foundIP = port[1]['devices'][0]['ipv4addresses'][0]['ipv4']
813 except:
814 print "Error in detecting IP address."
815 if foundIP == hostIP:
816 retswitch.append(switch[1]['dpid'])
817 retport.append(port[1]['desc'])
818 retmac.append(port[1]['devices'][0]['mac'])
819 retcode = retcode +1
820 foundIP =''
821 return(retcode, retswitch, retport, retmac)
822 except:
823 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
824 main.log.error( traceback.print_exc() )
825 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
826 main.cleanup()
827 main.exit()