Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(218)

Side by Side Diff: client/tests/kvm/html_report.py

Issue 6246035: Merge remote branch 'cros/upstream' into master (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/autotest.git@master
Patch Set: patch Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 """ 2 """
3 Script used to parse the test results and generate an HTML report. 3 Script used to parse the test results and generate an HTML report.
4 4
5 @copyright: (c)2005-2007 Matt Kruse (javascripttoolbox.com) 5 @copyright: (c)2005-2007 Matt Kruse (javascripttoolbox.com)
6 @copyright: Red Hat 2008-2009 6 @copyright: Red Hat 2008-2009
7 @author: Dror Russo (drusso@redhat.com) 7 @author: Dror Russo (drusso@redhat.com)
8 """ 8 """
9 9
10 import os, sys, re, getopt, time, datetime, commands 10 import os, sys, re, getopt, time, datetime, commands
11 import common 11 import common
12 12
13 13
14 format_css=""" 14 format_css = """
15 html,body { 15 html,body {
16 padding:0; 16 padding:0;
17 color:#222; 17 color:#222;
18 background:#FFFFFF; 18 background:#FFFFFF;
19 } 19 }
20 20
21 body { 21 body {
22 padding:0px; 22 padding:0px;
23 font:76%/150% "Lucida Grande", "Lucida Sans Unicode", Lucida, Verdana, Genev a, Arial, Helvetica, sans-serif; 23 font:76%/150% "Lucida Grande", "Lucida Sans Unicode", Lucida, Verdana, Genev a, Arial, Helvetica, sans-serif;
24 } 24 }
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 173
174 /* Format menu items differently depending on what level of the tree the y are in */ 174 /* Format menu items differently depending on what level of the tree the y are in */
175 /* Uncomment this if you want your fonts to decrease in size the deeper they are in the tree */ 175 /* Uncomment this if you want your fonts to decrease in size the deeper they are in the tree */
176 /* 176 /*
177 ul.mktree li ul li { font-size: 90% } 177 ul.mktree li ul li { font-size: 90% }
178 */ 178 */
179 } 179 }
180 """ 180 """
181 181
182 182
183 table_js=""" 183 table_js = """
184 /** 184 /**
185 * Copyright (c)2005-2007 Matt Kruse (javascripttoolbox.com) 185 * Copyright (c)2005-2007 Matt Kruse (javascripttoolbox.com)
186 * 186 *
187 * Dual licensed under the MIT and GPL licenses. 187 * Dual licensed under the MIT and GPL licenses.
188 * This basically means you can use this code however you want for 188 * This basically means you can use this code however you want for
189 * free, but don't claim to have written it yourself! 189 * free, but don't claim to have written it yourself!
190 * Donations always accepted: http://www.JavascriptToolbox.com/donate/ 190 * Donations always accepted: http://www.JavascriptToolbox.com/donate/
191 * 191 *
192 * Please do not link to the .js files on javascripttoolbox.com from 192 * Please do not link to the .js files on javascripttoolbox.com from
193 * your site. Copy the files locally to your server instead. 193 * your site. Copy the files locally to your server instead.
(...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 } 1373 }
1374 } 1374 }
1375 """ 1375 """
1376 1376
1377 1377
1378 ################################################################# 1378 #################################################################
1379 ## This script gets kvm autotest results directory path as an ## 1379 ## This script gets kvm autotest results directory path as an ##
1380 ## input and create a single html formatted result page. ## 1380 ## input and create a single html formatted result page. ##
1381 ################################################################# 1381 #################################################################
1382 1382
1383 stimelist=[] 1383 stimelist = []
1384 1384
1385 1385
1386 def make_html_file(metadata, results, tag, host, output_file_name, dirname): 1386 def make_html_file(metadata, results, tag, host, output_file_name, dirname):
1387 html_prefix=""" 1387 html_prefix = """
1388 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/st rict.dtd"> 1388 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/st rict.dtd">
1389 <html> 1389 <html>
1390 <head> 1390 <head>
1391 <title>KVM Autotest Results</title> 1391 <title>KVM Autotest Results</title>
1392 <style type="text/css"> 1392 <style type="text/css">
1393 %s 1393 %s
1394 </style> 1394 </style>
1395 <script type="text/javascript"> 1395 <script type="text/javascript">
1396 %s 1396 %s
1397 %s 1397 %s
1398 function popup(tag,text) { 1398 function popup(tag,text) {
1399 var w = window.open('', tag, 'toolbar=no,location=no,directories=no,status=no,me nubar=no,scrollbars=yes,resizable=yes, copyhistory=no,width=600,height=300,top=2 0,left=100'); 1399 var w = window.open('', tag, 'toolbar=no,location=no,directories=no,status=no,me nubar=no,scrollbars=yes,resizable=yes, copyhistory=no,width=600,height=300,top=2 0,left=100');
1400 w.document.open("text/html", "replace"); 1400 w.document.open("text/html", "replace");
1401 w.document.write(text); 1401 w.document.write(text);
1402 w.document.close(); 1402 w.document.close();
1403 return true; 1403 return true;
1404 } 1404 }
1405 </script> 1405 </script>
1406 </head> 1406 </head>
1407 <body> 1407 <body>
1408 """%(format_css, table_js, maketree_js) 1408 """ % (format_css, table_js, maketree_js)
1409 1409
1410 1410
1411 if output_file_name: 1411 if output_file_name:
1412 output = open(output_file_name, "w") 1412 output = open(output_file_name, "w")
1413 else: #if no output file defined, print html file to console 1413 else: #if no output file defined, print html file to console
1414 output = sys.stdout 1414 output = sys.stdout
1415 # create html page 1415 # create html page
1416 print >> output, html_prefix 1416 print >> output, html_prefix
1417 print >> output, '<h2 id=\"page_title\">KVM Autotest Execution Report</h2>' 1417 print >> output, '<h2 id=\"page_title\">KVM Autotest Execution Report</h2>'
1418 1418
1419 # formating date and time to print 1419 # formating date and time to print
1420 t = datetime.datetime.now() 1420 t = datetime.datetime.now()
1421 1421
1422 epoch_sec = time.mktime(t.timetuple()) 1422 epoch_sec = time.mktime(t.timetuple())
1423 now = datetime.datetime.fromtimestamp(epoch_sec) 1423 now = datetime.datetime.fromtimestamp(epoch_sec)
1424 1424
1425 # basic statistics 1425 # basic statistics
1426 total_executed = 0 1426 total_executed = 0
1427 total_failed = 0 1427 total_failed = 0
1428 total_passed = 0 1428 total_passed = 0
1429 for res in results: 1429 for res in results:
1430 total_executed+=1 1430 total_executed += 1
1431 if res['status'] == 'GOOD': 1431 if res['status'] == 'GOOD':
1432 total_passed+=1 1432 total_passed += 1
1433 else: 1433 else:
1434 total_failed+=1 1434 total_failed += 1
1435 stat_str = 'No test cases executed' 1435 stat_str = 'No test cases executed'
1436 if total_executed>0: 1436 if total_executed > 0:
1437 failed_perct = int(float(total_failed)/float(total_executed)*100) 1437 failed_perct = int(float(total_failed)/float(total_executed)*100)
1438 stat_str = ('From %d tests executed, %d have passed (%d%% failures)' % 1438 stat_str = ('From %d tests executed, %d have passed (%d%% failures)' %
1439 (total_executed, total_passed, failed_perct)) 1439 (total_executed, total_passed, failed_perct))
1440 1440
1441 kvm_ver_str = metadata['kvmver'] 1441 kvm_ver_str = metadata['kvmver']
1442 1442
1443 print >> output, '<table class="stats2">' 1443 print >> output, '<table class="stats2">'
1444 print >> output, '<tr><td>HOST</td><td>:</td><td>%s</td></tr>' % host 1444 print >> output, '<tr><td>HOST</td><td>:</td><td>%s</td></tr>' % host
1445 print >> output, '<tr><td>RESULTS DIR</td><td>:</td><td>%s</td></tr>' % tag 1445 print >> output, '<tr><td>RESULTS DIR</td><td>:</td><td>%s</td></tr>' % tag
1446 print >> output, '<tr><td>DATE</td><td>:</td><td>%s</td></tr>' % now.ctime() 1446 print >> output, '<tr><td>DATE</td><td>:</td><td>%s</td></tr>' % now.ctime()
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1479 elif res['status'] == 'ERROR': 1479 elif res['status'] == 'ERROR':
1480 print >> output, '<td align=\"left\"><b><font color="red">ERROR!</fo nt></b></td>' 1480 print >> output, '<td align=\"left\"><b><font color="red">ERROR!</fo nt></b></td>'
1481 else: 1481 else:
1482 print >> output, '<td align=\"left\">%s</td>' % res['status'] 1482 print >> output, '<td align=\"left\">%s</td>' % res['status']
1483 # print exec time (seconds) 1483 # print exec time (seconds)
1484 print >> output, '<td align="left">%s</td>' % res['exec_time_sec'] 1484 print >> output, '<td align="left">%s</td>' % res['exec_time_sec']
1485 # print log only if test failed.. 1485 # print log only if test failed..
1486 if res['log']: 1486 if res['log']:
1487 #chop all '\n' from log text (to prevent html errors) 1487 #chop all '\n' from log text (to prevent html errors)
1488 rx1 = re.compile('(\s+)') 1488 rx1 = re.compile('(\s+)')
1489 log_text = rx1.sub(' ',res['log']) 1489 log_text = rx1.sub(' ', res['log'])
1490 1490
1491 # allow only a-zA-Z0-9_ in html title name 1491 # allow only a-zA-Z0-9_ in html title name
1492 # (due to bug in MS-explorer) 1492 # (due to bug in MS-explorer)
1493 rx2 = re.compile('([^a-zA-Z_0-9])') 1493 rx2 = re.compile('([^a-zA-Z_0-9])')
1494 updated_tag = rx2.sub('_',res['title']) 1494 updated_tag = rx2.sub('_', res['title'])
1495 1495
1496 html_body_text = '<html><head><title>%s</title></head><body>%s</body ></html>'%(str(updated_tag),log_text) 1496 html_body_text = '<html><head><title>%s</title></head><body>%s</body ></html>' % (str(updated_tag), log_text)
1497 print >> output, '<td align=\"left\"><A HREF=\"#\" onClick=\"popup(\ '%s\',\'%s\')\">Info</A></td>'%(str(updated_tag),str(html_body_text)) 1497 print >> output, '<td align=\"left\"><A HREF=\"#\" onClick=\"popup(\ '%s\',\'%s\')\">Info</A></td>' % (str(updated_tag), str(html_body_text))
1498 else: 1498 else:
1499 print >> output, '<td align=\"left\"></td>' 1499 print >> output, '<td align=\"left\"></td>'
1500 # print execution time 1500 # print execution time
1501 print >> output, '<td align="left"><A HREF=\"%s\">Debug</A></td>' % os.p ath.join(dirname, res['title'], "debug") 1501 print >> output, '<td align="left"><A HREF=\"%s\">Debug</A></td>' % os.p ath.join(dirname, res['title'], "debug")
1502 1502
1503 print >> output, '</tr>' 1503 print >> output, '</tr>'
1504 print >> output, "</tbody></table>" 1504 print >> output, "</tbody></table>"
1505 1505
1506 1506
1507 print >> output, '<h2 id=\"page_sub_title\">Host Info</h2>' 1507 print >> output, '<h2 id=\"page_sub_title\">Host Info</h2>'
1508 print >> output, '<h2 id=\"comment\">click on each item to expend/collapse</ h2>' 1508 print >> output, '<h2 id=\"comment\">click on each item to expend/collapse</ h2>'
1509 ## Meta list comes here.. 1509 ## Meta list comes here..
1510 print >> output, '<p>' 1510 print >> output, '<p>'
1511 print >> output, '<A href="#" class="button" onClick="expandTree(\'meta_tree \');return false;">Expand All</A>' 1511 print >> output, '<A href="#" class="button" onClick="expandTree(\'meta_tree \');return false;">Expand All</A>'
1512 print >> output, '&nbsp;&nbsp;&nbsp' 1512 print >> output, '&nbsp;&nbsp;&nbsp'
1513 print >> output, '<A class="button" href="#" onClick="collapseTree(\'meta_tr ee\'); return false;">Collapse All</A>' 1513 print >> output, '<A class="button" href="#" onClick="collapseTree(\'meta_tr ee\'); return false;">Collapse All</A>'
1514 print >> output, '</p>' 1514 print >> output, '</p>'
1515 1515
1516 print >> output, '<ul class="mktree" id="meta_tree">' 1516 print >> output, '<ul class="mktree" id="meta_tree">'
1517 counter=0 1517 counter = 0
1518 keys = metadata.keys() 1518 keys = metadata.keys()
1519 keys.sort() 1519 keys.sort()
1520 for key in keys: 1520 for key in keys:
1521 val = metadata[key] 1521 val = metadata[key]
1522 print >> output, '<li id=\"meta_headline\">%s' % key 1522 print >> output, '<li id=\"meta_headline\">%s' % key
1523 print >> output, '<ul><table class="meta_table"><tr><td align="left">%s< /td></tr></table></ul></li>' % val 1523 print >> output, '<ul><table class="meta_table"><tr><td align="left">%s< /td></tr></table></ul></li>' % val
1524 print >> output, '</ul>' 1524 print >> output, '</ul>'
1525 1525
1526 print >> output, "</body></html>" 1526 print >> output, "</body></html>"
1527 if output_file_name: 1527 if output_file_name:
1528 output.close() 1528 output.close()
1529 1529
1530 1530
1531 def parse_result(dirname,line): 1531 def parse_result(dirname, line):
1532 parts = line.split() 1532 parts = line.split()
1533 if len(parts) < 4: 1533 if len(parts) < 4:
1534 return None 1534 return None
1535 global stimelist 1535 global stimelist
1536 if parts[0] == 'START': 1536 if parts[0] == 'START':
1537 pair = parts[3].split('=') 1537 pair = parts[3].split('=')
1538 stime = int(pair[1]) 1538 stime = int(pair[1])
1539 stimelist.append(stime) 1539 stimelist.append(stime)
1540 1540
1541 elif (parts[0] == 'END'): 1541 elif (parts[0] == 'END'):
(...skipping 11 matching lines...) Expand all
1553 result['exec_time_sec'] = 'na' 1553 result['exec_time_sec'] = 'na'
1554 tag = parts[3] 1554 tag = parts[3]
1555 1555
1556 # assign actual values 1556 # assign actual values
1557 rx = re.compile('^(\w+)\.(.*)$') 1557 rx = re.compile('^(\w+)\.(.*)$')
1558 m1 = rx.findall(parts[3]) 1558 m1 = rx.findall(parts[3])
1559 result['testcase'] = m1[0][1] 1559 result['testcase'] = m1[0][1]
1560 result['title'] = str(tag) 1560 result['title'] = str(tag)
1561 result['status'] = parts[1] 1561 result['status'] = parts[1]
1562 if result['status'] != 'GOOD': 1562 if result['status'] != 'GOOD':
1563 result['log'] = get_exec_log(dirname,tag) 1563 result['log'] = get_exec_log(dirname, tag)
1564 if len(stimelist)>0: 1564 if len(stimelist)>0:
1565 pair = parts[4].split('=') 1565 pair = parts[4].split('=')
1566 etime = int(pair[1]) 1566 etime = int(pair[1])
1567 stime = stimelist.pop() 1567 stime = stimelist.pop()
1568 total_exec_time_sec = etime - stime 1568 total_exec_time_sec = etime - stime
1569 result['exec_time_sec'] = total_exec_time_sec 1569 result['exec_time_sec'] = total_exec_time_sec
1570 return result 1570 return result
1571 return None 1571 return None
1572 1572
1573 1573
1574 def get_exec_log(resdir, tag): 1574 def get_exec_log(resdir, tag):
1575 stdout_file = os.path.join(resdir,tag) + '/debug/stdout' 1575 stdout_file = os.path.join(resdir, tag) + '/debug/stdout'
1576 stderr_file = os.path.join(resdir,tag) + '/debug/stderr' 1576 stderr_file = os.path.join(resdir, tag) + '/debug/stderr'
1577 status_file = os.path.join(resdir,tag) + '/status' 1577 status_file = os.path.join(resdir, tag) + '/status'
1578 dmesg_file = os.path.join(resdir,tag) + '/sysinfo/dmesg' 1578 dmesg_file = os.path.join(resdir, tag) + '/sysinfo/dmesg'
1579 log = '' 1579 log = ''
1580 log += '<br><b>STDERR:</b><br>' 1580 log += '<br><b>STDERR:</b><br>'
1581 log += get_info_file(stderr_file) 1581 log += get_info_file(stderr_file)
1582 log += '<br><b>STDOUT:</b><br>' 1582 log += '<br><b>STDOUT:</b><br>'
1583 log += get_info_file(stdout_file) 1583 log += get_info_file(stdout_file)
1584 log += '<br><b>STATUS:</b><br>' 1584 log += '<br><b>STATUS:</b><br>'
1585 log += get_info_file(status_file) 1585 log += get_info_file(status_file)
1586 log += '<br><b>DMESG:</b><br>' 1586 log += '<br><b>DMESG:</b><br>'
1587 log += get_info_file(dmesg_file) 1587 log += get_info_file(dmesg_file)
1588 return log 1588 return log
1589 1589
1590 1590
1591 def get_info_file(filename): 1591 def get_info_file(filename):
1592 data='' 1592 data = ''
1593 errors = re.compile(r"\b(error|fail|failed)\b", re.IGNORECASE) 1593 errors = re.compile(r"\b(error|fail|failed)\b", re.IGNORECASE)
1594 if os.path.isfile(filename): 1594 if os.path.isfile(filename):
1595 f = open('%s' % filename, "r") 1595 f = open('%s' % filename, "r")
1596 lines=f.readlines() 1596 lines = f.readlines()
1597 f.close() 1597 f.close()
1598 rx = re.compile('(\'|\")') 1598 rx = re.compile('(\'|\")')
1599 for line in lines: 1599 for line in lines:
1600 new_line = rx.sub('',line) 1600 new_line = rx.sub('', line)
1601 errors_found = errors.findall(new_line) 1601 errors_found = errors.findall(new_line)
1602 if len(errors_found)>0: 1602 if len(errors_found) > 0:
1603 data += '<font color=red>%s</font><br>'%str(new_line) 1603 data += '<font color=red>%s</font><br>' % str(new_line)
1604 else: 1604 else:
1605 data += '%s<br>'%str(new_line) 1605 data += '%s<br>' % str(new_line)
1606 if not data: 1606 if not data:
1607 data = 'No Information Found.<br>' 1607 data = 'No Information Found.<br>'
1608 else: 1608 else:
1609 data = 'File not found.<br>' 1609 data = 'File not found.<br>'
1610 return data 1610 return data
1611 1611
1612 1612
1613 1613
1614 def usage(): 1614 def usage():
1615 print 'usage:', 1615 print 'usage:',
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 html_path = '' 1680 html_path = ''
1681 1681
1682 if dirname: 1682 if dirname:
1683 if os.path.isdir(dirname): # TBD: replace it with a validation of 1683 if os.path.isdir(dirname): # TBD: replace it with a validation of
1684 # autotest result dir 1684 # autotest result dir
1685 res_dir = os.path.abspath(dirname) 1685 res_dir = os.path.abspath(dirname)
1686 tag = res_dir 1686 tag = res_dir
1687 status_file_name = dirname + '/status' 1687 status_file_name = dirname + '/status'
1688 sysinfo_dir = dirname + '/sysinfo' 1688 sysinfo_dir = dirname + '/sysinfo'
1689 host = get_info_file('%s/hostname' % sysinfo_dir) 1689 host = get_info_file('%s/hostname' % sysinfo_dir)
1690 rx=re.compile('^\s+[END|START].*$') 1690 rx = re.compile('^\s+[END|START].*$')
1691 # create the results set dict 1691 # create the results set dict
1692 results_data=[] 1692 results_data = []
1693 if os.path.exists(status_file_name): 1693 if os.path.exists(status_file_name):
1694 f = open(status_file_name, "r") 1694 f = open(status_file_name, "r")
1695 lines=f.readlines() 1695 lines = f.readlines()
1696 f.close() 1696 f.close()
1697 for line in lines: 1697 for line in lines:
1698 if rx.match(line): 1698 if rx.match(line):
1699 result_dict = parse_result(dirname, line) 1699 result_dict = parse_result(dirname, line)
1700 if result_dict: 1700 if result_dict:
1701 results_data.append(result_dict) 1701 results_data.append(result_dict)
1702 # create the meta info dict 1702 # create the meta info dict
1703 metalist = { 1703 metalist = {
1704 'uname': get_info_file('%s/uname' % sysinfo_dir), 1704 'uname': get_info_file('%s/uname' % sysinfo_dir),
1705 'cpuinfo':get_info_file('%s/cpuinfo' % sysinfo_dir), 1705 'cpuinfo':get_info_file('%s/cpuinfo' % sysinfo_dir),
(...skipping 12 matching lines...) Expand all
1718 else: 1718 else:
1719 print 'Invalid result directory <%s>' % dirname 1719 print 'Invalid result directory <%s>' % dirname
1720 sys.exit(1) 1720 sys.exit(1)
1721 else: 1721 else:
1722 usage() 1722 usage()
1723 sys.exit(1) 1723 sys.exit(1)
1724 1724
1725 1725
1726 if __name__ == "__main__": 1726 if __name__ == "__main__":
1727 main(sys.argv[1:]) 1727 main(sys.argv[1:])
OLDNEW
« cli/job.py ('K') | « client/tests/kvm/get_started.py ('k') | client/tests/kvm/installer.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698