• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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