blob: 8757f5b89ae652b32dcb00e0db84b88765c4d1e8 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
2'''
James Leec9cacaf2014-04-08 09:17:39 -07003Created on 31-May-2013
adminbae64d82013-08-01 10:50:15 -07004
James Leec9cacaf2014-04-08 09:17:39 -07005@author: Anil Kumar (anilkumar.s@paxterrasolutions.com)
adminbae64d82013-08-01 10:50:15 -07006
James Leec9cacaf2014-04-08 09:17:39 -07007TestON is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 2 of the License, or
10(at your option) any later version.
adminbae64d82013-08-01 10:50:15 -070011
James Leec9cacaf2014-04-08 09:17:39 -070012TestON is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070016
James Leec9cacaf2014-04-08 09:17:39 -070017You should have received a copy of the GNU General Public License
18along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070019
20
James Leec9cacaf2014-04-08 09:17:39 -070021'''
adminbae64d82013-08-01 10:50:15 -070022import 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):
Jon Halld8dc5772014-04-08 16:26:29 -070037 '''
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):
Jon Halld8dc5772014-04-08 16:26:29 -070068 '''
69 Starts ONOS on remote machine.
70 Returns false if any errors were encountered.
71 '''
James Leec9cacaf2014-04-08 09:17:39 -070072 try:
Jon Hallf89c8552014-04-02 13:14:06 -070073 self.handle.sendline("")
74 self.handle.expect("\$")
adminf939f8b2014-04-03 17:22:56 -070075 self.handle.sendline(self.home + "/onos.sh core start")
76 self.handle.expect("onos.sh core start")
James Leec9cacaf2014-04-08 09:17:39 -070077 i=self.handle.expect(["STARTED","FAILED"])
Jon Hallf89c8552014-04-02 13:14:06 -070078 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:
adminf939f8b2014-04-03 17:22:56 -070087 main.log.error(self.name + ": ONOS Failed ")
adminbae64d82013-08-01 10:50:15 -070088 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -070089 raise
James Leec9cacaf2014-04-08 09:17:39 -070090 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
adminbae64d82013-08-01 10:50:15 -070099 def start_rest(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700100 '''
101 Starts the rest server on ONOS.
102 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700103 try:
104 response = self.execute(cmd= self.home + "/start-rest.sh start",prompt="\$",timeout=10)
105 if re.search("admin",response):
106 main.log.info(self.name + ": Rest Server Started Successfully")
107 time.sleep(5)
108 return main.TRUE
109 else :
James Leec9cacaf2014-04-08 09:17:39 -0700110 main.log.warn(self.name + ": Failed to start Rest Server")
111 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -0700112 except:
113 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
114 main.log.error( traceback.print_exc() )
115 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
116 main.cleanup()
117 main.exit()
118
adminbae64d82013-08-01 10:50:15 -0700119 def status(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700120 '''
121 Called onos.sh core status and returns TRUE/FALSE accordingly
122 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700123 try:
124 self.execute(cmd="\n",prompt="\$",timeout=10)
adminf939f8b2014-04-03 17:22:56 -0700125 response = self.execute(cmd= self.home + "/onos.sh core status ",prompt="\d+\sinstance\sof\sonos\srunning",timeout=10)
Jon Hallf89c8552014-04-02 13:14:06 -0700126 self.execute(cmd="\n",prompt="\$",timeout=10)
127 if re.search("1\sinstance\sof\sonos\srunning",response):
128 return main.TRUE
129 elif re.search("0\sinstance\sof\sonos\srunning",response):
130 return main.FALSE
131 else :
132 main.log.info( self.name + " WARNING: status recieved unknown response")
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
142 def isup(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700143 '''
144 A more complete check to see if ONOS is up and running properly.
145 First, it checks if the process is up.
146 Second, it reads the logs for "Exception: Connection refused"
147 Third, it makes sure the logs are actually moving.
148 returns TRUE/FALSE accordingly.
149 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700150 try:
151 self.execute(cmd="\n",prompt="\$",timeout=10)
adminf939f8b2014-04-03 17:22:56 -0700152 response = self.execute(cmd= self.home + "/onos.sh core status ",prompt="running",timeout=10)
Jon Hallf89c8552014-04-02 13:14:06 -0700153 self.execute(cmd="\n",prompt="\$",timeout=10)
154 tail1 = self.execute(cmd="tail " + self.home + "/onos-logs/onos.*.log",prompt="\$",timeout=10)
155 time.sleep(30)
156 self.execute(cmd="\n",prompt="\$",timeout=10)
157 tail2 = self.execute(cmd="tail " + self.home + "/onos-logs/onos.*.log",prompt="\$",timeout=10)
158 pattern = '(.*)1 instance(.*)'
159 pattern2 = '(.*)Exception: Connection refused(.*)'
160 # if utilities.assert_matches(expect=pattern,actual=response,onpass="ONOS process is running...",onfail="ONOS process not running..."):
161
162 if re.search(pattern, response):
163 main.log.info(self.name + ": ONOS process is running...")
164 if tail1 == tail2:
165 main.log.error(self.name + ": ONOS is frozen...")#logs aren't moving
166 return main.FALSE
167 elif re.search( pattern2,tail1 ):
James Leec9cacaf2014-04-08 09:17:39 -0700168 main.log.info(self.name + ": Connection Refused found in onos log")
Jon Hallf89c8552014-04-02 13:14:06 -0700169 return main.FALSE
170 elif re.search( pattern2,tail2 ):
James Leec9cacaf2014-04-08 09:17:39 -0700171 main.log.info(self.name + ": Connection Refused found in onos log")
Jon Hallf89c8552014-04-02 13:14:06 -0700172 return main.FALSE
173 else:
174 main.log.info(self.name + ": Onos log is moving! It's looking good!")
175 return main.TRUE
adminbae64d82013-08-01 10:50:15 -0700176 else:
Jon Hallf89c8552014-04-02 13:14:06 -0700177 main.log.error(self.name + ": ONOS process not running...")
178 return main.FALSE
179 except:
180 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
181 main.log.error( traceback.print_exc() )
182 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
183 main.cleanup()
184 main.exit()
adminbae64d82013-08-01 10:50:15 -0700185
Jon Hallf89c8552014-04-02 13:14:06 -0700186
187
James Leec9cacaf2014-04-08 09:17:39 -0700188 def rest_status(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700189 '''
190 Checks if the rest server is running.
191 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700192 try:
193 response = self.execute(cmd= self.home + "/start-rest.sh status ",prompt="running",timeout=10)
194 if re.search("rest\sserver\sis\srunning",response):
195 main.log.info(self.name + ": Rest Server is running")
196 elif re.search("rest\sserver\sis\snot\srunning",response):
197 main.log.warn(self.name + ": Rest Server is not Running")
198 else :
199 main.log.error(self.name + ": No response" +response)
200 self.execute(cmd="\n",prompt="\$",timeout=10)
201
202 return response
203 except:
204 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
205 main.log.error( traceback.print_exc() )
206 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
207 main.cleanup()
208 main.exit()
209
210
adminbae64d82013-08-01 10:50:15 -0700211 def stop(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700212 '''
213 Runs ./onos.sh core stop to stop ONOS
214 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700215 try:
216 self.handle.sendline("")
217 self.handle.expect("\$")
adminf939f8b2014-04-03 17:22:56 -0700218 self.handle.sendline(self.home + "/onos.sh core stop")
Jon Hallf89c8552014-04-02 13:14:06 -0700219 self.handle.expect("stop", 2)
James Leec9cacaf2014-04-08 09:17:39 -0700220 result = self.handle.before
Jon Hallf89c8552014-04-02 13:14:06 -0700221 self.handle.expect("\$", 60)
222 if re.search("Killed", result):
223 main.log.info(self.name + ": ONOS Killed Successfully")
224 return main.TRUE
225 else :
226 main.log.warn(self.name + ": ONOS wasn't running")
227 return main.FALSE
228 except:
229 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
230 main.log.error( traceback.print_exc() )
231 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
232 main.cleanup()
233 main.exit()
234
adminbae64d82013-08-01 10:50:15 -0700235
236 def rest_stop(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700237 '''
238 Runs ./start-rest.sh stop to stop ONOS rest server
239 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700240 try:
241 response = self.execute(cmd= self.home + "/start-rest.sh stop ",prompt="killing",timeout=10)
242 self.execute(cmd="\n",prompt="\$",timeout=10)
243 if re.search("killing", response):
244 main.log.info(self.name + ": Rest Server Stopped")
245 return main.TRUE
246 else :
247 main.log.error(self.name + ": Failed to Stop, Rest Server is not Running")
248 return main.FALSE
249 except:
250 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
251 main.log.error( traceback.print_exc() )
252 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
253 main.cleanup()
254 main.exit()
255
256
adminbae64d82013-08-01 10:50:15 -0700257 def disconnect(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700258 '''
259 Called when Test is complete to disconnect the ONOS handle.
260 '''
adminaeedddd2013-08-02 15:14:15 -0700261 response = ''
262 try:
adminbae64d82013-08-01 10:50:15 -0700263 self.handle.sendline("exit")
adminaeedddd2013-08-02 15:14:15 -0700264 self.handle.expect("closed")
James Leec9cacaf2014-04-08 09:17:39 -0700265 except:
Jon Hallf89c8552014-04-02 13:14:06 -0700266 main.log.error(self.name + ": Connection failed to the host")
adminbae64d82013-08-01 10:50:15 -0700267 response = main.FALSE
adminaeedddd2013-08-02 15:14:15 -0700268 return response
269
adminbae64d82013-08-01 10:50:15 -0700270 def get_version(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700271 '''
272 Writes the COMMIT number to the report to be parsed by Jenkins data collecter.
273 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700274 try:
275 self.handle.sendline("export TERM=xterm-256color")
276 self.handle.expect("xterm-256color")
James Leec9cacaf2014-04-08 09:17:39 -0700277 self.handle.expect("\$")
adminf939f8b2014-04-03 17:22:56 -0700278 self.handle.sendline("cd " + self.home + "; git log -1 --pretty=fuller | grep -A 5 \"commit\"; cd \.\.")
Jon Hallf89c8552014-04-02 13:14:06 -0700279 self.handle.expect("cd ..")
280 self.handle.expect("\$")
281 main.log.report(self.name +": \n"+ str(self.handle.before + self.handle.after))
282 except:
283 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
284 main.log.error( traceback.print_exc() )
285 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
286 main.cleanup()
287 main.exit()
adminbae64d82013-08-01 10:50:15 -0700288
Jon Hallf89c8552014-04-02 13:14:06 -0700289 def add_flow(self, testONip, user, password, flowDef):
Jon Halld8dc5772014-04-08 16:26:29 -0700290 '''
291 Copies the flowdef file from TestStation -> ONOS machine
292 Then runs ./add_flow.py to add the flows to ONOS
293 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700294 try:
295 main.log.info("Adding Flows...")
296 self.handle.sendline("scp %s@%s:%s /tmp/flowtmp" %(user,testONip,flowDef))
297 i=self.handle.expect(['[pP]assword:', '100%', pexpect.TIMEOUT],30)
298 if(i==0):
299 self.handle.sendline("%s" %(password))
300 self.handle.sendline("")
301 self.handle.expect("100%")
302 self.handle.expect("\$", 30)
303 self.handle.sendline(self.home + "/web/add_flow.py -m onos -f /tmp/flowtmp")
304 self.handle.expect("\$", 1000)
305 main.log.info("Flows added")
306 return main.TRUE
307
308 elif(i==1):
309 self.handle.sendline("")
310 self.handle.expect("\$", 10)
311 self.handle.sendline( self.home + "/web/add_flow.py -m onos -f /tmp/flowtmp")
312 self.handle.expect("\$", 1000)
313 main.log.info("Flows added")
314 return main.TRUE
315
316 elif(i==2):
317 main.log.error("Flow Def file SCP Timed out...")
318 return main.FALSE
319
320 else:
321 main.log.error("Failed to add flows...")
James Leec9cacaf2014-04-08 09:17:39 -0700322 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -0700323 except:
324 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
325 main.log.error( traceback.print_exc() )
326 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
327 main.cleanup()
328 main.exit()
329
adminbae64d82013-08-01 10:50:15 -0700330
331 def delete_flow(self, *delParams):
Jon Halld8dc5772014-04-08 16:26:29 -0700332 '''
333 Deletes a specific flow, a range of flows, or all flows.
334 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700335 try:
336 if len(delParams)==1:
337 if str(delParams[0])=="all":
338 main.log.info(self.name + ": Deleting ALL flows...")
339 #self.execute(cmd="~/ONOS/scripts/TestON_delete_flow.sh all",prompt="done",timeout=150)
340 self.handle.sendline(self.home + "/web/delete_flow.py all")
341 self.handle.expect("delete_flow")
342 self.handle.expect("\$",1000)
343 main.log.info(self.name + ": Flows deleted")
344 else:
345 main.log.info(self.name + ": Deleting flow "+str(delParams[0])+"...")
346 #self.execute(cmd="~/ONOS/scripts/TestON_delete_flow.sh "+str(delParams[0]),prompt="done",timeout=150)
347 #self.execute(cmd="\n",prompt="\$",timeout=60)
348 self.handle.sendline(self.home +"/web/delete_flow.py %d" % int(delParams[0]))
349 self.handle.expect("delete_flow")
350 self.handle.expect("\$",60)
351 main.log.info(self.name + ": Flow deleted")
352 elif len(delParams)==2:
353 main.log.info(self.name + ": Deleting flows "+str(delParams[0])+" through "+str(delParams[1])+"...")
354 #self.execute(cmd="~/ONOS/scripts/TestON_delete_flow.sh "+str(delParams[0])+" "+str(delParams[1]),prompt="done",timeout=150)
355 #self.execute(cmd="\n",prompt="\$",timeout=60)
356 self.handle.sendline(self.home + "/web/delete_flow.py %d %d" % (int(delParams[0]), int(delParams[1])))
357 self.handle.expect("delete_flow")
358 self.handle.expect("\$",600)
359 main.log.info(self.name + ": Flows deleted")
360 except:
361 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
362 main.log.error( traceback.print_exc() )
363 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
364 main.cleanup()
365 main.exit()
adminbae64d82013-08-01 10:50:15 -0700366
367 def check_flow(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700368 '''
369 Calls the ./get_flow.py all and checks:
370 - If each FlowPath has at least one FlowEntry
371 - That there are no "NOT"s found
372 returns TRUE/FALSE
373 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700374 try:
375 flowEntryDetect = 1
376 count = 0
377 self.handle.sendline("clear")
378 time.sleep(1)
379 self.handle.sendline(self.home + "/web/get_flow.py all")
380 self.handle.expect("get_flow")
381 while 1:
382 i=self.handle.expect(['FlowPath','FlowEntry','NOT','\$',pexpect.TIMEOUT],timeout=180)
383 if i==0:
384 count = count + 1
385 if flowEntryDetect == 0:
386 main.log.info(self.name + ": FlowPath without FlowEntry")
387 return main.FALSE
388 else:
389 flowEntryDetect = 0
390 elif i==1:
391 flowEntryDetect = 1
392 elif i==2:
393 main.log.error(self.name + ": Found a NOT")
adminbae64d82013-08-01 10:50:15 -0700394 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -0700395 elif i==3:
396 if count == 0:
397 main.log.info(self.name + ": There don't seem to be any flows here...")
398 return main.FALSE
399 else:
400 main.log.info(self.name + ": All flows pass")
401 main.log.info(self.name + ": Number of FlowPaths: "+str(count))
402 return main.TRUE
403 elif i==4:
James Leec9cacaf2014-04-08 09:17:39 -0700404 main.log.error(self.name + ":Check_flow() - Command Timeout!")
Jon Hallf89c8552014-04-02 13:14:06 -0700405 return main.FALSE
406 except:
407 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
408 main.log.error( traceback.print_exc() )
409 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
410 main.cleanup()
411 main.exit()
adminbae64d82013-08-01 10:50:15 -0700412
413 def get_flow(self, *flowParams):
Jon Halld8dc5772014-04-08 16:26:29 -0700414 '''
415 Returns verbose output of ./get_flow.py
416 '''
417 try:
418 if len(flowParams)==1:
419 if str(flowParams[0])=="all":
420 self.execute(cmd="\n",prompt="\$",timeout=60)
421 main.log.info(self.name + ": Getting all flow data...")
422 data = self.execute(cmd=self.home + "/scripts/TestON_get_flow.sh all",prompt="done",timeout=150)
423 self.execute(cmd="\n",prompt="\$",timeout=60)
424 return data
425 else:
426 main.log.info(self.name + ": Retrieving flow "+str(flowParams[0])+" data...")
427 data = self.execute(cmd=self.home +"/scripts/TestON_get_flow.sh "+str(flowParams[0]),prompt="done",timeout=150)
428 self.execute(cmd="\n",prompt="\$",timeout=60)
429 return data
430 elif len(flowParams)==5:
431 main.log.info(self.name + ": Retrieving flow installer data...")
432 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)
433 self.execute(cmd="\n",prompt="\$",timeout=60)
434 return data
435 elif len(flowParams)==4:
436 main.log.info(self.name + ": Retrieving flow endpoints...")
437 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)
438 self.execute(cmd="\n",prompt="\$",timeout=60)
439 return data
440 except:
Jon Hallf89c8552014-04-02 13:14:06 -0700441 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
442 main.log.error( traceback.print_exc() )
443 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
444 main.cleanup()
445 main.exit()
adminbae64d82013-08-01 10:50:15 -0700446
447
448# http://localhost:8080/wm/core/topology/switches/all/json
449# http://localhost:8080/wm/core/topology/links/json
450# http://localhost:8080/wm/registry/controllers/json
451# http://localhost:8080/wm/registry/switches/json"
452
453 def get_json(self, url):
Jon Halld8dc5772014-04-08 16:26:29 -0700454 '''
455 Helper functions used to parse the json output of a rest call
456 '''
adminbae64d82013-08-01 10:50:15 -0700457 try:
Jon Hallf89c8552014-04-02 13:14:06 -0700458 try:
459 command = "curl -s %s" % (url)
460 result = os.popen(command).read()
461 parsedResult = json.loads(result)
462 except:
463 print "REST IF %s has issue" % command
464 parsedResult = ""
465
466 if type(parsedResult) == 'dict' and parsedResult.has_key('code'):
467 print "REST %s returned code %s" % (command, parsedResult['code'])
468 parsedResult = ""
James Leec9cacaf2014-04-08 09:17:39 -0700469 return parsedResult
adminbae64d82013-08-01 10:50:15 -0700470 except:
Jon Hallf89c8552014-04-02 13:14:06 -0700471 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
472 main.log.error( traceback.print_exc() )
473 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
474 main.cleanup()
475 main.exit()
adminbae64d82013-08-01 10:50:15 -0700476
Jon Hallf89c8552014-04-02 13:14:06 -0700477 def check_switch(self,RestIP,correct_nr_switch, RestPort ="8080" ):
Jon Halld8dc5772014-04-08 16:26:29 -0700478 '''
479 Used by check_status
480 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700481 try:
482 buf = ""
483 retcode = 0
484 #RestPort="8080"
adminf939f8b2014-04-03 17:22:56 -0700485 url="http://%s:%s/wm/onos/topology/switches/json" % (RestIP, RestPort)
Jon Hallf89c8552014-04-02 13:14:06 -0700486 parsedResult = self.get_json(url)
487 if parsedResult == "":
488 retcode = 1
489 return (retcode, "Rest API has an issue")
490 url = "http://%s:%s/wm/onos/registry/switches/json" % (RestIP, RestPort)
491 registry = self.get_json(url)
492
493 if registry == "":
494 retcode = 1
495 return (retcode, "Rest API has an issue")
496
497 cnt = 0
498 active = 0
adminbae64d82013-08-01 10:50:15 -0700499
Jon Hallf89c8552014-04-02 13:14:06 -0700500 for s in parsedResult:
501 cnt += 1
James Leec9cacaf2014-04-08 09:17:39 -0700502 if s['state'] == "ACTIVE":
Jon Hallf89c8552014-04-02 13:14:06 -0700503 active += 1
adminbae64d82013-08-01 10:50:15 -0700504
Jon Hallf89c8552014-04-02 13:14:06 -0700505 buf += "switch: network %d : %d switches %d active\n" % (0+1, cnt, active)
506 if correct_nr_switch != cnt:
507 buf += "switch fail: network %d should have %d switches but has %d\n" % (1, correct_nr_switch, cnt)
508 retcode = 1
adminbae64d82013-08-01 10:50:15 -0700509
Jon Hallf89c8552014-04-02 13:14:06 -0700510 if correct_nr_switch != active:
511 buf += "switch fail: network %d should have %d active switches but has %d\n" % (1, correct_nr_switch, active)
512 retcode = 1
513
514 return (retcode, buf)
515 except:
516 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
517 main.log.error( traceback.print_exc() )
518 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
519 main.cleanup()
520 main.exit()
adminbae64d82013-08-01 10:50:15 -0700521
Jon Hallf89c8552014-04-02 13:14:06 -0700522 def check_link(self,RestIP, nr_links, RestPort = "8080"):
Jon Halld8dc5772014-04-08 16:26:29 -0700523 '''
524 Used by check_status
525 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700526 try:
527 buf = ""
528 retcode = 0
529
530 url = "http://%s:%s/wm/onos/topology/links/json" % (RestIP, RestPort)
531 parsedResult = self.get_json(url)
532
533 if parsedResult == "":
534 retcode = 1
535 return (retcode, "Rest API has an issue")
536
537 buf += "link: total %d links (correct : %d)\n" % (len(parsedResult), nr_links)
538 intra = 0
539 interlink=0
540
541 for s in parsedResult:
James Leec9cacaf2014-04-08 09:17:39 -0700542 intra = intra + 1
Jon Hallf89c8552014-04-02 13:14:06 -0700543
544 if intra != nr_links:
545 buf += "link fail\n"
546 retcode = 1
547
548 return (retcode, buf)
549 except:
550 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
551 main.log.error( traceback.print_exc() )
552 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
553 main.cleanup()
554 main.exit()
adminbae64d82013-08-01 10:50:15 -0700555
Jon Hallf89c8552014-04-02 13:14:06 -0700556 def check_status_report(self, ip, numoswitch, numolink, port="8080"):
Jon Halld8dc5772014-04-08 16:26:29 -0700557 '''
558 Checks the number of swithes & links that ONOS sees against the supplied values.
559 Writes to the report log.
560 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700561 try:
James Leec9cacaf2014-04-08 09:17:39 -0700562 main.log.info(self.name + ": Making some rest calls...")
Jon Hallf89c8552014-04-02 13:14:06 -0700563 switch = self.check_switch(ip, int(numoswitch), port)
564 link = self.check_link(ip, int(numolink), port)
565 value = switch[0]
566 value += link[0]
567 main.log.report( self.name + ": \n-----\n%s%s-----\n" % ( switch[1], link[1]) )
568 if value != 0:
569 return main.FALSE
James Leec9cacaf2014-04-08 09:17:39 -0700570 else:
Jon Hallf89c8552014-04-02 13:14:06 -0700571 # "PASS"
572 return main.TRUE
573 except:
574 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
575 main.log.error( traceback.print_exc() )
576 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
577 main.cleanup()
578 main.exit()
adminbae64d82013-08-01 10:50:15 -0700579
Jon Hallf89c8552014-04-02 13:14:06 -0700580 def check_status(self, ip, numoswitch, numolink, port = "8080"):
Jon Halld8dc5772014-04-08 16:26:29 -0700581 '''
582 Checks the number of swithes & links that ONOS sees against the supplied values.
583 Writes to the main log.
584 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700585 try:
James Leec9cacaf2014-04-08 09:17:39 -0700586 main.log.info(self.name + ": Making some rest calls...")
Jon Hallf89c8552014-04-02 13:14:06 -0700587 switch = self.check_switch(ip, int(numoswitch), port)
588 link = self.check_link(ip, int(numolink), port)
589 value = switch[0]
590 value += link[0]
591 main.log.info(self.name + ": \n-----\n%s%s-----\n" % ( switch[1], link[1]) )
592 if value != 0:
593 return main.FALSE
James Leec9cacaf2014-04-08 09:17:39 -0700594 else:
Jon Hallf89c8552014-04-02 13:14:06 -0700595 # "PASS"
596 return main.TRUE
597 except:
598 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
599 main.log.error( traceback.print_exc() )
600 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
601 main.cleanup()
602 main.exit()
adminbae64d82013-08-01 10:50:15 -0700603
604 def drop_keyspace(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700605 '''
606 Drops the ONOS keyspace
607 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700608 try:
609 self.handle.sendline(self.home + "/scripts/drop-keyspace.sh")
610 self.handle.expect("keyspace")
611 self.handle.sendline("")
612 self.handle.expect("\$")
613 self.handle.expect("\$")
614 main.log.info(self.name + ": Keyspace dropped")
615 except:
616 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
617 main.log.error( traceback.print_exc() )
618 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
619 main.cleanup()
620 main.exit()
adminbae64d82013-08-01 10:50:15 -0700621
Jon Hallf89c8552014-04-02 13:14:06 -0700622
adminbae64d82013-08-01 10:50:15 -0700623 def check_for_no_exceptions(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700624 '''
625 TODO: Rewrite
626 Used by CassndraCheck.py to scan ONOS logs for Exceptions
627 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700628 try:
629 self.handle.sendline("dsh 'grep Exception ~/ONOS/onos-logs/onos.*.log'")
James Leec9cacaf2014-04-08 09:17:39 -0700630 self.handle.expect("\$ dsh")
Jon Hallf89c8552014-04-02 13:14:06 -0700631 self.handle.expect("\$")
632 output = self.handle.before
James Leec9cacaf2014-04-08 09:17:39 -0700633 main.log.info(self.name + ": " + output )
Jon Hallf89c8552014-04-02 13:14:06 -0700634 if re.search("Exception",output):
635 return main.FALSE
636 else :
637 return main.TRUE
638 except:
639 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
640 main.log.error( traceback.print_exc() )
641 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
642 main.cleanup()
643 main.exit()
644
645
adminbae64d82013-08-01 10:50:15 -0700646 def git_pull(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700647 '''
648 Stops the ONOS, pulls the latest code, and builds with mvn.
649 Assumes that "git pull" works without login
650 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700651 try:
James Leec9cacaf2014-04-08 09:17:39 -0700652 main.log.info(self.name + ": Stopping ONOS")
Jon Hallf89c8552014-04-02 13:14:06 -0700653 self.stop()
654 self.handle.sendline("cd " + self.home)
655 self.handle.expect("ONOS\$")
656 self.handle.sendline("git pull")
657
James Leec9cacaf2014-04-08 09:17:39 -0700658 uptodate = 0
Jon Hallf89c8552014-04-02 13:14:06 -0700659 i=self.handle.expect(['fatal','Username\sfor\s(.*):\s','Unpacking\sobjects',pexpect.TIMEOUT,'Already up-to-date','Aborting'],timeout=180)
660 #debug
James Leec9cacaf2014-04-08 09:17:39 -0700661 #main.log.report(self.name +": \n"+"git pull response: " + str(self.handle.before) + str(self.handle.after))
Jon Hallf89c8552014-04-02 13:14:06 -0700662 if i==0:
James Leec9cacaf2014-04-08 09:17:39 -0700663 main.log.error(self.name + ": Git pull had some issue...")
Jon Hallf89c8552014-04-02 13:14:06 -0700664 return main.FALSE
665 elif i==1:
James Leec9cacaf2014-04-08 09:17:39 -0700666 main.log.error(self.name + ": Git Pull Asking for username!!! BADD!")
667 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -0700668 elif i==2:
669 main.log.info(self.name + ": Git Pull - pulling repository now")
670 self.handle.expect("ONOS\$", 120)
671 elif i==3:
672 main.log.error(self.name + ": Git Pull - TIMEOUT")
673 return main.FALSE
674 elif i==4:
675 main.log.info(self.name + ": Git Pull - Already up to date")
James Leec9cacaf2014-04-08 09:17:39 -0700676 uptodate = 1
Jon Hallf89c8552014-04-02 13:14:06 -0700677 elif i==5:
678 main.log.info(self.name + ": Git Pull - Aborting... Are there conflicting git files?")
679 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700680 else:
Jon Hallf89c8552014-04-02 13:14:06 -0700681 main.log.error(self.name + ": Git Pull - Unexpected response, check for pull errors")
adminbae64d82013-08-01 10:50:15 -0700682 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -0700683
684 if uptodate == 0:
James Leec9cacaf2014-04-08 09:17:39 -0700685 main.log.info(self.name + ": mvn clean")
Jon Hallf89c8552014-04-02 13:14:06 -0700686 self.handle.sendline("mvn clean")
James Leec9cacaf2014-04-08 09:17:39 -0700687 while 1:
Jon Hallf89c8552014-04-02 13:14:06 -0700688 i=self.handle.expect(['BUILD\sFAILURE','BUILD\sSUCCESS','ONOS\$',pexpect.TIMEOUT],timeout=30)
689 if i == 0:
690 main.log.error(self.name + ": Build failure!")
691 return main.FALSE
692 elif i == 1:
693 main.log.info(self.name + ": Build success!")
694 elif i == 2:
James Leec9cacaf2014-04-08 09:17:39 -0700695 main.log.info(self.name + ": Build complete")
Jon Hallf89c8552014-04-02 13:14:06 -0700696 break;
697 elif i == 3:
698 main.log.error(self.name + ": mvn clean TIMEOUT!")
699 return main.FALSE
700
James Leec9cacaf2014-04-08 09:17:39 -0700701 main.log.info(self.name + ": mvn compile")
Jon Hallf89c8552014-04-02 13:14:06 -0700702 self.handle.sendline("mvn compile")
James Leec9cacaf2014-04-08 09:17:39 -0700703 while 1:
Jon Hallf89c8552014-04-02 13:14:06 -0700704 i=self.handle.expect(['BUILD\sFAILURE','BUILD\sSUCCESS','ONOS\$',pexpect.TIMEOUT],timeout=60)
705 if i == 0:
706 main.log.error(self.name + ": Build failure!")
707 return main.FALSE
708 elif i == 1:
709 main.log.info(self.name + ": Build success!")
710 return main.TRUE
711 elif i == 2:
James Leec9cacaf2014-04-08 09:17:39 -0700712 main.log.info(self.name + ": Build complete")
Jon Hallf89c8552014-04-02 13:14:06 -0700713 return main.TRUE
714 elif i == 3:
715 main.log.error(self.name + ": mvn compile TIMEOUT!")
716 return main.FALSE
717 else:
718 pass
719 except:
720 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
721 main.log.error( traceback.print_exc() )
722 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
723 main.cleanup()
724 main.exit()
admin4a58db92013-09-30 12:04:54 -0700725
Jon Hallf89c8552014-04-02 13:14:06 -0700726
727 def tcpdump(self, intf = "eth0"):
728 try:
729 self.handle.sendline("")
730 self.handle.expect("\$")
Jon Hall26f316b2014-04-11 11:21:25 -0700731 self.handle.sendline("sudo tcpdump -n -i "+ intf + " -s0 -w " + self.home +"/onos-logs/tcpdump &")
Jon Hallf89c8552014-04-02 13:14:06 -0700732 i=self.handle.expect(['No\ssuch\device','listening\son',pexpect.TIMEOUT],timeout=10)
733 if i == 0:
734 main.log.error(self.name + ": tcpdump - No such device exists. tcpdump attempted on: " + intf)
735 return main.FALSE
James Leec9cacaf2014-04-08 09:17:39 -0700736 elif i == 1:
Jon Hallf89c8552014-04-02 13:14:06 -0700737 main.log.info(self.name + ": tcpdump started on " + intf)
738 return main.TRUE
James Leec9cacaf2014-04-08 09:17:39 -0700739 elif i == 2:
Jon Hallf89c8552014-04-02 13:14:06 -0700740 main.log.error(self.name + ": tcpdump command timed out! Check interface name, given interface was: " + intf)
741 return main.FALSE
742 else:
743 main.log.error(self.name + ": tcpdump - unexpected response")
744 return main.FALSE
745 except:
746 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
747 main.log.error( traceback.print_exc() )
748 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
749 main.cleanup()
750 main.exit()
751
admin4a58db92013-09-30 12:04:54 -0700752 def kill_tcpdump(self):
Jon Hallf89c8552014-04-02 13:14:06 -0700753 try:
754 self.handle.sendline("")
755 self.handle.expect("\$")
756 self.handle.sendline("sudo kill -9 `ps -ef | grep \"tcpdump -n\" | grep -v grep | awk '{print $2}'`")
757 except:
758 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
759 main.log.error( traceback.print_exc() )
760 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
761 main.cleanup()
762 main.exit()
763
764 def find_host(self,RestIP,RestPort,RestAPI,hostIP):
765 retcode = 0
766 retswitch = []
767 retport = []
768 retmac = []
769 foundIP = []
770 try:
771 ##### device rest API is: 'host:8080/wm/core/topology/switches/all/json' ###
772 url ="http://%s:%s%s" %(RestIP,RestPort,RestAPI)
773
774 try:
775 command = "curl -s %s" % (url)
776 result = os.popen(command).read()
777 parsedResult = json.loads(result)
778 # print parsedResult
779 except:
780 print "REST IF %s has issue" % command
781 parsedResult = ""
782
783 if parsedResult == "":
784 return (retcode, "Rest API has an error")
785 else:
786 for switch in enumerate(parsedResult):
787 for port in enumerate(switch[1]['ports']):
788 if ( port[1]['devices'] != [] ):
789 try:
James Leec9cacaf2014-04-08 09:17:39 -0700790 foundIP = port[1]['devices'][0]['ipv4addresses'][0]['ipv4']
Jon Hallf89c8552014-04-02 13:14:06 -0700791 except:
792 print "Error in detecting IP address."
793 if foundIP == hostIP:
794 retswitch.append(switch[1]['dpid'])
795 retport.append(port[1]['desc'])
796 retmac.append(port[1]['devices'][0]['mac'])
797 retcode = retcode +1
798 foundIP =''
799 return(retcode, retswitch, retport, retmac)
800 except:
801 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
802 main.log.error( traceback.print_exc() )
803 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
804 main.cleanup()
805 main.exit()