1# Copyright 2019 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Test the functionality of the build image from commit module. 15The will consist of the following functional tests: 16 1. The inference of the main repo for a specific project. 17 2. The building of a projects fuzzers from a specific commit. 18 19IMPORTANT: This test needs to be run with root privileges. 20""" 21import os 22import tempfile 23import unittest 24 25import build_specified_commit 26import helper 27import repo_manager 28import test_repos 29 30# Necessary because __file__ changes with os.chdir 31TEST_DIR_PATH = os.path.dirname(os.path.realpath(__file__)) 32 33 34@unittest.skipIf(not os.getenv('INTEGRATION_TESTS'), 35 'INTEGRATION_TESTS=1 not set') 36class BuildImageIntegrationTest(unittest.TestCase): 37 """Tests if an image can be built from different states e.g. a commit.""" 38 39 @unittest.skip('Test is failing (spuriously?).') 40 def test_build_fuzzers_from_commit(self): 41 """Tests if the fuzzers can build at a specified commit. 42 43 This is done by using a known regression range for a specific test case. 44 The old commit should show the error when its fuzzers run and the new one 45 should not. 46 """ 47 with tempfile.TemporaryDirectory() as tmp_dir: 48 test_case = test_repos.TEST_REPOS[1] 49 self.assertTrue(helper.build_image_impl(test_case.project_name)) 50 host_src_dir = build_specified_commit.copy_src_from_docker( 51 test_case.project_name, tmp_dir) 52 53 test_repo_manager = repo_manager.clone_repo_and_get_manager( 54 test_case.git_url, host_src_dir, test_case.oss_repo_name) 55 build_data = build_specified_commit.BuildData( 56 sanitizer='address', 57 architecture='x86_64', 58 engine='libfuzzer', 59 project_name=test_case.project_name) 60 61 build_specified_commit.build_fuzzers_from_commit(test_case.old_commit, 62 test_repo_manager, 63 host_src_dir, build_data) 64 old_error_code = helper.reproduce_impl(test_case.project_name, 65 test_case.fuzz_target, False, [], 66 [], test_case.test_case_path) 67 build_specified_commit.build_fuzzers_from_commit(test_case.new_commit, 68 test_repo_manager, 69 host_src_dir, build_data) 70 new_error_code = helper.reproduce_impl(test_case.project_name, 71 test_case.fuzz_target, False, [], 72 [], test_case.test_case_path) 73 self.assertNotEqual(new_error_code, old_error_code) 74 75 def test_detect_main_repo_from_commit(self): 76 """Test the detect main repo function from build specific commit module.""" 77 # TODO(metzman): Fix these tests so they don't randomly break because of 78 # changes in the outside world. 79 for example_repo in test_repos.TEST_REPOS: 80 if example_repo.new_commit: 81 # TODO(metzman): This function calls _build_image_with_retries which 82 # has a long delay (30 seconds). Figure out how to make this quicker. 83 repo_origin, repo_name = build_specified_commit.detect_main_repo( 84 example_repo.project_name, commit=example_repo.new_commit) 85 self.assertEqual(repo_origin, example_repo.git_url) 86 self.assertEqual(repo_name, 87 os.path.join('/src', example_repo.oss_repo_name)) 88 89 repo_origin, repo_name = build_specified_commit.detect_main_repo( 90 test_repos.INVALID_REPO.project_name, 91 test_repos.INVALID_REPO.new_commit) 92 self.assertIsNone(repo_origin) 93 self.assertIsNone(repo_name) 94 95 def test_detect_main_repo_from_name(self): 96 """Test the detect main repo function from build specific commit module.""" 97 for example_repo in test_repos.TEST_REPOS: 98 if example_repo.project_name == 'gonids': 99 # It's unclear how this test ever passed, but we can't infer the repo 100 # because gonids doesn't really check it out, it uses "go get". 101 continue 102 repo_origin, repo_name = build_specified_commit.detect_main_repo( 103 example_repo.project_name, repo_name=example_repo.git_repo_name) 104 self.assertEqual(repo_origin, example_repo.git_url) 105 self.assertEqual( 106 repo_name, 107 os.path.join(example_repo.image_location, example_repo.oss_repo_name)) 108 109 repo_origin, repo_name = build_specified_commit.detect_main_repo( 110 test_repos.INVALID_REPO.project_name, 111 test_repos.INVALID_REPO.oss_repo_name) 112 self.assertIsNone(repo_origin) 113 self.assertIsNone(repo_name) 114 115 116if __name__ == '__main__': 117 # Change to oss-fuzz main directory so helper.py runs correctly. 118 if os.getcwd() != os.path.dirname(TEST_DIR_PATH): 119 os.chdir(os.path.dirname(TEST_DIR_PATH)) 120 unittest.main() 121