1*d68f33bcSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*d68f33bcSAndroid Build Coastguard Worker# Copyright 2016 The Android Open Source Project 3*d68f33bcSAndroid Build Coastguard Worker# 4*d68f33bcSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*d68f33bcSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*d68f33bcSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*d68f33bcSAndroid Build Coastguard Worker# 8*d68f33bcSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*d68f33bcSAndroid Build Coastguard Worker# 10*d68f33bcSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*d68f33bcSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 12*d68f33bcSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*d68f33bcSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*d68f33bcSAndroid Build Coastguard Worker# limitations under the License. 15*d68f33bcSAndroid Build Coastguard Worker 16*d68f33bcSAndroid Build Coastguard Worker"""Unittests for the config module.""" 17*d68f33bcSAndroid Build Coastguard Worker 18*d68f33bcSAndroid Build Coastguard Workerimport os 19*d68f33bcSAndroid Build Coastguard Workerimport shutil 20*d68f33bcSAndroid Build Coastguard Workerimport sys 21*d68f33bcSAndroid Build Coastguard Workerimport tempfile 22*d68f33bcSAndroid Build Coastguard Workerimport unittest 23*d68f33bcSAndroid Build Coastguard Worker 24*d68f33bcSAndroid Build Coastguard Worker_path = os.path.realpath(__file__ + '/../..') 25*d68f33bcSAndroid Build Coastguard Workerif sys.path[0] != _path: 26*d68f33bcSAndroid Build Coastguard Worker sys.path.insert(0, _path) 27*d68f33bcSAndroid Build Coastguard Workerdel _path 28*d68f33bcSAndroid Build Coastguard Worker 29*d68f33bcSAndroid Build Coastguard Worker# We have to import our local modules after the sys.path tweak. We can't use 30*d68f33bcSAndroid Build Coastguard Worker# relative imports because this is an executable program, not a module. 31*d68f33bcSAndroid Build Coastguard Worker# pylint: disable=wrong-import-position 32*d68f33bcSAndroid Build Coastguard Workerimport rh.hooks 33*d68f33bcSAndroid Build Coastguard Workerimport rh.config 34*d68f33bcSAndroid Build Coastguard Worker 35*d68f33bcSAndroid Build Coastguard Worker 36*d68f33bcSAndroid Build Coastguard Workerclass PreUploadConfigTests(unittest.TestCase): 37*d68f33bcSAndroid Build Coastguard Worker """Tests for the PreUploadConfig class.""" 38*d68f33bcSAndroid Build Coastguard Worker 39*d68f33bcSAndroid Build Coastguard Worker def testMissing(self): 40*d68f33bcSAndroid Build Coastguard Worker """Instantiating a non-existent config file should be fine.""" 41*d68f33bcSAndroid Build Coastguard Worker rh.config.PreUploadConfig() 42*d68f33bcSAndroid Build Coastguard Worker 43*d68f33bcSAndroid Build Coastguard Worker 44*d68f33bcSAndroid Build Coastguard Workerclass FileTestCase(unittest.TestCase): 45*d68f33bcSAndroid Build Coastguard Worker """Helper class for tests cases to setup configuration files.""" 46*d68f33bcSAndroid Build Coastguard Worker 47*d68f33bcSAndroid Build Coastguard Worker def setUp(self): 48*d68f33bcSAndroid Build Coastguard Worker self.tempdir = tempfile.mkdtemp() 49*d68f33bcSAndroid Build Coastguard Worker 50*d68f33bcSAndroid Build Coastguard Worker def tearDown(self): 51*d68f33bcSAndroid Build Coastguard Worker shutil.rmtree(self.tempdir) 52*d68f33bcSAndroid Build Coastguard Worker 53*d68f33bcSAndroid Build Coastguard Worker def _write_config(self, data, filename='temp.cfg'): 54*d68f33bcSAndroid Build Coastguard Worker """Helper to write out a config file for testing. 55*d68f33bcSAndroid Build Coastguard Worker 56*d68f33bcSAndroid Build Coastguard Worker Returns: 57*d68f33bcSAndroid Build Coastguard Worker Path to the file where the configuration was written. 58*d68f33bcSAndroid Build Coastguard Worker """ 59*d68f33bcSAndroid Build Coastguard Worker path = os.path.join(self.tempdir, filename) 60*d68f33bcSAndroid Build Coastguard Worker with open(path, 'w', encoding='utf-8') as fp: 61*d68f33bcSAndroid Build Coastguard Worker fp.write(data) 62*d68f33bcSAndroid Build Coastguard Worker return path 63*d68f33bcSAndroid Build Coastguard Worker 64*d68f33bcSAndroid Build Coastguard Worker def _write_local_config(self, data): 65*d68f33bcSAndroid Build Coastguard Worker """Helper to write out a local config file for testing.""" 66*d68f33bcSAndroid Build Coastguard Worker return self._write_config( 67*d68f33bcSAndroid Build Coastguard Worker data, filename=rh.config.LocalPreUploadFile.FILENAME) 68*d68f33bcSAndroid Build Coastguard Worker 69*d68f33bcSAndroid Build Coastguard Worker def _write_global_config(self, data): 70*d68f33bcSAndroid Build Coastguard Worker """Helper to write out a global config file for testing.""" 71*d68f33bcSAndroid Build Coastguard Worker return self._write_config( 72*d68f33bcSAndroid Build Coastguard Worker data, filename=rh.config.GlobalPreUploadFile.FILENAME) 73*d68f33bcSAndroid Build Coastguard Worker 74*d68f33bcSAndroid Build Coastguard Worker 75*d68f33bcSAndroid Build Coastguard Workerclass PreUploadFileTests(FileTestCase): 76*d68f33bcSAndroid Build Coastguard Worker """Tests for the PreUploadFile class.""" 77*d68f33bcSAndroid Build Coastguard Worker 78*d68f33bcSAndroid Build Coastguard Worker def testEmpty(self): 79*d68f33bcSAndroid Build Coastguard Worker """Instantiating an empty config file should be fine.""" 80*d68f33bcSAndroid Build Coastguard Worker path = self._write_config('') 81*d68f33bcSAndroid Build Coastguard Worker rh.config.PreUploadFile(path) 82*d68f33bcSAndroid Build Coastguard Worker 83*d68f33bcSAndroid Build Coastguard Worker def testValid(self): 84*d68f33bcSAndroid Build Coastguard Worker """Verify a fully valid file works.""" 85*d68f33bcSAndroid Build Coastguard Worker path = self._write_config("""# This be a comment me matey. 86*d68f33bcSAndroid Build Coastguard Worker[Hook Scripts] 87*d68f33bcSAndroid Build Coastguard Workername = script --with "some args" 88*d68f33bcSAndroid Build Coastguard Worker 89*d68f33bcSAndroid Build Coastguard Worker[Builtin Hooks] 90*d68f33bcSAndroid Build Coastguard Workercpplint = true 91*d68f33bcSAndroid Build Coastguard Worker 92*d68f33bcSAndroid Build Coastguard Worker[Builtin Hooks Options] 93*d68f33bcSAndroid Build Coastguard Workercpplint = --some 'more args' 94*d68f33bcSAndroid Build Coastguard Worker 95*d68f33bcSAndroid Build Coastguard Worker[Options] 96*d68f33bcSAndroid Build Coastguard Workerignore_merged_commits = true 97*d68f33bcSAndroid Build Coastguard Worker""") 98*d68f33bcSAndroid Build Coastguard Worker rh.config.PreUploadFile(path) 99*d68f33bcSAndroid Build Coastguard Worker 100*d68f33bcSAndroid Build Coastguard Worker def testUnknownSection(self): 101*d68f33bcSAndroid Build Coastguard Worker """Reject unknown sections.""" 102*d68f33bcSAndroid Build Coastguard Worker path = self._write_config('[BOOGA]') 103*d68f33bcSAndroid Build Coastguard Worker self.assertRaises(rh.config.ValidationError, rh.config.PreUploadFile, 104*d68f33bcSAndroid Build Coastguard Worker path) 105*d68f33bcSAndroid Build Coastguard Worker 106*d68f33bcSAndroid Build Coastguard Worker def testUnknownBuiltin(self): 107*d68f33bcSAndroid Build Coastguard Worker """Reject unknown builtin hooks.""" 108*d68f33bcSAndroid Build Coastguard Worker path = self._write_config('[Builtin Hooks]\nbooga = borg!') 109*d68f33bcSAndroid Build Coastguard Worker self.assertRaises(rh.config.ValidationError, rh.config.PreUploadFile, 110*d68f33bcSAndroid Build Coastguard Worker path) 111*d68f33bcSAndroid Build Coastguard Worker 112*d68f33bcSAndroid Build Coastguard Worker def testEmptyCustomHook(self): 113*d68f33bcSAndroid Build Coastguard Worker """Reject empty custom hooks.""" 114*d68f33bcSAndroid Build Coastguard Worker path = self._write_config('[Hook Scripts]\nbooga = \t \n') 115*d68f33bcSAndroid Build Coastguard Worker self.assertRaises(rh.config.ValidationError, rh.config.PreUploadFile, 116*d68f33bcSAndroid Build Coastguard Worker path) 117*d68f33bcSAndroid Build Coastguard Worker 118*d68f33bcSAndroid Build Coastguard Worker def testInvalidIni(self): 119*d68f33bcSAndroid Build Coastguard Worker """Reject invalid ini files.""" 120*d68f33bcSAndroid Build Coastguard Worker path = self._write_config('[Hook Scripts]\n =') 121*d68f33bcSAndroid Build Coastguard Worker self.assertRaises(rh.config.ValidationError, rh.config.PreUploadFile, 122*d68f33bcSAndroid Build Coastguard Worker path) 123*d68f33bcSAndroid Build Coastguard Worker 124*d68f33bcSAndroid Build Coastguard Worker def testInvalidString(self): 125*d68f33bcSAndroid Build Coastguard Worker """Catch invalid string quoting.""" 126*d68f33bcSAndroid Build Coastguard Worker path = self._write_config("""[Hook Scripts] 127*d68f33bcSAndroid Build Coastguard Workername = script --'bad-quotes 128*d68f33bcSAndroid Build Coastguard Worker""") 129*d68f33bcSAndroid Build Coastguard Worker self.assertRaises(rh.config.ValidationError, rh.config.PreUploadFile, 130*d68f33bcSAndroid Build Coastguard Worker path) 131*d68f33bcSAndroid Build Coastguard Worker 132*d68f33bcSAndroid Build Coastguard Worker 133*d68f33bcSAndroid Build Coastguard Workerclass LocalPreUploadFileTests(FileTestCase): 134*d68f33bcSAndroid Build Coastguard Worker """Test for the LocalPreUploadFile class.""" 135*d68f33bcSAndroid Build Coastguard Worker 136*d68f33bcSAndroid Build Coastguard Worker def testInvalidSectionConfig(self): 137*d68f33bcSAndroid Build Coastguard Worker """Reject local config that uses invalid sections.""" 138*d68f33bcSAndroid Build Coastguard Worker path = self._write_config("""[Builtin Hooks Exclude Paths] 139*d68f33bcSAndroid Build Coastguard Workercpplint = external/ 'test directory' ^vendor/(?!google/) 140*d68f33bcSAndroid Build Coastguard Worker""") 141*d68f33bcSAndroid Build Coastguard Worker self.assertRaises(rh.config.ValidationError, 142*d68f33bcSAndroid Build Coastguard Worker rh.config.LocalPreUploadFile, 143*d68f33bcSAndroid Build Coastguard Worker path) 144*d68f33bcSAndroid Build Coastguard Worker 145*d68f33bcSAndroid Build Coastguard Worker 146*d68f33bcSAndroid Build Coastguard Workerclass PreUploadSettingsTests(FileTestCase): 147*d68f33bcSAndroid Build Coastguard Worker """Tests for the PreUploadSettings class.""" 148*d68f33bcSAndroid Build Coastguard Worker 149*d68f33bcSAndroid Build Coastguard Worker def testGlobalConfigs(self): 150*d68f33bcSAndroid Build Coastguard Worker """Verify global configs stack properly.""" 151*d68f33bcSAndroid Build Coastguard Worker self._write_global_config("""[Builtin Hooks] 152*d68f33bcSAndroid Build Coastguard Workercommit_msg_bug_field = true 153*d68f33bcSAndroid Build Coastguard Workercommit_msg_changeid_field = true 154*d68f33bcSAndroid Build Coastguard Workercommit_msg_test_field = false""") 155*d68f33bcSAndroid Build Coastguard Worker self._write_local_config("""[Builtin Hooks] 156*d68f33bcSAndroid Build Coastguard Workercommit_msg_bug_field = false 157*d68f33bcSAndroid Build Coastguard Workercommit_msg_test_field = true""") 158*d68f33bcSAndroid Build Coastguard Worker config = rh.config.PreUploadSettings(paths=(self.tempdir,), 159*d68f33bcSAndroid Build Coastguard Worker global_paths=(self.tempdir,)) 160*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(config.builtin_hooks, 161*d68f33bcSAndroid Build Coastguard Worker ['commit_msg_changeid_field', 'commit_msg_test_field']) 162*d68f33bcSAndroid Build Coastguard Worker 163*d68f33bcSAndroid Build Coastguard Worker def testGlobalExcludeScope(self): 164*d68f33bcSAndroid Build Coastguard Worker """Verify exclude scope is valid for global config.""" 165*d68f33bcSAndroid Build Coastguard Worker self._write_global_config("""[Builtin Hooks Exclude Paths] 166*d68f33bcSAndroid Build Coastguard Workercpplint = external/ 'test directory' ^vendor/(?!google/) 167*d68f33bcSAndroid Build Coastguard Worker""") 168*d68f33bcSAndroid Build Coastguard Worker rh.config.PreUploadSettings(global_paths=(self.tempdir,)) 169*d68f33bcSAndroid Build Coastguard Worker 170*d68f33bcSAndroid Build Coastguard Worker 171*d68f33bcSAndroid Build Coastguard Workerif __name__ == '__main__': 172*d68f33bcSAndroid Build Coastguard Worker unittest.main() 173