| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 3 # Copyright (c) 2012, 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 glob | 7 import glob |
| 8 import optparse | 8 import optparse |
| 9 import os | 9 import os |
| 10 import re | 10 import re |
| 11 import shutil | 11 import shutil |
| 12 import subprocess | 12 import subprocess |
| 13 import sys | 13 import sys |
| 14 import tempfile | 14 import tempfile |
| 15 import gsutil | 15 import gsutil |
| 16 import ziputils | 16 import ziputils |
| 17 import hashlib | 17 import hashlib |
| 18 | 18 |
| 19 from os.path import join | 19 from os.path import join |
| 20 from xml.dom.minidom import parseString | |
| 21 | 20 |
| 22 BUILD_OS = None | 21 BUILD_OS = None |
| 23 DART_PATH = None | 22 DART_PATH = None |
| 24 TOOLS_PATH = None | 23 TOOLS_PATH = None |
| 25 | 24 |
| 26 GSU_PATH_REV = None | 25 GSU_PATH_REV = None |
| 27 GSU_PATH_LATEST = None | 26 GSU_PATH_LATEST = None |
| 28 GSU_API_DOCS_PATH = None | 27 GSU_API_DOCS_PATH = None |
| 29 GSU_API_DOCS_BUCKET = 'gs://dartlang-api-docs' | 28 GSU_API_DOCS_BUCKET = 'gs://dartlang-api-docs' |
| 30 | 29 |
| 31 REVISION = None | 30 REVISION = None |
| 32 TRUNK_BUILD = None | 31 TRUNK_BUILD = None |
| 33 MILESTONE_BUILD = None | 32 MILESTONE_BUILD = None |
| 34 PLUGINS_BUILD = None | 33 PLUGINS_BUILD = None |
| 35 | 34 |
| 35 NO_UPLOAD = None |
| 36 |
| 36 utils = None | 37 utils = None |
| 37 | 38 |
| 38 class AntWrapper(object): | 39 class AntWrapper(object): |
| 39 """A wrapper for ant build invocations""" | 40 """A wrapper for ant build invocations""" |
| 40 | 41 |
| 41 _antpath = None | 42 _antpath = None |
| 42 _bzippath = None | 43 _bzippath = None |
| 43 _propertyfile = None | 44 _propertyfile = None |
| 44 | 45 |
| 45 def __init__(self, propertyfile, antpath='/usr/bin', bzippath=None): | 46 def __init__(self, propertyfile, antpath='/usr/bin', bzippath=None): |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 global BUILD_OS | 196 global BUILD_OS |
| 196 global DART_PATH | 197 global DART_PATH |
| 197 global TOOLS_PATH | 198 global TOOLS_PATH |
| 198 global GSU_PATH_REV | 199 global GSU_PATH_REV |
| 199 global GSU_API_DOCS_PATH | 200 global GSU_API_DOCS_PATH |
| 200 global GSU_PATH_LATEST | 201 global GSU_PATH_LATEST |
| 201 global REVISION | 202 global REVISION |
| 202 global TRUNK_BUILD | 203 global TRUNK_BUILD |
| 203 global MILESTONE_BUILD | 204 global MILESTONE_BUILD |
| 204 global PLUGINS_BUILD | 205 global PLUGINS_BUILD |
| 206 global NO_UPLOAD |
| 205 global utils | 207 global utils |
| 206 | 208 |
| 207 if not sys.argv: | 209 if not sys.argv: |
| 208 print 'Script pathname not known, giving up.' | 210 print 'Script pathname not known, giving up.' |
| 209 return 1 | 211 return 1 |
| 210 | 212 |
| 211 scriptdir = os.path.abspath(os.path.dirname(sys.argv[0])) | 213 scriptdir = os.path.abspath(os.path.dirname(sys.argv[0])) |
| 212 editorpath = os.path.abspath(os.path.join(scriptdir, '..')) | 214 editorpath = os.path.abspath(os.path.join(scriptdir, '..')) |
| 213 thirdpartypath = os.path.abspath(os.path.join(scriptdir, '..', '..', | 215 thirdpartypath = os.path.abspath(os.path.join(scriptdir, '..', '..', |
| 214 'third_party')) | 216 'third_party')) |
| 215 toolspath = os.path.abspath(os.path.join(scriptdir, '..', '..', | 217 toolspath = os.path.abspath(os.path.join(scriptdir, '..', '..', |
| 216 'tools')) | 218 'tools')) |
| 217 dartpath = os.path.abspath(os.path.join(scriptdir, '..', '..')) | 219 dartpath = os.path.abspath(os.path.join(scriptdir, '..', '..')) |
| 218 antpath = os.path.join(thirdpartypath, 'apache_ant', '1.8.4') | 220 antpath = os.path.join(thirdpartypath, 'apache_ant', '1.8.4') |
| 219 bzip2libpath = os.path.join(thirdpartypath, 'bzip2') | 221 bzip2libpath = os.path.join(thirdpartypath, 'bzip2') |
| 220 buildpath = os.path.join(editorpath, 'tools', 'features', | 222 buildpath = os.path.join(editorpath, 'tools', 'features', |
| 221 'com.google.dart.tools.deploy.feature_releng') | 223 'com.google.dart.tools.deploy.feature_releng') |
| 222 utils = GetUtils(toolspath) | 224 utils = GetUtils(toolspath) |
| 223 buildos = utils.GuessOS() | 225 buildos = utils.GuessOS() |
| 224 | 226 |
| 225 BUILD_OS = utils.GuessOS() | 227 BUILD_OS = utils.GuessOS() |
| 226 DART_PATH = dartpath | 228 DART_PATH = dartpath |
| 227 TOOLS_PATH = toolspath | 229 TOOLS_PATH = toolspath |
| 228 | 230 |
| 231 if (os.environ.get('DART_NO_UPLOAD') is not None): |
| 232 NO_UPLOAD = True |
| 233 |
| 229 # TODO(devoncarew): remove this hardcoded e:\ path | 234 # TODO(devoncarew): remove this hardcoded e:\ path |
| 230 buildroot_parent = {'linux': dartpath, 'macos': dartpath, 'win32': r'e:\tmp'} | 235 buildroot_parent = {'linux': dartpath, 'macos': dartpath, 'win32': r'e:\tmp'} |
| 231 buildroot = os.path.join(buildroot_parent[buildos], 'build_root') | 236 buildroot = os.path.join(buildroot_parent[buildos], 'build_root') |
| 232 | 237 |
| 233 os.chdir(buildpath) | 238 os.chdir(buildpath) |
| 234 ant_property_file = None | 239 ant_property_file = None |
| 235 sdk_zip = None | 240 sdk_zip = None |
| 236 | 241 |
| 237 try: | 242 try: |
| 238 ant_property_file = tempfile.NamedTemporaryFile(suffix='.property', | 243 ant_property_file = tempfile.NamedTemporaryFile(suffix='.property', |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 #This is an override for local testing | 404 #This is an override for local testing |
| 400 force_run_install = os.environ.get('FORCE_RUN_INSTALL') | 405 force_run_install = os.environ.get('FORCE_RUN_INSTALL') |
| 401 | 406 |
| 402 if force_run_install or (not PLUGINS_BUILD): | 407 if force_run_install or (not PLUGINS_BUILD): |
| 403 InstallSdk(buildroot, buildout, buildos, buildout) | 408 InstallSdk(buildroot, buildout, buildos, buildout) |
| 404 InstallDartium(buildroot, buildout, buildos, gsu) | 409 InstallDartium(buildroot, buildout, buildos, gsu) |
| 405 | 410 |
| 406 if status: | 411 if status: |
| 407 return status | 412 return status |
| 408 | 413 |
| 409 junit_status = 0 | |
| 410 | |
| 411 if not build_skip_tests: | 414 if not build_skip_tests: |
| 412 StartBuildStep('run_tests') | 415 RunEditorTests(buildout, buildos) |
| 413 | |
| 414 junit_status = ant.RunAnt('../com.google.dart.tools.tests.feature_releng', | |
| 415 'buildTests.xml', | |
| 416 revision, builder_name, buildroot, buildout, | |
| 417 editorpath, buildos, | |
| 418 extra_artifacts=extra_artifacts) | |
| 419 | |
| 420 #<testsuite errors="0" failures="1" name="com.google.dart.tools.core_test" | |
| 421 # tests="740" time="40.713"> | |
| 422 testResults = parseString(open(join(buildout, 'test-results.xml')).read()) | |
| 423 testSuite = testResults.documentElement | |
| 424 | |
| 425 if testSuite.getAttribute("errors") != "0": | |
| 426 junit_status = 1 | |
| 427 if testSuite.getAttribute("failures") != "0": | |
| 428 junit_status = 1 | |
| 429 | |
| 430 if junit_status: | |
| 431 BuildStepFailure() | |
| 432 | |
| 433 StartBuildStep('test_summary') | |
| 434 PrintTestSummary(testSuite) | |
| 435 | |
| 436 if junit_status: | |
| 437 BuildStepFailure() | |
| 438 PrettyPrintTestFailures(testSuite) | |
| 439 | |
| 440 properties = ReadPropertyFile(buildos, ant_property_file.name) | |
| 441 if junit_status: | |
| 442 if properties['build.runtime']: | |
| 443 #if there is a build.runtime and the status is not | |
| 444 #zero see if there are any *.log entries | |
| 445 PrintErrorLog(properties['build.runtime']) | |
| 446 | 416 |
| 447 if buildos: | 417 if buildos: |
| 448 StartBuildStep('upload_artifacts') | 418 StartBuildStep('upload_artifacts') |
| 449 | 419 |
| 450 _InstallArtifacts(buildout, buildos, extra_artifacts) | 420 _InstallArtifacts(buildout, buildos, extra_artifacts) |
| 451 | 421 |
| 452 # dart-editor-linux.gtk.x86.zip --> darteditor-linux-32.zip | 422 # dart-editor-linux.gtk.x86.zip --> darteditor-linux-32.zip |
| 453 RenameRcpZipFiles(buildout) | 423 RenameRcpZipFiles(buildout) |
| 454 | 424 |
| 455 PostProcessEditorBuilds(buildout) | 425 PostProcessEditorBuilds(buildout) |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 | 758 |
| 789 checksum = CalculateChecksum(filename) | 759 checksum = CalculateChecksum(filename) |
| 790 checksum_filename = '%s.md5sum' % filename | 760 checksum_filename = '%s.md5sum' % filename |
| 791 | 761 |
| 792 with open(checksum_filename, 'w') as f: | 762 with open(checksum_filename, 'w') as f: |
| 793 f.write('%s *%s' % (checksum, os.path.basename(filename))) | 763 f.write('%s *%s' % (checksum, os.path.basename(filename))) |
| 794 | 764 |
| 795 return checksum_filename | 765 return checksum_filename |
| 796 | 766 |
| 797 | 767 |
| 768 def RunEditorTests(buildout, buildos): |
| 769 StartBuildStep('run_tests') |
| 770 |
| 771 for editorArchive in _FindRcpZipFiles(buildout): |
| 772 if (editorArchive.endswith('_64.zip')): |
| 773 print 'Running tests for %s...' % editorArchive |
| 774 tempDir = join(buildout, 'tests_temp') |
| 775 |
| 776 zipper = ziputils.ZipUtil(join(buildout, editorArchive), buildos) |
| 777 shutil.rmtree(tempDir, True) |
| 778 os.mkdir(tempDir) |
| 779 zipper.UnZip(tempDir) |
| 780 |
| 781 editorExecutable = GetEditorExecutable(join(tempDir, 'dart')) |
| 782 args = [editorExecutable, '-consoleLog', '--test', '--auto-exit', |
| 783 '-data', join(tempDir, 'workspace')] |
| 784 if sys.platform == 'linux': |
| 785 args = ['xvfb-run', '-a'] + args |
| 786 if (subprocess.call(args)): |
| 787 BuildStepFailure() |
| 788 |
| 789 shutil.rmtree(tempDir, True) |
| 790 |
| 791 |
| 792 def GetEditorExecutable(editorDir): |
| 793 if sys.platform == 'darwin': |
| 794 executable = join('DartEditor.app', 'Contents', 'MacOS', 'DartEditor') |
| 795 elif sys.platform == 'win32': |
| 796 executable = 'DartEditor.exe' |
| 797 else: |
| 798 executable = 'DartEditor' |
| 799 return join(editorDir, executable) |
| 800 |
| 801 |
| 798 def ReplaceInFiles(paths, subs): | 802 def ReplaceInFiles(paths, subs): |
| 799 '''Reads a series of files, applies a series of substitutions to each, and | 803 '''Reads a series of files, applies a series of substitutions to each, and |
| 800 saves them back out. subs should by a list of (pattern, replace) tuples.''' | 804 saves them back out. subs should by a list of (pattern, replace) tuples.''' |
| 801 for path in paths: | 805 for path in paths: |
| 802 contents = open(path).read() | 806 contents = open(path).read() |
| 803 for pattern, replace in subs: | 807 for pattern, replace in subs: |
| 804 contents = re.sub(pattern, replace, contents) | 808 contents = re.sub(pattern, replace, contents) |
| 805 dest = open(path, 'w') | 809 dest = open(path, 'w') |
| 806 dest.write(contents) | 810 dest.write(contents) |
| 807 dest.close() | 811 dest.close() |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 """tar gzip the given directory into the file""" | 993 """tar gzip the given directory into the file""" |
| 990 EnsureDirectoryExists(targetFile) | 994 EnsureDirectoryExists(targetFile) |
| 991 FileDelete(targetFile) | 995 FileDelete(targetFile) |
| 992 ExecuteCommand(['tar', 'czf', targetFile, os.path.basename(directory)], | 996 ExecuteCommand(['tar', 'czf', targetFile, os.path.basename(directory)], |
| 993 os.path.dirname(directory)) | 997 os.path.dirname(directory)) |
| 994 | 998 |
| 995 | 999 |
| 996 def UploadFile(targetFile, createChecksum=True): | 1000 def UploadFile(targetFile, createChecksum=True): |
| 997 """Upload the given file to google storage.""" | 1001 """Upload the given file to google storage.""" |
| 998 | 1002 |
| 1003 if (NO_UPLOAD): |
| 1004 return |
| 1005 |
| 999 filePathRev = "%s/%s" % (GSU_PATH_REV, os.path.basename(targetFile)) | 1006 filePathRev = "%s/%s" % (GSU_PATH_REV, os.path.basename(targetFile)) |
| 1000 filePathLatest = "%s/%s" % (GSU_PATH_LATEST, os.path.basename(targetFile)) | 1007 filePathLatest = "%s/%s" % (GSU_PATH_LATEST, os.path.basename(targetFile)) |
| 1001 | 1008 |
| 1002 if (createChecksum): | 1009 if (createChecksum): |
| 1003 checksum = CreateChecksumFile(targetFile) | 1010 checksum = CreateChecksumFile(targetFile) |
| 1004 | 1011 |
| 1005 checksumRev = "%s/%s" % (GSU_PATH_REV, os.path.basename(checksum)) | 1012 checksumRev = "%s/%s" % (GSU_PATH_REV, os.path.basename(checksum)) |
| 1006 checksumLatest = "%s/%s" % (GSU_PATH_LATEST, os.path.basename(checksum)) | 1013 checksumLatest = "%s/%s" % (GSU_PATH_LATEST, os.path.basename(checksum)) |
| 1007 | 1014 |
| 1008 Gsutil(['cp', '-a', 'public-read', r'file://' + targetFile, filePathRev]) | 1015 Gsutil(['cp', '-a', 'public-read', r'file://' + targetFile, filePathRev]) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 | 1064 |
| 1058 def StartBuildStep(name): | 1065 def StartBuildStep(name): |
| 1059 print "@@@BUILD_STEP %s@@@" % name | 1066 print "@@@BUILD_STEP %s@@@" % name |
| 1060 sys.stdout.flush() | 1067 sys.stdout.flush() |
| 1061 | 1068 |
| 1062 | 1069 |
| 1063 def BuildStepFailure(): | 1070 def BuildStepFailure(): |
| 1064 print '@@@STEP_FAILURE@@@' | 1071 print '@@@STEP_FAILURE@@@' |
| 1065 sys.stdout.flush() | 1072 sys.stdout.flush() |
| 1066 | 1073 |
| 1067 def PrintTestSummary(testSuite): | |
| 1068 print "\n%s:\n %s tests, %s errors, %s failures (time: %s)\n" % ( | |
| 1069 testSuite.getAttribute("name"), | |
| 1070 testSuite.getAttribute("tests"), | |
| 1071 testSuite.getAttribute("errors"), | |
| 1072 testSuite.getAttribute("failures"), | |
| 1073 testSuite.getAttribute("time")) | |
| 1074 sys.stdout.flush() | |
| 1075 | |
| 1076 | |
| 1077 def PrettyPrintTestFailures(testSuite): | |
| 1078 # for all testcase children | |
| 1079 # if they contain a failure or error child node | |
| 1080 # print out the name and node text | |
| 1081 for testCase in testSuite.getElementsByTagName('testcase'): | |
| 1082 for failureNode in testCase.getElementsByTagName('failure'): | |
| 1083 print 'test failed: %s' % testCase.getAttribute('name') | |
| 1084 print failureNode.childNodes[0].data | |
| 1085 for errorNode in testCase.getElementsByTagName('error'): | |
| 1086 print 'test error: %s' % testCase.getAttribute('name') | |
| 1087 print errorNode.childNodes[0].data | |
| 1088 sys.stdout.flush() | |
| 1089 | |
| 1090 | 1074 |
| 1091 def FileDelete(f): | 1075 def FileDelete(f): |
| 1092 """delete the given file - do not re-throw any exceptions that occur""" | 1076 """delete the given file - do not re-throw any exceptions that occur""" |
| 1093 if os.path.exists(f): | 1077 if os.path.exists(f): |
| 1094 try: | 1078 try: |
| 1095 os.remove(f) | 1079 os.remove(f) |
| 1096 except OSError: | 1080 except OSError: |
| 1097 print 'error deleting %s' % f | 1081 print 'error deleting %s' % f |
| 1098 | 1082 |
| 1099 | 1083 |
| 1100 if __name__ == '__main__': | 1084 if __name__ == '__main__': |
| 1101 sys.exit(main()) | 1085 sys.exit(main()) |
| OLD | NEW |