Repository: google/fuzzbench

Issue:
Building outside of fuzzbench cloud project is broken
I think this line is at fault: https://github.com/google/fuzzbench/blob/master/experiment/build/generate_cloudbuild.py#L26

To reproduce:
```
gcloud config set project fuzzbench-test
WORK=/tmp/work CLOUD_PROJECT=fuzzbench-test EXPERIMENT=test PYTHONPATH=. python experiment/build/builder.py --fuzzers afl --benchmarks zlib_zlib_uncompress_fuzzer
```


Discussion:

Resolving patch:
diff --git a/conftest.py b/conftest.py
--- a/conftest.py
+++ b/conftest.py
@@ -80,6 +80,7 @@ def experiment(environ):  # pylint: disable=redefined-outer-name,unused-argument
     os.environ['EXPERIMENT_FILESTORE'] = 'gs://experiment-data'
     os.environ['REPORT_FILESTORE'] = 'gs://web-bucket'
     os.environ['CLOUD_PROJECT'] = 'fuzzbench'
+    os.environ['DOCKER_REGISTRY'] = 'gcr.io/fuzzbench'
 
 
 @pytest.fixture
diff --git a/experiment/build/gcb_build.py b/experiment/build/gcb_build.py
--- a/experiment/build/gcb_build.py
+++ b/experiment/build/gcb_build.py
@@ -47,8 +47,8 @@ def _get_buildable_images(fuzzer=None, benchmark=None):
 def build_base_images():
     """Build base images on GCB."""
     image_templates = {'base-image': _get_buildable_images()['base-image']}
-    config = generate_cloudbuild.create_cloud_build_spec(image_templates,
-                                                         build_base_images=True)
+    config = generate_cloudbuild.create_cloudbuild_spec(image_templates,
+                                                        build_base_images=True)
     _build(config, 'base-images')
 
 
@@ -61,8 +61,8 @@ def build_coverage(benchmark):
         if (image_name == (benchmark + '-project-builder') or
             image_specs['type'] == 'coverage')
     }
-    config = generate_cloudbuild.create_cloud_build_spec(image_templates,
-                                                         benchmark=benchmark)
+    config = generate_cloudbuild.create_cloudbuild_spec(image_templates,
+                                                        benchmark=benchmark)
     config_name = 'benchmark-{benchmark}-coverage'.format(benchmark=benchmark)
     _build(config, config_name)
 
@@ -110,7 +110,7 @@ def build_fuzzer_benchmark(fuzzer: str, benchmark: str):
         if image_specs['type'] in ('base', 'coverage', 'dispatcher'):
             continue
         image_templates[image_name] = image_specs
-    config = generate_cloudbuild.create_cloud_build_spec(image_templates)
+    config = generate_cloudbuild.create_cloudbuild_spec(image_templates)
     config_name = 'benchmark-{benchmark}-fuzzer-{fuzzer}'.format(
         benchmark=benchmark, fuzzer=fuzzer)
 
diff --git a/experiment/build/generate_cloudbuild.py b/experiment/build/generate_cloudbuild.py
--- a/experiment/build/generate_cloudbuild.py
+++ b/experiment/build/generate_cloudbuild.py
@@ -16,14 +16,13 @@
 import os
 import posixpath
 
-from common import yaml_utils
-from common import experiment_utils
 from common import experiment_path as exp_path
+from common import experiment_utils
+from common import yaml_utils
 from common.utils import ROOT_DIR
 from experiment.build import build_utils
 
 DOCKER_IMAGE = 'docker:19.03.12'
-PROJECT_DOCKER_REGISTRY = 'gcr.io/fuzzbench'
 
 
 def get_experiment_tag_for_image(image_specs, tag_by_experiment=True):
@@ -60,9 +59,14 @@ def coverage_steps(benchmark):
     return steps
 
 
-def create_cloud_build_spec(image_templates,
-                            benchmark='',
-                            build_base_images=False):
+def get_docker_registry():
+    """Returns the docker registry for this experiment."""
+    return os.environ['DOCKER_REGISTRY']
+
+
+def create_cloudbuild_spec(image_templates,
+                           benchmark='',
+                           build_base_images=False):
     """Generates Cloud Build specification.
 
     Args:
@@ -73,18 +77,20 @@ def create_cloud_build_spec(image_templates,
     Returns:
       GCB build steps.
     """
-    cloud_build_spec = {'steps': [], 'images': []}
+    cloudbuild_spec = {'steps': [], 'images': []}
 
     # Workaround for bug https://github.com/moby/moby/issues/40262.
     # This is only needed for base-image as it inherits from ubuntu:xenial.
     if build_base_images:
-        cloud_build_spec['steps'].append({
+        cloudbuild_spec['steps'].append({
             'id': 'pull-ubuntu-xenial',
             'env': ['DOCKER_BUILDKIT=1'],
             'name': DOCKER_IMAGE,
             'args': ['pull', 'ubuntu:xenial'],
         })
 
+    docker_registry = get_docker_registry()
+
     for image_name, image_specs in image_templates.items():
         step = {
             'id': image_name,
@@ -93,8 +99,7 @@ def create_cloud_build_spec(image_templates,
         }
         step['args'] = [
             'build', '--tag',
-            posixpath.join(PROJECT_DOCKER_REGISTRY,
-                           image_specs['tag']), '--tag',
+            posixpath.join(docker_registry, image_specs['tag']), '--tag',
             get_experiment_tag_for_image(image_specs), '--cache-from',
             get_experiment_tag_for_image(image_specs, tag_by_experiment=False),
             '--build-arg', 'BUILDKIT_INLINE_CACHE=1'
@@ -113,24 +118,24 @@ def create_cloud_build_spec(image_templates,
                 continue
             step['wait_for'] += [dependency]
 
-        cloud_build_spec['steps'].append(step)
-        cloud_build_spec['images'].append(
+        cloudbuild_spec['steps'].append(step)
+        cloudbuild_spec['images'].append(
             get_experiment_tag_for_image(image_specs))
-        cloud_build_spec['images'].append(
+        cloudbuild_spec['images'].append(
             get_experiment_tag_for_image(image_specs, tag_by_experiment=False))
 
     if any(image_specs['type'] in 'coverage'
            for _, image_specs in image_templates.items()):
-        cloud_build_spec['steps'] += coverage_steps(benchmark)
+        cloudbuild_spec['steps'] += coverage_steps(benchmark)
 
-    return cloud_build_spec
+    return cloudbuild_spec
 
 
 def main():
     """Write base-images build spec when run from command line."""
     image_templates = yaml_utils.read(
         os.path.join(ROOT_DIR, 'docker', 'image_types.yaml'))
-    base_images_spec = create_cloud_build_spec(
+    base_images_spec = create_cloudbuild_spec(
         {'base-image': image_templates['base-image']}, build_base_images=True)
     base_images_spec_file = os.path.join(ROOT_DIR, 'docker', 'gcb',
                                          'base-images.yaml')


Test patch:
diff --git a/experiment/build/test_generate_cloudbuild.py b/experiment/build/test_generate_cloudbuild.py
--- a/experiment/build/test_generate_cloudbuild.py
+++ b/experiment/build/test_generate_cloudbuild.py
@@ -13,18 +13,12 @@
 # limitations under the License.
 """Tests for generate_cloudbuild.py."""
 
-import os
-
-from unittest.mock import patch
-
 from experiment.build import generate_cloudbuild
 
+# pylint: disable=unused-argument
+
 
-@patch.dict(os.environ, {
-    'CLOUD_PROJECT': 'fuzzbench',
-    'EXPERIMENT': 'test-experiment'
-})
-def test_generate_cloud_build_spec_build_base_image():
+def test_generate_cloudbuild_spec_build_base_image(experiment):
     """Tests cloud build configuration yaml for the base image."""
     image_templates = {
         'base-image': {
@@ -34,7 +28,7 @@ def test_generate_cloud_build_spec_build_base_image():
             'type': 'base'
         }
     }
-    generated_spec = generate_cloudbuild.create_cloud_build_spec(
+    generated_spec = generate_cloudbuild.create_cloudbuild_spec(
         image_templates, build_base_images=True)
 
     expected_spec = {
@@ -65,11 +59,7 @@ def test_generate_cloud_build_spec_build_base_image():
     assert generated_spec == expected_spec
 
 
-@patch.dict(os.environ, {
-    'CLOUD_PROJECT': 'fuzzbench',
-    'EXPERIMENT': 'test-experiment'
-})
-def test_generate_cloud_build_spec_build_fuzzer_benchmark():
+def test_generate_cloudbuild_spec_build_fuzzer_benchmark(experiment):
     """Tests cloud build configuration yaml for a fuzzer-benchmark build."""
     image_templates = {
         'afl-zlib-builder-intermediate': {
@@ -84,8 +74,7 @@ def test_generate_cloud_build_spec_build_fuzzer_benchmark():
         }
     }
 
-    generated_spec = generate_cloudbuild.create_cloud_build_spec(
-        image_templates)
+    generated_spec = generate_cloudbuild.create_cloudbuild_spec(image_templates)
 
     expected_spec = {
         'steps': [{
@@ -113,14 +102,7 @@ def test_generate_cloud_build_spec_build_fuzzer_benchmark():
     assert generated_spec == expected_spec
 
 
-@patch.dict(
-    os.environ, {
-        'CLOUD_PROJECT': 'fuzzbench',
-        'EXPERIMENT': 'test-experiment',
-        'EXPERIMENT_FILESTORE': 'gs://fuzzbench-data',
-        'WORK': '/work',
-    })
-def test_generate_cloud_build_spec_build_benchmark_coverage():
+def test_generate_cloudbuild_spec_build_benchmark_coverage(experiment):
     """Tests cloud build configuration yaml for a benchmark coverage build."""
     image_templates = {
         'zlib-project-builder': {
@@ -153,7 +135,7 @@ def test_generate_cloud_build_spec_build_benchmark_coverage():
         }
     }
 
-    generated_spec = generate_cloudbuild.create_cloud_build_spec(
+    generated_spec = generate_cloudbuild.create_cloudbuild_spec(
         image_templates, benchmark='zlib')
 
     expected_spec = {
@@ -218,7 +200,7 @@ def test_generate_cloud_build_spec_build_benchmark_coverage():
                 'gcr.io/cloud-builders/gsutil',
             'args': [
                 '-m', 'cp', '/workspace/out/coverage-build-zlib.tar.gz',
-                'gs://fuzzbench-data/test-experiment/coverage-binaries/'
+                'gs://experiment-data/test-experiment/coverage-binaries/'
             ]
         }],
         'images': [