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

Side by Side Diff: build/test_packages.py

Issue 2095173002: Teach build.py to cross-compile go-based packages. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Teach build.py to cross-compile go-based packages. Created 4 years, 6 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
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2015 The Chromium Authors. All rights reserved. 2 # Copyright 2015 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 """Tests generated CIPD packages. 6 """Tests generated CIPD packages.
7 7
8 Supposed to be invoked after build.py has run. Uses packages from out/*.cipd and 8 Supposed to be invoked after build.py has run. Uses packages from out/*.cipd and
9 tests from tests/*.py. 9 tests from tests/*.py.
10 10
11 Assumes cipd client is built in ../go/bin/cipd (true after build.py has run). 11 Assumes cipd client is built in out/.cipd_client/cipd_* (true after build.py has
12 run).
12 """ 13 """
13 14
14 import argparse 15 import argparse
15 import glob 16 import glob
16 import os 17 import os
17 import re 18 import re
18 import shutil 19 import shutil
19 import subprocess 20 import subprocess
20 import sys 21 import sys
21 import tempfile 22 import tempfile
(...skipping 23 matching lines...) Expand all
45 def get_docstring(test_script): 46 def get_docstring(test_script):
46 """Hacky way to grab a first line of a module docstring using regexps.""" 47 """Hacky way to grab a first line of a module docstring using regexps."""
47 with open(test_script, 'rt') as f: 48 with open(test_script, 'rt') as f:
48 text = f.read() 49 text = f.read()
49 m = re.match(r'^.*"""(.*?)"""', text, re.DOTALL) 50 m = re.match(r'^.*"""(.*?)"""', text, re.DOTALL)
50 if not m: 51 if not m:
51 return None 52 return None
52 return m.group(1).strip().splitlines()[0] 53 return m.group(1).strip().splitlines()[0]
53 54
54 55
56 def find_cipd_client(out_dir):
57 """Returns path to cipd client built by build.py.
58
59 See build_cipd_client in build.py. It puts cipd client into
60 '<out_dir>/.cipd_client/cipd_<digest>' and there's only one such file there.
61
62 Prints error message and returns None if the file cannot be found.
63 """
64 out_dir = os.path.join(out_dir, '.cipd_client')
65 files = [f for f in os.listdir(out_dir) if f.startswith('cipd_')]
66 if not files:
67 print >> sys.stderr, 'Cannot find CIPD client in %s' % out_dir
68 return None
69 if len(files) != 1:
70 print >> sys.stderr, (
71 'There should be only one cipd client binary in %s, found %s' %
72 (out_dir, files))
73 return None
74 cipd_client = os.path.join(out_dir, files[0])
75 if not os.access(cipd_client, os.X_OK):
76 print >> sys.stderr, 'CIPD client at %s is not runnable'
77 return None
78 return cipd_client
79
80
55 def run_test(cipd_client, package, work_dir, test_script): 81 def run_test(cipd_client, package, work_dir, test_script):
56 """Extracts a package to a dir and runs test_script with cwd == work_dir.""" 82 """Extracts a package to a dir and runs test_script with cwd == work_dir."""
57 print_title('Deploying %s' % os.path.basename(package)) 83 print_title('Deploying %s' % os.path.basename(package))
58 if not os.access(cipd_client, os.X_OK):
59 print >> sys.stderr, (
60 'CIPD client at %s doesn\'t exist or not runnable. Run build.py to '
61 'build it.' % cipd_client)
62 return 1
63 cmd_line = ['cipd', 'pkg-deploy', '-root', work_dir, package] 84 cmd_line = ['cipd', 'pkg-deploy', '-root', work_dir, package]
64 print ' '.join(cmd_line) 85 print ' '.join(cmd_line)
65 if subprocess.call(args=cmd_line, executable=cipd_client): 86 if subprocess.call(args=cmd_line, executable=cipd_client):
66 raise TestException('Failed to install %s, see logs' % package) 87 raise TestException('Failed to install %s, see logs' % package)
67 88
68 print_title(get_docstring(test_script) or 'Running tests...') 89 print_title(get_docstring(test_script) or 'Running tests...')
69 cmd_line = ['python', test_script] 90 cmd_line = ['python', test_script]
70 print '%s in %s' % (' '.join(cmd_line), work_dir) 91 print '%s in %s' % (' '.join(cmd_line), work_dir)
71 env = os.environ.copy() 92 env = os.environ.copy()
72 env.pop('PYTHONPATH', None) 93 env.pop('PYTHONPATH', None)
73 ret = subprocess.call( 94 ret = subprocess.call(
74 args=cmd_line, executable=sys.executable, env=env, cwd=work_dir) 95 args=cmd_line, executable=sys.executable, env=env, cwd=work_dir)
75 if ret: 96 if ret:
76 raise TestException('Non zero exit code (%d)' % ret) 97 raise TestException('Non zero exit code (%d)' % ret)
77 98
78 99
79 def run( 100 def run(
80 cipd_client,
81 package_out_dir, 101 package_out_dir,
82 package_tests_dir, 102 package_tests_dir,
83 work_dir, 103 work_dir,
84 packages): 104 packages):
85 """Deployes build *.cipd package locally and runs tests against them. 105 """Deployes build *.cipd package locally and runs tests against them.
86 106
87 Used to verify the packaged code works when installed as CIPD package, it is 107 Used to verify the packaged code works when installed as CIPD package, it is
88 important for infra_python package that has non-trivial structure. 108 important for infra_python package that has non-trivial structure.
89 109
90 Args: 110 Args:
91 cipd_client: path to cipd client executable.
92 package_out_dir: where to search for built packages. 111 package_out_dir: where to search for built packages.
93 work_dir: where to install/update packages into. 112 work_dir: where to install/update packages into.
94 packages: names of *.cipd files in package_out_dir or [] for all. 113 packages: names of *.cipd files in package_out_dir or [] for all.
95 114
96 Returns: 115 Returns:
97 0 on success, 1 or error. 116 0 on success, 1 or error.
98 """ 117 """
99 # Discover what to test. 118 # Discover what to test.
100 paths = [] 119 paths = []
101 if not packages: 120 if not packages:
102 paths = glob.glob(os.path.join(package_out_dir, '*.cipd')) 121 # Enumerate all known tests in tests/*.py and filter them based on
Vadim Sh. 2016/06/25 03:51:04 this method no longer works, since package_out_dir
122 # availability of corresponding *.cipd package in package_out_dir. It will
123 # skip any cross-compiled packages, since they have additional '+<platform>'
124 # suffix in the package file name.
125 for test in os.listdir(package_tests_dir):
126 if not test.endswith('.py'):
127 continue
128 pkg_file = os.path.join(
129 package_out_dir, os.path.splitext(test)[0] + '.cipd')
130 if os.path.exists(pkg_file):
131 paths.append(pkg_file)
103 else: 132 else:
104 for name in packages: 133 for name in packages:
105 abs_path = os.path.join(package_out_dir, name) 134 abs_path = os.path.join(package_out_dir, name)
106 if not os.path.isfile(abs_path): 135 if not os.path.isfile(abs_path):
107 raise TestException('No such package file: %s' % name) 136 raise TestException('No such package file: %s' % name)
108 paths.append(abs_path) 137 paths.append(abs_path)
109 paths = sorted(paths) 138 paths = sorted(paths)
110 if not paths: 139 if not paths:
111 print 'Nothing to test.' 140 print 'Nothing to test.'
112 return 0 141 return 0
113 142
114 # Run all tests sequentially. There're like 2 of them tops. 143 cipd_client = find_cipd_client(package_out_dir)
144 if not cipd_client:
145 return 1
146
147 # Run all tests sequentially. Most of the are extra fast.
115 nuke_temp = False 148 nuke_temp = False
116 if not work_dir: 149 if not work_dir:
117 work_dir = tempfile.mkdtemp(suffix='cipd_test') 150 work_dir = tempfile.mkdtemp(suffix='cipd_test')
118 nuke_temp = True 151 nuke_temp = True
119 work_dir = os.path.abspath(work_dir) 152 work_dir = os.path.abspath(work_dir)
120 try: 153 try:
121 fail = False 154 fail = False
122 for path in paths: 155 for path in paths:
123 name = os.path.splitext(os.path.basename(path))[0] 156 name = os.path.splitext(os.path.basename(path))[0]
124 test_script = os.path.join(package_tests_dir, '%s.py' % name) 157 test_script = os.path.join(package_tests_dir, '%s.py' % name)
(...skipping 17 matching lines...) Expand all
142 finally: 175 finally:
143 if nuke_temp: 176 if nuke_temp:
144 try: 177 try:
145 shutil.rmtree(work_dir, ignore_errors=True) 178 shutil.rmtree(work_dir, ignore_errors=True)
146 except OSError as exc: 179 except OSError as exc:
147 print >> sys.stderr, 'Failed to delete %s: %s' % (work_dir, exc) 180 print >> sys.stderr, 'Failed to delete %s: %s' % (work_dir, exc)
148 181
149 182
150 def main( 183 def main(
151 args, 184 args,
152 go_workspace=os.path.join(ROOT, 'go'),
153 package_out_dir=os.path.join(ROOT, 'build', 'out'), 185 package_out_dir=os.path.join(ROOT, 'build', 'out'),
154 package_tests_dir=os.path.join(ROOT, 'build', 'tests')): 186 package_tests_dir=os.path.join(ROOT, 'build', 'tests')):
155 parser = argparse.ArgumentParser(description='Tests infra CIPD packages') 187 parser = argparse.ArgumentParser(description='Tests infra CIPD packages')
156 parser.add_argument( 188 parser.add_argument(
157 'packages', metavar='NAME', type=str, nargs='*', 189 'packages', metavar='NAME', type=str, nargs='*',
158 help='name of a build package file in build/out/* to deploy and test') 190 help='name of a built package file in build/out/* to deploy and test')
159 parser.add_argument( 191 parser.add_argument(
160 '--work-dir', metavar='DIR', dest='work_dir', 192 '--work-dir', metavar='DIR', dest='work_dir',
161 help='directory to deploy packages into (temporary dir by default)') 193 help='directory to deploy packages into (temporary dir by default)')
162 args = parser.parse_args(args) 194 args = parser.parse_args(args)
163 return run( 195 return run(
164 os.path.join(go_workspace, 'bin', 'cipd' + EXE_SUFFIX),
165 package_out_dir, 196 package_out_dir,
166 package_tests_dir, 197 package_tests_dir,
167 args.work_dir, 198 args.work_dir,
168 [n + '.cipd' if not n.endswith('.cipd') else n for n in args.packages]) 199 [n + '.cipd' if not n.endswith('.cipd') else n for n in args.packages])
169 200
170 201
171 if __name__ == '__main__': 202 if __name__ == '__main__':
172 sys.exit(main(sys.argv[1:])) 203 sys.exit(main(sys.argv[1:]))
OLDNEW
« build/packages/cipd_client.yaml ('K') | « build/packages/luci_machine_tokend.yaml ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698