#!c:/Python24/python.exe # # ***** BEGIN LICENSE BLOCK ***** # Version: MPL 1.1/GPL 2.0/LGPL 2.1 # # The contents of this file are subject to the Mozilla Public License Version # 1.1 (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # http://www.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS IS" basis, # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License # for the specific language governing rights and limitations under the # License. # # The Original Code is standalone Firefox Windows performance test. # # The Initial Developer of the Original Code is Google Inc. # Portions created by the Initial Developer are Copyright (C) 2006 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Annie Sullivan (original author) # # Alternatively, the contents of this file may be used under the terms of # either the GNU General Public License Version 2 or later (the "GPL"), or # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), # in which case the provisions of the GPL or the LGPL are applicable instead # of those above. If you wish to allow use of your version of this file only # under the terms of either the GPL or the LGPL, and not to allow others to # use your version of this file under the terms of the MPL, indicate your # decision by deleting the provisions above and replace them with the notice # and other provisions required by the GPL or the LGPL. If you do not delete # the provisions above, a recipient may use your version of this file under # the terms of any one of the MPL, the GPL or the LGPL. # # ***** END LICENSE BLOCK ***** """Writes a report with the results of the Ts (startup) and Tp (page load) tests. The report contains the mean startup time for each profile and the standard deviation, the sum of page load times and the standard deviation, and a graph of each performance counter measured during the page load test. """ __author__ = 'annie.sullivan@gmail.com (Annie Sullivan)' import csv import math import matplotlib.mlab import os import pylab import re import time import paths def MakeArray(start, len, step): """Helper function to create an array for an axis to plot counter data. Args: start: The first value in the array len: The length of the array step: The difference between values in the array Returns: An array starting at start, with len values each step apart. """ count = start end = start + (len * step) array = [] while count < end: array.append(count) count += step return array def GetPlottableData(counter_name, data): """Some counters should be displayed as a moving average, or may need other adjustment to be plotted. This function makes adjustments to the data based on counter name. Args: counter_name: The name of the counter, i.e 'Working Set' data: The original data collected from the counter Returns: data array adjusted based on counter name. """ if counter_name == '% Processor Time': # Use a moving average for % processor time return matplotlib.mlab.movavg(data, 5) if counter_name == 'Working Set' or counter_name == 'Private Bytes': # Change the scale from bytes to megabytes for working set return [float(x) / 1000000 for x in data] # No change for other counters return data def GenerateReport(title, filename, configurations, ts_times, tp_times, tp_counters, tp_resolution): """ Generates a report file in html using the given data Args: title: Title of the report filename: Filename of the report, before the timestamp configurations: Array of strings, containing the name of each configuration tested. ts_times: Array of arrays of ts startup times for each configuration. tp_times: Array of page load times for each configuration tested. tp_counters: Array of counter data for page load configurations Returns: filename of html report. """ # Make sure the reports/ and reports/graphs/ directories exist graphs_subdir = os.path.join(paths.REPORTS_DIR, 'graphs') if not os.path.exists(graphs_subdir): os.makedirs(graphs_subdir) # Will create parent directories # Create html report file localtime = time.localtime() timestamp = int(time.mktime(localtime)) report_filename = os.path.join(paths.REPORTS_DIR, filename + "_" + str(timestamp) + ".html") report = open(report_filename, 'w') report.write('Performance Report for %s, %s\n' % (title, time.strftime('%m-%d-%y'))) report.write('\n') report.write('

%s, %s

' % (title, time.strftime('%m-%d-%y'))) # Write out TS data report.write('

Startup Test (Ts) Results

\n') report.write('\n') report.write('') report.write('') report.write('') report.write('\n') ts_csv_filename = os.path.join(paths.REPORTS_DIR, filename + "_" + str(timestamp) + '_ts.csv') ts_csv_file = open(ts_csv_filename, 'wb') ts_csv = csv.writer(ts_csv_file) for i in range (0, len(configurations)): # Calculate mean mean = 0 for ts_time in ts_times[i]: mean += float(ts_time) mean = mean / len(ts_times[i]) # Calculate standard deviation stdd = 0 for ts_time in ts_times[i]: stdd += (float(ts_time) - mean) * (float(ts_time) - mean) stdd = stdd / len(ts_times[i]) stdd = math.sqrt(stdd) report.write('\n' % (configurations[i], mean, stdd)) ts_csv.writerow([configurations[i], mean, stdd]) report.write('
Profile TestedMeanStandard Deviation
%s%f%f

\n') ts_csv_file.close() # Write out TP data report.write('

Page Load Test (Tp) Results

\n') report.write('\n') report.write('') report.write('') report.write('') report.write('\n') tp_csv_filename = os.path.join(paths.REPORTS_DIR, filename + "_" + str(timestamp) + '_tp.csv') tp_csv_file = open(tp_csv_filename, 'wb') tp_csv = csv.writer(tp_csv_file) # Write out TP data for i in range (0, len(tp_times)): (tmp1, mean, tmp2, stdd) = tp_times[i].split() report.write('\n' % (configurations[i], float(mean), float(stdd))) tp_csv.writerow([configurations[i], float(mean), float(stdd)]) report.write('
Profile TestedSum of mean timesSum of Standard Deviations
%s%f%f

\n') tp_csv_file.close() # Write out counter data from TP tests report.write('

Performance Data

\n') # Write out graph of performance for each counter colors = ['r-', 'g-', 'b-', 'y-', 'c-', 'm-'] nonchar = re.compile('[\W]*') if len(tp_counters) > 0: counter_names = [] for counter in tp_counters[0]: counter_names.append(counter) for counter_name in counter_names: # Create a new figure for this counter pylab.clf() # Label the figure, and the x/y axes pylab.title(counter_name) pylab.ylabel(counter_name) pylab.xlabel("Time") # Draw a line for each counter in a different color on the graph current_color = 0 line_handles = [] # Save the handle of each line for the legend for count_data in tp_counters: data = GetPlottableData(counter_name, count_data[counter_name]) times = MakeArray(0, len(data), tp_resolution) handle = pylab.plot(times, data, colors[current_color]) line_handles.append(handle) current_color = (current_color + 1) % len(colors) # Draw a legend in the upper right corner legend = pylab.legend(line_handles, configurations, 'upper right') ltext = legend.get_texts() pylab.setp(ltext, fontsize='small') # legend text is too large by default # Save the graph and link to it from html. image_name = os.path.join(graphs_subdir, filename + "_" + str(timestamp) + nonchar.sub('', counter_name) + '.png') pylab.savefig(image_name) img_src = image_name[len(paths.REPORTS_DIR) : ] if img_src.startswith('\\'): img_src = img_src[1 : ] img_src = img_src.replace('\\', '/') report.write('

%s

\n' % (img_src, counter_name)) report.write('\n') return report_filename