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 detect_repo module. 15This will consist of the following functional test: 16 1. Determine if an OSS-Fuzz projects main repo can be detected from example 17 commits. 18 2. Determine if an OSS-Fuzz project main repo can be detected from a 19 repo name. 20""" 21import os 22import re 23import sys 24import tempfile 25import unittest 26from unittest import mock 27 28import detect_repo 29 30# Appending to path for access to repo_manager module. 31# pylint: disable=wrong-import-position 32sys.path.append( 33 os.path.dirname(os.path.dirname(os.path.dirname( 34 os.path.abspath(__file__))))) 35import repo_manager 36import test_repos 37# pylint: enable=wrong-import-position 38 39 40class TestCheckForRepoName(unittest.TestCase): 41 """Tests for check_for_repo_name.""" 42 43 @mock.patch('os.path.exists', return_value=True) 44 @mock.patch('detect_repo.execute', 45 return_value=('https://github.com/google/syzkaller/', None)) 46 def test_go_get_style_url(self, _, __): 47 """Tests that check_for_repo_name works on repos that were downloaded using 48 go get.""" 49 self.assertTrue(detect_repo.check_for_repo_name('fake-path', 'syzkaller')) 50 51 @mock.patch('os.path.exists', return_value=True) 52 @mock.patch('detect_repo.execute', 53 return_value=('https://github.com/google/syzkaller', None)) 54 def test_missing_git_and_slash_url(self, _, __): 55 """Tests that check_for_repo_name works on repos who's URLs do not end in 56 ".git" or "/".""" 57 self.assertTrue(detect_repo.check_for_repo_name('fake-path', 'syzkaller')) 58 59 @mock.patch('os.path.exists', return_value=True) 60 @mock.patch('detect_repo.execute', 61 return_value=('https://github.com/google/syzkaller.git', None)) 62 def test_normal_style_repo_url(self, _, __): 63 """Tests that check_for_repo_name works on normally cloned repos.""" 64 self.assertTrue(detect_repo.check_for_repo_name('fake-path', 'syzkaller')) 65 66 67@unittest.skipIf(not os.getenv('INTEGRATION_TESTS'), 68 'INTEGRATION_TESTS=1 not set') 69class DetectRepoIntegrationTest(unittest.TestCase): 70 """Class to test the functionality of the detect_repo module.""" 71 72 def test_infer_main_repo_from_commit(self): 73 """Tests that the main repo can be inferred based on an example commit.""" 74 75 with tempfile.TemporaryDirectory() as tmp_dir: 76 # Construct example repo's to check for commits. 77 for test_repo in test_repos.TEST_REPOS: 78 repo_manager.clone_repo_and_get_manager(test_repo.git_url, tmp_dir) 79 self.check_with_repo(test_repo.git_url, 80 test_repo.git_repo_name, 81 tmp_dir, 82 commit=test_repo.old_commit) 83 84 def test_infer_main_repo_from_name(self): 85 """Tests that the main project repo can be inferred from a repo name.""" 86 with tempfile.TemporaryDirectory() as tmp_dir: 87 for test_repo in test_repos.TEST_REPOS: 88 repo_manager.clone_repo_and_get_manager(test_repo.git_url, tmp_dir) 89 self.check_with_repo(test_repo.git_url, test_repo.git_repo_name, 90 tmp_dir) 91 92 def check_with_repo(self, repo_origin, repo_name, tmp_dir, commit=None): 93 """Checks the detect repo's main method for a specific set of inputs. 94 95 Args: 96 repo_origin: URL of the git repo. 97 repo_name: The name of the directory it is cloned to. 98 tmp_dir: The location of the directory of git repos to be searched. 99 commit: The commit that should be used to look up the repo. 100 """ 101 command = ['python3', 'detect_repo.py', '--src_dir', tmp_dir] 102 103 if commit: 104 command += ['--example_commit', commit] 105 else: 106 command += ['--repo_name', repo_name] 107 108 out, _ = detect_repo.execute(command, 109 location=os.path.dirname( 110 os.path.realpath(__file__))) 111 match = re.search(r'\bDetected repo: ([^ ]+) ([^ ]+)', out.rstrip()) 112 if match and match.group(1) and match.group(2): 113 self.assertEqual(match.group(1), repo_origin) 114 self.assertEqual(match.group(2), os.path.join(tmp_dir, repo_name)) 115 else: 116 self.assertIsNone(repo_origin) 117 self.assertIsNone(repo_name) 118 119 120if __name__ == '__main__': 121 unittest.main() 122