blob: 40e4cf00c8df8ce3f710d634fb99241e7945dbee [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
admin2a9548d2014-06-17 14:08:07 -070028import urllib2
29from urllib2 import URLError, HTTPError
Ahmed El-Hassanyf60919d2014-08-20 09:14:01 -070030from socket import timeout
Ahmed El-Hassany2bd46192014-08-20 09:09:57 -070031
adminbae64d82013-08-01 10:50:15 -070032sys.path.append("../")
33from drivers.common.clidriver import CLI
34
Ahmed El-Hassanyf60919d2014-08-20 09:14:01 -070035URL_TIMEOUT = 10
36
adminbae64d82013-08-01 10:50:15 -070037class OnosCliDriver(CLI):
38
39 def __init__(self):
40 super(CLI, self).__init__()
41
42 def connect(self,**connectargs):
Jon Halld8dc5772014-04-08 16:26:29 -070043 '''
44 Creates ssh handle for ONOS.
45 '''
Jon Hallf89c8552014-04-02 13:14:06 -070046 try:
47 for key in connectargs:
admine0eeea22014-04-14 10:22:46 -070048 vars(self)[key] = connectargs[key]
Jon Hallf89c8552014-04-02 13:14:06 -070049 self.home = "~/ONOS"
50 for key in self.options:
admine0eeea22014-04-14 10:22:46 -070051 if key == "home":
52 self.home = self.options['home']
53 break
adminbae64d82013-08-01 10:50:15 -070054
Jon Hallf89c8552014-04-02 13:14:06 -070055
56 self.name = self.options['name']
57 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 -070058
Jon Hallf89c8552014-04-02 13:14:06 -070059 if self.handle:
Jon Hallf89c8552014-04-02 13:14:06 -070060 return self.handle
61 else :
62 main.log.info("NO ONOS HANDLE")
63 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -070064 except pexpect.EOF:
65 main.log.error(self.name + ": EOF exception found")
66 main.log.error(self.name + ": " + self.handle.before)
67 main.cleanup()
68 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -070069 except:
70 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
71 main.log.error( traceback.print_exc() )
72 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
73 main.cleanup()
74 main.exit()
admin680b78c2014-08-08 11:46:45 -070075
76 def portKill(self, port):
77 try:
78 self.handle.sendline("")
79 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
80 cmd = "sudo tcpkill -i eth0 port " + str(port) + " 2>/dev/null 1>/dev/null &"
81 self.handle.sendline(cmd)
82 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
83 except pexpect.EOF:
84 main.log.error(self.name + ": EOF exception found")
85 main.log.error(self.name + ": " + self.handle.before)
86 main.cleanup()
87 main.exit()
88 except:
89 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
90 main.log.error( traceback.print_exc() )
91 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
92 main.cleanup()
93 main.exit()
94
95 def endPortKill(self,port):
96 try:
97 self.handle.sendline("")
98 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
99 self.handle.sendline("sudo pkill tcpkill")
100 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
101 except pexpect.EOF:
102 main.log.error(self.name + ": EOF exception found")
103 main.log.error(self.name + ": " + self.handle.before)
104 main.cleanup()
105 main.exit()
106 except:
107 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
108 main.log.error( traceback.print_exc() )
109 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
110 main.cleanup()
111 main.exit()
adminbae64d82013-08-01 10:50:15 -0700112
Jon Hallf0a494f2014-06-23 15:37:40 -0700113 def start(self, env = ''):
Jon Halld8dc5772014-04-08 16:26:29 -0700114 '''
115 Starts ONOS on remote machine.
116 Returns false if any errors were encountered.
117 '''
James Leec9cacaf2014-04-08 09:17:39 -0700118 try:
Jon Hallf89c8552014-04-02 13:14:06 -0700119 self.handle.sendline("")
Jon Hallae05dc22014-04-16 10:56:28 -0700120 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
Jon Hall4a2b0482014-04-18 16:29:26 -0700121 self.handle.sendline("cd "+self.home)
Jon Hallf0a494f2014-06-23 15:37:40 -0700122 self.handle.sendline(env + "./onos.sh core start")
Jon Hallae05dc22014-04-16 10:56:28 -0700123 i=self.handle.expect(["STARTED","FAILED",pexpect.EOF,pexpect.TIMEOUT])
124 response = self.handle.before + str(self.handle.after)
Jon Hallf89c8552014-04-02 13:14:06 -0700125 if i==0:
Jon Hallae05dc22014-04-16 10:56:28 -0700126 j = self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT], timeout=60)
127 if re.search("Killed",response):
128 main.log.warn(self.name + ": Killed existing process")
129 if j==0:
Jon Hallf89c8552014-04-02 13:14:06 -0700130 main.log.info(self.name + ": ONOS Started ")
Jon Hallae05dc22014-04-16 10:56:28 -0700131 return main.TRUE
132 elif j==1:
133 main.log.error(self.name + ": EOF exception found")
134 main.log.error(self.name + ": " + self.handle.before)
135 main.cleanup()
136 main.exit()
137 elif j==2:
Jon Hallf89c8552014-04-02 13:14:06 -0700138 main.log.info(self.name + ": ONOS NOT Started, stuck while waiting for it to start ")
139 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -0700140 else:
141 main.log.warn(self.name +": Unexpected response in start")
142 return main.TRUE
Jon Hallf89c8552014-04-02 13:14:06 -0700143 elif i==1:
Jon Hallae05dc22014-04-16 10:56:28 -0700144 main.log.error(self.name + ": ONOS Failed to start")
adminbae64d82013-08-01 10:50:15 -0700145 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -0700146 elif i==2:
147 main.log.error(self.name + ": EOF exception found")
148 main.log.error(self.name + ": " + self.handle.before)
149 main.cleanup()
150 main.exit()
151 elif i==3:
152 main.log.error(self.name + ": ONOS timedout while starting")
153 return main.FALSE
154 else:
155 main.log.error(self.name + ": ONOS start expect script missed something... ")
adminbae64d82013-08-01 10:50:15 -0700156 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -0700157 except pexpect.EOF:
158 main.log.error(self.name + ": EOF exception found")
159 main.log.error(self.name + ": " + self.handle.before)
160 main.cleanup()
161 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -0700162 except:
163 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
164 main.log.error( traceback.print_exc() )
165 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
166 main.cleanup()
167 main.exit()
Jon Halle80ef8c2014-04-29 15:29:13 -0700168
169 def start_all(self):
170 '''
171 starts ZK, RC, and ONOS
172 '''
173 self.handle.sendline("cd "+self.home)
174 self.handle.sendline("./onos.sh start")
175 self.handle.expect("./onos.sh start")
176 self.handle.expect(["\$",pexpect.TIMEOUT])
177
178
179
adminbae64d82013-08-01 10:50:15 -0700180 def start_rest(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700181 '''
182 Starts the rest server on ONOS.
183 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700184 try:
Jon Hall4a2b0482014-04-18 16:29:26 -0700185 self.handle.sendline("cd "+self.home)
186 response = self.execute(cmd= "./start-rest.sh start",prompt="\$",timeout=10)
Jon Hallf89c8552014-04-02 13:14:06 -0700187 if re.search("admin",response):
188 main.log.info(self.name + ": Rest Server Started Successfully")
189 time.sleep(5)
190 return main.TRUE
191 else :
James Leec9cacaf2014-04-08 09:17:39 -0700192 main.log.warn(self.name + ": Failed to start Rest Server")
193 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -0700194 except pexpect.EOF:
195 main.log.error(self.name + ": EOF exception found")
196 main.log.error(self.name + ": " + self.handle.before)
197 main.cleanup()
198 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -0700199 except:
200 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
201 main.log.error( traceback.print_exc() )
202 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
203 main.cleanup()
204 main.exit()
Ahmed El-Hassany2bd46192014-08-20 09:09:57 -0700205
adminbae64d82013-08-01 10:50:15 -0700206 def status(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700207 '''
208 Called onos.sh core status and returns TRUE/FALSE accordingly
209 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700210 try:
211 self.execute(cmd="\n",prompt="\$",timeout=10)
Jon Hall4a2b0482014-04-18 16:29:26 -0700212 self.handle.sendline("cd "+self.home)
213 response = self.execute(cmd="./onos.sh core status ",prompt="\d+\sinstance\sof\sonos\srunning",timeout=10)
Jon Hallf89c8552014-04-02 13:14:06 -0700214 self.execute(cmd="\n",prompt="\$",timeout=10)
215 if re.search("1\sinstance\sof\sonos\srunning",response):
216 return main.TRUE
217 elif re.search("0\sinstance\sof\sonos\srunning",response):
218 return main.FALSE
Jon Hallbb650fe2014-07-14 14:54:48 -0700219 elif re.search("Expected\sPrompt\snot found\s,\sTime Out!!",response):
220 return main.ERROR
Jon Hallf89c8552014-04-02 13:14:06 -0700221 else :
Jon Hallf0a494f2014-06-23 15:37:40 -0700222 main.log.warn(self.name + " WARNING: status recieved unknown response")
223 main.log.warn(response)
Jon Hallf89c8552014-04-02 13:14:06 -0700224 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -0700225 except pexpect.EOF:
226 main.log.error(self.name + ": EOF exception found")
227 main.log.error(self.name + ": " + self.handle.before)
228 main.cleanup()
229 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -0700230 except:
231 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
232 main.log.error( traceback.print_exc() )
233 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
234 main.cleanup()
235 main.exit()
236
adminbae64d82013-08-01 10:50:15 -0700237
238 def isup(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700239 '''
240 A more complete check to see if ONOS is up and running properly.
241 First, it checks if the process is up.
242 Second, it reads the logs for "Exception: Connection refused"
243 Third, it makes sure the logs are actually moving.
244 returns TRUE/FALSE accordingly.
245 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700246 try:
247 self.execute(cmd="\n",prompt="\$",timeout=10)
Jon Hall4a2b0482014-04-18 16:29:26 -0700248 self.handle.sendline("cd "+self.home)
249 response = self.execute(cmd= "./onos.sh core status ",prompt="running",timeout=10)
Jon Hallf89c8552014-04-02 13:14:06 -0700250 self.execute(cmd="\n",prompt="\$",timeout=10)
251 tail1 = self.execute(cmd="tail " + self.home + "/onos-logs/onos.*.log",prompt="\$",timeout=10)
admine8c47d02014-06-03 11:59:16 -0700252 time.sleep(10)
Jon Hallf89c8552014-04-02 13:14:06 -0700253 self.execute(cmd="\n",prompt="\$",timeout=10)
254 tail2 = self.execute(cmd="tail " + self.home + "/onos-logs/onos.*.log",prompt="\$",timeout=10)
255 pattern = '(.*)1 instance(.*)'
256 pattern2 = '(.*)Exception: Connection refused(.*)'
257 # if utilities.assert_matches(expect=pattern,actual=response,onpass="ONOS process is running...",onfail="ONOS process not running..."):
admin2a9548d2014-06-17 14:08:07 -0700258 running = self.execute(cmd="cat "+self.home+"/onos-logs/onos.*.log | grep 'Sending LLDP out on all ports'",prompt="\$",timeout=10)
Jon Hallf89c8552014-04-02 13:14:06 -0700259 if re.search(pattern, response):
admin2a9548d2014-06-17 14:08:07 -0700260 if running != "":
Jon Halle80ef8c2014-04-29 15:29:13 -0700261 main.log.info(self.name + ": ONOS process is running...")
262 if tail1 == tail2:
263 main.log.error(self.name + ": ONOS is frozen...")#logs aren't moving
264 return main.FALSE
265 elif re.search( pattern2,tail1 ):
266 main.log.info(self.name + ": Connection Refused found in onos log")
267 return main.FALSE
268 elif re.search( pattern2,tail2 ):
269 main.log.info(self.name + ": Connection Refused found in onos log")
270 return main.FALSE
271 else:
272 main.log.info(self.name + ": Onos log is moving! It's looking good!")
273 return main.TRUE
Jon Hall55c79662014-05-19 15:03:40 -0700274 else:
275 main.log.info(self.name + ": ONOS not yet sending out LLDP messages")
276 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700277 else:
Jon Hallf89c8552014-04-02 13:14:06 -0700278 main.log.error(self.name + ": ONOS process not running...")
279 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -0700280 except pexpect.EOF:
281 main.log.error(self.name + ": EOF exception found")
282 main.log.error(self.name + ": " + self.handle.before)
283 main.cleanup()
284 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -0700285 except:
286 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
287 main.log.error( traceback.print_exc() )
288 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
289 main.cleanup()
290 main.exit()
adminbae64d82013-08-01 10:50:15 -0700291
Jon Hallf89c8552014-04-02 13:14:06 -0700292
James Leec9cacaf2014-04-08 09:17:39 -0700293 def rest_status(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700294 '''
295 Checks if the rest server is running.
296 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700297 try:
298 response = self.execute(cmd= self.home + "/start-rest.sh status ",prompt="running",timeout=10)
299 if re.search("rest\sserver\sis\srunning",response):
300 main.log.info(self.name + ": Rest Server is running")
Jon Hallae05dc22014-04-16 10:56:28 -0700301 return main.TRUE
Jon Hallf89c8552014-04-02 13:14:06 -0700302 elif re.search("rest\sserver\sis\snot\srunning",response):
303 main.log.warn(self.name + ": Rest Server is not Running")
Jon Hallae05dc22014-04-16 10:56:28 -0700304 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -0700305 else :
306 main.log.error(self.name + ": No response" +response)
Jon Hallae05dc22014-04-16 10:56:28 -0700307 return main.FALSE
308 except pexpect.EOF:
309 main.log.error(self.name + ": EOF exception found")
310 main.log.error(self.name + ": " + self.handle.before)
311 main.cleanup()
312 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -0700313 except:
314 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
315 main.log.error( traceback.print_exc() )
316 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
317 main.cleanup()
318 main.exit()
admine8c47d02014-06-03 11:59:16 -0700319
320 def stop_all(self):
321 '''
322 Runs ./onos.sh stop
323 '''
324 try:
325 self.handle.sendline("")
326 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
327 self.handle.sendline("cd "+self.home)
328 self.handle.sendline("./onos.sh stop")
Jon Halld79c7d02014-08-15 15:16:51 -0700329 self.handle.expect(["./onos.sh stop",pexpect.EOF,pexpect.TIMEOUT])
330 i=self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT],60)
admine8c47d02014-06-03 11:59:16 -0700331 result = self.handle.before
332 if re.search("Killed", result):
333 main.log.info(self.name + ": ONOS Killed Successfully")
334 return main.TRUE
335 else :
336 main.log.warn(self.name + ": ONOS wasn't running")
337 return main.FALSE
338 except pexpect.EOF:
339 main.log.error(self.name + ": EOF exception found")
340 main.log.error(self.name + ": " + self.handle.before)
341 main.cleanup()
342 main.exit()
343 except:
344 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
345 main.log.error( traceback.print_exc() )
346 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
347 main.cleanup()
348 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -0700349
350
adminbae64d82013-08-01 10:50:15 -0700351 def stop(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700352 '''
353 Runs ./onos.sh core stop to stop ONOS
354 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700355 try:
356 self.handle.sendline("")
Jon Hallae05dc22014-04-16 10:56:28 -0700357 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
Jon Hall4a2b0482014-04-18 16:29:26 -0700358 self.handle.sendline("cd "+self.home)
359 self.handle.sendline("./onos.sh core stop")
Jon Halld79c7d02014-08-15 15:16:51 -0700360 self.handle.expect(["./onos.sh stop",pexpect.EOF,pexpect.TIMEOUT])
361 i=self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT],60)
James Leec9cacaf2014-04-08 09:17:39 -0700362 result = self.handle.before
Jon Hallf89c8552014-04-02 13:14:06 -0700363 if re.search("Killed", result):
364 main.log.info(self.name + ": ONOS Killed Successfully")
365 return main.TRUE
366 else :
367 main.log.warn(self.name + ": ONOS wasn't running")
368 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -0700369 except pexpect.EOF:
370 main.log.error(self.name + ": EOF exception found")
371 main.log.error(self.name + ": " + self.handle.before)
372 main.cleanup()
373 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -0700374 except:
375 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
376 main.log.error( traceback.print_exc() )
377 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
378 main.cleanup()
379 main.exit()
admin6903e462014-07-22 15:30:54 -0700380#**********************************************************************************************
381#**********************************************************************************************
382# The purpose of comp_intents is to find if the high level intents have changed. preIntents
383# and postIntents should be the output of curl of the intents. preIntents being the original
384# and postIntents being the later. We are looking at the intents with the same id from both
385# and comparing the dst and src DPIDs and macs, and the state. If any of these are changed
386# we print that there are changes, then return a list of the intents that have changes`
387#**********************************************************************************************
388#**********************************************************************************************
389 def comp_intents(self,preIntents,postIntents):
390 import json
391 preDecoded = json.loads(preIntents)
392 postDecoded = json.loads(postIntents)
393 changes = []
394 if not preDecoded:
395 if postDecoded:
396 print "THERE ARE CHANGES TO THE HIGH LEVEL INTENTS!!!!"
397 return postDecoded
398 for k in preDecoded:
399 for l in postDecoded:
400 if l['id']==k['id']:
401 if k['dstSwitchDpid']==l['dstSwitchDpid'] and k['srcMac']==l['srcMac'] and k['dstMac']==l['dstMac'] and k['srcSwitchDpid']==l['srcSwitchDpid'] and k['state']==l['state']:
402 postDecoded.remove(l)
403 else:
404 changes.append(k)
405 print ("THERE ARE CHANGES TO THE HIGH LEVEL INTENTS!!!")
406 return changes
Jon Hallf89c8552014-04-02 13:14:06 -0700407
admin6903e462014-07-22 15:30:54 -0700408#**********************************************************************************************
409#**********************************************************************************************
410# the purpose of comp_low is to find if the low level intents have changed. The main idea
411# is to determine if the path has changed. Again, like with the comp_intents function, the
412# pre and post Intents variables are the json dumps of wm/onos/intent/low. The variables
413# that will be compared are the state, and the path.
414#**********************************************************************************************
415#**********************************************************************************************
416 def comp_low(self, preIntents,postIntents):
417 import json
418 preDecoded = json.loads(preIntents)
419 postDecoded = json.loads(postIntents)
420 changes = []
421 if not preDecoded:
422 if postDecoded:
423 print "THERE ARE CHANGES TO THE LOW LEVEL INTENTS!!!"
424 return postDecoded
425 for k in preDecoded:
426 for l in postDecoded:
427 if l['id']==k['id']:
428 if l['path']!=k['path']:
429 changes.append(l)
430 print "\n\n\n\nTHERE ARE CHANGES TO THE LOW LEVEL INTENTS!!!"
431 else:
432 if k['state']!=l['state']:
433 changes.append(l)
434 print "\n\n\n\nTHERE ARE CHANGES TO THE LOW LEVEL INTENTS!!!"
435 else:
436 print "NO CHANGES SO FAR\n\n\n"
437
438
439 return changes
440
441
adminbae64d82013-08-01 10:50:15 -0700442 def rest_stop(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700443 '''
444 Runs ./start-rest.sh stop to stop ONOS rest server
445 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700446 try:
447 response = self.execute(cmd= self.home + "/start-rest.sh stop ",prompt="killing",timeout=10)
448 self.execute(cmd="\n",prompt="\$",timeout=10)
449 if re.search("killing", response):
450 main.log.info(self.name + ": Rest Server Stopped")
451 return main.TRUE
452 else :
453 main.log.error(self.name + ": Failed to Stop, Rest Server is not Running")
454 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -0700455 except pexpect.EOF:
456 main.log.error(self.name + ": EOF exception found")
457 main.log.error(self.name + ": " + self.handle.before)
458 main.cleanup()
459 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -0700460 except:
461 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
462 main.log.error( traceback.print_exc() )
463 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
464 main.cleanup()
465 main.exit()
466
467
admin680b78c2014-08-08 11:46:45 -0700468 def kill(self):
469 import re
470 try:
471 self.handle.sendline("ps -ef |grep 'ONOS/conf/logback' |awk 'NR==1 {print $2}' |xargs sudo kill -9")
472 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
473 self.handle.sendline("ps -ef |grep 'ONOS/conf/logback' |wc -l")
474 self.handle.expect(["wc -l",pexpect.EOF,pexpect.TIMEOUT])
475 response = self.handle.after
476 if re.search("1",response):
477 return "ONOS Killed!"
478 else:
479 return "ERROR!!! ONOS MAY NOT HAVE BEEN KILLED PROPERLY!!!"
480 except pexpect.EOF:
481 main.log.error(self.name + ": EOF exception found")
482 main.log.error(self.hane + ": " + self.handle.before)
483 main.cleanup()
484 main.exit()
485 except:
486 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
487 main.log.error( traceback.print_exc() )
488 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
489 main.cleanup()
490 main.exit()
491
492
493
adminbae64d82013-08-01 10:50:15 -0700494 def disconnect(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700495 '''
496 Called when Test is complete to disconnect the ONOS handle.
497 '''
adminaeedddd2013-08-02 15:14:15 -0700498 response = ''
499 try:
adminbae64d82013-08-01 10:50:15 -0700500 self.handle.sendline("exit")
adminaeedddd2013-08-02 15:14:15 -0700501 self.handle.expect("closed")
Jon Hallae05dc22014-04-16 10:56:28 -0700502 except pexpect.EOF:
503 main.log.error(self.name + ": EOF exception found")
504 main.log.error(self.name + ": " + self.handle.before)
James Leec9cacaf2014-04-08 09:17:39 -0700505 except:
Jon Hallf89c8552014-04-02 13:14:06 -0700506 main.log.error(self.name + ": Connection failed to the host")
adminbae64d82013-08-01 10:50:15 -0700507 response = main.FALSE
adminaeedddd2013-08-02 15:14:15 -0700508 return response
509
Jon Hall76f2c462014-04-17 11:37:15 -0700510 def print_version(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700511 '''
512 Writes the COMMIT number to the report to be parsed by Jenkins data collecter.
513 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700514 try:
515 self.handle.sendline("export TERM=xterm-256color")
516 self.handle.expect("xterm-256color")
James Leec9cacaf2014-04-08 09:17:39 -0700517 self.handle.expect("\$")
Jon Hallcc0d30e2014-09-15 14:57:40 -0700518 self.handle.sendline("cd " + self.home + "; git log -1 --pretty=fuller --decorate=short | grep -A 5 \"commit\" --color=never; cd \.\.")
Jon Hallf89c8552014-04-02 13:14:06 -0700519 self.handle.expect("cd ..")
520 self.handle.expect("\$")
admine0eeea22014-04-14 10:22:46 -0700521 response=(self.name +": \n"+ str(self.handle.before + self.handle.after))
522 main.log.report(response)
Jon Hall76f2c462014-04-17 11:37:15 -0700523 except pexpect.EOF:
524 main.log.error(self.name + ": EOF exception found")
525 main.log.error(self.name + ": " + self.handle.before)
526 main.cleanup()
527 main.exit()
528 except:
529 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
530 main.log.error( traceback.print_exc() )
531 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
532 main.cleanup()
533 def get_version(self):
534 '''
535 Writes the COMMIT number to the report to be parsed by Jenkins data collecter.
536 '''
537 try:
538 self.handle.sendline("export TERM=xterm-256color")
539 self.handle.expect("xterm-256color")
540 self.handle.expect("\$")
Jon Hallcc0d30e2014-09-15 14:57:40 -0700541 self.handle.sendline("cd " + self.home + "; git log -1 --pretty=fuller --decorate=short | grep -A 5 \"commit\" --color=never; cd \.\.")
Jon Hall76f2c462014-04-17 11:37:15 -0700542 self.handle.expect("cd ..")
543 self.handle.expect("\$")
544 response=(self.name +": \n"+ str(self.handle.before + self.handle.after))
admine0eeea22014-04-14 10:22:46 -0700545 lines=response.splitlines()
546 for line in lines:
547 print line
548 return lines[2]
Jon Hallae05dc22014-04-16 10:56:28 -0700549 except pexpect.EOF:
550 main.log.error(self.name + ": EOF exception found")
551 main.log.error(self.name + ": " + self.handle.before)
552 main.cleanup()
553 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -0700554 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
admin2a9548d2014-06-17 14:08:07 -0700561
admindc1c5072014-06-24 15:57:19 -0700562
563#*********************************************************************
564#*********************************************************************
565# shortest_path is a command to find the shortest path between two
566# switches. It is called using the IP, port, and source and
567# destination dpids
568#*********************************************************************
569#*********************************************************************
570
571 def shortest_path(self,ONOSIP,ONOSPort,srcDPID,dstDPID):
572 main.log.report("Finding the shortest Path between "+str(srcDPID) + " to " + str(dstDPID))
573 url = "http://%s:%s/wm/onos/intent/path/switch/%s/shortest-path/%s"%(ONOSIP,ONOSPort,srcDPID,dstDPID)
574 parsed_result = []
575 try:
Ahmed El-Hassanyf60919d2014-08-20 09:14:01 -0700576 response = urllib2.urlopen(url, timeout=URL_TIMEOUT)
admindc1c5072014-06-24 15:57:19 -0700577 result = response.read()
578 response.close()
579 if len(result) != 0:
580 parsed_result = json.loads(result)
581 except HTTPError as exc:
582 print "ERROR:"
583 print " REST GET URL: %s" % url
584 # NOTE: exc.fp contains the object with the response payload
585 error_payload = json.loads(exc.fp.read())
586 print " REST Error Code: %s" % (error_payload['code'])
587 print " REST Error Summary: %s" % (error_payload['summary'])
588 print " REST Error Description: %s" % (error_payload['formattedDescription'])
589 print " HTTP Error Code: %s" % exc.code
590 print " HTTP Error Reason: %s" % exc.reason
591 except URLError as exc:
592 print "ERROR:"
593 print " REST GET URL: %s" % url
594 print " URL Error Reason: %s" % exc.reason
Ahmed El-Hassanyf60919d2014-08-20 09:14:01 -0700595 except timeout as exc:
596 print "ERROR:"
597 print " REST GET URL: %s" % url
598 print " URL Error Reason: %s" % exc.message
599 main.log.error("Socket timeout connecting to: %s", url)
600 return main.ERROR
admindc1c5072014-06-24 15:57:19 -0700601
602 if len(parsed_result)==0:
603 return
604 result = json.dumps(parsed_result,indent=4)
605 print(str(result))
606 return result
607
608
609#*********************************************************************
610#*********************************************************************
611# show_intent is a command to show intents.
612# Parameters include intentIP, intentPort, intentURL, and intent_id
613# Based on the url, it will show either high or low intents
614# If intent_id is left blank, it will show all high or all low intents
615# Else it will show the intent with the id
616#*********************************************************************
617#*********************************************************************
618
619
620
621 def show_intent(self,intentIP,intentPort=8080,intentURL="wm/onos/intent",intent_type="high",intent_id="all"):
622 main.log.report("Getting (an) intent(s)")
623 if intent_id=="all":
624 url = "http://%s:%s/%s/%s"%(intentIP,intentPort,intentURL,intent_type)
625 else:
626 url = "http://%s:%s/%s/%s/%s"%(intentIP,intentPort,intentURL,intent_type,intent_id)
627 print(url)
628 parsed_result = []
629 try:
Ahmed El-Hassanyf60919d2014-08-20 09:14:01 -0700630 response = urllib2.urlopen(url, timeout=URL_TIMEOUT)
admindc1c5072014-06-24 15:57:19 -0700631 result = response.read()
632 response.close()
633 if len(result) != 0:
634 parsed_result = json.loads(result)
635 except HTTPError as exc:
636 print "ERROR:"
637 print " REST GET URL: %s" % url
638 # NOTE: exc.fp contains the object with the response payload
639 error_payload = json.loads(exc.fp.read())
640 print " REST Error Code: %s" % (error_payload['code'])
641 print " REST Error Summary: %s" % (error_payload['summary'])
642 print " REST Error Description: %s" % (error_payload['formattedDescription'])
643 print " HTTP Error Code: %s" % exc.code
644 print " HTTP Error Reason: %s" % exc.reason
645 return str(error_payload['code'])
646 except URLError as exc:
647 print "ERROR:"
648 print " REST GET URL: %s" % url
649 print " URL Error Reason: %s" % exc.reason
650 return str(error_payload['code'])
Ahmed El-Hassanyf60919d2014-08-20 09:14:01 -0700651 except timeout as exc:
652 print "ERROR:"
653 print " REST GET URL: %s" % url
654 print " URL Error Reason: %s" % exc.message
655 main.log.error("Socket timeout connecting to: %s", url)
656 return main.ERROR
admindc1c5072014-06-24 15:57:19 -0700657
658 if len(parsed_result)==0:
659 return
660 result = json.dumps(parsed_result,indent=4)
661 print(str(result))
662 return result
663
664
665#*********************************************************************
666#*********************************************************************
667# del_intent is to delete either all or some or one intents
668# if intent_id is left blank, it will delete all intents
669# else, intent_id should be of the form "intent_id=1,2,3"
670#*********************************************************************
671#*********************************************************************
672
673 def del_intent(self,intentIP,intentPort=8080,intentURL="wm/onos/intent",intent_id="all"):
674 main.log.report("Deleting (an) intent(s)")
675 if intent_id=="all":
676 url = "http://%s:%s/%s/high"%(intentIP,intentPort,intentURL)
677 else:
678 url = "http://%s:%s/%s/high?%s"%(intentIP,intentPort,intentURL,intent_id)
679
680 print(url)
681
682 parsed_result = []
683 try:
684 request = urllib2.Request(url)
685 request.get_method = lambda: 'DELETE'
Ahmed El-Hassanyf60919d2014-08-20 09:14:01 -0700686 response = urllib2.urlopen(request, timeout=URL_TIMEOUT)
admindc1c5072014-06-24 15:57:19 -0700687 result = response.read()
688 response.close()
689 if len(result) != 0:
690 parsed_result = json.loads(result)
691 print(parsed_result)
Ahmed El-Hassany2bd46192014-08-20 09:09:57 -0700692 return parsed_result
693 return main.TRUE
admindc1c5072014-06-24 15:57:19 -0700694 except HTTPError as exc:
695 print "ERROR:"
696 print " REST DELETE URL: %s" % url
697 # NOTE: exc.fp contains the object with the response payload
698 error_payload = json.loads(exc.fp.read())
699 print " REST Error Code: %s" % (error_payload['code'])
700 print " REST Error Summary: %s" % (error_payload['summary'])
701 print " REST Error Description: %s" % (error_payload['formattedDescription'])
702 print " HTTP Error Code: %s" % exc.code
703 print " HTTP Error Reason: %s" % exc.reason
704 except URLError as exc:
705 print "ERROR:"
706 print " REST DELETE URL: %s" % url
707 print " URL Error Reason: %s" % exc.reason
Ahmed El-Hassanyf60919d2014-08-20 09:14:01 -0700708 except timeout as exc:
709 print "ERROR:"
710 print " REST GET URL: %s" % url
711 print " URL Error Reason: %s" % exc.message
712 main.log.error("Socket timeout connecting to: %s", url)
713 return main.ERROR
Ahmed El-Hassany2bd46192014-08-20 09:09:57 -0700714 return main.ERROR
admindc1c5072014-06-24 15:57:19 -0700715
716#*********************************************************************
717#*********************************************************************
718# add_intent will add a single intent by using dpids and macs.
719#*********************************************************************
720#*********************************************************************
721
722
723 def add_intent(self, intent_id,src_dpid,dst_dpid,src_mac,dst_mac,intentIP,intentPort=8080,intentURL="wm/onos/intent" , intent_type = 'SHORTEST_PATH', static_path=False, src_port=1,dst_port=1):
admin2a9548d2014-06-17 14:08:07 -0700724 "CLI command callback: set intent"
725
726 intents = []
727 oper = {}
728 # Create the POST payload
729 oper['intentId'] = intent_id
730 oper['intentType'] = intent_type # XXX: Hardcoded
731 oper['staticPath'] = static_path # XXX: Hardcoded
732 oper['srcSwitchDpid'] = src_dpid
733 oper['srcSwitchPort'] = src_port
734 oper['dstSwitchDpid'] = dst_dpid
735 oper['dstSwitchPort'] = dst_port
736 oper['matchSrcMac'] = src_mac
737 oper['matchDstMac'] = dst_mac
738 intents.append(oper)
admindc1c5072014-06-24 15:57:19 -0700739 url = "http://%s:%s/%s/high"%(intentIP,intentPort,intentURL)
admin2a9548d2014-06-17 14:08:07 -0700740 parsed_result = []
741 data_json = json.dumps(intents)
Jon Hall43d1e962014-08-08 11:51:24 -0700742 result = main.FALSE
admin2a9548d2014-06-17 14:08:07 -0700743 try:
744 request = urllib2.Request(url,data_json)
745 request.add_header("Content-Type", "application/json")
Ahmed El-Hassanyf60919d2014-08-20 09:14:01 -0700746 response=urllib2.urlopen(request, timeout=URL_TIMEOUT)
admin2a9548d2014-06-17 14:08:07 -0700747 result = response.read()
748 response.close()
749 if len(result) != 0:
750 parsed_result = json.loads(result)
Ahmed El-Hassany2bd46192014-08-20 09:09:57 -0700751 return parsed_result
752 return main.TRUE
admin2a9548d2014-06-17 14:08:07 -0700753 except HTTPError as exc:
754 print "ERROR:"
755 print " REST GET URL: %s" % url
756 # NOTE: exc.fp contains the object with the response payload
757 error_payload = json.loads(exc.fp.read())
758 print " REST Error Code: %s" % (error_payload['code'])
759 print " REST Error Summary: %s" % (error_payload['summary'])
760 print " REST Error Description: %s" % (error_payload['formattedDescription'])
761 print " HTTP Error Code: %s" % exc.code
762 print " HTTP Error Reason: %s" % exc.reason
Jon Hall43d1e962014-08-08 11:51:24 -0700763 return " HTTP Error Code: %s, Reason: %s" % exc.code, exc.reason
admin2a9548d2014-06-17 14:08:07 -0700764 except URLError as exc:
765 print "ERROR:"
766 print " REST GET URL: %s" % url
767 print " URL Error Reason: %s" % exc.reason
Jon Hall43d1e962014-08-08 11:51:24 -0700768 return " HTTP Error Reason: %s" % exc.reason
Ahmed El-Hassanyf60919d2014-08-20 09:14:01 -0700769 except timeout as exc:
770 print "ERROR:"
771 print " REST GET URL: %s" % url
772 print " URL Error Reason: %s" % exc.message
773 main.log.error("Socket timeout connecting to: %s", url)
774 return main.ERROR
Ahmed El-Hassany2bd46192014-08-20 09:09:57 -0700775 return main.ERROR
admin2a9548d2014-06-17 14:08:07 -0700776
admin2a9548d2014-06-17 14:08:07 -0700777
778
779 def add_intents(self):
780 main.log.info("Sending new intents to ONOS")
adminc6cfc1c2014-04-21 13:55:21 -0700781 self.handle.sendline("cd "+self.home+ "/scripts")
782 self.handle.expect("scripts")
admin2a9548d2014-06-17 14:08:07 -0700783 main.log.info("Adding intents")
adminc6cfc1c2014-04-21 13:55:21 -0700784 self.handle.sendline("./pyintents.py")
Jon Hall9c6e2c02014-05-02 10:18:53 -0700785 self.handle.expect(["$",pexpect.EOF,pexpect.TIMEOUT])
786 response = self.handle.before
adminc6cfc1c2014-04-21 13:55:21 -0700787 self.handle.sendline("cd "+self.home)
788 return main.TRUE
789
admin2a9548d2014-06-17 14:08:07 -0700790 def rm_intents(self):
791 main.log.info("Deleteing Intents from ONOS")
adminc6cfc1c2014-04-21 13:55:21 -0700792 self.handle.sendline("cd "+self.home+ "/scripts")
793 self.handle.expect("scripts")
admin2a9548d2014-06-17 14:08:07 -0700794 main.log.info("Deleting Intnents")
adminc6cfc1c2014-04-21 13:55:21 -0700795 self.handle.sendline("./rmpyintents.py")
Jon Hall9c6e2c02014-05-02 10:18:53 -0700796 self.handle.expect(["$",pexpect.EOF,pexpect.TIMEOUT])
797 response = self.handle.before
adminc6cfc1c2014-04-21 13:55:21 -0700798 self.handle.sendline("cd "+self.home)
799 return main.TRUE
800
admin2a9548d2014-06-17 14:08:07 -0700801 def purge_intents(self):
Jon Hall265149f2014-04-25 13:39:52 -0700802 main.log.info("Purging dead intents")
803 self.handle.sendline("cd "+self.home+ "/scripts")
804 self.handle.expect("scripts")
admin2a9548d2014-06-17 14:08:07 -0700805 main.log.info("Sending Purge Intent Rest call to ONOS")
Jon Hall265149f2014-04-25 13:39:52 -0700806 self.handle.sendline("./purgeintents.py")
807 self.handle.sendline("cd "+self.home)
808 return main.TRUE
adminc6cfc1c2014-04-21 13:55:21 -0700809
810
811
Jon Hall4a2b0482014-04-18 16:29:26 -0700812 def add_flow(self, testONip, user = "admin", password = "", flowDef = "/flowdef.txt"):
Jon Halld8dc5772014-04-08 16:26:29 -0700813 '''
814 Copies the flowdef file from TestStation -> ONOS machine
815 Then runs ./add_flow.py to add the flows to ONOS
816 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700817 try:
818 main.log.info("Adding Flows...")
819 self.handle.sendline("scp %s@%s:%s /tmp/flowtmp" %(user,testONip,flowDef))
820 i=self.handle.expect(['[pP]assword:', '100%', pexpect.TIMEOUT],30)
821 if(i==0):
822 self.handle.sendline("%s" %(password))
823 self.handle.sendline("")
824 self.handle.expect("100%")
825 self.handle.expect("\$", 30)
826 self.handle.sendline(self.home + "/web/add_flow.py -m onos -f /tmp/flowtmp")
827 self.handle.expect("\$", 1000)
828 main.log.info("Flows added")
829 return main.TRUE
830
831 elif(i==1):
832 self.handle.sendline("")
833 self.handle.expect("\$", 10)
834 self.handle.sendline( self.home + "/web/add_flow.py -m onos -f /tmp/flowtmp")
835 self.handle.expect("\$", 1000)
836 main.log.info("Flows added")
837 return main.TRUE
838
839 elif(i==2):
840 main.log.error("Flow Def file SCP Timed out...")
841 return main.FALSE
842
843 else:
844 main.log.error("Failed to add flows...")
James Leec9cacaf2014-04-08 09:17:39 -0700845 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -0700846 except pexpect.EOF:
847 main.log.error(self.name + ": EOF exception found")
848 main.log.error(self.name + ": " + self.handle.before)
849 main.cleanup()
850 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -0700851 except:
852 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
853 main.log.error( traceback.print_exc() )
854 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
855 main.cleanup()
856 main.exit()
857
adminbae64d82013-08-01 10:50:15 -0700858
859 def delete_flow(self, *delParams):
Jon Halld8dc5772014-04-08 16:26:29 -0700860 '''
861 Deletes a specific flow, a range of flows, or all flows.
862 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700863 try:
864 if len(delParams)==1:
865 if str(delParams[0])=="all":
866 main.log.info(self.name + ": Deleting ALL flows...")
867 #self.execute(cmd="~/ONOS/scripts/TestON_delete_flow.sh all",prompt="done",timeout=150)
868 self.handle.sendline(self.home + "/web/delete_flow.py all")
869 self.handle.expect("delete_flow")
870 self.handle.expect("\$",1000)
871 main.log.info(self.name + ": Flows deleted")
872 else:
873 main.log.info(self.name + ": Deleting flow "+str(delParams[0])+"...")
874 #self.execute(cmd="~/ONOS/scripts/TestON_delete_flow.sh "+str(delParams[0]),prompt="done",timeout=150)
875 #self.execute(cmd="\n",prompt="\$",timeout=60)
876 self.handle.sendline(self.home +"/web/delete_flow.py %d" % int(delParams[0]))
877 self.handle.expect("delete_flow")
878 self.handle.expect("\$",60)
879 main.log.info(self.name + ": Flow deleted")
880 elif len(delParams)==2:
881 main.log.info(self.name + ": Deleting flows "+str(delParams[0])+" through "+str(delParams[1])+"...")
882 #self.execute(cmd="~/ONOS/scripts/TestON_delete_flow.sh "+str(delParams[0])+" "+str(delParams[1]),prompt="done",timeout=150)
883 #self.execute(cmd="\n",prompt="\$",timeout=60)
884 self.handle.sendline(self.home + "/web/delete_flow.py %d %d" % (int(delParams[0]), int(delParams[1])))
885 self.handle.expect("delete_flow")
886 self.handle.expect("\$",600)
887 main.log.info(self.name + ": Flows deleted")
Jon Hallae05dc22014-04-16 10:56:28 -0700888 except pexpect.EOF:
889 main.log.error(self.name + ": EOF exception found")
890 main.log.error(self.name + ": " + self.handle.before)
891 main.cleanup()
892 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -0700893 except:
894 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
895 main.log.error( traceback.print_exc() )
896 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
897 main.cleanup()
898 main.exit()
adminbae64d82013-08-01 10:50:15 -0700899
900 def check_flow(self):
Jon Halld8dc5772014-04-08 16:26:29 -0700901 '''
902 Calls the ./get_flow.py all and checks:
903 - If each FlowPath has at least one FlowEntry
904 - That there are no "NOT"s found
905 returns TRUE/FALSE
906 '''
Jon Hallf89c8552014-04-02 13:14:06 -0700907 try:
908 flowEntryDetect = 1
909 count = 0
910 self.handle.sendline("clear")
911 time.sleep(1)
912 self.handle.sendline(self.home + "/web/get_flow.py all")
913 self.handle.expect("get_flow")
Jon Hall3bd7c792014-05-30 09:05:21 -0700914 for x in range(15):
Jon Hallf89c8552014-04-02 13:14:06 -0700915 i=self.handle.expect(['FlowPath','FlowEntry','NOT','\$',pexpect.TIMEOUT],timeout=180)
916 if i==0:
917 count = count + 1
918 if flowEntryDetect == 0:
919 main.log.info(self.name + ": FlowPath without FlowEntry")
920 return main.FALSE
921 else:
922 flowEntryDetect = 0
923 elif i==1:
924 flowEntryDetect = 1
925 elif i==2:
926 main.log.error(self.name + ": Found a NOT")
adminbae64d82013-08-01 10:50:15 -0700927 return main.FALSE
Jon Hallf89c8552014-04-02 13:14:06 -0700928 elif i==3:
929 if count == 0:
930 main.log.info(self.name + ": There don't seem to be any flows here...")
931 return main.FALSE
932 else:
933 main.log.info(self.name + ": All flows pass")
934 main.log.info(self.name + ": Number of FlowPaths: "+str(count))
935 return main.TRUE
936 elif i==4:
James Leec9cacaf2014-04-08 09:17:39 -0700937 main.log.error(self.name + ":Check_flow() - Command Timeout!")
Jon Hallf89c8552014-04-02 13:14:06 -0700938 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -0700939 except pexpect.EOF:
940 main.log.error(self.name + ": EOF exception found")
941 main.log.error(self.name + ": " + self.handle.before)
942 main.cleanup()
943 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -0700944 except:
945 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
946 main.log.error( traceback.print_exc() )
947 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
948 main.cleanup()
949 main.exit()
adminbae64d82013-08-01 10:50:15 -0700950
951 def get_flow(self, *flowParams):
Jon Halld8dc5772014-04-08 16:26:29 -0700952 '''
953 Returns verbose output of ./get_flow.py
954 '''
955 try:
956 if len(flowParams)==1:
957 if str(flowParams[0])=="all":
958 self.execute(cmd="\n",prompt="\$",timeout=60)
959 main.log.info(self.name + ": Getting all flow data...")
960 data = self.execute(cmd=self.home + "/scripts/TestON_get_flow.sh all",prompt="done",timeout=150)
961 self.execute(cmd="\n",prompt="\$",timeout=60)
962 return data
963 else:
964 main.log.info(self.name + ": Retrieving flow "+str(flowParams[0])+" data...")
965 data = self.execute(cmd=self.home +"/scripts/TestON_get_flow.sh "+str(flowParams[0]),prompt="done",timeout=150)
966 self.execute(cmd="\n",prompt="\$",timeout=60)
967 return data
968 elif len(flowParams)==5:
969 main.log.info(self.name + ": Retrieving flow installer data...")
970 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)
971 self.execute(cmd="\n",prompt="\$",timeout=60)
972 return data
973 elif len(flowParams)==4:
974 main.log.info(self.name + ": Retrieving flow endpoints...")
975 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)
976 self.execute(cmd="\n",prompt="\$",timeout=60)
977 return data
Jon Hallae05dc22014-04-16 10:56:28 -0700978 except pexpect.EOF:
979 main.log.error(self.name + ": EOF exception found")
980 main.log.error(self.name + ": " + self.handle.before)
981 main.cleanup()
982 main.exit()
Jon Halld8dc5772014-04-08 16:26:29 -0700983 except:
Jon Hallf89c8552014-04-02 13:14:06 -0700984 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
985 main.log.error( traceback.print_exc() )
986 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
987 main.cleanup()
988 main.exit()
adminbae64d82013-08-01 10:50:15 -0700989
990
Jon Hall2f42a672014-05-28 10:13:18 -0700991# http://localhost:8080/wm/onos/topology/switches
992# http://localhost:8080/wm/onos/topology/links
Jon Hall8060af02014-04-14 14:17:58 -0700993# http://localhost:8080/wm/onos/registry/controllers/json
994# http://localhost:8080/wm/onos/registry/switches/json"
adminbae64d82013-08-01 10:50:15 -0700995
996 def get_json(self, url):
Jon Halld8dc5772014-04-08 16:26:29 -0700997 '''
998 Helper functions used to parse the json output of a rest call
999 '''
adminbae64d82013-08-01 10:50:15 -07001000 try:
Jon Hallf89c8552014-04-02 13:14:06 -07001001 try:
1002 command = "curl -s %s" % (url)
1003 result = os.popen(command).read()
1004 parsedResult = json.loads(result)
1005 except:
1006 print "REST IF %s has issue" % command
1007 parsedResult = ""
1008
1009 if type(parsedResult) == 'dict' and parsedResult.has_key('code'):
1010 print "REST %s returned code %s" % (command, parsedResult['code'])
1011 parsedResult = ""
James Leec9cacaf2014-04-08 09:17:39 -07001012 return parsedResult
Jon Hallae05dc22014-04-16 10:56:28 -07001013 except pexpect.EOF:
1014 main.log.error(self.name + ": EOF exception found")
1015 main.log.error(self.name + ": " + self.handle.before)
1016 main.cleanup()
1017 main.exit()
adminbae64d82013-08-01 10:50:15 -07001018 except:
Jon Hallf89c8552014-04-02 13:14:06 -07001019 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1020 main.log.error( traceback.print_exc() )
1021 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1022 main.cleanup()
1023 main.exit()
adminbae64d82013-08-01 10:50:15 -07001024
admin680b78c2014-08-08 11:46:45 -07001025 def num_switch(self,RestIP,RestPort="8080"):
1026 url = "http://%s:%s/wm/onos/topology/switches" %(RestIP,RestPort)
1027 parsedResult = self.get_json(url)
1028 if parsedResult == "":
1029 retcode = 1
1030 return (retcode, "RestAPI has an issue")
1031 url = "http://%s:%s/wm/onos/registry/switches/json" %(RestIP,RestPort)
1032 registry = self.get_json(url)
1033 if registry == "":
1034 retcode = 1
1035 return (retcode, "REST API has an Issue")
1036 cnt = 0
1037 active = 0
1038 for s in parsedResult:
1039 cnt +=1
1040 if s['state']=="ACTIVE":
1041 active+=1
1042 return (cnt,active)
1043
1044
Jon Hallf89c8552014-04-02 13:14:06 -07001045 def check_switch(self,RestIP,correct_nr_switch, RestPort ="8080" ):
Jon Halld8dc5772014-04-08 16:26:29 -07001046 '''
1047 Used by check_status
1048 '''
Jon Hallf89c8552014-04-02 13:14:06 -07001049 try:
1050 buf = ""
1051 retcode = 0
admin2e131ab2014-05-28 10:03:42 -07001052 url="http://%s:%s/wm/onos/topology/switches" % (RestIP, RestPort)
Jon Hallf89c8552014-04-02 13:14:06 -07001053 parsedResult = self.get_json(url)
1054 if parsedResult == "":
1055 retcode = 1
1056 return (retcode, "Rest API has an issue")
1057 url = "http://%s:%s/wm/onos/registry/switches/json" % (RestIP, RestPort)
1058 registry = self.get_json(url)
1059
1060 if registry == "":
1061 retcode = 1
1062 return (retcode, "Rest API has an issue")
1063
1064 cnt = 0
1065 active = 0
adminbae64d82013-08-01 10:50:15 -07001066
Jon Hallf89c8552014-04-02 13:14:06 -07001067 for s in parsedResult:
1068 cnt += 1
James Leec9cacaf2014-04-08 09:17:39 -07001069 if s['state'] == "ACTIVE":
Jon Hallf89c8552014-04-02 13:14:06 -07001070 active += 1
adminbae64d82013-08-01 10:50:15 -07001071
Jon Hallf89c8552014-04-02 13:14:06 -07001072 buf += "switch: network %d : %d switches %d active\n" % (0+1, cnt, active)
1073 if correct_nr_switch != cnt:
1074 buf += "switch fail: network %d should have %d switches but has %d\n" % (1, correct_nr_switch, cnt)
1075 retcode = 1
adminbae64d82013-08-01 10:50:15 -07001076
Jon Hallf89c8552014-04-02 13:14:06 -07001077 if correct_nr_switch != active:
1078 buf += "switch fail: network %d should have %d active switches but has %d\n" % (1, correct_nr_switch, active)
1079 retcode = 1
1080
1081 return (retcode, buf)
Jon Hallae05dc22014-04-16 10:56:28 -07001082 except pexpect.EOF:
1083 main.log.error(self.name + ": EOF exception found")
1084 main.log.error(self.name + ": " + self.handle.before)
1085 main.cleanup()
1086 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -07001087 except:
1088 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1089 main.log.error( traceback.print_exc() )
1090 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1091 main.cleanup()
1092 main.exit()
adminbae64d82013-08-01 10:50:15 -07001093
admin680b78c2014-08-08 11:46:45 -07001094 def num_link(self,RestIP,RestPort="8080"):
1095 url = "http://%s:%s/wm/onos/topology/links" % (RestIP,RestPort)
1096 parsedResult = self.get_json(url)
1097 if parsedResult == "":
1098 retcode = 1
1099 return (retcode,"RestAPI has an issue")
1100 intra = 0
1101 for s in parsedResult:
1102 intra+=1
1103 return intra
1104
Jon Hallf89c8552014-04-02 13:14:06 -07001105 def check_link(self,RestIP, nr_links, RestPort = "8080"):
Jon Halld8dc5772014-04-08 16:26:29 -07001106 '''
1107 Used by check_status
1108 '''
Jon Hallf89c8552014-04-02 13:14:06 -07001109 try:
1110 buf = ""
1111 retcode = 0
1112
admin2e131ab2014-05-28 10:03:42 -07001113 url = "http://%s:%s/wm/onos/topology/links" % (RestIP, RestPort)
Jon Hallf89c8552014-04-02 13:14:06 -07001114 parsedResult = self.get_json(url)
1115
1116 if parsedResult == "":
1117 retcode = 1
1118 return (retcode, "Rest API has an issue")
1119
1120 buf += "link: total %d links (correct : %d)\n" % (len(parsedResult), nr_links)
1121 intra = 0
1122 interlink=0
1123
1124 for s in parsedResult:
James Leec9cacaf2014-04-08 09:17:39 -07001125 intra = intra + 1
Jon Hallf89c8552014-04-02 13:14:06 -07001126
1127 if intra != nr_links:
1128 buf += "link fail\n"
1129 retcode = 1
1130
1131 return (retcode, buf)
Jon Hallae05dc22014-04-16 10:56:28 -07001132 except pexpect.EOF:
1133 main.log.error(self.name + ": EOF exception found")
1134 main.log.error(self.name + ": " + self.handle.before)
1135 main.cleanup()
1136 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -07001137 except:
1138 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1139 main.log.error( traceback.print_exc() )
1140 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1141 main.cleanup()
1142 main.exit()
adminbae64d82013-08-01 10:50:15 -07001143
Jon Hallf89c8552014-04-02 13:14:06 -07001144 def check_status_report(self, ip, numoswitch, numolink, port="8080"):
Jon Halld8dc5772014-04-08 16:26:29 -07001145 '''
1146 Checks the number of swithes & links that ONOS sees against the supplied values.
1147 Writes to the report log.
1148 '''
Jon Hallf89c8552014-04-02 13:14:06 -07001149 try:
James Leec9cacaf2014-04-08 09:17:39 -07001150 main.log.info(self.name + ": Making some rest calls...")
Jon Hallf89c8552014-04-02 13:14:06 -07001151 switch = self.check_switch(ip, int(numoswitch), port)
1152 link = self.check_link(ip, int(numolink), port)
1153 value = switch[0]
1154 value += link[0]
1155 main.log.report( self.name + ": \n-----\n%s%s-----\n" % ( switch[1], link[1]) )
1156 if value != 0:
1157 return main.FALSE
James Leec9cacaf2014-04-08 09:17:39 -07001158 else:
Jon Hallf89c8552014-04-02 13:14:06 -07001159 # "PASS"
1160 return main.TRUE
Jon Hallae05dc22014-04-16 10:56:28 -07001161 except pexpect.EOF:
1162 main.log.error(self.name + ": EOF exception found")
1163 main.log.error(self.name + ": " + self.handle.before)
1164 main.cleanup()
1165 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -07001166 except:
1167 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1168 main.log.error( traceback.print_exc() )
1169 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1170 main.cleanup()
1171 main.exit()
adminbae64d82013-08-01 10:50:15 -07001172
Jon Hallf89c8552014-04-02 13:14:06 -07001173 def check_status(self, ip, numoswitch, numolink, port = "8080"):
Jon Halld8dc5772014-04-08 16:26:29 -07001174 '''
1175 Checks the number of swithes & links that ONOS sees against the supplied values.
1176 Writes to the main log.
1177 '''
Jon Hallf89c8552014-04-02 13:14:06 -07001178 try:
James Leec9cacaf2014-04-08 09:17:39 -07001179 main.log.info(self.name + ": Making some rest calls...")
Jon Hallf89c8552014-04-02 13:14:06 -07001180 switch = self.check_switch(ip, int(numoswitch), port)
1181 link = self.check_link(ip, int(numolink), port)
1182 value = switch[0]
1183 value += link[0]
1184 main.log.info(self.name + ": \n-----\n%s%s-----\n" % ( switch[1], link[1]) )
1185 if value != 0:
1186 return main.FALSE
James Leec9cacaf2014-04-08 09:17:39 -07001187 else:
Jon Hallf89c8552014-04-02 13:14:06 -07001188 # "PASS"
1189 return main.TRUE
Jon Hallae05dc22014-04-16 10:56:28 -07001190 except pexpect.EOF:
1191 main.log.error(self.name + ": EOF exception found")
1192 main.log.error(self.name + ": " + self.handle.before)
1193 main.cleanup()
1194 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -07001195 except:
1196 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1197 main.log.error( traceback.print_exc() )
1198 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1199 main.cleanup()
1200 main.exit()
Ahmed El-Hassany2bd46192014-08-20 09:09:57 -07001201
1202 def detailed_status(self, log_filename):
1203 '''
1204 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
1205 '''
1206 try:
1207 process_up = False
1208 self.execute(cmd="\n", prompt="\$", timeout=10)
1209 self.handle.sendline("cd " + self.home)
1210 response = self.execute(cmd="./onos.sh core status ",prompt="\d+\sinstance\sof\sonos\srunning",timeout=10)
1211 self.execute(cmd="\n",prompt="\$",timeout=10)
1212 if re.search("1\sinstance\sof\sonos\srunning",response):
1213 process_up = True
1214 elif re.search("0\sinstance\sof\sonos\srunning",response):
1215 process_up = False
1216 return 'STOPPED'
1217 elif re.search("Expected\sPrompt\snot found\s,\sTime Out!!",response):
1218 return "ERROR", "Time out on ./onos.sh core status"
1219 else :
1220 main.log.warn(self.name + " WARNING: status recieved unknown response")
1221 main.log.warn(response)
1222 return 'Error', "Unknown response: %s" % response
1223 '''
1224 self.execute(cmd="\n",prompt="\$",timeout=10)
1225 tail1 = self.execute(cmd="tail " + self.home + "%s" % log_filename, prompt="\$", timeout=10)
1226 time.sleep(10)
1227 self.execute(cmd="\n",prompt="\$",timeout=10)
1228 tail2 = self.execute(cmd="tail " + self.home + "%s" % log_filename, prompt="\$", timeout=10)
1229 '''
1230
1231 pattern = '(.*)1 instance(.*)'
1232 pattern2 = '(.*)Exception: Connection refused(.*)'
1233 # if utilities.assert_matches(expect=pattern,actual=response,onpass="ONOS process is running...",onfail="ONOS process not running..."):
1234 running = self.execute(cmd="cat " + self.home + " %s | grep 'Sending LLDP out on all ports'" % log_filename,prompt="\$",timeout=10)
1235 if re.search(pattern, response):
1236 if running == '':
1237 return 'STARTING',
1238 else:
1239 return 'RUNNING'
1240 else:
1241 main.log.error(self.name + ": ONOS process not running...")
1242 return 'STOPPED'
1243 except pexpect.EOF:
1244 main.log.error(self.name + ": EOF exception found")
1245 main.log.error(self.name + ": " + self.handle.before)
1246 main.cleanup()
1247 main.exit()
1248 except:
1249 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1250 main.log.error( traceback.print_exc() )
1251 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1252 main.cleanup()
1253 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -07001254
admine0eeea22014-04-14 10:22:46 -07001255 def git_pull(self, comp1=""):
Jon Halld8dc5772014-04-08 16:26:29 -07001256 '''
Jon Halld8dc5772014-04-08 16:26:29 -07001257 Assumes that "git pull" works without login
admine0eeea22014-04-14 10:22:46 -07001258
1259 This function will perform a git pull on the ONOS instance.
1260 If used as git_pull("NODE") it will do git pull + NODE. This is
1261 for the purpose of pulling from other nodes if necessary.
1262
1263 Otherwise, this function will perform a git pull in the
1264 ONOS repository. If it has any problems, it will return main.ERROR
1265 If it successfully does a git_pull, it will return a 1.
1266 If it has no updates, it will return a 0.
1267
Jon Halld8dc5772014-04-08 16:26:29 -07001268 '''
Jon Hallae05dc22014-04-16 10:56:28 -07001269 try:
Jon Halle80ef8c2014-04-29 15:29:13 -07001270 # main.log.info(self.name + ": Stopping ONOS")
1271 #self.stop()
Jon Hallae05dc22014-04-16 10:56:28 -07001272 self.handle.sendline("cd " + self.home)
1273 self.handle.expect("ONOS\$")
1274 if comp1=="":
1275 self.handle.sendline("git pull")
1276 else:
1277 self.handle.sendline("git pull " + comp1)
1278
1279 uptodate = 0
Jon Hall7dae6cf2014-09-11 15:09:48 -07001280 i=self.handle.expect(['fatal',
1281 'Username\sfor\s(.*):\s',
1282 '\sfile(s*) changed,\s',
1283 'Already up-to-date',
1284 'Aborting',
1285 'You\sare\snot\scurrently\son\sa\sbranch',
1286 'You\sasked\sme\sto\spull\swithout\stelling\sme\swhich\sbranch\syou',
1287 'Pull\sis\snot\spossible\sbecause\syou\shave\sunmerged\sfiles',
1288 pexpect.TIMEOUT],
1289 timeout=300)
Jon Hallae05dc22014-04-16 10:56:28 -07001290 #debug
1291 #main.log.report(self.name +": \n"+"git pull response: " + str(self.handle.before) + str(self.handle.after))
1292 if i==0:
1293 main.log.error(self.name + ": Git pull had some issue...")
1294 return main.ERROR
1295 elif i==1:
Jon Hall7dae6cf2014-09-11 15:09:48 -07001296 main.log.error(self.name + ": Git Pull Asking for username. ")
Jon Hallae05dc22014-04-16 10:56:28 -07001297 return main.ERROR
1298 elif i==2:
1299 main.log.info(self.name + ": Git Pull - pulling repository now")
1300 self.handle.expect("ONOS\$", 120)
1301 return 0
1302 elif i==3:
Jon Hallae05dc22014-04-16 10:56:28 -07001303 main.log.info(self.name + ": Git Pull - Already up to date")
1304 return 1
Jon Hall7dae6cf2014-09-11 15:09:48 -07001305 elif i==4:
Jon Hallae05dc22014-04-16 10:56:28 -07001306 main.log.info(self.name + ": Git Pull - Aborting... Are there conflicting git files?")
1307 return main.ERROR
Jon Hall7dae6cf2014-09-11 15:09:48 -07001308 elif i==5:
Jon Hall5a8aac62014-06-03 09:30:21 -07001309 main.log.info(self.name + ": Git Pull - You are not currently on a branch so git pull failed!")
1310 return main.ERROR
Jon Hall7dae6cf2014-09-11 15:09:48 -07001311 elif i==6:
Jon Hall847cfad2014-09-03 14:10:08 -07001312 main.log.info(self.name + ": Git Pull - You have not configured an upstream branch to pull from. Git pull failed!")
1313 return main.ERROR
Jon Hall7dae6cf2014-09-11 15:09:48 -07001314 elif i==7:
1315 main.log.info(self.name + ": Git Pull - Pull is not possible because you have unmerged files.")
1316 return main.ERROR
1317 elif i==8:
1318 main.log.error(self.name + ": Git Pull - TIMEOUT")
1319 main.log.error(self.name + " Response was: " + str(self.handle.before))
1320 return main.ERROR
Jon Hallae05dc22014-04-16 10:56:28 -07001321 else:
1322 main.log.error(self.name + ": Git Pull - Unexpected response, check for pull errors")
1323 return main.ERROR
1324 except pexpect.EOF:
1325 main.log.error(self.name + ": EOF exception found")
1326 main.log.error(self.name + ": " + self.handle.before)
1327 main.cleanup()
1328 main.exit()
1329 except:
1330 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1331 main.log.error( traceback.print_exc() )
1332 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1333 main.cleanup()
1334 main.exit()
admine0eeea22014-04-14 10:22:46 -07001335#********************************************************
1336
1337
admin680b78c2014-08-08 11:46:45 -07001338
1339
1340 def git_checkout(self, branch="onos13integration"):
1341 '''
1342 Assumes that "git pull" works without login
1343
1344 This function will perform a git pull on the ONOS instance.
1345 If used as git_pull("NODE") it will do git pull + NODE. This is
1346 for the purpose of pulling from other nodes if necessary.
1347
1348 Otherwise, this function will perform a git pull in the
1349 ONOS repository. If it has any problems, it will return main.ERROR
1350 If it successfully does a git_pull, it will return a 1.
1351 If it has no updates, it will return a 0.
1352
1353 '''
1354 try:
1355 # main.log.info(self.name + ": Stopping ONOS")
1356 #self.stop()
1357 self.handle.sendline("cd " + self.home)
1358 self.handle.expect("ONOS\$")
1359 if branch != 'master':
1360 #self.handle.sendline('git stash')
1361 #self.handle.expect('ONOS\$')
1362 #print "After issuing git stash cmnd: ", self.handle.before
1363 cmd = "git checkout "+branch
1364 print "checkout cmd = ", cmd
1365 self.handle.sendline(cmd)
1366 uptodate = 0
1367 i=self.handle.expect(['fatal','Username\sfor\s(.*):\s','Already\son\s\'onos13integration\'','Switched\sto\sbranch\s\'onos13integration\'', pexpect.TIMEOUT],timeout=60)
1368 else:
1369 #self.handle.sendline('git stash apply')
1370 #self.handle.expect('ONOS\$')
1371 #print "After issuing git stash apply cmnd: ", self.handle.before
1372 cmd = "git checkout "+branch
1373 print "checkout cmd = ", cmd
1374 self.handle.sendline(cmd)
1375 uptodate = 0
1376 switchedToMaster = 0
1377 i=self.handle.expect(['fatal','Username\sfor\s(.*):\s','Already\son\s\'master\'','Switched\sto\sbranch\s\'master\'', pexpect.TIMEOUT],timeout=60)
1378
1379
1380 if i==0:
1381 main.log.error(self.name + ": Git checkout had some issue...")
1382 return main.ERROR
1383 elif i==1:
1384 main.log.error(self.name + ": Git checkout Asking for username!!! BADD!")
1385 return main.ERROR
1386 elif i==2:
1387 main.log.info(self.name + ": Git Checkout %s : Already on this branch" %branch)
1388 self.handle.expect("ONOS\$")
1389 print "after checkout cmd = ", self.handle.before
1390 switchedToMaster = 1
1391 return 1
1392 elif i==3:
1393 main.log.info(self.name + ": Git checkout %s - Switched to this branch" %branch)
1394 self.handle.expect("ONOS\$")
1395 print "after checkout cmd = ", self.handle.before
1396 switchedToMaster = 1
1397 return 1
1398 elif i==4:
1399 main.log.error(self.name + ": Git Checkout- TIMEOUT")
1400 main.log.error(self.name + " Response was: " + str(self.handle.before))
1401 return main.ERROR
1402 else:
1403 main.log.error(self.name + ": Git Checkout - Unexpected response, check for pull errors")
1404 return main.ERROR
1405
1406 except pexpect.EOF:
1407 main.log.error(self.name + ": EOF exception found")
1408 main.log.error(self.name + ": " + self.handle.before)
1409 main.cleanup()
1410 main.exit()
1411 except:
1412 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1413 main.log.error( traceback.print_exc() )
1414 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1415 main.cleanup()
1416 main.exit()
1417#********************************************************
1418 self.handle.sendline("git branch")
1419 self.handle.expect("ONOS\$")
1420 print "git branch output = ", self.handle.before
1421 print "*****************************************"
1422 self.handle.sendline('cd\.\.')
1423 self.handle.expect("\$")
1424
1425
1426
1427
1428
1429
1430
1431
admin7373a812014-04-16 09:49:02 -07001432 def git_compile(self):
Jon Hallae05dc22014-04-16 10:56:28 -07001433 '''
1434 Compiles ONOS
1435 First runs mvn clean then mvn compile
1436 '''
1437 try:
1438 main.log.info(self.name + ": mvn clean")
admin8fc02822014-04-16 13:31:23 -07001439 self.handle.sendline("cd " + self.home)
Jon Hallae05dc22014-04-16 10:56:28 -07001440 self.handle.sendline("mvn clean")
1441 while 1:
Jon Hall1636f942014-04-17 10:07:23 -07001442 i=self.handle.expect(['There\sis\sinsufficient\smemory\sfor\sthe\sJava\sRuntime\sEnvironment\sto\scontinue','BUILD\sFAILURE','BUILD\sSUCCESS','ONOS\$',pexpect.TIMEOUT],timeout=30)
Jon Hallae05dc22014-04-16 10:56:28 -07001443 if i == 0:
Jon Hall1636f942014-04-17 10:07:23 -07001444 main.log.error(self.name + ":There is insufficient memory for the Java Runtime Environment to continue.")
Jon Hallae05dc22014-04-16 10:56:28 -07001445 return main.FALSE
1446 elif i == 1:
Jon Hall1636f942014-04-17 10:07:23 -07001447 main.log.error(self.name + ": Clean failure!")
1448 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -07001449 elif i == 2:
Jon Hall1636f942014-04-17 10:07:23 -07001450 main.log.info(self.name + ": Clean success!")
1451 elif i == 3:
admin8fc02822014-04-16 13:31:23 -07001452 main.log.info(self.name + ": Clean complete")
Jon Hallae05dc22014-04-16 10:56:28 -07001453 break;
Jon Hall1636f942014-04-17 10:07:23 -07001454 elif i == 4:
Jon Hallae05dc22014-04-16 10:56:28 -07001455 main.log.error(self.name + ": mvn clean TIMEOUT!")
1456 return main.FALSE
Jon Hall1636f942014-04-17 10:07:23 -07001457 else:
1458 main.log.error(self.name + ": unexpected response from mvn clean")
1459 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -07001460
1461 main.log.info(self.name + ": mvn compile")
1462 self.handle.sendline("mvn compile")
1463 while 1:
Jon Hall1636f942014-04-17 10:07:23 -07001464 i=self.handle.expect(['There\sis\sinsufficient\smemory\sfor\sthe\sJava\sRuntime\sEnvironment\sto\scontinue','BUILD\sFAILURE','BUILD\sSUCCESS','ONOS\$',pexpect.TIMEOUT],timeout=60)
Jon Hallae05dc22014-04-16 10:56:28 -07001465 if i == 0:
Jon Hall1636f942014-04-17 10:07:23 -07001466 main.log.error(self.name + ":There is insufficient memory for the Java Runtime Environment to continue.")
1467 return main.FALSE
1468 if i == 1:
Jon Hallae05dc22014-04-16 10:56:28 -07001469 main.log.error(self.name + ": Build failure!")
1470 return main.FALSE
Jon Hall1636f942014-04-17 10:07:23 -07001471 elif i == 2:
Jon Hallae05dc22014-04-16 10:56:28 -07001472 main.log.info(self.name + ": Build success!")
Jon Hall1636f942014-04-17 10:07:23 -07001473 elif i == 3:
Jon Hallae05dc22014-04-16 10:56:28 -07001474 main.log.info(self.name + ": Build complete")
Jon Hall010f5412014-05-21 15:10:12 -07001475 self.handle.expect("\$", timeout=60)
Jon Hallae05dc22014-04-16 10:56:28 -07001476 return main.TRUE
Jon Hall1636f942014-04-17 10:07:23 -07001477 elif i == 4:
Jon Hallae05dc22014-04-16 10:56:28 -07001478 main.log.error(self.name + ": mvn compile TIMEOUT!")
1479 return main.FALSE
1480 else:
Jon Hall1636f942014-04-17 10:07:23 -07001481 main.log.error(self.name + ": unexpected response from mvn compile")
1482 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -07001483 except pexpect.EOF:
1484 main.log.error(self.name + ": EOF exception found")
1485 main.log.error(self.name + ": " + self.handle.before)
1486 main.cleanup()
1487 main.exit()
1488 except:
1489 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1490 main.log.error( traceback.print_exc() )
1491 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1492 main.cleanup()
1493 main.exit()
admin4a58db92013-09-30 12:04:54 -07001494
Jon Hallf89c8552014-04-02 13:14:06 -07001495 def tcpdump(self, intf = "eth0"):
Jon Hallae05dc22014-04-16 10:56:28 -07001496 '''
1497 Runs tpdump on an intferface and saves in onos-logs under the ONOS home directory
1498 intf can be specified, or the default eth0 is used
1499 '''
Jon Hallf89c8552014-04-02 13:14:06 -07001500 try:
1501 self.handle.sendline("")
1502 self.handle.expect("\$")
Jon Hall26f316b2014-04-11 11:21:25 -07001503 self.handle.sendline("sudo tcpdump -n -i "+ intf + " -s0 -w " + self.home +"/onos-logs/tcpdump &")
Jon Hallf89c8552014-04-02 13:14:06 -07001504 i=self.handle.expect(['No\ssuch\device','listening\son',pexpect.TIMEOUT],timeout=10)
1505 if i == 0:
1506 main.log.error(self.name + ": tcpdump - No such device exists. tcpdump attempted on: " + intf)
1507 return main.FALSE
James Leec9cacaf2014-04-08 09:17:39 -07001508 elif i == 1:
Jon Hallf89c8552014-04-02 13:14:06 -07001509 main.log.info(self.name + ": tcpdump started on " + intf)
1510 return main.TRUE
James Leec9cacaf2014-04-08 09:17:39 -07001511 elif i == 2:
Jon Hallf89c8552014-04-02 13:14:06 -07001512 main.log.error(self.name + ": tcpdump command timed out! Check interface name, given interface was: " + intf)
1513 return main.FALSE
1514 else:
1515 main.log.error(self.name + ": tcpdump - unexpected response")
1516 return main.FALSE
Jon Hallae05dc22014-04-16 10:56:28 -07001517 except pexpect.EOF:
1518 main.log.error(self.name + ": EOF exception found")
1519 main.log.error(self.name + ": " + self.handle.before)
1520 main.cleanup()
1521 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -07001522 except:
1523 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1524 main.log.error( traceback.print_exc() )
1525 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1526 main.cleanup()
1527 main.exit()
1528
admin4a58db92013-09-30 12:04:54 -07001529 def kill_tcpdump(self):
Jon Hallae05dc22014-04-16 10:56:28 -07001530 '''
1531 Kills any tcpdump processes running
1532 '''
Jon Hallf89c8552014-04-02 13:14:06 -07001533 try:
1534 self.handle.sendline("")
1535 self.handle.expect("\$")
1536 self.handle.sendline("sudo kill -9 `ps -ef | grep \"tcpdump -n\" | grep -v grep | awk '{print $2}'`")
Jon Hallae05dc22014-04-16 10:56:28 -07001537 except pexpect.EOF:
1538 main.log.error(self.name + ": EOF exception found")
1539 main.log.error(self.name + ": " + self.handle.before)
1540 main.cleanup()
1541 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -07001542 except:
1543 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1544 main.log.error( traceback.print_exc() )
1545 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1546 main.cleanup()
1547 main.exit()
1548
Jon Hallf15f7852014-05-20 10:37:23 -07001549 def find_host(self,RestIP,RestPort,RestAPI,hostMAC):
admin2a9548d2014-06-17 14:08:07 -07001550 retcode = 0 # number of hosts found with given MAC
1551 retswitch = [] # Switch DPID's of hosts found with MAC
1552 retport = [] # Switch port connected to to hosts found with MAC
Jon Hallf15f7852014-05-20 10:37:23 -07001553 foundHost = []
Jon Hallf89c8552014-04-02 13:14:06 -07001554 try:
Jon Hall2f42a672014-05-28 10:13:18 -07001555 ##### device rest API is: 'host:8080/wm/onos/topology/switches' ###
Jon Hallf89c8552014-04-02 13:14:06 -07001556 url ="http://%s:%s%s" %(RestIP,RestPort,RestAPI)
1557
1558 try:
1559 command = "curl -s %s" % (url)
1560 result = os.popen(command).read()
1561 parsedResult = json.loads(result)
1562 # print parsedResult
1563 except:
1564 print "REST IF %s has issue" % command
1565 parsedResult = ""
1566
1567 if parsedResult == "":
Jon Hallf15f7852014-05-20 10:37:23 -07001568 return (retcode, "Rest API has an error", retport)
Jon Hallf89c8552014-04-02 13:14:06 -07001569 else:
Jon Hallf15f7852014-05-20 10:37:23 -07001570 for host in enumerate(parsedResult):
Jon Hallf15f7852014-05-20 10:37:23 -07001571 if (host[1] != []):
1572 try:
1573 foundHost = host[1]['mac']
1574 except:
1575 print "Error in detecting MAC address."
Jon Hallf15f7852014-05-20 10:37:23 -07001576 if foundHost == hostMAC:
1577 for switch in enumerate(host[1]['attachmentPoints']):
1578 retswitch.append(switch[1]['dpid'])
Jon Hallbb650fe2014-07-14 14:54:48 -07001579 retport.append(switch[1]['portNumber'])
Jon Hallf15f7852014-05-20 10:37:23 -07001580 retcode = retcode +1
1581 foundHost =''
1582 '''
Jon Hallf89c8552014-04-02 13:14:06 -07001583 for switch in enumerate(parsedResult):
1584 for port in enumerate(switch[1]['ports']):
admin2a9548d2014-06-17 14:08:07 -07001585 if ( port[1]['hosts'] != [] ):
Jon Hallf89c8552014-04-02 13:14:06 -07001586 try:
admin2a9548d2014-06-17 14:08:07 -07001587 foundHost = port[1]['hosts'][0]['ipv4addresses'][0]['ipv4']
Jon Hallf89c8552014-04-02 13:14:06 -07001588 except:
Jon Hallf15f7852014-05-20 10:37:23 -07001589 print "Error in detecting MAC address."
1590 if foundHost == hostMAC:
Jon Hallf89c8552014-04-02 13:14:06 -07001591 retswitch.append(switch[1]['dpid'])
1592 retport.append(port[1]['desc'])
admin2a9548d2014-06-17 14:08:07 -07001593 retmac.append(port[1]['hosts'][0]['mac'])
Jon Hallf89c8552014-04-02 13:14:06 -07001594 retcode = retcode +1
Jon Hallf15f7852014-05-20 10:37:23 -07001595 foundHost =''
1596 '''
1597 return(retcode, retswitch, retport)
Jon Hallae05dc22014-04-16 10:56:28 -07001598 except pexpect.EOF:
1599 main.log.error(self.name + ": EOF exception found")
1600 main.log.error(self.name + ": " + self.handle.before)
1601 main.cleanup()
1602 main.exit()
Jon Hallf89c8552014-04-02 13:14:06 -07001603 except:
1604 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1605 main.log.error( traceback.print_exc() )
1606 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1607 main.cleanup()
1608 main.exit()
SeanCorcoran29b70542014-05-14 14:53:42 -07001609
1610 def check_exceptions(self):
1611 '''
1612 Greps the logs for "xception"
1613 '''
1614 try:
1615 output = ''
1616 self.handle.sendline("")
Jon Halla78cf9a2014-05-16 10:49:30 -07001617 i = self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
Jon Hall2c4f5542014-08-05 13:45:29 -07001618 main.log.warn("first expect response: " +str(i))
SeanCorcoran29b70542014-05-14 14:53:42 -07001619 self.handle.sendline("cd "+self.home+"/onos-logs")
Jon Hall2c4f5542014-08-05 13:45:29 -07001620 i = self.handle.expect(["onos-logs\$",pexpect.EOF,pexpect.TIMEOUT])
1621 main.log.warn("second expect response: " +str(i))
1622
1623 self.handle.sendline("zgrep \"xception\" *.log *.log.gz *.stderr")
1624 #i = self.handle.expect(["\*.stdout",pexpect.EOF,pexpect.TIMEOUT])
Jon Halla78cf9a2014-05-16 10:49:30 -07001625 #main.log.warn("third expect response: " +str(i))
Jon Hall2c4f5542014-08-05 13:45:29 -07001626 print self.handle.before
1627 print
1628 print self.handle.after
1629 i = self.handle.expect(["ONOS/onos-logs\$",pexpect.EOF,pexpect.TIMEOUT],timeout=120)
1630 main.log.warn("fourth expect response: " +str(i))
SeanCorcoran29b70542014-05-14 14:53:42 -07001631 response = self.handle.before
admin6903e462014-07-22 15:30:54 -07001632 print response
Jon Halla78cf9a2014-05-16 10:49:30 -07001633 count = 0
Jon Hallbb650fe2014-07-14 14:54:48 -07001634 print response
SeanCorcoran29b70542014-05-14 14:53:42 -07001635 for line in response.splitlines():
Jon Hallbb650fe2014-07-14 14:54:48 -07001636 if re.search("gzip: \*\.log\.gz:", line):
Jon Hall2c4f5542014-08-05 13:45:29 -07001637 #gzip complaining about file not found
Jon Hallbb650fe2014-07-14 14:54:48 -07001638 pass
Jon Hall724a2f42014-06-23 16:04:22 -07001639 elif re.search("log\.gz:",line):
1640 output+="Exceptions found in " + line + "\n"
1641 count +=1
Jon Hall2c4f5542014-08-05 13:45:29 -07001642 elif re.search("log:", line):
1643 output +="Exceptions found in " + line + "\n"
1644 count +=1
SeanCorcoran29b70542014-05-14 14:53:42 -07001645 elif re.search("std...:",line):
1646 output+="Exceptions found in " + line + "\n"
Jon Halla78cf9a2014-05-16 10:49:30 -07001647 count +=1
SeanCorcoran29b70542014-05-14 14:53:42 -07001648 else:
1649 pass
1650 #these should be the old logs
admin1723f1c2014-05-19 16:08:39 -07001651 main.log.report(str(count) + " Exceptions were found on "+self.name)
SeanCorcoran29b70542014-05-14 14:53:42 -07001652 return output
1653 except pexpect.TIMEOUT:
1654 main.log.error(self.name + ": Timeout exception found in check_exceptions function")
1655 except pexpect.EOF:
1656 main.log.error(self.name + ": EOF exception found")
1657 main.log.error(self.name + ": " + self.handle.before)
1658 main.cleanup()
1659 main.exit()
1660 except:
1661 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1662 main.log.error( traceback.print_exc() )
1663 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1664 main.cleanup()
1665 main.exit()
Ahmed El-Hassany41e70fd2014-07-02 14:59:36 -07001666
Ahmed El-Hassanyab175ff2014-08-20 11:50:38 -07001667
Ahmed El-Hassany41e70fd2014-07-02 14:59:36 -07001668 def block_peer(self, ip_address):
1669 '''
1670 Block traffic to the destination IP address.
1671 '''
1672 try:
1673 for chain in ['INPUT', 'OUTPUT']:
1674 check_block_cmd = "sudo iptables -L %s -n | grep \"DROP.*%s\"" % (chain, ip_address)
1675 add_block_cmd = "sudo iptables -I %s 1 -s %s -j DROP" % (chain, ip_address)
1676 response1 = self.execute(cmd=check_block_cmd,prompt="\$",timeout=10)
1677 if ip_address in response1:
1678 main.log.error("Already blocked: %s" % response1)
1679 return main.TRUE
1680 response2 = self.execute(cmd=add_block_cmd,prompt="\$",timeout=10)
1681 main.log.info("add_block_cmd: %s" % response2)
1682 return main.TRUE
1683 except pexpect.EOF:
1684 main.log.error(self.name + ": EOF exception found")
1685 main.log.error(self.name + ": " + self.handle.before)
1686 main.cleanup()
1687 main.exit()
1688 except:
1689 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1690 main.log.error( traceback.print_exc() )
1691 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1692 main.cleanup()
1693 main.exit()
1694
1695 def unblock_peer(self, ip_address):
1696 '''
1697 Unblock traffic to the destination IP address.
1698 '''
1699 try:
1700 for chain in ['INPUT', 'OUTPUT']:
1701 # To make sure all rules are deleted in case there were multiple
1702 # installed in the iptables
1703 max_iterations = 10
1704 for i in range(max_iterations):
1705 check_block_cmd = "sudo iptables -L %s -n | grep \"DROP.*%s\"" % (chain, ip_address)
1706 remove_block_cmd = "sudo iptables -D %s -s %s -j DROP" % (chain, ip_address)
1707 response1 = self.execute(cmd=check_block_cmd,prompt="\$",timeout=10)
1708 if ip_address not in response1:
1709 main.log.warn("Already unblocked: %s" % response1)
1710 return main.TRUE
1711 response2 = self.execute(cmd=remove_block_cmd,prompt="\$",timeout=10)
1712 main.log.info("remove_block_cmd: %s" % response2)
1713 return main.TRUE
1714 except pexpect.EOF:
1715 main.log.error(self.name + ": EOF exception found")
1716 main.log.error(self.name + ": " + self.handle.before)
1717 main.cleanup()
1718 main.exit()
1719 except:
1720 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1721 main.log.error( traceback.print_exc() )
1722 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1723 main.cleanup()
1724 main.exit()
Ahmed El-Hassanyab175ff2014-08-20 11:50:38 -07001725
1726
1727 def unblock_all(self):
1728 '''
1729 Remove all controller block rules
1730 '''
1731 try:
1732 unblock_cmd = "sudo iptables --flush"
1733 response = self.execute(cmd=unblock_cmd,prompt="\$", timeout=10)
1734 return main.TRUE
1735 except pexpect.EOF:
1736 main.log.error(self.name + ": EOF exception found")
1737 main.log.error(self.name + ": " + self.handle.before)
1738 main.cleanup()
1739 main.exit()
1740 except:
1741 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1742 main.log.error( traceback.print_exc() )
1743 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
1744 main.cleanup()
1745 main.exit()
Jon Hall44a450f2014-09-12 13:24:48 -07001746 return main.ERROR