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

Side by Side Diff: scripts/slave/chromium/archive_layout_test_results.py

Issue 2429583002: In archive_layout_test_results.py, simplify argument handling. (Closed)
Patch Set: Rebase Created 4 years, 2 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """A tool to archive layout test results. 6 """A tool to archive layout test results.
7 7
8 To archive files on Google Storage, pass a GS bucket name via --gs-bucket. 8 To archive files on Google Storage, pass a GS bucket name via --gs-bucket.
9 To control access to archives, pass a value for --gs-acl (e.g. 'public-read', 9 To control access to archives, pass a value for --gs-acl (e.g. 'public-read',
10 see https://developers.google.com/storage/docs/accesscontrol#extension 10 see https://developers.google.com/storage/docs/accesscontrol#extension
11 for other supported canned-acl values). If no gs_acl key is given, 11 for other supported canned-acl values). If no gs_acl key is given,
12 then the bucket's default object ACL will be applied (see 12 then the bucket's default object ACL will be applied (see
13 https://developers.google.com/storage/docs/accesscontrol#defaultobjects). 13 https://developers.google.com/storage/docs/accesscontrol#defaultobjects).
14 14
15 When this is run, the current directory (cwd) should be the outer build 15 When this is run, the current directory (cwd) should be the outer build
16 directory (e.g., chrome-release/build/). 16 directory (e.g., chrome-release/build/).
17 17
18 For a list of command-line options, call this script with '--help'. 18 For a list of command-line options, call this script with '--help'.
19 """ 19 """
20 20
21 import logging 21 import logging
22 import optparse 22 import argparse
23 import os 23 import os
24 import re 24 import re
25 import socket 25 import socket
26 import sys 26 import sys
27 27
28 from common import archive_utils 28 from common import archive_utils
29 from common import chromium_utils 29 from common import chromium_utils
30 from slave import build_directory 30 from slave import build_directory
31 from slave import slave_utils 31 from slave import slave_utils
32 32
33 # Directory name, above the build directory, in which test results can be
34 # found if no --results-dir option is given.
35 RESULT_DIR = 'layout-test-results'
36
37 33
38 def _CollectArchiveFiles(output_dir): 34 def _CollectArchiveFiles(output_dir):
39 """Returns a list of actual layout test result files to archive.""" 35 """Returns a list of actual layout test result files to archive."""
40 actual_file_list = [] 36 actual_file_list = []
41 37
42 for path, _, files in os.walk(output_dir): 38 for path, _, files in os.walk(output_dir):
43 rel_path = path[len(output_dir + '\\'):] 39 rel_path = path[len(output_dir + '\\'):]
44 for name in files: 40 for name in files:
45 if _IsActualResultFile(name): 41 if _IsActualResultFile(name):
46 actual_file_list.append(os.path.join(rel_path, name)) 42 actual_file_list.append(os.path.join(rel_path, name))
(...skipping 13 matching lines...) Expand all
60 56
61 57
62 def _IsActualResultFile(name): 58 def _IsActualResultFile(name):
63 if '-stack.' in name or '-crash-log.' in name: 59 if '-stack.' in name or '-crash-log.' in name:
64 return True 60 return True
65 extension = os.path.splitext(name)[1] 61 extension = os.path.splitext(name)[1]
66 return ('-actual.' in name and extension in 62 return ('-actual.' in name and extension in
67 ('.txt', '.png', '.checksum', '.wav')) 63 ('.txt', '.png', '.checksum', '.wav'))
68 64
69 65
70 def archive_layout(options): 66 def archive_layout(args):
71 chrome_dir = os.path.abspath(options.build_dir) 67 chrome_dir = os.path.abspath(args.build_dir)
72 results_dir_basename = os.path.basename(options.results_dir) 68 results_dir_basename = os.path.basename(args.results_dir)
73 if options.results_dir is not None: 69 args.results_dir = os.path.abspath(args.results_dir)
74 options.results_dir = os.path.abspath(os.path.join(options.build_dir, 70 print 'Archiving results from %s' % args.results_dir
75 options.results_dir)) 71 staging_dir = args.staging_dir or slave_utils.GetStagingDir(chrome_dir)
76 else:
77 options.results_dir = chromium_utils.FindUpward(chrome_dir, RESULT_DIR)
78 print 'Archiving results from %s' % options.results_dir
79 staging_dir = options.staging_dir or slave_utils.GetStagingDir(chrome_dir)
80 print 'Staging in %s' % staging_dir 72 print 'Staging in %s' % staging_dir
81 if not os.path.exists(staging_dir): 73 if not os.path.exists(staging_dir):
82 os.makedirs(staging_dir) 74 os.makedirs(staging_dir)
83 75
84 actual_file_list = _CollectArchiveFiles(options.results_dir) 76 actual_file_list = _CollectArchiveFiles(args.results_dir)
85 zip_file = chromium_utils.MakeZip(staging_dir, 77 zip_file = chromium_utils.MakeZip(staging_dir,
86 results_dir_basename, 78 results_dir_basename,
87 actual_file_list, 79 actual_file_list,
88 options.results_dir)[1] 80 args.results_dir)[1]
89
90 # Extract the build name of this slave (e.g., 'chrome-release') from its
91 # configuration file if not provided as a param.
92 build_name = options.builder_name or slave_utils.SlaveBuildName(chrome_dir)
93 build_name = re.sub('[ .()]', '_', build_name)
94 81
95 wc_dir = os.path.dirname(chrome_dir) 82 wc_dir = os.path.dirname(chrome_dir)
96 last_change = slave_utils.GetHashOrRevision(wc_dir) 83 last_change = slave_utils.GetHashOrRevision(wc_dir)
97 84
98 # TODO(dpranke): Is it safe to assume build_number is not blank? Should we 85 builder_name = re.sub('[ .()]', '_', args.builder_name)
99 # assert() this ? 86 build_number = str(args.build_number)
100 build_number = str(options.build_number) 87
101 print 'last change: %s' % last_change 88 print 'last change: %s' % last_change
102 print 'build name: %s' % build_name 89 print 'build name: %s' % builder_name
103 print 'build number: %s' % build_number 90 print 'build number: %s' % build_number
104 print 'host name: %s' % socket.gethostname() 91 print 'host name: %s' % socket.gethostname()
105 92
106 # Create a file containing last_change revision. This file will be uploaded 93 # Create a file containing last_change revision. This file will be uploaded
107 # after all layout test results are uploaded so the client can check this 94 # after all layout test results are uploaded so the client can check this
108 # file to see if the upload for the revision is complete. 95 # file to see if the upload for the revision is complete.
109 # See crbug.com/574272 for more details. 96 # See crbug.com/574272 for more details.
110 last_change_file = os.path.join(staging_dir, 'LAST_CHANGE') 97 last_change_file = os.path.join(staging_dir, 'LAST_CHANGE')
111 with open(last_change_file, 'w') as f: 98 with open(last_change_file, 'w') as f:
112 f.write(last_change) 99 f.write(last_change)
113 100
114 # Copy the results to a directory archived by build number. 101 # Copy the results to a directory archived by build number.
115 gs_base = '/'.join([options.gs_bucket, build_name, build_number]) 102 gs_base = '/'.join([args.gs_bucket, builder_name, build_number])
116 gs_acl = options.gs_acl 103 gs_acl = args.gs_acl
117 # These files never change, cache for a year. 104 # These files never change, cache for a year.
118 cache_control = "public, max-age=31556926" 105 cache_control = "public, max-age=31556926"
119 slave_utils.GSUtilCopyFile(zip_file, gs_base, gs_acl=gs_acl, 106 slave_utils.GSUtilCopyFile(zip_file, gs_base, gs_acl=gs_acl,
120 cache_control=cache_control) 107 cache_control=cache_control)
121 slave_utils.GSUtilCopyDir(options.results_dir, gs_base, gs_acl=gs_acl, 108 slave_utils.GSUtilCopyDir(args.results_dir, gs_base, gs_acl=gs_acl,
122 cache_control=cache_control) 109 cache_control=cache_control)
123 slave_utils.GSUtilCopyFile(last_change_file, 110 slave_utils.GSUtilCopyFile(last_change_file,
124 gs_base + '/' + results_dir_basename, 111 gs_base + '/' + results_dir_basename,
125 gs_acl=gs_acl, 112 gs_acl=gs_acl,
126 cache_control=cache_control) 113 cache_control=cache_control)
127 114
128 # And also to the 'results' directory to provide the 'latest' results 115 # And also to the 'results' directory to provide the 'latest' results
129 # and make sure they are not cached at all (Cloud Storage defaults to 116 # and make sure they are not cached at all (Cloud Storage defaults to
130 # caching w/ a max-age=3600). 117 # caching w/ a max-age=3600).
131 gs_base = '/'.join([options.gs_bucket, build_name, 'results']) 118 gs_base = '/'.join([args.gs_bucket, builder_name, 'results'])
132 cache_control = 'no-cache' 119 cache_control = 'no-cache'
133 slave_utils.GSUtilCopyFile(zip_file, gs_base, gs_acl=gs_acl, 120 slave_utils.GSUtilCopyFile(zip_file, gs_base, gs_acl=gs_acl,
134 cache_control=cache_control) 121 cache_control=cache_control)
135 slave_utils.GSUtilCopyDir(options.results_dir, gs_base, gs_acl=gs_acl, 122 slave_utils.GSUtilCopyDir(args.results_dir, gs_base, gs_acl=gs_acl,
136 cache_control=cache_control) 123 cache_control=cache_control)
137 slave_utils.GSUtilCopyFile(last_change_file, 124 slave_utils.GSUtilCopyFile(last_change_file,
138 gs_base + '/' + results_dir_basename, 125 gs_base + '/' + results_dir_basename,
139 gs_acl=gs_acl, 126 gs_acl=gs_acl,
140 cache_control=cache_control) 127 cache_control=cache_control)
141 return 0 128 return 0
142 129
143 130
144 def _ParseOptions(): 131 def _ParseArgs():
145 option_parser = optparse.OptionParser() 132 parser = argparse.ArgumentParser()
146 option_parser.add_option('', '--build-dir', help='ignored') 133 # TODO(crbug.com/655798): Make --build-dir not ignored.
147 option_parser.add_option('', '--results-dir', 134 parser.add_argument('--build-dir', help='ignored')
148 help='path to layout test results, relative to ' 135 parser.add_argument('--results-dir', required=True,
Dirk Pranke 2016/10/18 20:03:03 Nice, didn't know about the required flag.
149 'the build_dir') 136 help='path to layout test results')
150 option_parser.add_option('', '--builder-name', 137 parser.add_argument('--builder-name', required=True,
151 default=None, 138 help='The name of the builder running this script.')
152 help='The name of the builder running this script.') 139 parser.add_argument('--build-number', type=int, required=True,
153 option_parser.add_option('', '--build-number', 140 help='Build number of the builder running this script.')
154 default=None, 141 parser.add_argument('--gs-bucket', required=True,
155 help=('The build number of the builder running' 142 help='The Google Storage bucket to upload to.')
156 'this script.')) 143 parser.add_argument('--gs-acl',
157 option_parser.add_option('', '--gs-bucket', 144 help='The access policy for Google Storage files.')
158 default=None, 145 parser.add_argument('--staging-dir',
159 help=('The google storage bucket to upload to. ' 146 help='Directory to use for staging the archives. '
160 'If provided, this script will upload to gs ' 147 'Default behavior is to automatically detect '
161 'instead of the master.')) 148 'slave\'s build directory.')
162 option_parser.add_option('', '--gs-acl', 149 args = parser.parse_args()
163 default=None, 150 args.build_dir = build_directory.GetBuildOutputDirectory()
164 help=('The ACL of the google storage files.')) 151 return args
165 option_parser.add_option('--staging-dir',
166 help='Directory to use for staging the archives. '
167 'Default behavior is to automatically detect '
168 'slave\'s build directory.')
169 chromium_utils.AddPropertiesOptions(option_parser)
170 options, _ = option_parser.parse_args()
171 if not options.gs_bucket:
172 option_parser.error('--gs-bucket is required.')
173 options.build_dir = build_directory.GetBuildOutputDirectory()
174 return options
175 152
176 153
177 def main(): 154 def main():
178 options = _ParseOptions() 155 args = _ParseArgs()
179 logging.basicConfig(level=logging.INFO, 156 logging.basicConfig(level=logging.INFO,
180 format='%(asctime)s %(filename)s:%(lineno)-3d' 157 format='%(asctime)s %(filename)s:%(lineno)-3d'
181 ' %(levelname)s %(message)s', 158 ' %(levelname)s %(message)s',
182 datefmt='%y%m%d %H:%M:%S') 159 datefmt='%y%m%d %H:%M:%S')
183 return archive_layout(options) 160 return archive_layout(args)
184 161
185 162
186 if '__main__' == __name__: 163 if '__main__' == __name__:
187 sys.exit(main()) 164 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698