blob: ed9b0bddf9e1ffe05971f1f9c5bcc311e0a6ed59 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#/usr/bin/env python
2'''
3Created on 07-Jan-2013
Jeremy Songsterae01bba2016-07-11 15:39:17 -07004Modified 2015 by ON.Lab
Jon Hall81d3d392015-04-24 14:40:35 -07005
Jeremy Songsterae01bba2016-07-11 15:39:17 -07006Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
7the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
8or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
adminbae64d82013-08-01 10:50:15 -07009
10 TestON is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 2 of the License, or
13 (at your option) any later version.
14
15 TestON is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
Jon Hall81d3d392015-04-24 14:40:35 -070021 along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070022
23
24'''
25
26import logging
27import datetime
28import re
29import os
30class Logger:
31 '''
32 Add continuous logs and reports of the test.
Jon Hall81d3d392015-04-24 14:40:35 -070033
adminbae64d82013-08-01 10:50:15 -070034 @author: Raghav Kashyap(raghavkashyap@paxterrasolutions.com)
35 '''
36 def _printHeader(self,main) :
37 '''
38 Log's header will be append to the Log file
39 '''
40 logmsg = "\n"+" " * 32+"+----------------+\n" +"-" * 30+" { Script And Files } "+"-" * 30+"\n" +" " * 32+"+----------------+\n";
41 logmsg = logmsg + "\n\tScript Log File : " + main.LogFileName + ""
42 logmsg = logmsg + "\n\tReport Log File : " + main.ReportFileName + ""
43 for component in main.componentDictionary.keys():
44 logmsg = logmsg + "\n\t"+component+" Session Log : " + main.logdir+"/"+component+".session" + ""
Jon Hall81d3d392015-04-24 14:40:35 -070045
adminbae64d82013-08-01 10:50:15 -070046 logmsg = logmsg + "\n\tTest Script :" + path + "Tests/" + main.TEST + ".py"+ ""
47 logmsg = logmsg + "\n\tTest Params : " + path + "Tests/" + main.TEST + ".params" + ""
Jon Hall368769f2014-11-19 15:43:35 -080048 logmsg = logmsg + "\n\tTopology : " + path + "Tests/" +main.TEST + ".topo" + ""
adminbae64d82013-08-01 10:50:15 -070049 logmsg = logmsg + "\n"+" " * 30+"+" +"-" * 18+"+" +"\n" +"-" * 27+" { Script Exec Params } "+"-" * 27 +"\n" +" " * 30 +"+"+"-" * 18 +"+\n";
50 values = "\n\t" + str(main.params)
51 values = re.sub(",", "\n\t", values)
52 values = re.sub("{", "\n\t", values)
53 values = re.sub("}", "\n\t", values)
54 logmsg = logmsg + values
adminbae64d82013-08-01 10:50:15 -070055 logmsg = logmsg + "\n\n"+" " * 31+"+---------------+\n" +"-" * 29+" { Components Used } " +"-" * 29+"\n"+" " * 31+"+---------------+\n"
56 component_list = []
57 component_list.append(None)
Jon Hall81d3d392015-04-24 14:40:35 -070058
adminbae64d82013-08-01 10:50:15 -070059 # Listing the components in the order of test_target component should be first.
60 if type(main.componentDictionary) == dict:
61 for key in main.componentDictionary.keys():
62 if main.test_target == key :
63 component_list[0] = key+"-Test Target"
64 else :
65 component_list.append(key)
Jon Hall81d3d392015-04-24 14:40:35 -070066
adminbae64d82013-08-01 10:50:15 -070067 for index in range(len(component_list)) :
68 if index==0:
69 if component_list[index]:
70 logmsg+="\t"+component_list[index]+"\n"
71 elif index > 0 :
72 logmsg+="\t"+str(component_list[index])+"\n"
Jon Hall81d3d392015-04-24 14:40:35 -070073
adminbae64d82013-08-01 10:50:15 -070074 logmsg = logmsg + "\n\n"+" " * 30+"+--------+\n" +"-" * 28+" { Topology } "+"-" * 28 +"\n" +" " * 30+"+--------+\n"
75 values = "\n\t" + str(main.topology['COMPONENT'])
76 values = re.sub(",", "\n\t", values)
77 values = re.sub("{", "\n\t", values)
78 values = re.sub("}", "\n\t", values)
79 logmsg = logmsg + values
adminbae64d82013-08-01 10:50:15 -070080 logmsg = logmsg + "\n"+"-" * 60+"\n"
Jon Hall81d3d392015-04-24 14:40:35 -070081
adminbae64d82013-08-01 10:50:15 -070082 # enter into log file all headers
83 logfile = open(main.LogFileName,"w+")
84 logfile.write (logmsg)
85 print logmsg
86 main.logHeader = logmsg
adminbae64d82013-08-01 10:50:15 -070087 logfile.close()
Jon Hall81d3d392015-04-24 14:40:35 -070088
adminbae64d82013-08-01 10:50:15 -070089 #enter into report file all headers
90 main.reportFile = open(main.ReportFileName,"w+")
91 main.reportFile.write(logmsg)
92 main.reportFile.close()
Jon Hall81d3d392015-04-24 14:40:35 -070093
Jon Hall79bec222015-04-30 16:23:30 -070094 #Sumamry file header
95 currentTime = str( main.STARTTIME.strftime("%d %b %Y %H:%M:%S") )
96 main.summaryFile = open( main.SummaryFileName, "w+" )
97 main.summaryFile.write( main.TEST + " at " + currentTime + "\n" )
98 main.summaryFile.close()
99
Jon Hall81d3d392015-04-24 14:40:35 -0700100 #wiki file header
101 currentTime = str( main.STARTTIME.strftime("%d %b %Y %H:%M:%S") )
102 main.wikiFile = open( main.WikiFileName, "w+" )
Jon Hall79bec222015-04-30 16:23:30 -0700103 main.wikiFile.write( main.TEST + " at " + currentTime + "<p></p>\n" )
Jon Hall81d3d392015-04-24 14:40:35 -0700104 main.wikiFile.close()
105
adminbae64d82013-08-01 10:50:15 -0700106 def initlog(self,main):
107 '''
108 Initialise all the log handles.
109 '''
110 main._getTest()
Jon Hall81d3d392015-04-24 14:40:35 -0700111 main.STARTTIME = datetime.datetime.now()
adminbae64d82013-08-01 10:50:15 -0700112
113 currentTime = re.sub("-|\s|:|\.", "_", str(main.STARTTIME.strftime("%d %b %Y %H:%M:%S")))
114 if main.logdir:
115 main.logdir = main.logdir+ "/"+main.TEST + "_" + currentTime
116 else:
117 main.logdir = main.logs_path + main.TEST + "_" + currentTime
Jon Hall81d3d392015-04-24 14:40:35 -0700118
adminbae64d82013-08-01 10:50:15 -0700119 os.mkdir(main.logdir)
Jon Hall81d3d392015-04-24 14:40:35 -0700120
adminbae64d82013-08-01 10:50:15 -0700121 main.LogFileName = main.logdir + "/" + main.TEST + "_" +str(currentTime) + ".log"
122 main.ReportFileName = main.logdir + "/" + main.TEST + "_" + str(currentTime) + ".rpt"
Jon Hall79bec222015-04-30 16:23:30 -0700123 main.WikiFileName = main.logdir + "/" + main.TEST + "Wiki.txt"
124 main.SummaryFileName = main.logdir + "/" + main.TEST + "Summary.txt"
Jon Hall94fd0472014-12-08 11:52:42 -0800125 main.JenkinsCSV = main.logdir + "/" + main.TEST + ".csv"
Devin Lim90803a82017-08-29 13:41:44 -0700126 main.resultFile = main.logdir + "/" + main.TEST + "Result.txt"
127
Jon Hall25079782015-10-13 13:54:39 -0700128 main.TOTAL_TC_SUCCESS = 0
Jon Hall81d3d392015-04-24 14:40:35 -0700129
adminbae64d82013-08-01 10:50:15 -0700130 #### Add log-level - Report
131 logging.addLevelName(9, "REPORT")
132 logging.addLevelName(7, "EXACT")
Jon Hall0bde9ba2015-03-19 11:32:57 -0700133 logging.addLevelName(11, "CASE")
134 logging.addLevelName(12, "STEP")
adminbae64d82013-08-01 10:50:15 -0700135 main.log = logging.getLogger(main.TEST)
Jon Hall81d3d392015-04-24 14:40:35 -0700136 def report(msg):
adminbae64d82013-08-01 10:50:15 -0700137 '''
138 Will append the report message to the logs.
139 '''
140 main.log._log(9,msg,"OpenFlowAutoMattion","OFAutoMation")
141 currentTime = datetime.datetime.now()
142 currentTime = currentTime.strftime("%d %b %Y %H:%M:%S")
143 newmsg = "\n[REPORT] " +"["+ str(currentTime)+"] "+msg
144 print newmsg
145 main.reportFile = open(main.ReportFileName,"a+")
146 main.reportFile.write(newmsg)
147 main.reportFile.close()
Jon Hall81d3d392015-04-24 14:40:35 -0700148
149 main.log.report = report
150
Jon Hall79bec222015-04-30 16:23:30 -0700151 def summary( msg ):
152 '''
153 Will append the message to the txt file for the summary.
154 '''
155 main.log._log(6,msg,"OpenFlowAutoMattion","OFAutoMation")
156 main.summaryFile = open(main.SummaryFileName,"a+")
157 main.summaryFile.write(msg+"\n")
158 main.summaryFile.close()
159
160 main.log.summary = summary
161
Jon Hall81d3d392015-04-24 14:40:35 -0700162 def wiki( msg ):
163 '''
164 Will append the message to the txt file for the wiki.
165 '''
166 main.log._log(6,msg,"OpenFlowAutoMattion","OFAutoMation")
167 main.wikiFile = open(main.WikiFileName,"a+")
168 main.wikiFile.write(msg+"\n")
169 main.wikiFile.close()
170
171 main.log.wiki = wiki
172
173 def exact(exmsg):
adminbae64d82013-08-01 10:50:15 -0700174 '''
175 Will append the raw formatted message to the logs
176 '''
177 main.log._log(7,exmsg,"OpenFlowAutoMattion","OFAutoMation")
178 main.reportFile = open(main.ReportFileName,"a+")
179 main.reportFile.write(exmsg)
180 main.reportFile.close()
181 logfile = open(main.LogFileName,"a")
182 logfile.write("\n"+ str(exmsg) +"\n")
183 logfile.close()
184 print exmsg
Jon Hall81d3d392015-04-24 14:40:35 -0700185
186 main.log.exact = exact
187
adminbae64d82013-08-01 10:50:15 -0700188 def case(msg):
189 '''
190 Format of the case type log defined here.
191 '''
192 main.log._log(9,msg,"OpenFlowAutoMattion","OFAutoMation")
193 currentTime = datetime.datetime.now()
194 newmsg = "["+str(currentTime)+"] " + "["+main.TEST+"] " + "[CASE] " +msg
195 logfile = open(main.LogFileName,"a")
196 logfile.write("\n"+ str(newmsg) +"\n")
197 logfile.close()
198 print newmsg
Jon Hall81d3d392015-04-24 14:40:35 -0700199
Jon Hall4ba53f02015-07-29 13:07:41 -0700200 main.log.case = case
Jon Hall81d3d392015-04-24 14:40:35 -0700201
202 def step(msg):
adminbae64d82013-08-01 10:50:15 -0700203 '''
204 Format of the step type log defined here.
205 '''
206 main.log._log(9,msg,"OpenFlowAutoMattion","OFAutoMation")
207 currentTime = datetime.datetime.now()
208 newmsg = "["+str(currentTime)+"] " + "["+main.TEST+"] " + "[STEP] " +msg
209 logfile = open(main.LogFileName,"a")
210 logfile.write("\n"+ str(newmsg) +"\n")
211 logfile.close()
212 print newmsg
Jon Hall81d3d392015-04-24 14:40:35 -0700213
214 main.log.step = step
215
adminbae64d82013-08-01 10:50:15 -0700216 main.LogFileHandler = logging.FileHandler(main.LogFileName)
217 self._printHeader(main)
218
219 ### initializing logging module and settig log level
220 main.log.setLevel(logging.INFO)
Jon Hall0bde9ba2015-03-19 11:32:57 -0700221 main.log.setLevel(logging.DEBUG) # Temporary
adminbae64d82013-08-01 10:50:15 -0700222 main.LogFileHandler.setLevel(logging.INFO)
Jon Hall81d3d392015-04-24 14:40:35 -0700223
adminbae64d82013-08-01 10:50:15 -0700224 # create console handler with a higher log level
225 main.ConsoleHandler = logging.StreamHandler()
226 main.ConsoleHandler.setLevel(logging.INFO)
Jon Hall0bde9ba2015-03-19 11:32:57 -0700227 main.ConsoleHandler.setLevel(logging.DEBUG) #Temporary
adminbae64d82013-08-01 10:50:15 -0700228 # create formatter and add it to the handlers
Jon Hall0bde9ba2015-03-19 11:32:57 -0700229 #formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
230 class MyFormatter( logging.Formatter ):
231 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
232 'blue': '\033[94m', 'green': '\033[92m',
233 'yellow': '\033[93m', 'red': '\033[91m',
234 'end': '\033[0m' }
235
236 FORMATS = {'DEFAULT': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'}
237 if COLORS: # NOTE:colors will only be loaded if command is run from one line
238 # IE: './cli.py run testname'
239 # This is to prevent issues with Jenkins parsing
240 # TODO: Make colors configurable
241 levels = { logging.ERROR : colors['red'] +
242 FORMATS['DEFAULT'] +
243 colors['end'],
244 logging.WARN : colors['yellow'] +
245 FORMATS['DEFAULT'] +
246 colors['end'],
247 logging.DEBUG : colors['purple'] +
248 FORMATS['DEFAULT'] +
249 colors['end'] }
250 FORMATS.update( levels )
251
252 def format( self, record ):
253 self._fmt = self.FORMATS.get( record.levelno,
254 self.FORMATS[ 'DEFAULT' ] )
255 return logging.Formatter.format( self, record )
256 formatter = MyFormatter()
adminbae64d82013-08-01 10:50:15 -0700257 main.ConsoleHandler.setFormatter(formatter)
258 main.LogFileHandler.setFormatter(formatter)
259
260 # add the handlers to logger
261 main.log.addHandler(main.ConsoleHandler)
262 main.log.addHandler(main.LogFileHandler)
Jon Hall81d3d392015-04-24 14:40:35 -0700263
adminbae64d82013-08-01 10:50:15 -0700264 def testSummary(self,main):
265 '''
266 testSummary will take care about the Summary of test.
267 '''
268
269 main.ENDTIME = datetime.datetime.now()
270 main.EXECTIME = main.ENDTIME - main.STARTTIME
271 if (main.TOTAL_TC_PASS == 0):
272 main.TOTAL_TC_SUCCESS = 0
273 else:
274 main.TOTAL_TC_SUCCESS = str((main.TOTAL_TC_PASS*100)/main.TOTAL_TC_RUN)
adminbae64d82013-08-01 10:50:15 -0700275 if (main.TOTAL_TC_RUN == 0) :
276 main.TOTAL_TC_EXECPERCENT = 0
277 else :
278 main.TOTAL_TC_EXECPERCENT = str((main.TOTAL_TC_RUN*100)/main.TOTAL_TC_PLANNED)
adminbae64d82013-08-01 10:50:15 -0700279 testResult = "\n\n"+"*" * 37+"\n" + "\tTest Execution Summary\n" + "\n"+"*" * 37+" \n"
280 testResult = testResult + "\n Test Start : " + str(main.STARTTIME.strftime("%d %b %Y %H:%M:%S"))
281 testResult = testResult + "\n Test End : " + str(main.ENDTIME.strftime("%d %b %Y %H:%M:%S"))
282 testResult = testResult + "\n Execution Time : " + str(main.EXECTIME)
283 testResult = testResult + "\n Total tests planned : " + str(main.TOTAL_TC_PLANNED)
284 testResult = testResult + "\n Total tests RUN : " + str(main.TOTAL_TC_RUN)
285 testResult = testResult + "\n Total Pass : " + str(main.TOTAL_TC_PASS)
286 testResult = testResult + "\n Total Fail : " + str(main.TOTAL_TC_FAIL)
287 testResult = testResult + "\n Total No Result : " + str(main.TOTAL_TC_NORESULT)
288 testResult = testResult + "\n Success Percentage : " + str(main.TOTAL_TC_SUCCESS) + "%"
Devin Limec989792017-08-15 15:57:55 -0700289 testResult = testResult + "\n Execution Result : " + str(main.TOTAL_TC_EXECPERCENT) + "%\n"
290 if main.failedCase:
291 testResult = testResult + "\n Case Failed : " + str( main.failedCase )
292 if main.noResultCase:
293 testResult = testResult + "\n Case NoResult : " + str( main.noResultCase )
294 testResult = testResult + "\n Case Executed : " + str( main.executedCase )
295 testResult = testResult + "\n Case Not Executed : " + str( main.leftCase )
adminbae64d82013-08-01 10:50:15 -0700296 #main.log.report(testResult)
297 main.testResult = testResult
298 main.log.exact(testResult)
Jon Hall94fd0472014-12-08 11:52:42 -0800299
Jon Hall368769f2014-11-19 15:43:35 -0800300 ##CSV output needed for Jenkin's plot plugin
301 #NOTE: the elements were orded based on the colors assigned to the data
302 logfile = open(main.JenkinsCSV ,"w")
303 logfile.write(",".join( ['Tests Failed', 'Tests Passed', 'Tests Planned'] ) + "\n")
Devin Lim90803a82017-08-29 13:41:44 -0700304 logfile.write(",".join( [str(int(main.TOTAL_TC_FAIL)), str(int(main.TOTAL_TC_PASS)), str(int(main.TOTAL_TC_PLANNED))] ) + "\n")
Jon Hall94fd0472014-12-08 11:52:42 -0800305 logfile.close()
306
Devin Lim90803a82017-08-29 13:41:44 -0700307 executedStatus = open(main.resultFile, "w")
308 if main.TOTAL_TC_FAIL == 0 and main.TOTAL_TC_NORESULT + main.TOTAL_TC_PASS == main.TOTAL_TC_PLANNED:
309 executedStatus.write("1\n")
310 else:
311 executedStatus.write("0\n")
312 executedStatus.close()
313
adminbae64d82013-08-01 10:50:15 -0700314 def updateCaseResults(self,main):
315 '''
316 Update the case result based on the steps execution and asserting each step in the test-case
317 '''
318 case = str(main.CurrentTestCaseNumber)
Jon Hall79bec222015-04-30 16:23:30 -0700319 currentResult = main.testCaseResult.get(case, 2)
Jon Hall81d3d392015-04-24 14:40:35 -0700320
Jon Hall79bec222015-04-30 16:23:30 -0700321 if currentResult == 2:
adminbae64d82013-08-01 10:50:15 -0700322 main.TOTAL_TC_RUN = main.TOTAL_TC_RUN + 1
323 main.TOTAL_TC_NORESULT = main.TOTAL_TC_NORESULT + 1
324 main.log.exact("\n "+"*" * 29+"\n" + "\n Result: No Assertion Called \n"+"*" * 29+"\n")
Jon Hall79bec222015-04-30 16:23:30 -0700325 line = "Case "+case+": "+main.CurrentTestCase+" - No Result"
326 elif currentResult == 1:
adminbae64d82013-08-01 10:50:15 -0700327 main.TOTAL_TC_RUN = main.TOTAL_TC_RUN + 1
328 main.TOTAL_TC_PASS = main.TOTAL_TC_PASS + 1
329 main.log.exact("\n"+"*" * 29+"\n Result: Pass \n"+"*" * 29+"\n")
Jon Hall79bec222015-04-30 16:23:30 -0700330 line = "Case "+case+": "+main.CurrentTestCase+" - PASS"
331 elif currentResult == 0:
adminbae64d82013-08-01 10:50:15 -0700332 main.TOTAL_TC_RUN = main.TOTAL_TC_RUN + 1
333 main.TOTAL_TC_FAIL = main.TOTAL_TC_FAIL + 1
334 main.log.exact("\n"+"*" * 29+"\n Result: Failed \n"+"*" * 29+"\n")
Jon Hall79bec222015-04-30 16:23:30 -0700335 line = "Case "+case+": "+main.CurrentTestCase+" - FAIL"
336 else:
337 main.log.error( " Unknown result of case " + case +
338 ". Result was: " + currentResult )
339 line = "Case "+case+": "+main.CurrentTestCase+" - ERROR"
340 main.log.wiki( "<h3>" + line + "</h3>" )
341 main.log.summary( line )
Jon Hall81d3d392015-04-24 14:40:35 -0700342