• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#  Copyright 2016 Google Inc. All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS-IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import yaml
17
18# "smoke tests" are run before other build matrix rows.
19build_matrix_smoke_test_rows = []
20build_matrix_rows = []
21
22def determine_compiler_kind(compiler):
23  if compiler.startswith('gcc'):
24    return 'gcc'
25  elif compiler.startswith('clang'):
26    return 'clang'
27  else:
28    raise Exception('Unexpected compiler: %s' % compiler)
29
30def determine_tests(asan, ubsan, smoke_tests, use_precompiled_headers_in_tests, exclude_tests,
31                    include_only_tests):
32  tests = []
33  has_debug_build = False
34  tests += ['ReleasePlain']
35  if asan:
36    has_debug_build = True
37    if ubsan:
38      tests += ['DebugAsanUbsan']
39    else:
40      tests += ['DebugAsan']
41  if ubsan and not asan:
42    raise Exception('Enabling UBSan but not ASan is not currently supported.')
43  if not has_debug_build:
44    tests += ['DebugPlain']
45  for smoke_test in smoke_tests:
46    if smoke_test not in tests:
47      tests += [smoke_test]
48  excessive_excluded_tests = set(exclude_tests) - set(tests)
49  if excessive_excluded_tests:
50    raise Exception(
51      'Some tests were excluded but were not going to run anyway: %s. '
52      'Tests to run (ignoring the possible NoPch prefix): %s'
53      % (excessive_excluded_tests, tests))
54  if include_only_tests is not None:
55    if exclude_tests != []:
56      raise Exception('Using exclude_tests and include_only_tests together is not supported.')
57    tests = include_only_tests
58  else:
59    tests = [test for test in tests if test not in exclude_tests]
60  if not use_precompiled_headers_in_tests:
61    tests = [test + 'NoPch' for test in tests]
62  return tests
63
64def generate_export_statements_for_env(env):
65  return ' '.join(['export %s=\'%s\';' % (var_name, value) for (var_name, value) in sorted(env.items())])
66
67def generate_env_string_for_env(env):
68  return ' '.join(['%s=%s' % (var_name, value) for (var_name, value) in sorted(env.items())])
69
70def add_ubuntu_tests(ubuntu_version, compiler, os='linux', stl=None, asan=True, ubsan=True,
71                     use_precompiled_headers_in_tests=True, smoke_tests=[], exclude_tests=[], include_only_tests=None):
72  env = {
73    'UBUNTU': ubuntu_version,
74    'COMPILER': compiler
75  }
76  if stl is not None:
77    env['STL'] = stl
78  compiler_kind = determine_compiler_kind(compiler)
79  export_statements = 'export OS=' + os + '; ' + generate_export_statements_for_env(env=env)
80  test_environment_template = {'os': 'linux', 'compiler': compiler_kind,
81                               'install': '%s extras/scripts/travis_ci_install_linux.sh' % export_statements}
82  tests = determine_tests(asan, ubsan, smoke_tests,
83                          use_precompiled_headers_in_tests=use_precompiled_headers_in_tests,
84                          exclude_tests=exclude_tests,
85                          include_only_tests=include_only_tests)
86  for test in tests:
87    test_environment = test_environment_template.copy()
88    test_environment['script'] = '%s extras/scripts/postsubmit.sh %s' % (export_statements, test)
89    # The TEST variable has no effect on the test run, but allows to see the test name in the Travis CI dashboard.
90    test_environment['env'] = generate_env_string_for_env(env) + " TEST=%s" % test
91    if test in smoke_tests:
92      build_matrix_smoke_test_rows.append(test_environment)
93    else:
94      build_matrix_rows.append(test_environment)
95
96
97def add_osx_tests(compiler, xcode_version=None, stl=None, asan=True, ubsan=True,
98                  use_precompiled_headers_in_tests=True, smoke_tests=[], exclude_tests=[], include_only_tests=None):
99  env = {'COMPILER': compiler}
100  if stl is not None:
101    env['STL'] = stl
102  compiler_kind = determine_compiler_kind(compiler)
103  export_statements = 'export OS=osx; ' + generate_export_statements_for_env(env=env)
104  test_environment_template = {'os': 'osx', 'compiler': compiler_kind,
105                               'install': '%s extras/scripts/travis_ci_install_osx.sh' % export_statements}
106  if xcode_version is not None:
107    test_environment_template['osx_image'] = 'xcode%s' % xcode_version
108
109  tests = determine_tests(asan, ubsan, smoke_tests,
110                          use_precompiled_headers_in_tests=use_precompiled_headers_in_tests,
111                          exclude_tests=exclude_tests, include_only_tests=include_only_tests)
112  for test in tests:
113    test_environment = test_environment_template.copy()
114    test_environment['script'] = '%s extras/scripts/postsubmit.sh %s' % (export_statements, test)
115    # The TEST variable has no effect on the test run, but allows to see the test name in the Travis CI dashboard.
116    test_environment['env'] = generate_env_string_for_env(env) + " TEST=%s" % test
117    if test in smoke_tests:
118      build_matrix_smoke_test_rows.append(test_environment)
119    else:
120      build_matrix_rows.append(test_environment)
121
122
123def add_bazel_tests(ubuntu_version, smoke_tests=[]):
124  env = {
125    'UBUNTU': ubuntu_version,
126    'COMPILER': 'bazel',
127  }
128  test = 'DebugPlain'
129  export_statements = 'export OS=linux; ' + generate_export_statements_for_env(env=env)
130  test_environment = {'os': 'linux',
131                      'compiler': 'gcc',
132                      'env': generate_env_string_for_env(env),
133                      'install': '%s extras/scripts/travis_ci_install_linux.sh' % export_statements,
134                      'script': '%s extras/scripts/postsubmit.sh %s' % (export_statements, test)}
135  if test in smoke_tests:
136    build_matrix_smoke_test_rows.append(test_environment)
137  else:
138    build_matrix_rows.append(test_environment)
139
140# TODO: re-enable ASan/UBSan once they work in Travis CI. ATM (as of 18 November 2017) they fail due to https://github.com/google/sanitizers/issues/837
141add_ubuntu_tests(ubuntu_version='18.10', compiler='gcc-8', asan=False, ubsan=False, smoke_tests=['DebugPlain', 'ReleasePlain'])
142add_ubuntu_tests(ubuntu_version='18.10', compiler='clang-4.0', stl='libstdc++')
143add_ubuntu_tests(ubuntu_version='18.10', compiler='clang-7.0', stl='libstdc++', smoke_tests=['DebugPlain', 'DebugAsanUbsan', 'ReleasePlain'])
144
145add_bazel_tests(ubuntu_version='16.04', smoke_tests=['DebugPlain'])
146
147# ASan/UBSan are disabled for all these, the analysis on later versions is better anyway.
148# Also, in some combinations they wouldn't work.
149add_ubuntu_tests(ubuntu_version='14.04', compiler='gcc-5', asan=False, ubsan=False)
150add_ubuntu_tests(ubuntu_version='14.04', compiler='clang-3.5', stl='libstdc++', asan=False, ubsan=False)
151add_ubuntu_tests(ubuntu_version='14.04', compiler='clang-3.9', stl='libstdc++', asan=False, ubsan=False)
152add_ubuntu_tests(ubuntu_version='14.04', compiler='clang-3.5', stl='libc++', asan=False, ubsan=False)
153add_ubuntu_tests(ubuntu_version='14.04', compiler='clang-3.9', stl='libc++', asan=False, ubsan=False)
154
155# Asan/Ubsan are disabled because it generates lots of warnings like:
156#    warning: direct access in [...] to global weak symbol guard variable for [...] means the weak symbol cannot be
157#    overridden at runtime. This was likely caused by different translation units being compiled with different
158#    visibility settings.
159# and the build eventually fails or times out.
160add_osx_tests(compiler='gcc-5', xcode_version='8', asan=False, ubsan=False)
161add_osx_tests(compiler='gcc-6', xcode_version='8', asan=False, ubsan=False, smoke_tests=['DebugPlain'])
162add_osx_tests(compiler='clang-4.0', xcode_version='8', stl='libc++', smoke_tests=['DebugPlain'])
163
164# UBSan is disabled because AppleClang does not support -fsanitize=undefined.
165add_osx_tests(compiler='clang-default', xcode_version='7.3', stl='libc++', ubsan=False)
166# UBSan is disabled because AppleClang does not support -fsanitize=undefined.
167add_osx_tests(compiler='clang-default', xcode_version='8.2', stl='libc++', ubsan=False)
168
169add_osx_tests(compiler='clang-default', xcode_version='9.4', stl='libc++')
170add_osx_tests(compiler='clang-default', xcode_version='10', stl='libc++', smoke_tests=['DebugPlain'])
171
172# ** Disabled combinations **
173#
174# These fail with "'type_traits' file not found" (the <type_traits> header is missing).
175#
176#   add_osx_tests('gcc-default', stl='libstdc++')
177#   add_osx_tests('clang-default', stl='libstdc++')
178#   add_osx_tests('clang-3.5', stl='libstdc++')
179#   add_osx_tests('clang-3.6', stl='libstdc++')
180#
181#
182# The compiler complains that the 2-argument constructor of std::pair is ambiguous, even after
183# adding explicit casts to the exact types of the expected overload.
184#
185#   add_osx_tests('clang-default', stl='libc++')
186#
187#
188# This triggers an assert error in the compiler, with the message:
189# "expected to get called on an inlined function!" [...] function isMSExternInline, file Decl.cpp, line 2647.
190#
191#   add_osx_tests('clang-3.5', stl='libc++', asan=False, ubsan=False)
192#
193#
194# This fails with this error:
195# /usr/include/c++/v1/string:1938:44: error: 'basic_string<_CharT, _Traits, _Allocator>' is missing
196# exception specification 'noexcept(is_nothrow_copy_constructible<allocator_type>::value)'
197# TODO: Try again every once in a while (to re-enable these once the bug in libc++ is fixed).
198#
199#   add_ubuntu_tests(ubuntu_version='16.04', compiler='clang-3.8', stl='libc++', asan=False, ubsan=False)
200#
201
202
203yaml_file = {
204  'sudo': 'required',
205  'dist': 'trusty',
206  'services' : ['docker'],
207  'language': 'cpp',
208  'branches': {
209    'only': ['master'],
210  },
211  'matrix': {
212    'fast_finish': True,
213    'include': build_matrix_smoke_test_rows + build_matrix_rows,
214  },
215}
216
217class CustomDumper(yaml.SafeDumper):
218   def ignore_aliases(self, _data):
219       return True
220
221print('#')
222print('# This file was auto-generated from extras/scripts/travis_yml_generator.py, DO NOT EDIT')
223print('#')
224print(yaml.dump(yaml_file, default_flow_style=False, Dumper=CustomDumper))
225