diff options
author | 2020-01-15 13:30:57 -0800 | |
---|---|---|
committer | 2020-01-15 13:30:57 -0800 | |
commit | 14582175d07c8a66adf3f9087a464612f2a3f630 (patch) | |
tree | 831d57d5a406af6be2dcb3bd0ca7ba1970956cea /infra/base-images/base-builder | |
parent | 79860344beaf5b228c0f619451d860ec0f2adcfa (diff) |
[infra] Scripts for building fuzzers with CIFuzz (#3207)
Diffstat (limited to 'infra/base-images/base-builder')
-rw-r--r-- | infra/base-images/base-builder/detect_repo.py | 81 | ||||
-rw-r--r-- | infra/base-images/base-builder/detect_repo_test.py | 64 |
2 files changed, 108 insertions, 37 deletions
diff --git a/infra/base-images/base-builder/detect_repo.py b/infra/base-images/base-builder/detect_repo.py index d7974ca5..f57947e7 100644 --- a/infra/base-images/base-builder/detect_repo.py +++ b/infra/base-images/base-builder/detect_repo.py @@ -16,9 +16,11 @@ inside of an OSS-Fuzz project. Example Usage: - python detect_repo.py --src_dir /src --example_commit b534f03eecd8a109db2b085ab24d419b6486de97 + python detect_repo.py --src_dir /src --example_commit + b534f03eecd8a109db2b085ab24d419b6486de97 -Prints the location of the git remote repo as well as the repos name seperated by a space. +Prints the location of the git remote repo as well as the repo's name +seperated by a space. https://github.com/VirusTotal/yara.git yara @@ -29,26 +31,36 @@ import subprocess def main(): - """Function to get a git repos information based on its commit.""" + """Function to get a git repo's url and name referenced by OSS-Fuzz + Dockerfile. + + Raises: + ValueError when a commit or a ref is not provided. + """ parser = argparse.ArgumentParser( - description='Finds a specific git repo in an oss-fuzz projects docker file.' - ) + description= + 'Finds a specific git repo in an oss-fuzz project\'s docker file.') parser.add_argument( '--src_dir', - help='The location of the oss-fuzz projects source directory', - required=True) - parser.add_argument( - '--example_commit', - help='A commit SHA refrencing the projects main repo', + help='The location of an oss-fuzz project\'s source directory.', required=True) + parser.add_argument('--repo_name', help='The name of the git repo.') + parser.add_argument('--example_commit', + help='A commit SHA referencing the project\'s main repo.') + args = parser.parse_args() + if not args.repo_name and not args.example_commit: + raise ValueError( + 'Requires an example commit or a repo name to find repo location.') for single_dir in os.listdir(args.src_dir): full_path = os.path.join(args.src_dir, single_dir) if not os.path.isdir(full_path): continue - if check_for_commit( - os.path.join(args.src_dir, full_path), args.example_commit): - print('Detected repo: %s %s' % (get_repo(full_path), single_dir.rstrip())) + if args.example_commit and check_for_commit(full_path, args.example_commit): + print('Detected repo:', get_repo(full_path), single_dir) + return + if args.repo_name and check_for_repo_name(full_path, args.repo_name): + print('Detected repo:', get_repo(full_path), single_dir) return print('No git repos with specific commit: %s found in %s' % (args.example_commit, args.src_dir)) @@ -61,26 +73,41 @@ def get_repo(repo_path): repo_path: The directory on the image where the git repo exists. Returns: - The repo location or None + The repo location or None. """ - output, return_code = execute( - ['git', 'config', '--get', 'remote.origin.url'], - location=repo_path, - check_result=True) + output, return_code = execute(['git', 'config', '--get', 'remote.origin.url'], + location=repo_path, + check_result=True) if return_code == 0 and output: return output.rstrip() return None +def check_for_repo_name(repo_path, repo_name): + """Check to see if the repo_name matches the remote repository repo name. + + Args: + repo_path: The directory of the git repo. + repo_name: The name of the target git repo. + """ + if not os.path.exists(os.path.join(repo_path, '.git')): + return False + + out, _ = execute(['git', 'config', '--get', 'remote.origin.url'], + location=repo_path) + out = out.split('/')[-1].replace('.git', '').rstrip() + return out == repo_name + + def check_for_commit(repo_path, commit): """Checks a directory for a specific commit. Args: - repo_path: The name of the directory to test for the commit - commit: The commit SHA to check for + repo_path: The name of the directory to test for the commit. + commit: The commit SHA to check for. Returns: - True if directory contains that commit + True if directory contains that commit. """ # Check if valid git repo. @@ -93,7 +120,7 @@ def check_for_commit(repo_path, commit): # Check if commit is in history. _, return_code = execute(['git', 'cat-file', '-e', commit], - location=repo_path) + location=repo_path) return return_code == 0 @@ -101,15 +128,15 @@ def execute(command, location, check_result=False): """Runs a shell command in the specified directory location. Args: - command: The command as a list to be run - location: The directory the command is run in - check_result: Should an exception be thrown on failed command + command: The command as a list to be run. + location: The directory the command is run in. + check_result: Should an exception be thrown on failed command. Returns: - The stdout of the command, the error code + The stdout of the command, the error code. Raises: - RuntimeError: running a command resulted in an error + RuntimeError: running a command resulted in an error. """ process = subprocess.Popen(command, stdout=subprocess.PIPE, cwd=location) output, err = process.communicate() diff --git a/infra/base-images/base-builder/detect_repo_test.py b/infra/base-images/base-builder/detect_repo_test.py index cac0f882..e9029b7f 100644 --- a/infra/base-images/base-builder/detect_repo_test.py +++ b/infra/base-images/base-builder/detect_repo_test.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """Test the functionality of the detect_repo module. -The will consist of the following functional test +This will consist of the following functional test: 1. Determine if a OSS-Fuzz projects main repo can be accurately deduce from example commits. """ @@ -23,11 +23,14 @@ import tempfile import unittest import detect_repo + # Appending to path for access to repo_manager module. +# pylint: disable=wrong-import-position sys.path.append( - os.path.dirname( - os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) + os.path.dirname(os.path.dirname(os.path.dirname( + os.path.abspath(__file__))))) import repo_manager +# pylint: enable=wrong-import-position class DetectRepoTest(unittest.TestCase): @@ -62,25 +65,66 @@ class DetectRepoTest(unittest.TestCase): self.check_commit_with_repo(None, None, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', tmp_dir) - def check_commit_with_repo(self, repo_origin, repo_name, commit, tmp_dir): + def test_infer_main_repo_from_name(self): + """Tests that the main project repo can be inferred from a repo name.""" + + with tempfile.TemporaryDirectory() as tmp_dir: + # Construct example repos to check for name. + repo_manager.RepoManager('https://github.com/curl/curl.git', tmp_dir) + repo_manager.RepoManager('https://github.com/ntop/nDPI.git', tmp_dir) + repo_manager.RepoManager('https://github.com/libarchive/libarchive.git', + tmp_dir) + self.check_ref_with_repo('https://github.com/curl/curl.git', 'curl', + tmp_dir) + self.check_ref_with_repo('https://github.com/ntop/nDPI.git', 'nDPI', + tmp_dir) + self.check_ref_with_repo('https://github.com/libarchive/libarchive.git', + 'libarchive', tmp_dir) + + def check_ref_with_repo(self, repo_origin, repo_name, tmp_dir): """Checks the detect repo's main method for a specific set of inputs. + Args: + repo_origin: URL of the git repo. + repo_name: The name of the directory it is cloned to. + tmp_dir: The location of the directory of git repos to be searched. + """ + command = [ + 'python3', 'detect_repo.py', '--src_dir', tmp_dir, '--repo_name', + repo_name + ] + out, _ = detect_repo.execute(command, + location=os.path.dirname( + os.path.realpath(__file__))) + match = re.search(r'\bDetected repo: ([^ ]+) ([^ ]+)', out.rstrip()) + if match and match.group(1) and match.group(2): + self.assertEqual(match.group(1), repo_origin) + else: + self.assertIsNone(repo_origin) + + def check_commit_with_repo(self, repo_origin, repo_name, commit, tmp_dir): + """Checks the detect repos main method for a specific set of inputs. + Args: - repo_origin: The location of where the git repo is stored - repo_name: The name of the directory it is cloned to - commit: The commit that should be used to look up the repo - tmp_dir: The location of the directory of git repos to be searched + repo_origin: URL of the git repo. + repo_name: The name of the directory it is cloned to. + commit: The commit that should be used to look up the repo. + tmp_dir: The location of the directory of git repos to be searched. """ command = [ 'python3', 'detect_repo.py', '--src_dir', tmp_dir, '--example_commit', commit ] - out, _ = detect_repo.execute( - command, location=os.path.dirname(os.path.realpath(__file__))) + out, _ = detect_repo.execute(command, + location=os.path.dirname( + os.path.abspath(__file__))) match = re.search(r'\bDetected repo: ([^ ]+) ([^ ]+)', out.rstrip()) if match and match.group(1) and match.group(2): self.assertEqual(match.group(1), repo_origin) self.assertEqual(match.group(2), repo_name) + else: + self.assertIsNone(repo_origin) + self.assertIsNone(repo_name) if __name__ == '__main__': |