blob: 02db0241bf359eb612618a7411c74ed29980a8c8 [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:
admine0eeea22014-04-14 10:22:46 -070042 vars(self)[key] = connectargs[key]
Jon Hallf89c8552014-04-02 13:14:06 -070043 self.home = "~/ONOS"
44 for key in self.options:
admine0eeea22014-04-14 10:22:46 -070045 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("\$")
admine0eeea22014-04-14 10:22:46 -0700281 response=(self.name +": \n"+ str(self.handle.before + self.handle.after))
282 main.log.report(response)
283 lines=response.splitlines()
284 for line in lines:
285 print line
286 return lines[2]
Jon Hallf89c8552014-04-02 13:14:06 -0700287 except:
288 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
289 main.log.error( traceback.print_exc() )
290 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
291 main.cleanup()
292 main.exit()
adminbae64d82013-08-01 10:50:15 -0700293
Jon Hallf89c8552014-04-02 13:14:06 -0700294 def add_flow(self, testONip, user, password, flowDef):
Jon Halld8dc5772014-04-08 16:26:29 -0700295 '''
296 Copies the flowdef file from TestStation -> ONOS machine
297 Then runs ./add_flow.py to add the flows to ONOS
298 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700299 try:
300 main.log.info("Adding Flows...")
301 self.handle.sendline("scp %s@%s:%s /tmp/flowtmp" %(user,testONip,flowDef))
302 i=self.handle.expect(['[pP]assword:', '100%', pexpect.TIMEOUT],30)
303 if(i==0):
304 self.handle.sendline("%s" %(password))
305 self.handle.sendline("")
306 self.handle.expect("100%")
307 self.handle.expect("\$", 30)
308 self.handle.sendline(self.home + "/web/add_flow.py -m onos -f /tmp/flowtmp")
309 self.handle.expect("\$", 1000)
310 main.log.info("Flows added")
311 return main.TRUE
312
313 elif(i==1):
314 self.handle.sendline("")
315 self.handle.expect("\$", 10)
316 self.handle.sendline( self.home + "/web/add_flow.py -m onos -f /tmp/flowtmp")
317 self.handle.expect("\$", 1000)
318 main.log.info("Flows added")
319 return main.TRUE
320
321 elif(i==2):
322 main.log.error("Flow Def file SCP Timed out...")
323 return main.FALSE
324
325 else:
326 main.log.error("Failed to add flows...")
James Leec9cacaf2014-04-08 09:17:39 -0700327 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -0700328 except:
329 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
330 main.log.error( traceback.print_exc() )
331 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
332 main.cleanup()
333 main.exit()
334
adminbae64d82013-08-01 10:50:15 -0700335
336 def delete_flow(self, *delParams):
Jon Halld8dc5772014-04-08 16:26:29 -0700337 '''
338 Deletes a specific flow, a range of flows, or all flows.
339 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700340 try:
341 if len(delParams)==1:
342 if str(delParams[0])=="all":
343 main.log.info(self.name + ": Deleting ALL flows...")
344 #self.execute(cmd="~/ONOS/scripts/TestON_delete_flow.sh all",prompt="done",timeout=150)
345 self.handle.sendline(self.home + "/web/delete_flow.py all")
346 self.handle.expect("delete_flow")
347 self.handle.expect("\$",1000)
348 main.log.info(self.name + ": Flows deleted")
349 else:
350 main.log.info(self.name + ": Deleting flow "+str(delParams[0])+"...")
351 #self.execute(cmd="~/ONOS/scripts/TestON_delete_flow.sh "+str(delParams[0]),prompt="done",timeout=150)
352 #self.execute(cmd="\n",prompt="\$",timeout=60)
353 self.handle.sendline(self.home +"/web/delete_flow.py %d" % int(delParams[0]))
354 self.handle.expect("delete_flow")
355 self.handle.expect("\$",60)
356 main.log.info(self.name + ": Flow deleted")
357 elif len(delParams)==2:
358 main.log.info(self.name + ": Deleting flows "+str(delParams[0])+" through "+str(delParams[1])+"...")
359 #self.execute(cmd="~/ONOS/scripts/TestON_delete_flow.sh "+str(delParams[0])+" "+str(delParams[1]),prompt="done",timeout=150)
360 #self.execute(cmd="\n",prompt="\$",timeout=60)
361 self.handle.sendline(self.home + "/web/delete_flow.py %d %d" % (int(delParams[0]), int(delParams[1])))
362 self.handle.expect("delete_flow")
363 self.handle.expect("\$",600)
364 main.log.info(self.name + ": Flows deleted")
365 except:
366 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
367 main.log.error( traceback.print_exc() )
368 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
369 main.cleanup()
370 main.exit()
adminbae64d82013-08-01 10:50:15 -0700371
372 def check_flow(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700373 '''
374 Calls the ./get_flow.py all and checks:
375 - If each FlowPath has at least one FlowEntry
376 - That there are no "NOT"s found
377 returns TRUE/FALSE
378 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700379 try:
380 flowEntryDetect = 1
381 count = 0
382 self.handle.sendline("clear")
383 time.sleep(1)
384 self.handle.sendline(self.home + "/web/get_flow.py all")
385 self.handle.expect("get_flow")
386 while 1:
387 i=self.handle.expect(['FlowPath','FlowEntry','NOT','\$',pexpect.TIMEOUT],timeout=180)
388 if i==0:
389 count = count + 1
390 if flowEntryDetect == 0:
391 main.log.info(self.name + ": FlowPath without FlowEntry")
392 return main.FALSE
393 else:
394 flowEntryDetect = 0
395 elif i==1:
396 flowEntryDetect = 1
397 elif i==2:
398 main.log.error(self.name + ": Found a NOT")
adminbae64d82013-08-01 10:50:15 -0700399 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -0700400 elif i==3:
401 if count == 0:
402 main.log.info(self.name + ": There don't seem to be any flows here...")
403 return main.FALSE
404 else:
405 main.log.info(self.name + ": All flows pass")
406 main.log.info(self.name + ": Number of FlowPaths: "+str(count))
407 return main.TRUE
408 elif i==4:
James Leec9cacaf2014-04-08 09:17:39 -0700409 main.log.error(self.name + ":Check_flow() - Command Timeout!")
Jon Hallf89c8552014-04-02 13:14:06 -0700410 return main.FALSE
411 except:
412 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
413 main.log.error( traceback.print_exc() )
414 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
415 main.cleanup()
416 main.exit()
adminbae64d82013-08-01 10:50:15 -0700417
418 def get_flow(self, *flowParams):
Jon Halld8dc5772014-04-08 16:26:29 -0700419 '''
420 Returns verbose output of ./get_flow.py
421 '''
422 try:
423 if len(flowParams)==1:
424 if str(flowParams[0])=="all":
425 self.execute(cmd="\n",prompt="\$",timeout=60)
426 main.log.info(self.name + ": Getting all flow data...")
427 data = self.execute(cmd=self.home + "/scripts/TestON_get_flow.sh all",prompt="done",timeout=150)
428 self.execute(cmd="\n",prompt="\$",timeout=60)
429 return data
430 else:
431 main.log.info(self.name + ": Retrieving flow "+str(flowParams[0])+" data...")
432 data = self.execute(cmd=self.home +"/scripts/TestON_get_flow.sh "+str(flowParams[0]),prompt="done",timeout=150)
433 self.execute(cmd="\n",prompt="\$",timeout=60)
434 return data
435 elif len(flowParams)==5:
436 main.log.info(self.name + ": Retrieving flow installer data...")
437 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)
438 self.execute(cmd="\n",prompt="\$",timeout=60)
439 return data
440 elif len(flowParams)==4:
441 main.log.info(self.name + ": Retrieving flow endpoints...")
442 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)
443 self.execute(cmd="\n",prompt="\$",timeout=60)
444 return data
445 except:
Jon Hallf89c8552014-04-02 13:14:06 -0700446 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
447 main.log.error( traceback.print_exc() )
448 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
449 main.cleanup()
450 main.exit()
adminbae64d82013-08-01 10:50:15 -0700451
452
453# http://localhost:8080/wm/core/topology/switches/all/json
454# http://localhost:8080/wm/core/topology/links/json
455# http://localhost:8080/wm/registry/controllers/json
456# http://localhost:8080/wm/registry/switches/json"
457
458 def get_json(self, url):
Jon Halld8dc5772014-04-08 16:26:29 -0700459 '''
460 Helper functions used to parse the json output of a rest call
461 '''
adminbae64d82013-08-01 10:50:15 -0700462 try:
Jon Hallf89c8552014-04-02 13:14:06 -0700463 try:
464 command = "curl -s %s" % (url)
465 result = os.popen(command).read()
466 parsedResult = json.loads(result)
467 except:
468 print "REST IF %s has issue" % command
469 parsedResult = ""
470
471 if type(parsedResult) == 'dict' and parsedResult.has_key('code'):
472 print "REST %s returned code %s" % (command, parsedResult['code'])
473 parsedResult = ""
James Leec9cacaf2014-04-08 09:17:39 -0700474 return parsedResult
adminbae64d82013-08-01 10:50:15 -0700475 except:
Jon Hallf89c8552014-04-02 13:14:06 -0700476 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
477 main.log.error( traceback.print_exc() )
478 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
479 main.cleanup()
480 main.exit()
adminbae64d82013-08-01 10:50:15 -0700481
Jon Hallf89c8552014-04-02 13:14:06 -0700482 def check_switch(self,RestIP,correct_nr_switch, RestPort ="8080" ):
Jon Halld8dc5772014-04-08 16:26:29 -0700483 '''
484 Used by check_status
485 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700486 try:
487 buf = ""
488 retcode = 0
489 #RestPort="8080"
admine0eeea22014-04-14 10:22:46 -0700490 url="http://%s:%s/wm/onos/ng/switches/json" % (RestIP, RestPort)
Jon Hallf89c8552014-04-02 13:14:06 -0700491 parsedResult = self.get_json(url)
492 if parsedResult == "":
493 retcode = 1
494 return (retcode, "Rest API has an issue")
495 url = "http://%s:%s/wm/onos/registry/switches/json" % (RestIP, RestPort)
496 registry = self.get_json(url)
497
498 if registry == "":
499 retcode = 1
500 return (retcode, "Rest API has an issue")
501
502 cnt = 0
503 active = 0
adminbae64d82013-08-01 10:50:15 -0700504
Jon Hallf89c8552014-04-02 13:14:06 -0700505 for s in parsedResult:
506 cnt += 1
James Leec9cacaf2014-04-08 09:17:39 -0700507 if s['state'] == "ACTIVE":
Jon Hallf89c8552014-04-02 13:14:06 -0700508 active += 1
adminbae64d82013-08-01 10:50:15 -0700509
Jon Hallf89c8552014-04-02 13:14:06 -0700510 buf += "switch: network %d : %d switches %d active\n" % (0+1, cnt, active)
511 if correct_nr_switch != cnt:
512 buf += "switch fail: network %d should have %d switches but has %d\n" % (1, correct_nr_switch, cnt)
513 retcode = 1
adminbae64d82013-08-01 10:50:15 -0700514
Jon Hallf89c8552014-04-02 13:14:06 -0700515 if correct_nr_switch != active:
516 buf += "switch fail: network %d should have %d active switches but has %d\n" % (1, correct_nr_switch, active)
517 retcode = 1
518
519 return (retcode, buf)
520 except:
521 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
522 main.log.error( traceback.print_exc() )
523 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
524 main.cleanup()
525 main.exit()
adminbae64d82013-08-01 10:50:15 -0700526
Jon Hallf89c8552014-04-02 13:14:06 -0700527 def check_link(self,RestIP, nr_links, RestPort = "8080"):
Jon Halld8dc5772014-04-08 16:26:29 -0700528 '''
529 Used by check_status
530 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700531 try:
532 buf = ""
533 retcode = 0
534
admine0eeea22014-04-14 10:22:46 -0700535 url = "http://%s:%s/wm/onos/ng/links/json" % (RestIP, RestPort)
Jon Hallf89c8552014-04-02 13:14:06 -0700536 parsedResult = self.get_json(url)
537
538 if parsedResult == "":
539 retcode = 1
540 return (retcode, "Rest API has an issue")
541
542 buf += "link: total %d links (correct : %d)\n" % (len(parsedResult), nr_links)
543 intra = 0
544 interlink=0
545
546 for s in parsedResult:
James Leec9cacaf2014-04-08 09:17:39 -0700547 intra = intra + 1
Jon Hallf89c8552014-04-02 13:14:06 -0700548
549 if intra != nr_links:
550 buf += "link fail\n"
551 retcode = 1
552
553 return (retcode, buf)
554 except:
555 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
556 main.log.error( traceback.print_exc() )
557 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
558 main.cleanup()
559 main.exit()
adminbae64d82013-08-01 10:50:15 -0700560
Jon Hallf89c8552014-04-02 13:14:06 -0700561 def check_status_report(self, ip, numoswitch, numolink, port="8080"):
Jon Halld8dc5772014-04-08 16:26:29 -0700562 '''
563 Checks the number of swithes & links that ONOS sees against the supplied values.
564 Writes to the report log.
565 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700566 try:
James Leec9cacaf2014-04-08 09:17:39 -0700567 main.log.info(self.name + ": Making some rest calls...")
Jon Hallf89c8552014-04-02 13:14:06 -0700568 switch = self.check_switch(ip, int(numoswitch), port)
569 link = self.check_link(ip, int(numolink), port)
570 value = switch[0]
571 value += link[0]
572 main.log.report( self.name + ": \n-----\n%s%s-----\n" % ( switch[1], link[1]) )
573 if value != 0:
574 return main.FALSE
James Leec9cacaf2014-04-08 09:17:39 -0700575 else:
Jon Hallf89c8552014-04-02 13:14:06 -0700576 # "PASS"
577 return main.TRUE
578 except:
579 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
580 main.log.error( traceback.print_exc() )
581 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
582 main.cleanup()
583 main.exit()
adminbae64d82013-08-01 10:50:15 -0700584
Jon Hallf89c8552014-04-02 13:14:06 -0700585 def check_status(self, ip, numoswitch, numolink, port = "8080"):
Jon Halld8dc5772014-04-08 16:26:29 -0700586 '''
587 Checks the number of swithes & links that ONOS sees against the supplied values.
588 Writes to the main log.
589 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700590 try:
James Leec9cacaf2014-04-08 09:17:39 -0700591 main.log.info(self.name + ": Making some rest calls...")
Jon Hallf89c8552014-04-02 13:14:06 -0700592 switch = self.check_switch(ip, int(numoswitch), port)
593 link = self.check_link(ip, int(numolink), port)
594 value = switch[0]
595 value += link[0]
596 main.log.info(self.name + ": \n-----\n%s%s-----\n" % ( switch[1], link[1]) )
597 if value != 0:
598 return main.FALSE
James Leec9cacaf2014-04-08 09:17:39 -0700599 else:
Jon Hallf89c8552014-04-02 13:14:06 -0700600 # "PASS"
601 return main.TRUE
602 except:
603 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
604 main.log.error( traceback.print_exc() )
605 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
606 main.cleanup()
607 main.exit()
adminbae64d82013-08-01 10:50:15 -0700608
609 def drop_keyspace(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700610 '''
611 Drops the ONOS keyspace
612 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700613 try:
614 self.handle.sendline(self.home + "/scripts/drop-keyspace.sh")
615 self.handle.expect("keyspace")
616 self.handle.sendline("")
617 self.handle.expect("\$")
618 self.handle.expect("\$")
619 main.log.info(self.name + ": Keyspace dropped")
620 except:
621 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
622 main.log.error( traceback.print_exc() )
623 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
624 main.cleanup()
625 main.exit()
adminbae64d82013-08-01 10:50:15 -0700626
Jon Hallf89c8552014-04-02 13:14:06 -0700627
adminbae64d82013-08-01 10:50:15 -0700628 def check_for_no_exceptions(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700629 '''
630 TODO: Rewrite
631 Used by CassndraCheck.py to scan ONOS logs for Exceptions
632 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700633 try:
634 self.handle.sendline("dsh 'grep Exception ~/ONOS/onos-logs/onos.*.log'")
James Leec9cacaf2014-04-08 09:17:39 -0700635 self.handle.expect("\$ dsh")
Jon Hallf89c8552014-04-02 13:14:06 -0700636 self.handle.expect("\$")
637 output = self.handle.before
James Leec9cacaf2014-04-08 09:17:39 -0700638 main.log.info(self.name + ": " + output )
Jon Hallf89c8552014-04-02 13:14:06 -0700639 if re.search("Exception",output):
640 return main.FALSE
641 else :
642 return main.TRUE
643 except:
644 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
645 main.log.error( traceback.print_exc() )
646 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
647 main.cleanup()
648 main.exit()
649
650
admine0eeea22014-04-14 10:22:46 -0700651 def git_pull(self, comp1=""):
Jon Halld8dc5772014-04-08 16:26:29 -0700652 '''
Jon Halld8dc5772014-04-08 16:26:29 -0700653 Assumes that "git pull" works without login
admine0eeea22014-04-14 10:22:46 -0700654
655 This function will perform a git pull on the ONOS instance.
656 If used as git_pull("NODE") it will do git pull + NODE. This is
657 for the purpose of pulling from other nodes if necessary.
658
659 Otherwise, this function will perform a git pull in the
660 ONOS repository. If it has any problems, it will return main.ERROR
661 If it successfully does a git_pull, it will return a 1.
662 If it has no updates, it will return a 0.
663
Jon Halld8dc5772014-04-08 16:26:29 -0700664 '''
admine0eeea22014-04-14 10:22:46 -0700665 main.log.info(self.name + ": Stopping ONOS")
666 self.stop()
667 self.handle.sendline("cd " + self.home)
668 self.handle.expect("ONOS\$")
669 if comp1=="":
Jon Hallf89c8552014-04-02 13:14:06 -0700670 self.handle.sendline("git pull")
admine0eeea22014-04-14 10:22:46 -0700671 else:
672 self.handle.sendline("git pull " + comp1)
673
674 uptodate = 0
675 i=self.handle.expect(['fatal','Username\sfor\s(.*):\s','Unpacking\sobjects',pexpect.TIMEOUT,'Already up-to-date','Aborting'],timeout=180)
676 #debug
677 #main.log.report(self.name +": \n"+"git pull response: " + str(self.handle.before) + str(self.handle.after))
678 if i==0:
679 main.log.error(self.name + ": Git pull had some issue...")
680 return main.ERROR
681 elif i==1:
682 main.log.error(self.name + ": Git Pull Asking for username!!! BADD!")
683 return main.ERROR
684 elif i==2:
685 main.log.info(self.name + ": Git Pull - pulling repository now")
686 self.handle.expect("ONOS\$", 120)
687 return 0
688 elif i==3:
689 main.log.error(self.name + ": Git Pull - TIMEOUT")
690 return main.ERROR
691 elif i==4:
692 main.log.info(self.name + ": Git Pull - Already up to date")
693 return 1
694 elif i==5:
695 main.log.info(self.name + ": Git Pull - Aborting... Are there conflicting git files?")
696 return main.ERROR
697 else:
698 main.log.error(self.name + ": Git Pull - Unexpected response, check for pull errors")
699 return main.ERROR
700#********************************************************
701
702
admin076a6a32014-04-14 10:42:02 -0700703 def compile(self):
admine0eeea22014-04-14 10:22:46 -0700704 main.log.info(self.name + ": mvn clean")
705 self.handle.sendline("mvn clean")
706 while 1:
707 i=self.handle.expect(['BUILD\sFAILURE','BUILD\sSUCCESS','ONOS\$',pexpect.TIMEOUT],timeout=30)
708 if i == 0:
709 main.log.error(self.name + ": Build failure!")
Jon Hallf89c8552014-04-02 13:14:06 -0700710 return main.FALSE
admine0eeea22014-04-14 10:22:46 -0700711 elif i == 1:
712 main.log.info(self.name + ": Build success!")
713 elif i == 2:
714 main.log.info(self.name + ": Build complete")
715 break;
716 elif i == 3:
717 main.log.error(self.name + ": mvn clean TIMEOUT!")
James Leec9cacaf2014-04-08 09:17:39 -0700718 return main.FALSE
admine0eeea22014-04-14 10:22:46 -0700719
720 main.log.info(self.name + ": mvn compile")
721 self.handle.sendline("mvn compile")
722 while 1:
723 i=self.handle.expect(['BUILD\sFAILURE','BUILD\sSUCCESS','ONOS\$',pexpect.TIMEOUT],timeout=60)
724 if i == 0:
725 main.log.error(self.name + ": Build failure!")
Jon Hallf89c8552014-04-02 13:14:06 -0700726 return main.FALSE
admine0eeea22014-04-14 10:22:46 -0700727 elif i == 1:
728 main.log.info(self.name + ": Build success!")
729 return main.TRUE
730 elif i == 2:
731 main.log.info(self.name + ": Build complete")
732 return main.TRUE
733 elif i == 3:
734 main.log.error(self.name + ": mvn compile TIMEOUT!")
Jon Hallf89c8552014-04-02 13:14:06 -0700735 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700736 else:
admine0eeea22014-04-14 10:22:46 -0700737 pass
admin4a58db92013-09-30 12:04:54 -0700738
Jon Hallf89c8552014-04-02 13:14:06 -0700739
740 def tcpdump(self, intf = "eth0"):
741 try:
742 self.handle.sendline("")
743 self.handle.expect("\$")
Jon Hall26f316b2014-04-11 11:21:25 -0700744 self.handle.sendline("sudo tcpdump -n -i "+ intf + " -s0 -w " + self.home +"/onos-logs/tcpdump &")
Jon Hallf89c8552014-04-02 13:14:06 -0700745 i=self.handle.expect(['No\ssuch\device','listening\son',pexpect.TIMEOUT],timeout=10)
746 if i == 0:
747 main.log.error(self.name + ": tcpdump - No such device exists. tcpdump attempted on: " + intf)
748 return main.FALSE
James Leec9cacaf2014-04-08 09:17:39 -0700749 elif i == 1:
Jon Hallf89c8552014-04-02 13:14:06 -0700750 main.log.info(self.name + ": tcpdump started on " + intf)
751 return main.TRUE
James Leec9cacaf2014-04-08 09:17:39 -0700752 elif i == 2:
Jon Hallf89c8552014-04-02 13:14:06 -0700753 main.log.error(self.name + ": tcpdump command timed out! Check interface name, given interface was: " + intf)
754 return main.FALSE
755 else:
756 main.log.error(self.name + ": tcpdump - unexpected response")
757 return main.FALSE
758 except:
759 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
760 main.log.error( traceback.print_exc() )
761 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
762 main.cleanup()
763 main.exit()
764
admin4a58db92013-09-30 12:04:54 -0700765 def kill_tcpdump(self):
Jon Hallf89c8552014-04-02 13:14:06 -0700766 try:
767 self.handle.sendline("")
768 self.handle.expect("\$")
769 self.handle.sendline("sudo kill -9 `ps -ef | grep \"tcpdump -n\" | grep -v grep | awk '{print $2}'`")
770 except:
771 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
772 main.log.error( traceback.print_exc() )
773 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
774 main.cleanup()
775 main.exit()
776
777 def find_host(self,RestIP,RestPort,RestAPI,hostIP):
778 retcode = 0
779 retswitch = []
780 retport = []
781 retmac = []
782 foundIP = []
783 try:
784 ##### device rest API is: 'host:8080/wm/core/topology/switches/all/json' ###
785 url ="http://%s:%s%s" %(RestIP,RestPort,RestAPI)
786
787 try:
788 command = "curl -s %s" % (url)
789 result = os.popen(command).read()
790 parsedResult = json.loads(result)
791 # print parsedResult
792 except:
793 print "REST IF %s has issue" % command
794 parsedResult = ""
795
796 if parsedResult == "":
797 return (retcode, "Rest API has an error")
798 else:
799 for switch in enumerate(parsedResult):
800 for port in enumerate(switch[1]['ports']):
801 if ( port[1]['devices'] != [] ):
802 try:
James Leec9cacaf2014-04-08 09:17:39 -0700803 foundIP = port[1]['devices'][0]['ipv4addresses'][0]['ipv4']
Jon Hallf89c8552014-04-02 13:14:06 -0700804 except:
805 print "Error in detecting IP address."
806 if foundIP == hostIP:
807 retswitch.append(switch[1]['dpid'])
808 retport.append(port[1]['desc'])
809 retmac.append(port[1]['devices'][0]['mac'])
810 retcode = retcode +1
811 foundIP =''
812 return(retcode, retswitch, retport, retmac)
813 except:
814 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
815 main.log.error( traceback.print_exc() )
816 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
817 main.cleanup()
818 main.exit()