| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 4 # for details. All rights reserved. Use of this source code is governed by a | 4 # for details. All rights reserved. Use of this source code is governed by a |
| 5 # BSD-style license that can be found in the LICENSE file. | 5 # BSD-style license that can be found in the LICENSE file. |
| 6 | 6 |
| 7 import datetime | 7 import datetime |
| 8 import math | 8 import math |
| 9 try: | 9 try: |
| 10 from matplotlib.font_manager import FontProperties | 10 from matplotlib.font_manager import FontProperties |
| 11 import matplotlib.pyplot as plt | 11 import matplotlib.pyplot as plt |
| 12 except ImportError: | 12 except ImportError: |
| 13 print 'Warning: no matplotlib. ' + \ | 13 print 'Warning: no matplotlib. ' + \ |
| 14 'Please ignore if you are running buildbot smoketests.' | 14 'Please ignore if you are running buildbot smoketests.' |
| 15 import optparse | 15 import optparse |
| 16 import os | 16 import os |
| 17 from os.path import dirname, abspath |
| 17 import platform | 18 import platform |
| 18 import shutil | 19 import shutil |
| 19 import subprocess | 20 import subprocess |
| 20 import time | 21 import time |
| 21 import traceback | 22 import traceback |
| 23 import sys |
| 24 |
| 25 TOOLS_PATH = os.path.join(dirname(dirname(dirname(abspath(__file__))))) |
| 26 sys.path.append(TOOLS_PATH) |
| 27 import utils |
| 22 | 28 |
| 23 """This script runs to track performance and correctness progress of | 29 """This script runs to track performance and correctness progress of |
| 24 different svn revisions. It tests to see if there a newer version of the code on | 30 different svn revisions. It tests to see if there a newer version of the code on |
| 25 the server, and will sync and run the performance tests if so.""" | 31 the server, and will sync and run the performance tests if so.""" |
| 26 | 32 |
| 27 DART_INSTALL_LOCATION = os.path.join(os.path.dirname(os.path.abspath(__file__)), | 33 DART_INSTALL_LOCATION = os.path.join(dirname(abspath(__file__)), |
| 28 '..', '..', '..') | 34 '..', '..', '..') |
| 29 V8_MEAN = 'V8 Mean' | 35 V8_MEAN = 'V8 Mean' |
| 30 FROG_MEAN = 'frog Mean' | 36 FROG_MEAN = 'frog Mean' |
| 31 COMMAND_LINE = 'commandline' | 37 COMMAND_LINE = 'commandline' |
| 32 V8 = 'v8' | 38 V8 = 'v8' |
| 33 FROG = 'frog' | 39 FROG = 'frog' |
| 34 V8_AND_FROG = [V8, FROG] | 40 V8_AND_FROG = [V8, FROG] |
| 35 CORRECTNESS = 'Percent passing' | 41 CORRECTNESS = 'Percent passing' |
| 36 COLORS = ['blue', 'green', 'red', 'cyan', 'magenta', 'black'] | 42 COLORS = ['blue', 'green', 'red', 'cyan', 'magenta', 'black'] |
| 37 GRAPH_OUT_DIR = 'graphs' | 43 GRAPH_OUT_DIR = 'graphs' |
| 38 SLEEP_TIME = 200 | 44 SLEEP_TIME = 200 |
| 39 PERFBOT_MODE = False | 45 PERFBOT_MODE = False |
| 40 VERBOSE = False | 46 VERBOSE = False |
| 47 HAS_SHELL = False |
| 48 if platform.system() == 'Windows': |
| 49 # On Windows, shell must be true to get the correct environment variables. |
| 50 HAS_SHELL = True |
| 41 | 51 |
| 42 """First, some utility methods.""" | 52 """First, some utility methods.""" |
| 43 | 53 |
| 44 def RunCmd(cmd_list, outfile=None, append=False): | 54 def RunCmd(cmd_list, outfile=None, append=False): |
| 45 """Run the specified command and print out any output to stdout. | 55 """Run the specified command and print out any output to stdout. |
| 46 Args: | 56 Args: |
| 47 cmd_list a list of strings that make up the command to run | 57 cmd_list a list of strings that make up the command to run |
| 48 outfile a string indicating the name of the file that we should write stdout | 58 outfile a string indicating the name of the file that we should write stdout |
| 49 to | 59 to |
| 50 append True if we want to append to the file instead of overwriting it""" | 60 append True if we want to append to the file instead of overwriting it""" |
| 51 if VERBOSE: | 61 if VERBOSE: |
| 52 print ' '.join(cmd_list) | 62 print ' '.join(cmd_list) |
| 53 out = subprocess.PIPE | 63 out = subprocess.PIPE |
| 54 if outfile: | 64 if outfile: |
| 55 mode = 'w' | 65 mode = 'w' |
| 56 if append: | 66 if append: |
| 57 mode = 'a' | 67 mode = 'a' |
| 58 out = open(outfile, mode) | 68 out = open(outfile, mode) |
| 59 p = '' | 69 p = subprocess.Popen(cmd_list, stdout = out, stderr = subprocess.PIPE, |
| 60 if platform.system() == 'Windows': | 70 shell=HAS_SHELL) |
| 61 # On Windows, shell must be true to get the correct environment variables. | |
| 62 p = subprocess.Popen(cmd_list, stdout = out, stderr = subprocess.PIPE, | |
| 63 shell=True) | |
| 64 else: | |
| 65 p = subprocess.Popen(cmd_list, stdout = out, stderr = subprocess.PIPE) | |
| 66 output, not_used = p.communicate(); | 71 output, not_used = p.communicate(); |
| 67 if output: | 72 if output: |
| 68 print output | 73 print output |
| 69 return output | 74 return output |
| 70 | 75 |
| 71 def TimeCmd(cmd): | 76 def TimeCmd(cmd): |
| 72 """Determine the amount of (real) time it takes to execute a given command.""" | 77 """Determine the amount of (real) time it takes to execute a given command.""" |
| 73 start = time.time() | 78 start = time.time() |
| 74 RunCmd(cmd) | 79 RunCmd(cmd) |
| 75 return time.time() - start | 80 return time.time() - start |
| 76 | 81 |
| 77 def SyncAndBuild(failed_once=False): | 82 def SyncAndBuild(failed_once=False): |
| 78 """Make sure we have the latest version of of the repo, and build it. We | 83 """Make sure we have the latest version of of the repo, and build it. We |
| 79 begin and end standing in DART_INSTALL_LOCATION. | 84 begin and end standing in DART_INSTALL_LOCATION. |
| 80 Args: | 85 Args: |
| 81 failed_once True if we have attempted to build this once before, and we've | 86 failed_once True if we have attempted to build this once before, and we've |
| 82 failed, indicating the build is broken. | 87 failed, indicating the build is broken. |
| 83 Returns: | 88 Returns: |
| 84 err_code = 1 if there was a problem building two times in a row.""" | 89 err_code = 1 if there was a problem building two times in a row.""" |
| 85 os.chdir(DART_INSTALL_LOCATION) | 90 os.chdir(DART_INSTALL_LOCATION) |
| 86 #Revert our newly built minfrog to prevent conflicts when we update | 91 #Revert our newly built minfrog to prevent conflicts when we update |
| 87 RunCmd(['svn', 'revert', os.path.join(os.getcwd(), 'frog', 'minfrog')]) | 92 RunCmd(['svn', 'revert', os.path.join(os.getcwd(), 'frog', 'minfrog')]) |
| 88 | 93 |
| 89 RunCmd(['gclient', 'sync']) | 94 RunCmd(['gclient', 'sync']) |
| 90 #TODO(efortuna): Temporary fix to get IE data without requiring Dart to build | 95 # TODO(efortuna): building the sdk locally is a band-aid until all build |
| 91 # on Windows. Take this out once we have SDKs or can build on Windows. | 96 # platform SDKs are hosted in Google storage. Pull from https://sandbox. |
| 92 if platform.system() != 'Windows': | 97 # google.com/storage/?arg=dart-dump-render-tree#dart-dump-render-tree%2Fsdk |
| 93 lines = RunCmd([os.path.join('.', 'tools', 'build.py'), '-m', 'release']) | 98 # eventually. |
| 94 os.chdir('frog') | 99 # TODO(efortuna): Currently always building ia32 architecture because we don't |
| 95 lines += RunCmd([os.path.join('..', 'tools', 'build.py'), '-m', | 100 # have test statistics for what's passing on x64. Eliminate arch specification |
| 96 'debug,release']) | 101 # when we have tests running on x64, too. |
| 97 os.chdir('..') | 102 lines = RunCmd([os.path.join('.', 'tools', 'build.py'), '-m', 'release', |
| 103 '--arch=ia32', 'create_sdk']) |
| 98 | 104 |
| 99 for line in lines: | 105 for line in lines: |
| 100 if 'BUILD FAILED' in lines: | 106 if 'BUILD FAILED' in lines: |
| 101 if failed_once: | 107 if failed_once: |
| 102 # Someone checked in a broken build! Just stop trying to make it work | 108 # Someone checked in a broken build! Just stop trying to make it work |
| 103 # and wait for the next hour to try again. | 109 # and wait to try again. |
| 104 print 'Broken Build' | 110 print 'Broken Build' |
| 105 return 1 | 111 return 1 |
| 106 #Remove the xcode directory and attempt to build again. If it still | 112 #Remove the output directory and attempt to build again. If it still |
| 107 #fails, abort, and try again next hour. | 113 #fails, abort, and try again in a little bit. |
| 108 out_dir = 'out' | 114 shutil.rmtree(os.path.join(os.getcwd(), |
| 109 if platform.system() == 'Darwin': | 115 utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32'))) |
| 110 out_dir = 'xcodebuild' | 116 SyncAndBuild(True) |
| 111 shutil.rmtree(os.path.join(os.getcwd(), out_dir, 'Release_ia32')) | |
| 112 shutil.rmtree(os.path.join(os.getcwd(), 'frog', out_dir, | |
| 113 'Debug_ia32')) | |
| 114 shutil.rmtree(os.path.join(os.getcwd(), 'frog', out_dir, | |
| 115 'Release_ia32')) | |
| 116 SyncAndBuild(True) | |
| 117 return 0 | 117 return 0 |
| 118 | 118 |
| 119 def EnsureOutputDirectory(dir_name): | 119 def EnsureOutputDirectory(dir_name): |
| 120 """Test that the listed directory name exists, and if not, create one for | 120 """Test that the listed directory name exists, and if not, create one for |
| 121 our output to be placed. | 121 our output to be placed. |
| 122 Args: | 122 Args: |
| 123 dir_name the directory we will create if it does not exist.""" | 123 dir_name the directory we will create if it does not exist.""" |
| 124 dir_path = os.path.join(DART_INSTALL_LOCATION, 'tools', 'testing', | 124 dir_path = os.path.join(DART_INSTALL_LOCATION, 'tools', 'testing', |
| 125 'perf_testing', dir_name) | 125 'perf_testing', dir_name) |
| 126 if not os.path.exists(dir_path): | 126 if not os.path.exists(dir_path): |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 fontP.set_size('small') | 256 fontP.set_size('small') |
| 257 plt.legend(loc=legend_loc, prop = fontP) | 257 plt.legend(loc=legend_loc, prop = fontP) |
| 258 | 258 |
| 259 fig = plt.gcf() | 259 fig = plt.gcf() |
| 260 fig.set_size_inches(size_x, size_y) | 260 fig.set_size_inches(size_x, size_y) |
| 261 fig.savefig(os.path.join(GRAPH_OUT_DIR, filename)) | 261 fig.savefig(os.path.join(GRAPH_OUT_DIR, filename)) |
| 262 | 262 |
| 263 def AddSvnRevisionToTrace(self, outfile): | 263 def AddSvnRevisionToTrace(self, outfile): |
| 264 """Add the svn version number to the provided tracefile.""" | 264 """Add the svn version number to the provided tracefile.""" |
| 265 p = subprocess.Popen(['svn', 'info'], stdout = subprocess.PIPE, | 265 p = subprocess.Popen(['svn', 'info'], stdout = subprocess.PIPE, |
| 266 stderr = subprocess.STDOUT) | 266 stderr = subprocess.STDOUT, shell = HAS_SHELL) |
| 267 output, not_used = p.communicate() | 267 output, not_used = p.communicate() |
| 268 for line in output.split('\n'): | 268 for line in output.split('\n'): |
| 269 if 'Revision' in line: | 269 if 'Revision' in line: |
| 270 RunCmd(['echo', line.strip()], outfile) | 270 RunCmd(['echo', line.strip()], outfile) |
| 271 | 271 |
| 272 def WriteHtml(self, delimiter, rev_nums, label_1, dict_1, label_2, dict_2, | 272 def WriteHtml(self, delimiter, rev_nums, label_1, dict_1, label_2, dict_2, |
| 273 cleanFile=False): | 273 cleanFile=False): |
| 274 """Adds an html table to the webpage to display the data values. This method | 274 """Adds an html table to the webpage to display the data values. This method |
| 275 will be removed when we have a nicer way to display data values.""" | 275 will be removed when we have a nicer way to display data values.""" |
| 276 #TODO(efortuna): fix this. | 276 #TODO(efortuna): fix this. |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 GetBrowsers(), [FROG], [CORRECTNESS]) | 531 GetBrowsers(), [FROG], [CORRECTNESS]) |
| 532 self.test_type = test_type | 532 self.test_type = test_type |
| 533 | 533 |
| 534 def RunTests(self): | 534 def RunTests(self): |
| 535 """Run a test of the latest svn revision.""" | 535 """Run a test of the latest svn revision.""" |
| 536 for browser in GetBrowsers(): | 536 for browser in GetBrowsers(): |
| 537 current_file = 'correctness%s-%s' % (self.cur_time, browser) | 537 current_file = 'correctness%s-%s' % (self.cur_time, browser) |
| 538 self.trace_file = os.path.join('tools', 'testing', | 538 self.trace_file = os.path.join('tools', 'testing', |
| 539 'perf_testing', self.result_folder_name, current_file) | 539 'perf_testing', self.result_folder_name, current_file) |
| 540 self.AddSvnRevisionToTrace(self.trace_file) | 540 self.AddSvnRevisionToTrace(self.trace_file) |
| 541 dart_sdk = os.path.join(os.getcwd(), utils.GetBuildRoot(utils.GuessOS(), |
| 542 'release', 'ia32'), 'dart-sdk') |
| 541 RunCmd([os.path.join('.', 'tools', 'test.py'), | 543 RunCmd([os.path.join('.', 'tools', 'test.py'), |
| 542 '--component=webdriver', '--flag=%s' % browser, '--report', | 544 '--component=webdriver', '--flag=%s' % browser, '--flag=--frog=%s' % \ |
| 545 os.path.join(dart_sdk, 'bin', 'frogc'), |
| 546 '--flag=--froglib=%s' % os.path.join(dart_sdk, 'lib'), |
| 543 '--timeout=20', '--progress=color', '--mode=release', '-j1', | 547 '--timeout=20', '--progress=color', '--mode=release', '-j1', |
| 544 self.test_type], self.trace_file, append=True) | 548 self.test_type], self.trace_file, append=True) |
| 545 | 549 |
| 546 def ProcessFile(self, afile): | 550 def ProcessFile(self, afile): |
| 547 """Given a trace file, extract all the relevant information out of it to | 551 """Given a trace file, extract all the relevant information out of it to |
| 548 determine the number of correctly passing tests. | 552 determine the number of correctly passing tests. |
| 549 | 553 |
| 550 Arguments: | 554 Arguments: |
| 551 afile the filename string""" | 555 afile the filename string""" |
| 552 browser = afile.rpartition('-')[2] | 556 browser = afile.rpartition('-')[2] |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 if HasNewCode(): | 754 if HasNewCode(): |
| 751 RunTestSequence(cl, size, language, perf) | 755 RunTestSequence(cl, size, language, perf) |
| 752 else: | 756 else: |
| 753 time.sleep(SLEEP_TIME) | 757 time.sleep(SLEEP_TIME) |
| 754 else: | 758 else: |
| 755 RunTestSequence(cl, size, language, perf) | 759 RunTestSequence(cl, size, language, perf) |
| 756 | 760 |
| 757 if __name__ == '__main__': | 761 if __name__ == '__main__': |
| 758 main() | 762 main() |
| 759 | 763 |
| OLD | NEW |