[travis] Use job matrix to split up builds to avoid timeout (#2423)

This commit is contained in:
jonathanmetzman 2019-05-15 11:01:53 -07:00 committed by GitHub
parent 95dd538c60
commit 898fc435c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 27 deletions

View File

@ -10,4 +10,33 @@ before_install:
install:
- pip install -r infra/travis/requirements.txt
matrix:
include:
- name: "libfuzzer address x86_64"
env:
- TRAVIS_ENGINE=libfuzzer
- TRAVIS_SANITIZER=address
- TRAVIS_ARCHITECTURE=x86_64
- name: "libfuzzer memory x86_64"
env:
- TRAVIS_ENGINE=libfuzzer
- TRAVIS_SANITIZER=memory
- TRAVIS_ARCHITECTURE=x86_64
- name: "libfuzzer undefined x86_64"
env:
- TRAVIS_SANITIZER=undefined
- TRAVIS_ENGINE=libfuzzer
- TRAVIS_ARCHITECTURE=x86_64
- name: "afl address x86_64"
env:
- TRAVIS_ENGINE=afl
- TRAVIS_SANITIZER=address
- TRAVIS_ARCHITECTURE=x86_64
- name: "none address x86_64"
env:
- TRAVIS_ENGINE=none
- TRAVIS_SANITIZER=address
- TRAVIS_ARCHITECTURE=x86_64
# TODO(metzman) Add a libfuzzer address i386 job.
script: ./infra/travis/travis_build.py

View File

@ -23,7 +23,8 @@ import re
import subprocess
import yaml
DEFAULT_FUZZING_ENGINES = ['afl', 'libfuzzer']
DEFAULT_ARCHITECTURES = ['x86_64']
DEFAULT_ENGINES = ['afl', 'libfuzzer']
DEFAULT_SANITIZERS = ['address', 'undefined']
@ -53,57 +54,62 @@ def execute_helper_command(helper_command):
subprocess.check_call(command)
def build_fuzzers(project, sanitizer, engine, architecture='x86_64'):
def build_fuzzers(project, engine, sanitizer, architecture):
"""Execute helper.py's build_fuzzers command on |project|. Build the fuzzers
with |sanitizer| and |engine|."""
with |engine| and |sanitizer| for |architecture|."""
execute_helper_command([
'build_fuzzers', project, '--engine', engine, '--sanitizer', sanitizer,
'--architecture', architecture
])
def check_build(project, sanitizer, engine, architecture='x86_64'):
def check_build(project, engine, sanitizer, architecture):
"""Execute helper.py's check_build command on |project|, assuming it was most
recently built with |sanitizer| and |engine|."""
recently built with |engine| and |sanitizer| for |architecture|."""
execute_helper_command([
'check_build', project, '--engine', engine, '--sanitizer', sanitizer,
'--architecture', architecture
])
def should_build(project_yaml):
"""Is the build specified by travis enabled in the |project_yaml|?"""
def is_enabled(env_var, yaml_name, defaults):
"""Is the value of |env_var| enabled in |project_yaml| (in the |yaml_name|
section)? Uses |defaults| if |yaml_name| section is unspecified."""
return os.getenv(env_var) in project_yaml.get(yaml_name, defaults)
return (is_enabled('TRAVIS_ENGINE', 'fuzzing_engines', DEFAULT_ENGINES) and
is_enabled('TRAVIS_SANITIZER', 'sanitizers', DEFAULT_SANITIZERS) and
is_enabled(
'TRAVIS_ARCHITECTURE', 'architectures', DEFAULT_ARCHITECTURES))
def build_project(project):
"""Do all build of |project|."""
print('Building project', project)
"""Do the build of |project| that is specified by the TRAVIS_* environment
variables (TRAVIS_SANITIZER, TRAVIS_ENGINE, and TRAVIS_ARCHITECTURE)."""
root = get_oss_fuzz_root()
project_yaml_path = os.path.join(root, 'projects', project, 'project.yaml')
with open(project_yaml_path) as fp:
project_yaml = yaml.safe_load(fp)
if project_yaml.get('disabled', False):
print('Project {0} is disabled, not building.'.format(project))
return
fuzzing_engines = project_yaml.get('fuzzing_engines', DEFAULT_FUZZING_ENGINES)
if 'none' in fuzzing_engines:
# no engine builds always use ASAN.
build_fuzzers(project, 'address', 'none')
engine = os.getenv('TRAVIS_ENGINE')
sanitizer = os.getenv('TRAVIS_SANITIZER')
architecture = os.getenv('TRAVIS_ARCHITECTURE')
if not should_build(project_yaml):
print(('Specified build: engine: {0}, sanitizer: {1}, architecture: {2} '
'not enabled for this project: {3}. Not building.').format(
engine, sanitizer, architecture, project))
return
if 'afl' in fuzzing_engines:
# AFL builds always use ASAN.
build_fuzzers(project, 'address', 'afl')
check_build(project, 'address', 'afl')
if 'libfuzzer' not in fuzzing_engines:
return
for sanitizer in project_yaml.get('sanitizers', DEFAULT_SANITIZERS):
build_fuzzers(project, sanitizer, 'libfuzzer')
check_build(project, sanitizer, 'libfuzzer')
if 'i386' in project_yaml.get('architectures', []):
# i386 builds always use libFuzzer and ASAN.
build_fuzzers(project, 'address', 'libfuzzer', 'i386')
check_build(project, 'address', 'libfuzzer', 'i386')
print('Building project', project)
build_fuzzers(project, engine, sanitizer, architecture)
check_build(project, engine, sanitizer, architecture)
def main():