blob: 7734ca196901c62b7d25bbf01b7023f338b6af20 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#/usr/bin/env python
2'''
3Created on 07-Jan-2013
Jon Hall81d3d392015-04-24 14:40:35 -07004
adminbae64d82013-08-01 10:50:15 -07005@author: Raghav Kashyap(raghavkashyap@paxterrasolutions.com)
6
7 TestON is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
11
12 TestON is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
Jon Hall81d3d392015-04-24 14:40:35 -070018 along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070019
20
21'''
22
23import logging
24import datetime
25import re
26import os
27class Logger:
28 '''
29 Add continuous logs and reports of the test.
Jon Hall81d3d392015-04-24 14:40:35 -070030
adminbae64d82013-08-01 10:50:15 -070031 @author: Raghav Kashyap(raghavkashyap@paxterrasolutions.com)
32 '''
33 def _printHeader(self,main) :
34 '''
35 Log's header will be append to the Log file
36 '''
37 logmsg = "\n"+" " * 32+"+----------------+\n" +"-" * 30+" { Script And Files } "+"-" * 30+"\n" +" " * 32+"+----------------+\n";
38 logmsg = logmsg + "\n\tScript Log File : " + main.LogFileName + ""
39 logmsg = logmsg + "\n\tReport Log File : " + main.ReportFileName + ""
40 for component in main.componentDictionary.keys():
41 logmsg = logmsg + "\n\t"+component+" Session Log : " + main.logdir+"/"+component+".session" + ""
Jon Hall81d3d392015-04-24 14:40:35 -070042
adminbae64d82013-08-01 10:50:15 -070043 logmsg = logmsg + "\n\tTest Script :" + path + "Tests/" + main.TEST + ".py"+ ""
44 logmsg = logmsg + "\n\tTest Params : " + path + "Tests/" + main.TEST + ".params" + ""
Jon Hall368769f2014-11-19 15:43:35 -080045 logmsg = logmsg + "\n\tTopology : " + path + "Tests/" +main.TEST + ".topo" + ""
adminbae64d82013-08-01 10:50:15 -070046 logmsg = logmsg + "\n"+" " * 30+"+" +"-" * 18+"+" +"\n" +"-" * 27+" { Script Exec Params } "+"-" * 27 +"\n" +" " * 30 +"+"+"-" * 18 +"+\n";
47 values = "\n\t" + str(main.params)
48 values = re.sub(",", "\n\t", values)
49 values = re.sub("{", "\n\t", values)
50 values = re.sub("}", "\n\t", values)
51 logmsg = logmsg + values
adminbae64d82013-08-01 10:50:15 -070052 logmsg = logmsg + "\n\n"+" " * 31+"+---------------+\n" +"-" * 29+" { Components Used } " +"-" * 29+"\n"+" " * 31+"+---------------+\n"
53 component_list = []
54 component_list.append(None)
Jon Hall81d3d392015-04-24 14:40:35 -070055
adminbae64d82013-08-01 10:50:15 -070056 # Listing the components in the order of test_target component should be first.
57 if type(main.componentDictionary) == dict:
58 for key in main.componentDictionary.keys():
59 if main.test_target == key :
60 component_list[0] = key+"-Test Target"
61 else :
62 component_list.append(key)
Jon Hall81d3d392015-04-24 14:40:35 -070063
adminbae64d82013-08-01 10:50:15 -070064 for index in range(len(component_list)) :
65 if index==0:
66 if component_list[index]:
67 logmsg+="\t"+component_list[index]+"\n"
68 elif index > 0 :
69 logmsg+="\t"+str(component_list[index])+"\n"
Jon Hall81d3d392015-04-24 14:40:35 -070070
adminbae64d82013-08-01 10:50:15 -070071 logmsg = logmsg + "\n\n"+" " * 30+"+--------+\n" +"-" * 28+" { Topology } "+"-" * 28 +"\n" +" " * 30+"+--------+\n"
72 values = "\n\t" + str(main.topology['COMPONENT'])
73 values = re.sub(",", "\n\t", values)
74 values = re.sub("{", "\n\t", values)
75 values = re.sub("}", "\n\t", values)
76 logmsg = logmsg + values
adminbae64d82013-08-01 10:50:15 -070077 logmsg = logmsg + "\n"+"-" * 60+"\n"
Jon Hall81d3d392015-04-24 14:40:35 -070078
adminbae64d82013-08-01 10:50:15 -070079 # enter into log file all headers
80 logfile = open(main.LogFileName,"w+")
81 logfile.write (logmsg)
82 print logmsg
83 main.logHeader = logmsg
adminbae64d82013-08-01 10:50:15 -070084 logfile.close()
Jon Hall81d3d392015-04-24 14:40:35 -070085
adminbae64d82013-08-01 10:50:15 -070086 #enter into report file all headers
87 main.reportFile = open(main.ReportFileName,"w+")
88 main.reportFile.write(logmsg)
89 main.reportFile.close()
Jon Hall81d3d392015-04-24 14:40:35 -070090
Jon Hall79bec222015-04-30 16:23:30 -070091 #Sumamry file header
92 currentTime = str( main.STARTTIME.strftime("%d %b %Y %H:%M:%S") )
93 main.summaryFile = open( main.SummaryFileName, "w+" )
94 main.summaryFile.write( main.TEST + " at " + currentTime + "\n" )
95 main.summaryFile.close()
96
Jon Hall81d3d392015-04-24 14:40:35 -070097 #wiki file header
98 currentTime = str( main.STARTTIME.strftime("%d %b %Y %H:%M:%S") )
99 main.wikiFile = open( main.WikiFileName, "w+" )
Jon Hall79bec222015-04-30 16:23:30 -0700100 main.wikiFile.write( main.TEST + " at " + currentTime + "<p></p>\n" )
Jon Hall81d3d392015-04-24 14:40:35 -0700101 main.wikiFile.close()
102
adminbae64d82013-08-01 10:50:15 -0700103 def initlog(self,main):
104 '''
105 Initialise all the log handles.
106 '''
107 main._getTest()
Jon Hall81d3d392015-04-24 14:40:35 -0700108 main.STARTTIME = datetime.datetime.now()
adminbae64d82013-08-01 10:50:15 -0700109
110 currentTime = re.sub("-|\s|:|\.", "_", str(main.STARTTIME.strftime("%d %b %Y %H:%M:%S")))
111 if main.logdir:
112 main.logdir = main.logdir+ "/"+main.TEST + "_" + currentTime
113 else:
114 main.logdir = main.logs_path + main.TEST + "_" + currentTime
Jon Hall81d3d392015-04-24 14:40:35 -0700115
adminbae64d82013-08-01 10:50:15 -0700116 os.mkdir(main.logdir)
Jon Hall81d3d392015-04-24 14:40:35 -0700117
Jon Hallf9572352016-03-09 10:21:18 -0800118 main.LogFileName = "/home/admin/ONS16/Demo.log"
adminbae64d82013-08-01 10:50:15 -0700119 main.ReportFileName = main.logdir + "/" + main.TEST + "_" + str(currentTime) + ".rpt"
Jon Hall79bec222015-04-30 16:23:30 -0700120 main.WikiFileName = main.logdir + "/" + main.TEST + "Wiki.txt"
Jon Hallf9572352016-03-09 10:21:18 -0800121 #main.DemoCodeFileName = main.logdir + "/" + main.TEST + "-DemoCode.txt"
122 main.DemoCodeFileName = "/home/admin/ONS16/DemoCode.txt"
Jon Hall88de9ee2016-03-04 12:29:56 -0800123 main.DemoSummaryFileName = "/usr/local/apr/htdocs/ONS2016/testLog"
Jon Hall79bec222015-04-30 16:23:30 -0700124 main.SummaryFileName = main.logdir + "/" + main.TEST + "Summary.txt"
Jon Hall94fd0472014-12-08 11:52:42 -0800125 main.JenkinsCSV = main.logdir + "/" + main.TEST + ".csv"
Jon Hall25079782015-10-13 13:54:39 -0700126 main.TOTAL_TC_SUCCESS = 0
Jon Hallf9572352016-03-09 10:21:18 -0800127 demoFile = open(main.DemoCodeFileName,"w+")
128 demoFile.close()
129 logfile = open(main.LogFileName,"w+")
130 logfile.close()
Jon Hall81d3d392015-04-24 14:40:35 -0700131
adminbae64d82013-08-01 10:50:15 -0700132 #### Add log-level - Report
133 logging.addLevelName(9, "REPORT")
134 logging.addLevelName(7, "EXACT")
Jon Hall0bde9ba2015-03-19 11:32:57 -0700135 logging.addLevelName(11, "CASE")
136 logging.addLevelName(12, "STEP")
adminbae64d82013-08-01 10:50:15 -0700137 main.log = logging.getLogger(main.TEST)
Jon Hall81d3d392015-04-24 14:40:35 -0700138 def report(msg):
adminbae64d82013-08-01 10:50:15 -0700139 '''
140 Will append the report message to the logs.
141 '''
142 main.log._log(9,msg,"OpenFlowAutoMattion","OFAutoMation")
143 currentTime = datetime.datetime.now()
144 currentTime = currentTime.strftime("%d %b %Y %H:%M:%S")
145 newmsg = "\n[REPORT] " +"["+ str(currentTime)+"] "+msg
146 print newmsg
147 main.reportFile = open(main.ReportFileName,"a+")
148 main.reportFile.write(newmsg)
149 main.reportFile.close()
Jon Hall81d3d392015-04-24 14:40:35 -0700150
151 main.log.report = report
152
Jon Hall79bec222015-04-30 16:23:30 -0700153 def summary( msg ):
154 '''
155 Will append the message to the txt file for the summary.
156 '''
157 main.log._log(6,msg,"OpenFlowAutoMattion","OFAutoMation")
158 main.summaryFile = open(main.SummaryFileName,"a+")
159 main.summaryFile.write(msg+"\n")
160 main.summaryFile.close()
161
162 main.log.summary = summary
163
Jon Hall81d3d392015-04-24 14:40:35 -0700164 def wiki( msg ):
165 '''
166 Will append the message to the txt file for the wiki.
167 '''
168 main.log._log(6,msg,"OpenFlowAutoMattion","OFAutoMation")
169 main.wikiFile = open(main.WikiFileName,"a+")
170 main.wikiFile.write(msg+"\n")
171 main.wikiFile.close()
172
173 main.log.wiki = wiki
174
Jon Hallef822822016-02-19 10:36:47 -0800175 def demoCode( msg ):
176 '''
177 Will append the message to the txt file for the Demo.
178 '''
179 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
180 'blue': '\033[94m', 'green': '\033[92m',
181 'yellow': '\033[93m', 'red': '\033[91m',
182 'end': '\033[0m' }
183
184 main.demoCodeFile = open( main.DemoCodeFileName, "a+" )
185 parsedMsg = ''
186 wrapped = False
187 for line in msg.splitlines():
188 if wrapped:
189 parsedMsg += line
190 if ')' in line:
191 wrapped = False
192 parsedMsg += colors['end']
193 elif "main.case(" in line:
Jon Halld1baa9e2016-03-08 09:46:09 -0800194 parsedMsg += colors['blue'] + line + colors['end']
Jon Hallef822822016-02-19 10:36:47 -0800195 elif "main.step" in line:
Jon Halld1baa9e2016-03-08 09:46:09 -0800196 parsedMsg += colors['cyan'] + line + colors['end']
Jon Hallef822822016-02-19 10:36:47 -0800197 elif "utilities.assert_" in line and "(" in line:
Jon Hallf9572352016-03-09 10:21:18 -0800198 parsedMsg += colors['green'] + line
Jon Hallef822822016-02-19 10:36:47 -0800199 if ')' not in line:
200 wrapped = True
201 else:
202 parsedMsg += colors['end']
203 else:
204 parsedMsg += line
205 parsedMsg += '\n'
206 main.demoCodeFile.write( parsedMsg + "\n" )
207 main.demoCodeFile.close()
208
209 main.log.demo = demoCode
210
211 def demoSummary( msg, level=None ):
212 '''
213 Will append the message to the txt file for the Demo.
214 '''
215 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
216 'blue': '\033[94m', 'green': '\033[92m',
217 'yellow': '\033[93m', 'red': '\033[91m',
218 'end': '\033[0m' }
219
220 main.demoSummaryFile = open( main.DemoSummaryFileName, "a+" )
Jon Hall88de9ee2016-03-04 12:29:56 -0800221 #parsedMsg = msg[msg.find("DEMO:"):]
222 main.demoSummaryFile.write( msg + "\n" )
Jon Hallef822822016-02-19 10:36:47 -0800223 main.demoSummaryFile.close()
224
225 main.log.demoSummary = demoSummary
226
227
228
Jon Hall81d3d392015-04-24 14:40:35 -0700229 def exact(exmsg):
adminbae64d82013-08-01 10:50:15 -0700230 '''
231 Will append the raw formatted message to the logs
232 '''
233 main.log._log(7,exmsg,"OpenFlowAutoMattion","OFAutoMation")
234 main.reportFile = open(main.ReportFileName,"a+")
235 main.reportFile.write(exmsg)
236 main.reportFile.close()
237 logfile = open(main.LogFileName,"a")
238 logfile.write("\n"+ str(exmsg) +"\n")
239 logfile.close()
240 print exmsg
Jon Hall81d3d392015-04-24 14:40:35 -0700241
242 main.log.exact = exact
243
adminbae64d82013-08-01 10:50:15 -0700244 def case(msg):
245 '''
246 Format of the case type log defined here.
247 '''
248 main.log._log(9,msg,"OpenFlowAutoMattion","OFAutoMation")
249 currentTime = datetime.datetime.now()
250 newmsg = "["+str(currentTime)+"] " + "["+main.TEST+"] " + "[CASE] " +msg
251 logfile = open(main.LogFileName,"a")
252 logfile.write("\n"+ str(newmsg) +"\n")
253 logfile.close()
254 print newmsg
Jon Hall81d3d392015-04-24 14:40:35 -0700255
Jon Hall4ba53f02015-07-29 13:07:41 -0700256 main.log.case = case
Jon Hall81d3d392015-04-24 14:40:35 -0700257
258 def step(msg):
adminbae64d82013-08-01 10:50:15 -0700259 '''
260 Format of the step type log defined here.
261 '''
262 main.log._log(9,msg,"OpenFlowAutoMattion","OFAutoMation")
263 currentTime = datetime.datetime.now()
264 newmsg = "["+str(currentTime)+"] " + "["+main.TEST+"] " + "[STEP] " +msg
265 logfile = open(main.LogFileName,"a")
266 logfile.write("\n"+ str(newmsg) +"\n")
267 logfile.close()
268 print newmsg
Jon Hall81d3d392015-04-24 14:40:35 -0700269
270 main.log.step = step
271
adminbae64d82013-08-01 10:50:15 -0700272 main.LogFileHandler = logging.FileHandler(main.LogFileName)
273 self._printHeader(main)
274
275 ### initializing logging module and settig log level
276 main.log.setLevel(logging.INFO)
Jon Hall0bde9ba2015-03-19 11:32:57 -0700277 main.log.setLevel(logging.DEBUG) # Temporary
adminbae64d82013-08-01 10:50:15 -0700278 main.LogFileHandler.setLevel(logging.INFO)
Jon Hall81d3d392015-04-24 14:40:35 -0700279
adminbae64d82013-08-01 10:50:15 -0700280 # create console handler with a higher log level
281 main.ConsoleHandler = logging.StreamHandler()
282 main.ConsoleHandler.setLevel(logging.INFO)
Jon Hall0bde9ba2015-03-19 11:32:57 -0700283 main.ConsoleHandler.setLevel(logging.DEBUG) #Temporary
adminbae64d82013-08-01 10:50:15 -0700284 # create formatter and add it to the handlers
Jon Hall0bde9ba2015-03-19 11:32:57 -0700285 #formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
286 class MyFormatter( logging.Formatter ):
287 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
288 'blue': '\033[94m', 'green': '\033[92m',
289 'yellow': '\033[93m', 'red': '\033[91m',
290 'end': '\033[0m' }
291
292 FORMATS = {'DEFAULT': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'}
293 if COLORS: # NOTE:colors will only be loaded if command is run from one line
294 # IE: './cli.py run testname'
295 # This is to prevent issues with Jenkins parsing
296 # TODO: Make colors configurable
297 levels = { logging.ERROR : colors['red'] +
298 FORMATS['DEFAULT'] +
299 colors['end'],
300 logging.WARN : colors['yellow'] +
301 FORMATS['DEFAULT'] +
302 colors['end'],
303 logging.DEBUG : colors['purple'] +
304 FORMATS['DEFAULT'] +
305 colors['end'] }
306 FORMATS.update( levels )
307
308 def format( self, record ):
309 self._fmt = self.FORMATS.get( record.levelno,
310 self.FORMATS[ 'DEFAULT' ] )
311 return logging.Formatter.format( self, record )
312 formatter = MyFormatter()
adminbae64d82013-08-01 10:50:15 -0700313 main.ConsoleHandler.setFormatter(formatter)
314 main.LogFileHandler.setFormatter(formatter)
315
316 # add the handlers to logger
317 main.log.addHandler(main.ConsoleHandler)
318 main.log.addHandler(main.LogFileHandler)
Jon Hall81d3d392015-04-24 14:40:35 -0700319
adminbae64d82013-08-01 10:50:15 -0700320 def testSummary(self,main):
321 '''
322 testSummary will take care about the Summary of test.
323 '''
324
325 main.ENDTIME = datetime.datetime.now()
326 main.EXECTIME = main.ENDTIME - main.STARTTIME
327 if (main.TOTAL_TC_PASS == 0):
328 main.TOTAL_TC_SUCCESS = 0
329 else:
330 main.TOTAL_TC_SUCCESS = str((main.TOTAL_TC_PASS*100)/main.TOTAL_TC_RUN)
adminbae64d82013-08-01 10:50:15 -0700331 if (main.TOTAL_TC_RUN == 0) :
332 main.TOTAL_TC_EXECPERCENT = 0
333 else :
334 main.TOTAL_TC_EXECPERCENT = str((main.TOTAL_TC_RUN*100)/main.TOTAL_TC_PLANNED)
adminbae64d82013-08-01 10:50:15 -0700335 testResult = "\n\n"+"*" * 37+"\n" + "\tTest Execution Summary\n" + "\n"+"*" * 37+" \n"
336 testResult = testResult + "\n Test Start : " + str(main.STARTTIME.strftime("%d %b %Y %H:%M:%S"))
337 testResult = testResult + "\n Test End : " + str(main.ENDTIME.strftime("%d %b %Y %H:%M:%S"))
338 testResult = testResult + "\n Execution Time : " + str(main.EXECTIME)
339 testResult = testResult + "\n Total tests planned : " + str(main.TOTAL_TC_PLANNED)
340 testResult = testResult + "\n Total tests RUN : " + str(main.TOTAL_TC_RUN)
341 testResult = testResult + "\n Total Pass : " + str(main.TOTAL_TC_PASS)
342 testResult = testResult + "\n Total Fail : " + str(main.TOTAL_TC_FAIL)
343 testResult = testResult + "\n Total No Result : " + str(main.TOTAL_TC_NORESULT)
344 testResult = testResult + "\n Success Percentage : " + str(main.TOTAL_TC_SUCCESS) + "%"
345 testResult = testResult + "\n Execution Result : " + str(main.TOTAL_TC_EXECPERCENT) + "%"
Jon Hall81d3d392015-04-24 14:40:35 -0700346
adminbae64d82013-08-01 10:50:15 -0700347 #main.log.report(testResult)
348 main.testResult = testResult
349 main.log.exact(testResult)
Jon Hall94fd0472014-12-08 11:52:42 -0800350
Jon Hall368769f2014-11-19 15:43:35 -0800351 ##CSV output needed for Jenkin's plot plugin
352 #NOTE: the elements were orded based on the colors assigned to the data
353 logfile = open(main.JenkinsCSV ,"w")
354 logfile.write(",".join( ['Tests Failed', 'Tests Passed', 'Tests Planned'] ) + "\n")
Jon Hall94fd0472014-12-08 11:52:42 -0800355 logfile.write(",".join( [str(int(main.TOTAL_TC_FAIL)), str(int(main.TOTAL_TC_PASS)), str(int(main.TOTAL_TC_PLANNED))] ))
356 logfile.close()
357
adminbae64d82013-08-01 10:50:15 -0700358 def updateCaseResults(self,main):
359 '''
360 Update the case result based on the steps execution and asserting each step in the test-case
361 '''
362 case = str(main.CurrentTestCaseNumber)
Jon Hall79bec222015-04-30 16:23:30 -0700363 currentResult = main.testCaseResult.get(case, 2)
Jon Hall81d3d392015-04-24 14:40:35 -0700364
Jon Hall79bec222015-04-30 16:23:30 -0700365 if currentResult == 2:
adminbae64d82013-08-01 10:50:15 -0700366 main.TOTAL_TC_RUN = main.TOTAL_TC_RUN + 1
367 main.TOTAL_TC_NORESULT = main.TOTAL_TC_NORESULT + 1
368 main.log.exact("\n "+"*" * 29+"\n" + "\n Result: No Assertion Called \n"+"*" * 29+"\n")
Jon Hall79bec222015-04-30 16:23:30 -0700369 line = "Case "+case+": "+main.CurrentTestCase+" - No Result"
370 elif currentResult == 1:
adminbae64d82013-08-01 10:50:15 -0700371 main.TOTAL_TC_RUN = main.TOTAL_TC_RUN + 1
372 main.TOTAL_TC_PASS = main.TOTAL_TC_PASS + 1
373 main.log.exact("\n"+"*" * 29+"\n Result: Pass \n"+"*" * 29+"\n")
Jon Hall79bec222015-04-30 16:23:30 -0700374 line = "Case "+case+": "+main.CurrentTestCase+" - PASS"
375 elif currentResult == 0:
adminbae64d82013-08-01 10:50:15 -0700376 main.TOTAL_TC_RUN = main.TOTAL_TC_RUN + 1
377 main.TOTAL_TC_FAIL = main.TOTAL_TC_FAIL + 1
378 main.log.exact("\n"+"*" * 29+"\n Result: Failed \n"+"*" * 29+"\n")
Jon Hall79bec222015-04-30 16:23:30 -0700379 line = "Case "+case+": "+main.CurrentTestCase+" - FAIL"
380 else:
381 main.log.error( " Unknown result of case " + case +
382 ". Result was: " + currentResult )
383 line = "Case "+case+": "+main.CurrentTestCase+" - ERROR"
384 main.log.wiki( "<h3>" + line + "</h3>" )
385 main.log.summary( line )
Jon Hall81d3d392015-04-24 14:40:35 -0700386