[CIFuzz][helper] Fix external project support and add tests. (#6161)
diff --git a/infra/helper.py b/infra/helper.py
index 246c9e7..e9209713 100755
--- a/infra/helper.py
+++ b/infra/helper.py
@@ -91,7 +91,7 @@
@property
def dockerfile_path(self):
"""Returns path to the project Dockerfile."""
- return os.path.join(self.path, 'Dockerfile')
+ return os.path.join(self.build_integration_path, 'Dockerfile')
@property
def language(self):
@@ -193,8 +193,9 @@
# Use hacky method for extracting attributes so that ShellTest works.
# TODO(metzman): Fix this.
- is_external = getattr(parsed_args, 'is_external', False)
- build_integration_path = getattr(parsed_args, 'build_integration_path', False)
+ is_external = getattr(parsed_args, 'external', False)
+ build_integration_path = getattr(parsed_args, 'build_integration_path',
+ DEFAULT_RELATIVE_BUILD_INTEGRATION_PATH)
parsed_args.project = Project(parsed_args.project, is_external,
build_integration_path)
@@ -459,17 +460,11 @@
image_project = 'oss-fuzz-base'
docker_build_dir = os.path.join(OSS_FUZZ_DIR, 'infra', 'base-images',
image_name)
- docker_file_path = None
- elif project.is_external:
- # External projects need to use the repo root as the build directory.
- docker_file_path = os.path.join(project.build_integration_path,
- 'Dockerfile')
- docker_build_dir = project.path
- image_project = 'oss-fuzz'
+ dockerfile_path = os.path.join(docker_build_dir, 'Dockerfile')
else:
if not check_project_exists(project):
return False
- docker_file_path = None
+ dockerfile_path = project.dockerfile_path
docker_build_dir = project.path
image_project = 'oss-fuzz'
@@ -480,12 +475,10 @@
if not cache:
build_args.append('--no-cache')
- build_args += ['-t', 'gcr.io/%s/%s' % (image_project, image_name)]
- if docker_file_path:
- build_args += [
- '--file',
- docker_file_path,
- ]
+ build_args += [
+ '-t',
+ 'gcr.io/%s/%s' % (image_project, image_name), '--file', dockerfile_path
+ ]
build_args.append(docker_build_dir)
return docker_build(build_args)
diff --git a/infra/helper_test.py b/infra/helper_test.py
index cb9e6a6..572a767 100644
--- a/infra/helper_test.py
+++ b/infra/helper_test.py
@@ -15,6 +15,7 @@
import datetime
import os
+import tempfile
import unittest
from unittest import mock
@@ -57,17 +58,20 @@
def test_pull(self, mocked_pull_images, _):
"""Tests that pull=True is handled properly."""
image_name = 'base-image'
- helper.build_image_impl(helper.Project(image_name), pull=True)
+ self.assertTrue(
+ helper.build_image_impl(helper.Project(image_name), pull=True))
mocked_pull_images.assert_called_with()
@mock.patch('helper.docker_build')
def test_base_image(self, mocked_docker_build):
"""Tests that build_image_impl works as intended with a base-image."""
image_name = 'base-image'
- helper.build_image_impl(helper.Project(image_name))
+ self.assertTrue(helper.build_image_impl(helper.Project(image_name)))
+ build_dir = os.path.join(helper.OSS_FUZZ_DIR,
+ 'infra/base-images/base-image')
mocked_docker_build.assert_called_with([
- '-t', 'gcr.io/oss-fuzz-base/base-image',
- os.path.join(helper.OSS_FUZZ_DIR, 'infra/base-images/base-image')
+ '-t', 'gcr.io/oss-fuzz-base/base-image', '--file',
+ os.path.join(build_dir, 'Dockerfile'), build_dir
])
@mock.patch('helper.docker_build')
@@ -75,26 +79,30 @@
"""Tests that build_image_impl works as intended with an OSS-Fuzz
project."""
project_name = 'example'
- helper.build_image_impl(helper.Project(project_name))
+ self.assertTrue(helper.build_image_impl(helper.Project(project_name)))
+ build_dir = os.path.join(helper.OSS_FUZZ_DIR, 'projects', project_name)
mocked_docker_build.assert_called_with([
- '-t', 'gcr.io/oss-fuzz/example',
- os.path.join(helper.OSS_FUZZ_DIR, 'projects/example')
+ '-t', 'gcr.io/oss-fuzz/example', '--file',
+ os.path.join(build_dir, 'Dockerfile'), build_dir
])
@mock.patch('helper.docker_build')
def test_external_project(self, mocked_docker_build):
"""Tests that build_image_impl works as intended with a non-OSS-Fuzz
project."""
- project_src_path = '/example'
- build_integration_path = 'build-integration'
- project = helper.Project(project_src_path,
- is_external=True,
- build_integration_path=build_integration_path)
- helper.build_image_impl(project)
- mocked_docker_build.assert_called_with([
- '-t', 'gcr.io/oss-fuzz/example', '--file',
- '/example/build-integration/Dockerfile', project_src_path
- ])
+ with tempfile.TemporaryDirectory() as temp_dir:
+ project_src_path = os.path.join(temp_dir, 'example')
+ os.mkdir(project_src_path)
+ build_integration_path = 'build-integration'
+ project = helper.Project(project_src_path,
+ is_external=True,
+ build_integration_path=build_integration_path)
+ self.assertTrue(helper.build_image_impl(project))
+ mocked_docker_build.assert_called_with([
+ '-t', 'gcr.io/oss-fuzz/example', '--file',
+ os.path.join(project_src_path, build_integration_path, 'Dockerfile'),
+ project_src_path
+ ])
class GenerateImplTest(fake_filesystem_unittest.TestCase):
@@ -131,3 +139,80 @@
build_integration_path=build_integration_path))
self._verify_templated_files(templates.EXTERNAL_TEMPLATES,
build_integration_path)
+
+
+class ProjectTest(fake_filesystem_unittest.TestCase):
+ """Tests for Project class."""
+
+ def setUp(self):
+ self.project_name = 'project'
+ self.internal_project = helper.Project(self.project_name)
+ self.external_project_path = os.path.join('path', 'to', self.project_name)
+ self.external_project = helper.Project(self.external_project_path,
+ is_external=True)
+ self.setUpPyfakefs()
+
+ def test_init_external_project(self):
+ """Tests __init__ method for external projects."""
+ self.assertEqual(self.external_project.name, self.project_name)
+ self.assertEqual(self.external_project.path, self.external_project_path)
+ self.assertEqual(
+ self.external_project.build_integration_path,
+ os.path.join(self.external_project_path,
+ helper.DEFAULT_RELATIVE_BUILD_INTEGRATION_PATH))
+
+ def test_init_internal_project(self):
+ """Tests __init__ method for internal projects."""
+ self.assertEqual(self.internal_project.name, self.project_name)
+ path = os.path.join(helper.OSS_FUZZ_DIR, 'projects', self.project_name)
+ self.assertEqual(self.internal_project.path, path)
+ self.assertEqual(self.internal_project.build_integration_path, path)
+
+ def test_dockerfile_path_internal_project(self):
+ """Tests that dockerfile_path works as intended."""
+ self.assertEqual(
+ self.internal_project.dockerfile_path,
+ os.path.join(helper.OSS_FUZZ_DIR, 'projects', self.project_name,
+ 'Dockerfile'))
+
+ def test_dockerfile_path_external_project(self):
+ """Tests that dockerfile_path works as intended."""
+ self.assertEqual(
+ self.external_project.dockerfile_path,
+ os.path.join(self.external_project_path,
+ helper.DEFAULT_RELATIVE_BUILD_INTEGRATION_PATH,
+ 'Dockerfile'))
+
+ def test_out(self):
+ """Tests that out works as intended."""
+ out_dir = self.internal_project.out
+ self.assertEqual(
+ out_dir,
+ os.path.join(helper.OSS_FUZZ_DIR, 'build', 'out', self.project_name))
+ self.assertTrue(os.path.exists(out_dir))
+
+ def test_work(self):
+ """Tests that work works as intended."""
+ work_dir = self.internal_project.work
+ self.assertEqual(
+ work_dir,
+ os.path.join(helper.OSS_FUZZ_DIR, 'build', 'work', self.project_name))
+ self.assertTrue(os.path.exists(work_dir))
+
+ def test_corpus(self):
+ """Tests that corpus works as intended."""
+ corpus_dir = self.internal_project.corpus
+ self.assertEqual(
+ corpus_dir,
+ os.path.join(helper.OSS_FUZZ_DIR, 'build', 'corpus', self.project_name))
+ self.assertTrue(os.path.exists(corpus_dir))
+
+ def test_language_internal_project(self):
+ """Tests that language works as intended for an internal project."""
+ project_yaml_path = os.path.join(self.internal_project.path, 'project.yaml')
+ self.fs.create_file(project_yaml_path, contents='language: python')
+ self.assertEqual(self.internal_project.language, 'python')
+
+ def test_language_external_project(self):
+ """Tests that language works as intended for an external project."""
+ self.assertEqual(self.external_project.language, 'c++')