aboutsummaryrefslogtreecommitdiffhomepage
path: root/infra
diff options
context:
space:
mode:
authorGravatar jonathanmetzman <31354670+jonathanmetzman@users.noreply.github.com>2021-11-01 08:29:38 -0400
committerGravatar GitHub <noreply@github.com>2021-11-01 12:29:38 +0000
commit36e5931a19707da5d72f8f9bbcf3d28b190bfba3 (patch)
treef4e747d4edda69bdb94f4bf5fd45e36c52fae2f8 /infra
parent446b56c31b008f69ce1f12279ab0eb642ba12156 (diff)
Make a better api for platform specific config. (#6708)
1. Move most of the generic stuff into BasePlatformConfig. 2. Make a GCB platform config that sets WORKSPACE and PROJECT_SRC_PATH so users don't have to. 3. Make a skeleton prow platform_config for Mitchel to fill out. 4. Make users explicitly specify the CFL_PLATFORM so we can pick CI environments
Diffstat (limited to 'infra')
-rw-r--r--infra/cifuzz/actions/build_fuzzers/action.yml1
-rw-r--r--infra/cifuzz/actions/run_fuzzers/action.yml1
-rw-r--r--infra/cifuzz/affected_fuzz_targets_test.py2
-rw-r--r--infra/cifuzz/build_fuzzers_test.py16
-rw-r--r--infra/cifuzz/clusterfuzz_deployment_test.py10
-rw-r--r--infra/cifuzz/config_utils.py355
-rw-r--r--infra/cifuzz/config_utils_test.py106
-rw-r--r--infra/cifuzz/external-actions/build_fuzzers/action.yml1
-rw-r--r--infra/cifuzz/external-actions/run_fuzzers/action.yml1
-rw-r--r--infra/cifuzz/filestore/github_actions/github_actions_test.py4
-rw-r--r--infra/cifuzz/filestore_utils_test.py8
-rw-r--r--infra/cifuzz/fuzz_target_test.py2
-rw-r--r--infra/cifuzz/platform_config/__init__.py112
-rw-r--r--infra/cifuzz/platform_config/gcb.py35
-rw-r--r--infra/cifuzz/platform_config/github.py145
-rw-r--r--infra/cifuzz/platform_config/github_test.py87
-rw-r--r--infra/cifuzz/platform_config/platform_config_test.py82
-rw-r--r--infra/cifuzz/platform_config/prow.py22
-rw-r--r--infra/cifuzz/run_fuzzers_test.py6
-rw-r--r--infra/cifuzz/test_helpers.py3
20 files changed, 554 insertions, 445 deletions
diff --git a/infra/cifuzz/actions/build_fuzzers/action.yml b/infra/cifuzz/actions/build_fuzzers/action.yml
index cc278455..85aba863 100644
--- a/infra/cifuzz/actions/build_fuzzers/action.yml
+++ b/infra/cifuzz/actions/build_fuzzers/action.yml
@@ -38,3 +38,4 @@ runs:
LOW_DISK_SPACE: 'True'
BAD_BUILD_CHECK: ${{ inputs.bad-build-check }}
CIFUZZ_DEBUG: 'True'
+ CFL_PLATFORM: 'github'
diff --git a/infra/cifuzz/actions/run_fuzzers/action.yml b/infra/cifuzz/actions/run_fuzzers/action.yml
index 59309fd2..ff326525 100644
--- a/infra/cifuzz/actions/run_fuzzers/action.yml
+++ b/infra/cifuzz/actions/run_fuzzers/action.yml
@@ -54,3 +54,4 @@ runs:
LOW_DISK_SPACE: 'True'
REPORT_UNREPRODUCIBLE_CRASHES: ${{ inputs.report-unreproducible-crashes }}
CIFUZZ_DEBUG: 'True'
+ CFL_PLATFORM: 'github'
diff --git a/infra/cifuzz/affected_fuzz_targets_test.py b/infra/cifuzz/affected_fuzz_targets_test.py
index 823654d1..aed05842 100644
--- a/infra/cifuzz/affected_fuzz_targets_test.py
+++ b/infra/cifuzz/affected_fuzz_targets_test.py
@@ -61,7 +61,7 @@ class RemoveUnaffectedFuzzTargets(unittest.TestCase):
def test_remove_unaffected_fuzz_targets(self, side_effect, expected_dir_len):
"""Tests that remove_unaffected_fuzzers has the intended effect."""
config = test_helpers.create_run_config(
- is_github=True,
+ cfl_platform='github',
oss_fuzz_project_name=EXAMPLE_PROJECT,
workspace='/workspace')
workspace = workspace_utils.Workspace(config)
diff --git a/infra/cifuzz/build_fuzzers_test.py b/infra/cifuzz/build_fuzzers_test.py
index 31c055e4..daaf84b4 100644
--- a/infra/cifuzz/build_fuzzers_test.py
+++ b/infra/cifuzz/build_fuzzers_test.py
@@ -105,9 +105,9 @@ class InternalGithubBuildTest(unittest.TestCase):
sanitizer=self.SANITIZER,
git_sha=self.GIT_SHA,
pr_ref=self.PR_REF,
- is_github=True)
- ci_system = continuous_integration.get_ci(config)
- builder = build_fuzzers.Builder(config, ci_system)
+ cfl_platform='github')
+ cfl_platform = continuous_integration.get_ci(config)
+ builder = build_fuzzers.Builder(config, cfl_platform)
builder.repo_manager = repo_manager.RepoManager('/fake')
return builder
@@ -181,7 +181,7 @@ class BuildFuzzersIntegrationTest(unittest.TestCase):
workspace=self.workspace,
git_url=git_url,
git_sha='HEAD',
- is_github=True,
+ cfl_platform='github',
base_commit='HEAD^1')
self.assertTrue(build_fuzzers.build_fuzzers(config))
self.assertTrue(
@@ -217,7 +217,7 @@ class BuildFuzzersIntegrationTest(unittest.TestCase):
workspace=self.workspace,
git_sha='0b95fe1039ed7c38fea1f97078316bfc1030c523',
base_commit='da0746452433dc18bae699e355a9821285d863c8',
- is_github=True)
+ cfl_platform='github')
self.assertTrue(build_fuzzers.build_fuzzers(config))
self.assertTrue(
os.path.exists(os.path.join(self.out_dir, EXAMPLE_BUILD_FUZZER)))
@@ -230,7 +230,7 @@ class BuildFuzzersIntegrationTest(unittest.TestCase):
workspace=self.workspace,
pr_ref='refs/pull/1757/merge',
base_ref='master',
- is_github=True)
+ cfl_platform='github')
self.assertTrue(build_fuzzers.build_fuzzers(config))
self.assertTrue(
os.path.exists(os.path.join(self.out_dir, EXAMPLE_BUILD_FUZZER)))
@@ -243,7 +243,7 @@ class BuildFuzzersIntegrationTest(unittest.TestCase):
workspace=self.workspace,
pr_ref='ref-1/merge',
base_ref='master',
- is_github=True)
+ cfl_platform='github')
self.assertTrue(build_fuzzers.build_fuzzers(config))
def test_invalid_oss_fuzz_project_name(self):
@@ -271,7 +271,7 @@ class BuildFuzzersIntegrationTest(unittest.TestCase):
project_repo_name='oss-fuzz',
workspace=self.workspace,
git_sha='',
- is_github=True)
+ cfl_platform='github')
with self.assertRaises(AssertionError):
build_fuzzers.build_fuzzers(config)
diff --git a/infra/cifuzz/clusterfuzz_deployment_test.py b/infra/cifuzz/clusterfuzz_deployment_test.py
index a7cbf3d2..31c7b03e 100644
--- a/infra/cifuzz/clusterfuzz_deployment_test.py
+++ b/infra/cifuzz/clusterfuzz_deployment_test.py
@@ -43,7 +43,7 @@ def _create_config(**kwargs):
|kwargs| to the corresponding value. Asserts that each key in |kwargs| is an
attribute of Config."""
defaults = {
- 'is_github': True,
+ 'cfl_platform': 'github',
'oss_fuzz_project_name': EXAMPLE_PROJECT,
'workspace': WORKSPACE,
}
@@ -132,8 +132,7 @@ class ClusterFuzzLiteTest(fake_filesystem_unittest.TestCase):
self.setUpPyfakefs()
self.deployment = _create_deployment(mode='batch',
oss_fuzz_project_name='',
- cloud_bucket='gs://bucket',
- is_github=True)
+ cloud_bucket='gs://bucket')
self.corpus_dir = os.path.join(self.deployment.workspace.corpora,
EXAMPLE_FUZZER)
@@ -196,7 +195,7 @@ class NoClusterFuzzDeploymentTest(fake_filesystem_unittest.TestCase):
def setUp(self):
self.setUpPyfakefs()
config = test_helpers.create_run_config(workspace=WORKSPACE,
- is_github=False,
+ cfl_platform='other',
filestore='no_filestore',
no_clusterfuzz_deployment=True)
workspace = workspace_utils.Workspace(config)
@@ -255,7 +254,8 @@ class GetClusterFuzzDeploymentTest(unittest.TestCase):
return_value=platform,
new_callable=mock.PropertyMock):
with mock.patch('filestore_utils.get_filestore', return_value=None):
- with mock.patch('config_utils._get_event_data', return_value={}):
+ with mock.patch('platform_config.github._get_event_data',
+ return_value={}):
config = _create_config()
workspace = workspace_utils.Workspace(config)
diff --git a/infra/cifuzz/config_utils.py b/infra/cifuzz/config_utils.py
index b29f3095..e6563359 100644
--- a/infra/cifuzz/config_utils.py
+++ b/infra/cifuzz/config_utils.py
@@ -13,17 +13,18 @@
# limitations under the License.
"""Module for getting the configuration CIFuzz needs to run."""
-import logging
import enum
+import importlib
+import logging
import os
import sys
-import json
import environment
# pylint: disable=wrong-import-position,import-error
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+import platform_config
import constants
SANITIZERS = ['address', 'memory', 'undefined', 'coverage']
@@ -59,293 +60,13 @@ def _get_language():
return os.getenv('LANGUAGE', constants.DEFAULT_LANGUAGE)
-# pylint: disable=too-few-public-methods,too-many-instance-attributes
-
-
-class BaseCiEnvironment:
- """Base class for CiEnvironment subclasses."""
-
- @property
- def workspace(self):
- """Returns the workspace."""
- raise NotImplementedError('Child class must implement method.')
-
- @property
- def git_sha(self):
- """Returns the Git SHA to checkout and fuzz. This is used only by GitHub
- projects when commit fuzzing. It is not used when PR fuzzing. It is
- definitely needed by OSS-Fuzz on GitHub since they have no copy of the repo
- on the host and the repo on the builder image is a clone from main/master.
- Right now it is needed by external on GitHub because we need to clone a new
- repo because the copy they give us doesn't work for diffing.
-
- TODO(metzman): Try to eliminate the need for this by 1. Making the clone
- from external github projects usable. 2. Forcing OSS-Fuzz on Github to clone
- before starting CIFuzz."""
- raise NotImplementedError('Child class must implement method.')
-
- @property
- def actor(self):
- """Name of the actor for the CI."""
- raise NotImplementedError('Child class must implement method.')
-
- @property
- def token(self):
- """Returns the CI API token."""
- raise NotImplementedError('Child class must implement method.')
-
- @property
- def project_src_path(self):
- """Returns the manually checked out path of the project's source if
- specified or None."""
-
- path = os.getenv('PROJECT_SRC_PATH')
- if not path:
- logging.debug('No PROJECT_SRC_PATH.')
- return path
-
- logging.debug('PROJECT_SRC_PATH set: %s.', path)
- return path
-
- @property
- def base_commit(self):
- """Returns the base commit to diff against (commit fuzzing)."""
- raise NotImplementedError('Child class must implement method.')
-
- @property
- def pr_ref(self):
- """Returns the pull request to checkout and fuzz. This is used only by
- GitHub projects when PR fuzzing. It is not used when commit fuzzing. It is
- definitely needed by OSS-Fuzz on GitHub since they have no copy of the repo
- on the host and the repo on the builder image is a clone from main/master.
- Right now it is needed by external on GitHub because we need to clone a new
- repo because the copy they give us doesn't work for diffing.
-
- TODO(metzman): Try to eliminate the need for this by 1. Making the clone
- from external github projects usable. 2. Forcing OSS-Fuzz on Github to clone
- before starting CIFuzz."""
- raise NotImplementedError('Child class must implement method.')
-
- @property
- def base_ref(self):
- """Returns the base branch to diff against (pr fuzzing)."""
- raise NotImplementedError('Child class must implement method.')
-
- @property
- def git_url(self):
- """Returns the repo URL. This is only used by GitHub users. Right now it is
- needed by external on GitHub because we need to clone a new repo because the
- copy they give us doesn't work for diffing. It isn't used by OSS-Fuzz on
- github users since the Git URL is determined using repo detection.
-
- TODO(metzman): Try to eliminate the need for this by making the clone
- from external github projects usable.
- TODO(metzman): As an easier goal, maybe make OSS-Fuzz GitHub use this too
- for: 1. Consistency 2. Maybe it will allow use on forks."""
- raise NotImplementedError('Child class must implement method.')
-
-
-class GenericCiEnvironment(BaseCiEnvironment):
- """CI Environment for generic CI systems."""
-
- @property
- def workspace(self):
- """Returns the workspace."""
- return os.getenv('WORKSPACE')
-
- @property
- def git_sha(self):
- """Returns the Git SHA to checkout and fuzz. This is used only by GitHub
- projects when commit fuzzing. It is not used when PR fuzzing. It is
- definitely needed by OSS-Fuzz on GitHub since they have no copy of the repo
- on the host and the repo on the builder image is a clone from main/master.
- Right now it is needed by external on GitHub because we need to clone a new
- repo because the copy they give us doesn't work for diffing.
-
- TODO(metzman): Try to eliminate the need for this by 1. Making the clone
- from external github projects usable. 2. Forcing OSS-Fuzz on Github to clone
- before starting CIFuzz."""
- return None
-
- @property
- def token(self):
- """Returns the CI API token."""
- return os.getenv('TOKEN')
-
- @property
- def actor(self):
- """Name of the actor for the CI."""
- return os.getenv('ACTOR')
-
- @property
- def project_repo_owner_and_name(self):
- """Returns a tuple containing the project repo owner and None."""
- repository = os.getenv('REPOSITORY')
- # Repo owner is a githubism.
- return None, repository
-
- @property
- def git_url(self):
- """Returns the repo URL. This is only used by GitHub users. Right now it is
- needed by external on GitHub because we need to clone a new repo because the
- copy they give us doesn't work for diffing. It isn't used by OSS-Fuzz on
- github users since the Git URL is determined using repo detection.
-
- TODO(metzman): Try to eliminate the need for this by making the clone
- from external github projects usable.
- TODO(metzman): As an easier goal, maybe make OSS-Fuzz GitHub use this too
- for: 1. Consistency 2. Maybe it will allow use on forks."""
- return None
-
- @property
- def base_commit(self):
- """Returns the base commit to diff against (commit fuzzing)."""
- return os.getenv('GIT_BASE_COMMIT')
-
- @property
- def pr_ref(self):
- """Returns the pull request to checkout and fuzz. This is used only by
- GitHub projects when PR fuzzing. It is not used when commit fuzzing. It is
- definitely needed by OSS-Fuzz on GitHub since they have no copy of the repo
- on the host and the repo on the builder image is a clone from main/master.
- Right now it is needed by external on GitHub because we need to clone a new
- repo because the copy they give us doesn't work for diffing.
-
- TODO(metzman): Try to eliminate the need for this by 1. Making the clone
- from external github projects usable. 2. Forcing OSS-Fuzz on Github to clone
- before starting CIFuzz."""
- return None
-
- @property
- def base_ref(self):
- """Returns the base branch to diff against (pr fuzzing)."""
- return os.getenv('GIT_BASE_REF')
-
-
-def _get_event_data():
- github_event_path = _get_github_event_path()
- with open(github_event_path, encoding='utf-8') as file_handle:
- return json.load(file_handle)
-
-
-class GithubEnvironment(BaseCiEnvironment):
- """CI environment for GitHub."""
-
- def __init__(self):
- self._event_data = _get_event_data()
- self._event = os.getenv('GITHUB_EVENT_NAME')
-
- @property
- def workspace(self):
- """Returns the workspace."""
- return os.getenv('GITHUB_WORKSPACE')
-
- @property
- def git_sha(self):
- """Returns the Git SHA to checkout and fuzz. This is used only by GitHub
- projects when commit fuzzing. It is not used when PR fuzzing. It is
- definitely needed by OSS-Fuzz on GitHub since they have no copy of the repo
- on the host and the repo on the builder image is a clone from main/master.
- Right now it is needed by external on GitHub because we need to clone a new
- repo because the copy they give us doesn't work for diffing.
-
- TODO(metzman): Try to eliminate the need for this by 1. Making the clone
- from external github projects usable. 2. Forcing OSS-Fuzz on Github to clone
- before starting CIFuzz."""
- return os.getenv('GITHUB_SHA')
-
- @property
- def actor(self):
- """Name of the actor for the CI."""
- return os.getenv('GITHUB_ACTOR')
-
- @property
- def token(self):
- """Returns the CI API token."""
- return os.getenv('GITHUB_TOKEN')
-
- @property
- def project_src_path(self):
- """Returns the manually checked out path of the project's source if
- specified or None. The path returned is relative to |self.workspace| since
- on github the checkout will be relative to there."""
- # On GitHub, they don't know the absolute path, it is relative to
- # |workspace|.
- project_src_path = super().project_src_path
- if project_src_path is None:
- return project_src_path
- return os.path.join(self.workspace, project_src_path)
-
- @property
- def project_repo_owner_and_name(self):
- """Returns a tuple containing the project repo owner and the name of the
- repo."""
- # On GitHub this includes owner and repo name.
- repository = os.getenv('GITHUB_REPOSITORY')
- # Use os.path.split to split owner from repo.
- return os.path.split(repository)
-
- @property
- def git_url(self):
- """Returns the repo URL. This is only used by GitHub users. Right now it is
- needed by external on GitHub because we need to clone a new repo because the
- copy they give us doesn't work for diffing. It isn't used by OSS-Fuzz on
- github users since the Git URL is determined using repo detection.
-
- TODO(metzman): Try to eliminate the need for this by making the clone
- from external github projects usable.
- TODO(metzman): As an easier goal, maybe make OSS-Fuzz GitHub use this too
- for: 1. Consistency 2. Maybe it will allow use on forks."""
- repository = os.getenv('GITHUB_REPOSITORY')
- # TODO(metzman): Probably need to change this to github.server_url.
- return f'https://github.com/{repository}.git'
-
- @property
- def base_commit(self):
- """Returns the base commit to diff against (commit fuzzing)."""
- base_commit = None
- if self._event == 'push':
- base_commit = self._event_data['before']
- logging.debug('base_commit: %s', base_commit)
- return base_commit
-
- @property
- def pr_ref(self):
- """Returns the pull request to checkout and fuzz. This is used only by
- GitHub projects when PR fuzzing. It is not used when commit fuzzing. It is
- definitely needed by OSS-Fuzz on GitHub since they have no copy of the repo
- on the host and the repo on the builder image is a clone from main/master.
- Right now it is needed by external on GitHub because we need to clone a new
- repo because the copy they give us doesn't work for diffing.
-
- TODO(metzman): Try to eliminate the need for this by 1. Making the clone
- from external github projects usable. 2. Forcing OSS-Fuzz on Github to clone
- before starting CIFuzz."""
- if self._event == 'pull_request':
- pr_ref = f'refs/pull/{self._event_data["pull_request"]["number"]}/merge'
- logging.debug('pr_ref: %s', pr_ref)
- return pr_ref
- return None
-
- @property
- def base_ref(self):
- """Returns the base branch to diff against (pr fuzzing)."""
- return os.getenv('GITHUB_BASE_REF')
+# pylint: disable=too-many-instance-attributes
class ConfigError(Exception):
"""Error for invalid configuration."""
-def _is_github():
- """Returns True if running on Github Actions."""
- return bool(_get_github_event_path())
-
-
-def _get_github_event_path():
- return os.getenv('GITHUB_EVENT_PATH')
-
-
class BaseConfig:
"""Object containing constant configuration for CIFuzz."""
@@ -356,43 +77,44 @@ class BaseConfig:
INTERNAL_GENERIC_CI = 2 # OSS-Fuzz on any CI.
EXTERNAL_GENERIC_CI = 3 # Non-OSS-Fuzz on any CI.
+ @property
+ def is_github(self):
+ """Returns True if running on GitHub."""
+ return self.cfl_platform == 'github'
+
def __init__(self):
# Need to set these before calling self.platform.
- self.is_github = _is_github()
- logging.debug('Is github: %s.', self.is_github)
-
self.oss_fuzz_project_name = os.getenv('OSS_FUZZ_PROJECT_NAME')
- self._ci_env = _get_ci_environment(self.platform)
- self.base_commit = self._ci_env.base_commit
- self.base_ref = self._ci_env.base_ref
- self.pr_ref = self._ci_env.pr_ref
- self.workspace = self._ci_env.workspace
-
- self.project_repo_owner, self.project_repo_name = (
- self._ci_env.project_repo_owner_and_name)
-
- # Check if failures should not be reported.
- self.dry_run = _is_dry_run()
+ self.cfl_platform = os.getenv('CFL_PLATFORM')
+ logging.debug('Is github: %s.', self.is_github)
+ self.platform_conf = _get_platform_config(self.cfl_platform)
+ self.base_commit = self.platform_conf.base_commit
+ self.base_ref = self.platform_conf.base_ref
+ self.pr_ref = self.platform_conf.pr_ref
+ self.workspace = self.platform_conf.workspace
+ self.project_src_path = self.platform_conf.project_src_path
+ self.actor = self.platform_conf.actor
+ self.token = self.platform_conf.token
+ self.project_repo_owner = self.platform_conf.project_repo_owner
+ self.project_repo_name = self.platform_conf.project_repo_name
+
+ self.dry_run = _is_dry_run() # Check if failures should not be reported.
self.sanitizer = _get_sanitizer()
-
- self.build_integration_path = (
- constants.DEFAULT_EXTERNAL_BUILD_INTEGRATION_PATH)
self.language = _get_language()
self.low_disk_space = environment.get_bool('LOW_DISK_SPACE', False)
- self.actor = self._ci_env.actor
- self.token = self._ci_env.token
self.git_store_repo = os.environ.get('GIT_STORE_REPO')
self.git_store_branch = os.environ.get('GIT_STORE_BRANCH')
self.git_store_branch_coverage = os.environ.get('GIT_STORE_BRANCH_COVERAGE',
self.git_store_branch)
- self.project_src_path = self._ci_env.project_src_path
self.docker_in_docker = os.environ.get('DOCKER_IN_DOCKER')
self.filestore = os.environ.get('FILESTORE')
self.cloud_bucket = os.environ.get('CLOUD_BUCKET')
- self.no_clusterfuzz_deployment = os.environ.get('NO_CLUSTERFUZZ_DEPLOYMENT',
- False)
+ self.no_clusterfuzz_deployment = environment.get_bool(
+ 'NO_CLUSTERFUZZ_DEPLOYMENT', False)
+ self.build_integration_path = (
+ constants.DEFAULT_EXTERNAL_BUILD_INTEGRATION_PATH)
# TODO(metzman): Fix tests to create valid configurations and get rid of
# CIFUZZ_TEST here and in presubmit.py.
@@ -447,17 +169,14 @@ class BaseConfig:
return self.sanitizer == 'coverage'
-_CI_ENVIRONMENT_MAPPING = {
- BaseConfig.Platform.EXTERNAL_GITHUB: GithubEnvironment,
- BaseConfig.Platform.INTERNAL_GITHUB: GithubEnvironment,
- BaseConfig.Platform.INTERNAL_GENERIC_CI: GenericCiEnvironment,
- BaseConfig.Platform.EXTERNAL_GENERIC_CI: GenericCiEnvironment,
-}
-
-
-def _get_ci_environment(platform):
- """Returns the CI environment object for |platform|."""
- return _CI_ENVIRONMENT_MAPPING[platform]()
+def _get_platform_config(cfl_platform):
+ """Returns the CI environment object for |cfl_platform|."""
+ module_name = f'platform_config.{cfl_platform}'
+ try:
+ cls = importlib.import_module(module_name).PlatformConfig
+ except ImportError:
+ cls = platform_config.BasePlatformConfig
+ return cls()
class RunFuzzersConfig(BaseConfig):
@@ -500,8 +219,8 @@ class BuildFuzzersConfig(BaseConfig):
"""Get the configuration from CIFuzz from the environment. These variables
are set by GitHub or the user."""
super().__init__()
- self.git_sha = self._ci_env.git_sha
- self.git_url = self._ci_env.git_url
+ self.git_sha = self.platform_conf.git_sha
+ self.git_url = self.platform_conf.git_url
self.allowed_broken_targets_percentage = os.getenv(
'ALLOWED_BROKEN_TARGETS_PERCENTAGE')
diff --git a/infra/cifuzz/config_utils_test.py b/infra/cifuzz/config_utils_test.py
index a54bb9d1..cb82dee4 100644
--- a/infra/cifuzz/config_utils_test.py
+++ b/infra/cifuzz/config_utils_test.py
@@ -20,7 +20,7 @@ import config_utils
import constants
import test_helpers
-# pylint: disable=no-self-use,protected-access,arguments-differ
+# pylint: disable=no-self-use,protected-access
class BaseConfigTest(unittest.TestCase):
@@ -105,12 +105,12 @@ class BuildFuzzersConfigTest(unittest.TestCase):
def _create_config(self):
return config_utils.BuildFuzzersConfig()
- @mock.patch('config_utils._get_event_data', return_value={})
+ @mock.patch('platform_config.github._get_event_data', return_value={})
def test_github_base_ref(self, _):
"""Tests that base_ref is set properly."""
expected_base_ref = 'expected_base_ref'
os.environ['GITHUB_BASE_REF'] = expected_base_ref
- os.environ['GITHUB_EVENT_PATH'] = '/event'
+ os.environ['CFL_PLATFORM'] = 'github'
os.environ['GITHUB_REPOSITORY'] = 'owner/repo'
config = self._create_config()
self.assertEqual(config.base_ref, expected_base_ref)
@@ -174,71 +174,6 @@ class RunFuzzersConfigTest(unittest.TestCase):
config_utils.RunFuzzersConfig.MODES)
-class GetProjectRepoOwnerAndNameTest(unittest.TestCase):
- """Tests for BaseCiEnv.get_project_repo_owner_and_name."""
-
- @mock.patch('config_utils._get_event_data', return_value={})
- def setUp(self, _):
- test_helpers.patch_environ(self)
- self.repo_owner = 'repo-owner'
- self.repo_name = 'repo-name'
- self.github_env = config_utils.GithubEnvironment()
- self.generic_ci_env = config_utils.GenericCiEnvironment()
-
- def test_unset_repository(self):
- """Tests that the correct result is returned when repository is not set."""
- self.assertEqual(self.generic_ci_env.project_repo_owner_and_name,
- (None, None))
-
- def test_empty_repository(self):
- """Tests that the correct result is returned when repository is an empty
- string."""
- os.environ['REPOSITORY'] = ''
- self.assertEqual(self.generic_ci_env.project_repo_owner_and_name,
- (None, ''))
-
- def test_github_repository(self):
- """Tests that the correct result is returned when repository contains the
- owner and repo name (as it does on GitHub)."""
- os.environ['GITHUB_REPOSITORY'] = f'{self.repo_owner}/{self.repo_name}'
- self.assertEqual(self.github_env.project_repo_owner_and_name,
- (self.repo_owner, self.repo_name))
-
- def test_nongithub_repository(self):
- """Tests that the correct result is returned when repository contains the
- just the repo name (as it does outside of GitHub)."""
- os.environ['REPOSITORY'] = self.repo_name
- self.assertEqual(self.generic_ci_env.project_repo_owner_and_name,
- (None, self.repo_name))
-
-
-class GetGitUrlTest(unittest.TestCase):
- """Tests for GenericCiEnvironment.git_url."""
-
- @mock.patch('config_utils._get_event_data', return_value={})
- def setUp(self, _):
- test_helpers.patch_environ(self)
- self.github_env = config_utils.GithubEnvironment()
- self.generic_ci_env = config_utils.GenericCiEnvironment()
-
- def test_unset_repository(self):
- """Tests that the correct result is returned when repository is not set."""
- self.assertEqual(self.generic_ci_env.git_url, None)
-
- def test_github_repository(self):
- """Tests that the correct result is returned when repository contains the
- owner and repo name (as it does on GitHub)."""
- os.environ['GITHUB_REPOSITORY'] = 'repo/owner'
- self.assertEqual('https://github.com/repo/owner.git',
- self.github_env.git_url)
-
- def test_nongithub_repository(self):
- """Tests that the correct result is returned when repository contains the
- just the repo name (as it does outside of GitHub)."""
- os.environ['GITHUB_REPOSITORY'] = 'repo/owner'
- self.assertEqual(None, self.generic_ci_env.git_url)
-
-
class GetSanitizerTest(unittest.TestCase):
"""Tests for _get_sanitizer."""
@@ -261,40 +196,5 @@ class GetSanitizerTest(unittest.TestCase):
self.assertEqual(config_utils._get_sanitizer(), self.sanitizer)
-class ProjectSrcPathTest(unittest.TestCase):
- """Tests for project_src_path."""
-
- def setUp(self):
- test_helpers.patch_environ(self)
- self.workspace = '/workspace'
- os.environ['GITHUB_WORKSPACE'] = self.workspace
-
- self.project_src_dir_name = 'project-src'
-
- @mock.patch('config_utils._get_event_data', return_value={})
- def test_github_unset(self, _):
- """Tests that project_src_path returns None when no PROJECT_SRC_PATH is
- set."""
- github_env = config_utils.GithubEnvironment()
- self.assertIsNone(github_env.project_src_path)
-
- @mock.patch('config_utils._get_event_data', return_value={})
- def test_github(self, _):
- """Tests that project_src_path returns the correct result on GitHub."""
- os.environ['PROJECT_SRC_PATH'] = self.project_src_dir_name
- expected_project_src_path = os.path.join(self.workspace,
- self.project_src_dir_name)
- github_env = config_utils.GithubEnvironment()
- self.assertEqual(github_env.project_src_path, expected_project_src_path)
-
- def test_not_github(self):
- """Tests that project_src_path returns the correct result not on
- GitHub."""
- project_src_path = os.path.join('/', self.project_src_dir_name)
- os.environ['PROJECT_SRC_PATH'] = project_src_path
- generic_ci_env = config_utils.GenericCiEnvironment()
- self.assertEqual(generic_ci_env.project_src_path, project_src_path)
-
-
if __name__ == '__main__':
unittest.main()
diff --git a/infra/cifuzz/external-actions/build_fuzzers/action.yml b/infra/cifuzz/external-actions/build_fuzzers/action.yml
index 3772be50..11efec79 100644
--- a/infra/cifuzz/external-actions/build_fuzzers/action.yml
+++ b/infra/cifuzz/external-actions/build_fuzzers/action.yml
@@ -62,3 +62,4 @@ runs:
BAD_BUILD_CHECK: ${{ inputs.bad-build-check }}
UPLOAD_BUILD: ${{ inputs.upload-build }}
CIFUZZ_DEBUG: 'True'
+ CFL_PLATFORM: 'github'
diff --git a/infra/cifuzz/external-actions/run_fuzzers/action.yml b/infra/cifuzz/external-actions/run_fuzzers/action.yml
index eecd627f..4aaef208 100644
--- a/infra/cifuzz/external-actions/run_fuzzers/action.yml
+++ b/infra/cifuzz/external-actions/run_fuzzers/action.yml
@@ -69,3 +69,4 @@ runs:
GIT_STORE_BRANCH_COVERAGE: ${{ inputs.storage-repo-branch-coverage }}
REPORT_UNREPRODUCIBLE_CRASHES: ${{ inputs.report-unreproducible-crashes }}
CIFUZZ_DEBUG: 'True'
+ CFL_PLATFORM: 'github'
diff --git a/infra/cifuzz/filestore/github_actions/github_actions_test.py b/infra/cifuzz/filestore/github_actions/github_actions_test.py
index 8aafa4c8..90a0b070 100644
--- a/infra/cifuzz/filestore/github_actions/github_actions_test.py
+++ b/infra/cifuzz/filestore/github_actions/github_actions_test.py
@@ -36,7 +36,7 @@ import test_helpers
class GithubActionsFilestoreTest(fake_filesystem_unittest.TestCase):
"""Tests for GithubActionsFilestore."""
- @mock.patch('config_utils._get_event_data', return_value={})
+ @mock.patch('platform_config.github._get_event_data', return_value={})
def setUp(self, _): # pylint: disable=arguments-differ
test_helpers.patch_environ(self)
self.token = 'example githubtoken'
@@ -44,6 +44,8 @@ class GithubActionsFilestoreTest(fake_filesystem_unittest.TestCase):
self.repo = 'examplerepo'
os.environ['GITHUB_REPOSITORY'] = f'{self.owner}/{self.repo}'
os.environ['GITHUB_EVENT_PATH'] = '/fake'
+ os.environ['CFL_PLATFORM'] = 'github'
+ os.environ['GITHUB_WORKSPACE'] = '/workspace'
self.config = test_helpers.create_run_config(token=self.token)
self.local_dir = '/local-dir'
self.testcase = os.path.join(self.local_dir, 'testcase')
diff --git a/infra/cifuzz/filestore_utils_test.py b/infra/cifuzz/filestore_utils_test.py
index db5fc5bc..d5e13073 100644
--- a/infra/cifuzz/filestore_utils_test.py
+++ b/infra/cifuzz/filestore_utils_test.py
@@ -17,7 +17,7 @@ from unittest import mock
import parameterized
-import config_utils
+import platform_config
import filestore
from filestore import github_actions
import filestore_utils
@@ -29,7 +29,7 @@ class GetFilestoreTest(unittest.TestCase):
@parameterized.parameterized.expand([
({
- 'is_github': True,
+ 'cfl_platform': 'github',
}, github_actions.GithubActionsFilestore),
])
def test_get_filestore(self, config_kwargs, filestore_cls):
@@ -40,8 +40,8 @@ class GetFilestoreTest(unittest.TestCase):
self.assertIsInstance(filestore_impl, filestore_cls)
@mock.patch('config_utils.BaseConfig.platform', return_value='other')
- @mock.patch('config_utils._get_ci_environment',
- return_value=config_utils.GenericCiEnvironment())
+ @mock.patch('config_utils._get_platform_config',
+ return_value=platform_config.BasePlatformConfig())
def test_get_filestore_unsupported_platform(self, _, __):
"""Tests that get_filestore exceptions given a platform it doesn't
support."""
diff --git a/infra/cifuzz/fuzz_target_test.py b/infra/cifuzz/fuzz_target_test.py
index 33d58a49..59b541a3 100644
--- a/infra/cifuzz/fuzz_target_test.py
+++ b/infra/cifuzz/fuzz_target_test.py
@@ -48,7 +48,7 @@ def _create_config(**kwargs):
|kwargs| to the corresponding value. Asserts that each key in |kwargs| is an
attribute of Config."""
defaults = {
- 'is_github': True,
+ 'cfl_platform': 'github',
'oss_fuzz_project_name': EXAMPLE_PROJECT,
'workspace': '/workspace'
}
diff --git a/infra/cifuzz/platform_config/__init__.py b/infra/cifuzz/platform_config/__init__.py
new file mode 100644
index 00000000..d90e3609
--- /dev/null
+++ b/infra/cifuzz/platform_config/__init__.py
@@ -0,0 +1,112 @@
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Module for getting the configuration CIFuzz needs to run."""
+import logging
+import os
+
+
+class BasePlatformConfig:
+ """Base class for PlatformConfig subclasses."""
+
+ @property
+ def project_src_path(self):
+ """Returns the manually checked out path of the project's source if
+ specified or None."""
+ path = os.getenv('PROJECT_SRC_PATH')
+ if not path:
+ logging.debug('No PROJECT_SRC_PATH.')
+ return path
+
+ logging.debug('PROJECT_SRC_PATH: %s.', path)
+ return path
+
+ @property
+ def workspace(self):
+ """Returns the workspace."""
+ return os.getenv('WORKSPACE')
+
+ # Optional config variables.
+
+ @property
+ def git_sha(self):
+ """Returns the Git SHA to checkout and fuzz. This is used only by GitHub
+ projects when commit fuzzing. It is not used when PR fuzzing. It is
+ definitely needed by OSS-Fuzz on GitHub since they have no copy of the repo
+ on the host and the repo on the builder image is a clone from main/master.
+ Right now it is needed by external on GitHub because we need to clone a new
+ repo because the copy they give us doesn't work for diffing.
+
+ TODO(metzman): Try to eliminate the need for this by 1. Making the clone
+ from external github projects usable. 2. Forcing OSS-Fuzz on Github to clone
+ before starting CIFuzz."""
+ return None
+
+ @property
+ def base_commit(self):
+ """Returns the base commit to diff against (commit fuzzing)."""
+ # TODO(metzman) Rename base_commit to git_base_commit.
+ return os.getenv('GIT_BASE_COMMIT')
+
+ @property
+ def base_ref(self):
+ """Returns the base branch to diff against (pr fuzzing)."""
+ # TODO(metzman) Rename base_ref to git_base_ref.
+ return os.getenv('GIT_BASE_REF')
+
+ @property
+ def pr_ref(self):
+ """Returns the pull request to checkout and fuzz. This is used only by
+ GitHub projects when PR fuzzing. It is not used when commit fuzzing. It is
+ definitely needed by OSS-Fuzz on GitHub since they have no copy of the repo
+ on the host and the repo on the builder image is a clone from main/master.
+ Right now it is needed by external on GitHub because we need to clone a new
+ repo because the copy they give us doesn't work for diffing.
+
+ TODO(metzman): Try to eliminate the need for this by 1. Making the clone
+ from external github projects usable. 2. Forcing OSS-Fuzz on Github to clone
+ before starting CIFuzz."""
+ return None
+
+ @property
+ def project_repo_owner(self):
+ """Returns the project repo owner (githubism)."""
+ return None
+
+ @property
+ def project_repo_name(self):
+ """Returns the project repo name."""
+ return os.environ.get('REPOSITORY')
+
+ @property
+ def actor(self):
+ """Name of the actor for the CI."""
+ return None
+
+ @property
+ def token(self):
+ """Returns the CI API token."""
+ return None
+
+ @property
+ def git_url(self):
+ """Returns the repo URL. This is only used by GitHub users. Right now it is
+ needed by external on GitHub because we need to clone a new repo because the
+ copy they give us doesn't work for diffing. It isn't used by OSS-Fuzz on
+ github users since the Git URL is determined using repo detection.
+
+ TODO(metzman): Try to eliminate the need for this by making the clone
+ from external github projects usable.
+ TODO(metzman): As an easier goal, maybe make OSS-Fuzz GitHub use this too
+ for: 1. Consistency 2. Maybe it will allow use on forks."""
+ return None
diff --git a/infra/cifuzz/platform_config/gcb.py b/infra/cifuzz/platform_config/gcb.py
new file mode 100644
index 00000000..176f5247
--- /dev/null
+++ b/infra/cifuzz/platform_config/gcb.py
@@ -0,0 +1,35 @@
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Module for getting the configuration CIFuzz needs to run on Github."""
+import logging
+import os
+
+import platform_config
+
+
+class PlatformConfig(platform_config.BasePlatformConfig):
+ """CI environment for Google Cloud Build."""
+
+ @property
+ def project_src_path(self):
+ """Returns the manually checked out path of the project's source if
+ specified or the default."""
+ project_src_path = os.getenv('PROJECT_SRC_PATH', '/workspace')
+ logging.debug('PROJECT_SRC_PATH: %s.', project_src_path)
+ return project_src_path
+
+ @property
+ def workspace(self):
+ """Returns the workspace."""
+ return os.getenv('WORKSPACE', '/builder/home')
diff --git a/infra/cifuzz/platform_config/github.py b/infra/cifuzz/platform_config/github.py
new file mode 100644
index 00000000..2648cd11
--- /dev/null
+++ b/infra/cifuzz/platform_config/github.py
@@ -0,0 +1,145 @@
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Module for getting the configuration CIFuzz needs to run on Github."""
+import json
+import logging
+import os
+
+import platform_config
+
+
+def _get_github_event_path():
+ return os.getenv('GITHUB_EVENT_PATH')
+
+
+def _get_event_data():
+ """Returns the GitHub event data."""
+ github_event_path = _get_github_event_path()
+ with open(github_event_path, encoding='utf-8') as file_handle:
+ return json.load(file_handle)
+
+
+class PlatformConfig(platform_config.BasePlatformConfig):
+ """CI environment for GitHub."""
+
+ def __init__(self):
+ self._event_data = _get_event_data()
+ self._event = os.getenv('GITHUB_EVENT_NAME')
+
+ @property
+ def workspace(self):
+ """Returns the workspace."""
+ return os.getenv('GITHUB_WORKSPACE')
+
+ @property
+ def git_sha(self):
+ """Returns the Git SHA to checkout and fuzz. This is used only by GitHub
+ projects when commit fuzzing. It is not used when PR fuzzing. It is
+ definitely needed by OSS-Fuzz on GitHub since they have no copy of the repo
+ on the host and the repo on the builder image is a clone from main/master.
+ Right now it is needed by external on GitHub because we need to clone a new
+ repo because the copy they give us doesn't work for diffing.
+
+ TODO(metzman): Try to eliminate the need for this by 1. Making the clone
+ from external github projects usable. 2. Forcing OSS-Fuzz on Github to clone
+ before starting CIFuzz."""
+ return os.getenv('GITHUB_SHA')
+
+ @property
+ def actor(self):
+ """Name of the actor for the CI."""
+ return os.getenv('GITHUB_ACTOR')
+
+ @property
+ def token(self):
+ """Returns the CI API token."""
+ return os.getenv('GITHUB_TOKEN')
+
+ @property
+ def project_src_path(self):
+ """Returns the manually checked out path of the project's source if
+ specified or None. The path returned is relative to |self.workspace| since
+ on github the checkout will be relative to there."""
+ project_src_path = super().project_src_path
+ if project_src_path is None:
+ # Not set for internal GitHub users.
+ return project_src_path
+ # On GitHub (external users), this path is relative to |workspace|.
+ return os.path.join(self.workspace, project_src_path)
+
+ @property
+ def _project_repo_owner_and_name(self):
+ """Returns a tuple containing the project repo owner and the name of the
+ repo."""
+ # On GitHub this includes owner and repo name.
+ repository = os.getenv('GITHUB_REPOSITORY')
+ # Use os.path.split to split owner from repo.
+ return os.path.split(repository)
+
+ @property
+ def project_repo_owner(self):
+ """Returns the project repo owner (githubism)."""
+ return self._project_repo_owner_and_name[0]
+
+ @property
+ def project_repo_name(self):
+ """Returns the project repo name."""
+ return self._project_repo_owner_and_name[1]
+
+ @property
+ def git_url(self):
+ """Returns the repo URL. This is only used by GitHub users. Right now it is
+ needed by external on GitHub because we need to clone a new repo because the
+ copy they give us doesn't work for diffing. It isn't used by OSS-Fuzz on
+ github users since the Git URL is determined using repo detection.
+
+ TODO(metzman): Try to eliminate the need for this by making the clone
+ from external github projects usable.
+ TODO(metzman): As an easier goal, maybe make OSS-Fuzz GitHub use this too
+ for: 1. Consistency 2. Maybe it will allow use on forks."""
+ repository = os.getenv('GITHUB_REPOSITORY')
+ # TODO(metzman): Probably need to change this to github.server_url.
+ return f'https://github.com/{repository}.git'
+
+ @property
+ def base_commit(self):
+ """Returns the base commit to diff against (commit fuzzing)."""
+ base_commit = None
+ if self._event == 'push':
+ base_commit = self._event_data['before']
+ logging.debug('base_commit: %s', base_commit)
+ return base_commit
+
+ @property
+ def pr_ref(self):
+ """Returns the pull request to checkout and fuzz. This is used only by
+ GitHub projects when PR fuzzing. It is not used when commit fuzzing. It is
+ definitely needed by OSS-Fuzz on GitHub since they have no copy of the repo
+ on the host and the repo on the builder image is a clone from main/master.
+ Right now it is needed by external on GitHub because we need to clone a new
+ repo because the copy they give us doesn't work for diffing.
+
+ TODO(metzman): Try to eliminate the need for this by 1. Making the clone
+ from external github projects usable. 2. Forcing OSS-Fuzz on Github to clone
+ before starting CIFuzz."""
+ if self._event == 'pull_request':
+ pr_ref = f'refs/pull/{self._event_data["pull_request"]["number"]}/merge'
+ logging.debug('pr_ref: %s', pr_ref)
+ return pr_ref
+ return None
+
+ @property
+ def base_ref(self):
+ """Returns the base branch to diff against (pr fuzzing)."""
+ return os.getenv('GITHUB_BASE_REF')
diff --git a/infra/cifuzz/platform_config/github_test.py b/infra/cifuzz/platform_config/github_test.py
new file mode 100644
index 00000000..614d1f82
--- /dev/null
+++ b/infra/cifuzz/platform_config/github_test.py
@@ -0,0 +1,87 @@
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Tests for platform_config.github."""
+import os
+import unittest
+from unittest import mock
+
+import platform_config.github
+import test_helpers
+
+# pylint: disable=arguments-differ
+
+
+class GetProjectRepoOwnerAndNameTest(unittest.TestCase):
+ """Tests for get_project_repo_owner and get_project_repo_name."""
+
+ @mock.patch('platform_config.github._get_event_data', return_value={})
+ def setUp(self, _):
+ test_helpers.patch_environ(self)
+ self.repo_owner = 'repo-owner'
+ self.repo_name = 'repo-name'
+ os.environ['GITHUB_REPOSITORY'] = f'{self.repo_owner}/{self.repo_name}'
+ self.platform_conf = platform_config.github.PlatformConfig()
+
+ def test_github_repository_owner(self):
+ """Tests that the correct result is returned when repository contains the
+ owner and repo name (as it does on GitHub)."""
+ self.assertEqual(self.platform_conf.project_repo_owner, self.repo_owner)
+
+ def test_github_repository_name(self):
+ """Tests that the correct result is returned when repository contains the
+ owner and repo name (as it does on GitHub)."""
+ os.environ['GITHUB_REPOSITORY'] = f'{self.repo_owner}/{self.repo_name}'
+ self.assertEqual(self.platform_conf.project_repo_name, self.repo_name)
+
+
+class ProjectSrcPathTest(unittest.TestCase):
+ """Tests for project_src_path."""
+
+ def setUp(self):
+ test_helpers.patch_environ(self)
+ self.workspace = '/workspace'
+ os.environ['GITHUB_WORKSPACE'] = self.workspace
+ self.project_src_dir_name = 'project-src'
+
+ @mock.patch('platform_config.github._get_event_data', return_value={})
+ def test_github_unset(self, _):
+ """Tests that project_src_path returns None when no PROJECT_SRC_PATH is
+ set."""
+ github_env = platform_config.github.PlatformConfig()
+ self.assertIsNone(github_env.project_src_path)
+
+ @mock.patch('platform_config.github._get_event_data', return_value={})
+ def test_github(self, _):
+ """Tests that project_src_path returns the correct result on GitHub."""
+ os.environ['PROJECT_SRC_PATH'] = self.project_src_dir_name
+ expected_project_src_path = os.path.join(self.workspace,
+ self.project_src_dir_name)
+ github_env = platform_config.github.PlatformConfig()
+ self.assertEqual(github_env.project_src_path, expected_project_src_path)
+
+
+class GetGitUrlTest(unittest.TestCase):
+ """Tests for GenericPlatformConfig.git_url."""
+
+ @mock.patch('platform_config.github._get_event_data', return_value={})
+ def setUp(self, _):
+ test_helpers.patch_environ(self)
+ self.platform_conf = platform_config.github.PlatformConfig()
+
+ def test_repository(self):
+ """Tests that the correct result is returned when repository contains the
+ owner and repo name (as it does on GitHub)."""
+ os.environ['GITHUB_REPOSITORY'] = 'repo/owner'
+ self.assertEqual('https://github.com/repo/owner.git',
+ self.platform_conf.git_url)
diff --git a/infra/cifuzz/platform_config/platform_config_test.py b/infra/cifuzz/platform_config/platform_config_test.py
new file mode 100644
index 00000000..75b26f52
--- /dev/null
+++ b/infra/cifuzz/platform_config/platform_config_test.py
@@ -0,0 +1,82 @@
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Tests for platform_config."""
+import os
+import unittest
+
+import platform_config
+import test_helpers
+
+
+class GetProjectRepoOwnerAndNameTest(unittest.TestCase):
+ """Tests for get_project_repo_owner and get_project_repo_name."""
+
+ def setUp(self):
+ test_helpers.patch_environ(self)
+ self.repo_owner = 'repo-owner'
+ self.repo_name = 'repo-name'
+ self.env = platform_config.BasePlatformConfig()
+
+ def test_unset_repository(self):
+ """Tests that the correct result is returned when repository is not set."""
+ self.assertIsNone(self.env.project_repo_name)
+
+ def test_owner(self):
+ """Tests that the correct result is returned for owner."""
+ self.assertIsNone(self.env.project_repo_owner)
+
+ def test_empty_repository(self):
+ """Tests that the correct result is returned when repository is an empty
+ string."""
+ os.environ['REPOSITORY'] = ''
+ self.assertEqual(self.env.project_repo_name, '')
+
+ def test_repository(self):
+ """Tests that the correct result is returned when repository contains the
+ just the repo name (as it does outside of GitHub)."""
+ os.environ['REPOSITORY'] = self.repo_name
+ self.assertEqual(self.env.project_repo_name, self.repo_name)
+
+
+class ProjectSrcPathTest(unittest.TestCase):
+ """Tests for project_src_path."""
+
+ def setUp(self):
+ test_helpers.patch_environ(self)
+
+ def test_not_github(self):
+ """Tests that project_src_path returns the correct result not on
+ GitHub."""
+ project_src_path = 'project-src'
+ os.environ['PROJECT_SRC_PATH'] = project_src_path
+ generic_ci_env = platform_config.BasePlatformConfig()
+ self.assertEqual(generic_ci_env.project_src_path, project_src_path)
+
+
+class GetGitUrlTest(unittest.TestCase):
+ """Tests for BasePlatformConfig.git_url."""
+
+ def setUp(self):
+ test_helpers.patch_environ(self)
+ self.env = platform_config.BasePlatformConfig()
+
+ def test_unset_repository(self):
+ """Tests that the correct result is returned when repository is not set."""
+ self.assertEqual(self.env.git_url, None)
+
+ def test_repository(self):
+ """Tests that the correct result is returned when GITHUB_REPOSITORY is
+ set."""
+ os.environ['GITHUB_REPOSITORY'] = 'repo/owner'
+ self.assertIsNone(self.env.git_url)
diff --git a/infra/cifuzz/platform_config/prow.py b/infra/cifuzz/platform_config/prow.py
new file mode 100644
index 00000000..80f291e5
--- /dev/null
+++ b/infra/cifuzz/platform_config/prow.py
@@ -0,0 +1,22 @@
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Module for getting the configuration CIFuzz needs to run on prow."""
+import platform_config
+
+# pylint: disable=too-few-public-methods
+
+
+class PlatformConfig(platform_config.BasePlatformConfig):
+ """CI environment for Prow."""
+ # TODO(mpherman2) Fill this out.
diff --git a/infra/cifuzz/run_fuzzers_test.py b/infra/cifuzz/run_fuzzers_test.py
index 6f352303..87341385 100644
--- a/infra/cifuzz/run_fuzzers_test.py
+++ b/infra/cifuzz/run_fuzzers_test.py
@@ -268,7 +268,7 @@ class BatchFuzzTargetRunnerTest(fake_filesystem_unittest.TestCase):
self.fs.create_file(self.testcase2)
self.config = test_helpers.create_run_config(fuzz_seconds=FUZZ_SECONDS,
workspace=self.WORKSPACE,
- is_github=True)
+ cfl_platform='github')
@mock.patch('utils.get_fuzz_targets', return_value=['target1', 'target2'])
@mock.patch('clusterfuzz_deployment.ClusterFuzzLite.upload_crashes')
@@ -338,7 +338,7 @@ class CoverageReportIntegrationTest(unittest.TestCase):
git_sha='0b95fe1039ed7c38fea1f97078316bfc1030c523',
base_commit='da0746452433dc18bae699e355a9821285d863c8',
sanitizer=self.SANITIZER,
- is_github=True,
+ cfl_platform='github',
# Needed for test not to fail because of permissions issues.
bad_build_check=False)
self.assertTrue(build_fuzzers.build_fuzzers(build_config))
@@ -357,7 +357,7 @@ class CoverageReportIntegrationTest(unittest.TestCase):
workspace=temp_dir,
sanitizer=self.SANITIZER,
mode='coverage',
- is_github=True)
+ cfl_platform='github')
result = run_fuzzers.run_fuzzers(run_config)
self.assertEqual(result, run_fuzzers.RunFuzzersResult.NO_BUG_FOUND)
expected_summary_path = os.path.join(
diff --git a/infra/cifuzz/test_helpers.py b/infra/cifuzz/test_helpers.py
index 85b5a8a6..846a8a88 100644
--- a/infra/cifuzz/test_helpers.py
+++ b/infra/cifuzz/test_helpers.py
@@ -31,8 +31,9 @@ sys.path.append(INFRA_DIR)
import helper
+# TODO(metzman): Get rid of these decorators.
@mock.patch('config_utils._is_dry_run', return_value=True)
-@mock.patch('config_utils.GenericCiEnvironment.project_src_path',
+@mock.patch('platform_config.BasePlatformConfig.project_src_path',
return_value=None)
@mock.patch('os.path.basename', return_value=None)
def _create_config(config_cls, _, __, ___, **kwargs):