aboutsummaryrefslogtreecommitdiffhomepage
path: root/infra/base-images/base-builder
diff options
context:
space:
mode:
authorGravatar Leo Neat <leosneat@gmail.com>2020-01-15 13:30:57 -0800
committerGravatar jonathanmetzman <31354670+jonathanmetzman@users.noreply.github.com>2020-01-15 13:30:57 -0800
commit14582175d07c8a66adf3f9087a464612f2a3f630 (patch)
tree831d57d5a406af6be2dcb3bd0ca7ba1970956cea /infra/base-images/base-builder
parent79860344beaf5b228c0f619451d860ec0f2adcfa (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.py81
-rw-r--r--infra/base-images/base-builder/detect_repo_test.py64
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__':