Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / native_client_sdk / src / build_tools / test_sdk.py
blob7a4e774ed97c307021be5098dc1e4832f745b22f
1 #!/usr/bin/env python
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
4 # found in the LICENSE file.
6 """Script for a testing an existing SDK.
8 This script is normally run immediately after build_sdk.py.
9 """
11 import argparse
12 import os
13 import subprocess
14 import sys
16 import buildbot_common
17 import build_projects
18 import build_sdk
19 import build_version
20 import parse_dsc
22 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
23 SDK_SRC_DIR = os.path.dirname(SCRIPT_DIR)
24 SDK_LIBRARY_DIR = os.path.join(SDK_SRC_DIR, 'libraries')
25 SDK_DIR = os.path.dirname(SDK_SRC_DIR)
26 SRC_DIR = os.path.dirname(SDK_DIR)
27 OUT_DIR = os.path.join(SRC_DIR, 'out')
29 sys.path.append(os.path.join(SDK_SRC_DIR, 'tools'))
30 import getos
32 def StepBuildExamples(pepperdir):
33 for config in ('Debug', 'Release'):
34 build_sdk.BuildStepMakeAll(pepperdir, 'getting_started',
35 'Build Getting Started (%s)' % config,
36 deps=False, config=config)
38 build_sdk.BuildStepMakeAll(pepperdir, 'examples',
39 'Build Examples (%s)' % config,
40 deps=False, config=config)
43 def StepCopyTests(pepperdir, toolchains, build_experimental):
44 buildbot_common.BuildStep('Copy Tests')
46 # Update test libraries and test apps
47 filters = {
48 'DEST': ['tests']
50 if not build_experimental:
51 filters['EXPERIMENTAL'] = False
53 tree = parse_dsc.LoadProjectTree(SDK_SRC_DIR, include=filters)
54 build_projects.UpdateHelpers(pepperdir, clobber=False)
55 build_projects.UpdateProjects(pepperdir, tree, clobber=False,
56 toolchains=toolchains)
59 def StepBuildTests(pepperdir):
60 for config in ('Debug', 'Release'):
61 build_sdk.BuildStepMakeAll(pepperdir, 'tests',
62 'Build Tests (%s)' % config,
63 deps=False, config=config)
66 def StepRunSelLdrTests(pepperdir, sanitizer):
67 filters = {
68 'SEL_LDR': True
71 tree = parse_dsc.LoadProjectTree(SDK_SRC_DIR, include=filters)
73 def RunTest(test, toolchain, config, arch=None):
74 args = ['STANDALONE=1', 'TOOLCHAIN=%s' % toolchain]
75 if arch is not None:
76 args.append('NACL_ARCH=%s' % arch)
77 deps = False
79 if sanitizer is not None:
80 # For sanitizer builds we pass extra argument for make, and do
81 # full clean build to make sure everything is rebuilt with the
82 # correct flags
83 deps = True
84 if sanitizer == 'valgrind':
85 args += ['RUN_UNDER=valgrind']
86 elif sanitizer == 'address':
87 args += ['ASAN=1']
88 elif sanitizer == 'thread':
89 args += ['TSAN=1']
91 build_projects.BuildProjectsBranch(pepperdir, test, clean=False,
92 deps=deps, config=config,
93 args=args + ['run'])
95 if getos.GetPlatform() == 'win':
96 # On win32 we only support running on the system
97 # arch
98 archs = (getos.GetSystemArch('win'),)
99 elif getos.GetPlatform() == 'mac':
100 # We only ship 32-bit version of sel_ldr on mac.
101 archs = ('x86_32',)
102 else:
103 # On linux we can run both 32 and 64-bit, and arm (via qemu)
104 archs = ('x86_64', 'x86_32', 'arm')
106 for root, projects in tree.iteritems():
107 for project in projects:
108 if sanitizer:
109 sanitizer_name = '[sanitizer=%s]' % sanitizer
110 else:
111 sanitizer_name = ''
112 title = 'standalone test%s: %s' % (sanitizer_name,
113 os.path.basename(project['NAME']))
114 location = os.path.join(root, project['NAME'])
115 buildbot_common.BuildStep(title)
116 configs = ('Debug', 'Release')
118 # On linux we can run the standalone tests natively using the host
119 # compiler.
120 if getos.GetPlatform() == 'linux':
121 if sanitizer:
122 configs = ('Debug',)
123 for config in configs:
124 RunTest(location, 'linux', config)
126 if sanitizer:
127 continue
129 for toolchain in ('clang-newlib', 'newlib', 'glibc', 'pnacl'):
130 for arch in archs:
131 # TODO(sbc): Remove this once we get elf_loader.nexe added to the SDK
132 if toolchain == 'glibc' and arch == 'arm':
133 continue
134 for config in configs:
135 RunTest(location, toolchain, config, arch)
138 def StepRunBrowserTests(toolchains, experimental):
139 buildbot_common.BuildStep('Run Tests')
141 args = [
142 sys.executable,
143 os.path.join(SCRIPT_DIR, 'test_projects.py'),
144 '--retry-times=3',
147 if experimental:
148 args.append('-x')
149 for toolchain in toolchains:
150 args.extend(['-t', toolchain])
152 try:
153 subprocess.check_call(args)
154 except subprocess.CalledProcessError:
155 buildbot_common.ErrorExit('Error running tests.')
158 def main(args):
159 parser = argparse.ArgumentParser(description=__doc__)
160 parser.add_argument('--experimental', help='build experimental tests',
161 action='store_true')
162 parser.add_argument('--sanitizer',
163 help='Run sanitizer (asan/tsan/valgrind) tests',
164 action='store_true')
165 parser.add_argument('--verbose', '-v', help='Verbose output',
166 action='store_true')
167 parser.add_argument('phases', nargs="*")
169 if 'NACL_SDK_ROOT' in os.environ:
170 # We don't want the currently configured NACL_SDK_ROOT to have any effect
171 # of the build.
172 del os.environ['NACL_SDK_ROOT']
174 # To setup bash completion for this command first install optcomplete
175 # and then add this line to your .bashrc:
176 # complete -F _optcomplete test_sdk.py
177 try:
178 import optcomplete
179 optcomplete.autocomplete(parser)
180 except ImportError:
181 pass
183 options = parser.parse_args(args)
185 pepper_ver = str(int(build_version.ChromeMajorVersion()))
186 pepperdir = os.path.join(OUT_DIR, 'pepper_' + pepper_ver)
187 toolchains = ['clang-newlib', 'newlib', 'glibc', 'pnacl']
188 toolchains.append(getos.GetPlatform())
190 if options.verbose:
191 build_projects.verbose = True
193 phases = [
194 ('build_examples', StepBuildExamples, pepperdir),
195 ('copy_tests', StepCopyTests, pepperdir, toolchains, options.experimental),
196 ('build_tests', StepBuildTests, pepperdir),
197 ('sel_ldr_tests', StepRunSelLdrTests, pepperdir, None),
198 ('browser_tests', StepRunBrowserTests, toolchains, options.experimental),
201 if options.sanitizer:
202 if getos.GetPlatform() != 'linux':
203 buildbot_common.ErrorExit('sanitizer tests only run on linux.')
204 phases += [
205 ('sel_ldr_tests_asan', StepRunSelLdrTests, pepperdir, 'address'),
206 ('sel_ldr_tests_tsan', StepRunSelLdrTests, pepperdir, 'thread'),
207 ('sel_ldr_tests_valgrind', StepRunSelLdrTests, pepperdir, 'valgrind')
210 if options.phases:
211 phase_names = [p[0] for p in phases]
212 for arg in options.phases:
213 if arg not in phase_names:
214 msg = 'Invalid argument: %s\n' % arg
215 msg += 'Possible arguments:\n'
216 for name in phase_names:
217 msg += ' %s\n' % name
218 parser.error(msg.strip())
220 for phase in phases:
221 phase_name = phase[0]
222 if options.phases and phase_name not in options.phases:
223 continue
224 phase_func = phase[1]
225 phase_args = phase[2:]
226 phase_func(*phase_args)
228 return 0
231 if __name__ == '__main__':
232 try:
233 sys.exit(main(sys.argv[1:]))
234 except KeyboardInterrupt:
235 buildbot_common.ErrorExit('test_sdk: interrupted')