1# Copyright 2021 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"""Tests for git.""" 15import filecmp 16import os 17import tempfile 18import subprocess 19import sys 20import unittest 21from unittest import mock 22 23# pylint: disable=wrong-import-position 24INFRA_DIR = os.path.dirname( 25 os.path.dirname(os.path.dirname(os.path.dirname( 26 os.path.abspath(__file__))))) 27sys.path.append(INFRA_DIR) 28 29from filestore import git 30import test_helpers 31 32# pylint: disable=protected-access,no-self-use 33 34 35class GitFilestoreTest(unittest.TestCase): 36 """Tests for GitFilestore.""" 37 38 def setUp(self): 39 self.git_dir = tempfile.TemporaryDirectory() 40 self.addCleanup(self.git_dir.cleanup) 41 42 self.local_dir = tempfile.TemporaryDirectory() 43 self.addCleanup(self.local_dir.cleanup) 44 45 self.download_dir = tempfile.TemporaryDirectory() 46 self.addCleanup(self.download_dir.cleanup) 47 48 with open(os.path.join(self.local_dir.name, 'a'), 'w') as handle: 49 handle.write('') 50 51 os.makedirs(os.path.join(self.local_dir.name, 'b')) 52 53 with open(os.path.join(self.local_dir.name, 'b', 'c'), 'w') as handle: 54 handle.write('') 55 56 self.git_repo = git.git_runner(self.git_dir.name) 57 self.git_repo('init', '--bare') 58 59 self.config = test_helpers.create_run_config( 60 git_store_repo='file://' + self.git_dir.name, 61 git_store_branch='main', 62 git_store_branch_coverage='cov-branch') 63 64 self.mock_ci_filestore = mock.MagicMock() 65 self.git_store = git.GitFilestore(self.config, self.mock_ci_filestore) 66 67 def assert_dirs_same(self, first, second): 68 """Asserts two dirs are the same.""" 69 dcmp = filecmp.dircmp(first, second) 70 if dcmp.diff_files or dcmp.left_only or dcmp.right_only: 71 return False 72 73 return all( 74 self.assert_dirs_same(os.path.join(first, subdir), 75 os.path.join(second, subdir)) 76 for subdir in dcmp.common_dirs) 77 78 def get_repo_filelist(self, branch): 79 """Get files in repo.""" 80 return subprocess.check_output([ 81 'git', '-C', self.git_dir.name, 'ls-tree', '-r', '--name-only', branch 82 ]).decode().splitlines() 83 84 def test_upload_download_corpus(self): 85 """Tests uploading and downloading corpus.""" 86 self.git_store.upload_corpus('target', self.local_dir.name) 87 self.git_store.download_corpus('target', self.download_dir.name) 88 self.assert_dirs_same(self.local_dir.name, self.download_dir.name) 89 90 self.assertCountEqual([ 91 'corpus/target/a', 92 'corpus/target/b/c', 93 ], self.get_repo_filelist('main')) 94 95 def test_upload_download_coverage(self): 96 """Tests uploading and downloading corpus.""" 97 self.git_store.upload_coverage('latest', self.local_dir.name) 98 self.git_store.download_coverage('latest', self.download_dir.name) 99 self.assert_dirs_same(self.local_dir.name, self.download_dir.name) 100 101 self.assertCountEqual([ 102 'coverage/latest/a', 103 'coverage/latest/b/c', 104 ], self.get_repo_filelist('cov-branch')) 105 106 def test_upload_crashes(self): 107 """Tests uploading crashes.""" 108 self.git_store.upload_crashes('current', self.local_dir.name) 109 self.mock_ci_filestore.upload_crashes.assert_called_with( 110 'current', self.local_dir.name) 111 112 def test_upload_build(self): 113 """Tests uploading build.""" 114 self.git_store.upload_build('sanitizer', self.local_dir.name) 115 self.mock_ci_filestore.upload_build.assert_called_with( 116 'sanitizer', self.local_dir.name) 117 118 def test_download_build(self): 119 """Tests downloading build.""" 120 self.git_store.download_build('sanitizer', self.download_dir.name) 121 self.mock_ci_filestore.download_build.assert_called_with( 122 'sanitizer', self.download_dir.name) 123