1#!/usr/bin/env python3
2# -*- coding:utf-8 -*-
3# Copyright 2016 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""Unittests for the config module."""
18
19from __future__ import print_function
20
21import os
22import shutil
23import sys
24import tempfile
25import unittest
26
27_path = os.path.realpath(__file__ + '/../..')
28if sys.path[0] != _path:
29    sys.path.insert(0, _path)
30del _path
31
32# We have to import our local modules after the sys.path tweak.  We can't use
33# relative imports because this is an executable program, not a module.
34# pylint: disable=wrong-import-position
35import rh.hooks
36import rh.config
37
38
39class PreUploadConfigTests(unittest.TestCase):
40    """Tests for the PreUploadConfig class."""
41
42    def setUp(self):
43        self.tempdir = tempfile.mkdtemp()
44
45    def tearDown(self):
46        shutil.rmtree(self.tempdir)
47
48    def _write_config(self, data, filename=None):
49        """Helper to write out a config file for testing."""
50        if filename is None:
51            filename = rh.config.PreUploadConfig.FILENAME
52        path = os.path.join(self.tempdir, filename)
53        with open(path, 'w') as fp:
54            fp.write(data)
55
56    def _write_global_config(self, data):
57        """Helper to write out a global config file for testing."""
58        self._write_config(
59            data, filename=rh.config.PreUploadConfig.GLOBAL_FILENAME)
60
61    def testMissing(self):
62        """Instantiating a non-existent config file should be fine."""
63        rh.config.PreUploadConfig()
64
65    def testEmpty(self):
66        """Instantiating an empty config file should be fine."""
67        self._write_config('')
68        rh.config.PreUploadConfig(paths=(self.tempdir,))
69
70    def testValid(self):
71        """Verify a fully valid file works."""
72        self._write_config("""# This be a comment me matey.
73[Hook Scripts]
74name = script --with "some args"
75
76[Builtin Hooks]
77cpplint = true
78
79[Builtin Hooks Options]
80cpplint = --some 'more args'
81
82[Options]
83ignore_merged_commits = true
84""")
85        rh.config.PreUploadConfig(paths=(self.tempdir,))
86
87    def testUnknownSection(self):
88        """Reject unknown sections."""
89        self._write_config('[BOOGA]')
90        self.assertRaises(rh.config.ValidationError, rh.config.PreUploadConfig,
91                          paths=(self.tempdir,))
92
93    def testUnknownBuiltin(self):
94        """Reject unknown builtin hooks."""
95        self._write_config('[Builtin Hooks]\nbooga = borg!')
96        self.assertRaises(rh.config.ValidationError, rh.config.PreUploadConfig,
97                          paths=(self.tempdir,))
98
99    def testEmptyCustomHook(self):
100        """Reject empty custom hooks."""
101        self._write_config('[Hook Scripts]\nbooga = \t \n')
102        self.assertRaises(rh.config.ValidationError, rh.config.PreUploadConfig,
103                          paths=(self.tempdir,))
104
105    def testInvalidIni(self):
106        """Reject invalid ini files."""
107        self._write_config('[Hook Scripts]\n =')
108        self.assertRaises(rh.config.ValidationError, rh.config.PreUploadConfig,
109                          paths=(self.tempdir,))
110
111    def testInvalidString(self):
112        """Catch invalid string quoting."""
113        self._write_config("""[Hook Scripts]
114name = script --'bad-quotes
115""")
116        self.assertRaises(rh.config.ValidationError, rh.config.PreUploadConfig,
117                          paths=(self.tempdir,))
118
119    def testGlobalConfigs(self):
120        """Verify global configs stack properly."""
121        self._write_global_config("""[Builtin Hooks]
122commit_msg_bug_field = true
123commit_msg_changeid_field = true
124commit_msg_test_field = false""")
125        self._write_config("""[Builtin Hooks]
126commit_msg_bug_field = false
127commit_msg_test_field = true""")
128        config = rh.config.PreUploadConfig(paths=(self.tempdir,),
129                                           global_paths=(self.tempdir,))
130        self.assertEqual(config.builtin_hooks,
131                         ['commit_msg_changeid_field', 'commit_msg_test_field'])
132
133
134if __name__ == '__main__':
135    unittest.main()
136