xref: /aosp_15_r20/tools/repohooks/rh/config_unittest.py (revision d68f33bc6fb0cc2476107c2af0573a2f5a63dfc1)
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