blob: bcee2feab368a16978cf464b25c6e8b9220fbde1 [file] [log] [blame]
Kuang-che Wu6e4beca2018-06-27 17:45:02 +08001# -*- coding: utf-8 -*-
Kuang-che Wu385279d2017-09-27 14:48:28 +08002# Copyright 2017 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5"""Configure module."""
6
7from __future__ import print_function
8import contextlib
9import os
10import shutil
11import tempfile
12import textwrap
13import unittest
14
15import mock
16
Kuang-che Wu3b46aa42019-03-14 15:59:52 +080017from bisect_kit import common
Kuang-che Wu385279d2017-09-27 14:48:28 +080018from bisect_kit import configure
19
20
21@contextlib.contextmanager
22def scoped_file(folder, filename, content=''):
23 """Helper to create file and auto delete after use.
24
25 This is with-context manager. It creates file with given content when at
26 start. After the context finished, it will delete the created file.
27
28 Args:
29 folder: where to put the file.
30 filename: filename to create.
31 content: file content.
32
33 Yields:
34 full path of created file.
35 """
36 full_path = os.path.join(folder, filename)
37 with file(full_path, 'w') as f:
38 f.write(content)
39 yield full_path
40 os.unlink(full_path)
41
42
43class TestConfigure(unittest.TestCase):
44 """Test configure.Configure class."""
45
46 def setUp(self):
47 assert configure.CONFIG_ENV_NAME not in os.environ, (
48 '"%s" should not be set during unittest' % configure.CONFIG_ENV_NAME)
49 self.oldcwd = os.getcwd()
50 self.cwddir = tempfile.mkdtemp()
51 self.progdir = tempfile.mkdtemp()
52 # Make sure current working directory and is clean.
53 os.chdir(self.cwddir)
54
55 def tearDown(self):
56 os.chdir(self.oldcwd)
57 shutil.rmtree(self.progdir)
58 shutil.rmtree(self.cwddir)
59
60 def test_scoped_file(self):
61 with scoped_file(self.cwddir, 'foo', 'abc') as path:
62 assert os.path.exists(path)
63 self.assertEqual(file(path).read(), 'abc')
64 assert not os.path.exists(path)
65
66 def test_search_config_file(self):
67 args = [os.path.join(self.progdir, 'foo.py')]
68
69 self.assertEqual(configure.search_config_file(args), None)
70
71 with scoped_file(self.cwddir, 'foo') as path:
72 self.assertEqual(
73 configure.search_config_file(args + ['--rc', path]), path)
74
75 with scoped_file(self.cwddir, 'bar') as path:
76 with mock.patch.dict(os.environ, {configure.CONFIG_ENV_NAME: path}):
77 self.assertEqual(configure.search_config_file(args), path)
78
79 with scoped_file(self.cwddir, configure.DEFAULT_CONFIG_FILENAME) as path:
80 self.assertEqual(configure.search_config_file(args), path)
81
82 with scoped_file(self.progdir, configure.DEFAULT_CONFIG_FILENAME) as path:
83 self.assertEqual(configure.search_config_file(args), path)
84
85 def test_search_config_file_precedence(self):
86 args = [os.path.join(self.progdir, 'foo.py')]
87
88 self.assertEqual(configure.search_config_file(args), None)
89
90 with scoped_file(self.progdir, configure.DEFAULT_CONFIG_FILENAME) as path1:
91 self.assertEqual(configure.search_config_file(args), path1)
92
93 with scoped_file(self.cwddir, configure.DEFAULT_CONFIG_FILENAME) as path2:
94 self.assertEqual(configure.search_config_file(args), path2)
95
96 with scoped_file(self.cwddir, 'bar') as path3:
97 with mock.patch.dict(os.environ, {configure.CONFIG_ENV_NAME: 'none'}):
98 self.assertEqual(configure.search_config_file(args), None)
99
100 with mock.patch.dict(os.environ, {configure.CONFIG_ENV_NAME: path3}):
101 self.assertEqual(configure.search_config_file(args), path3)
102
103 with scoped_file(self.cwddir, 'foo') as path4:
104 self.assertEqual(
105 configure.search_config_file(args + ['--rc', path4]), path4)
106 self.assertEqual(
107 configure.search_config_file(args + ['--rc', 'none']), None)
108
109 def test_search_config_file_not_found(self):
110 args = [os.path.join(self.progdir, 'foo.py')]
111 path = os.path.join(self.cwddir, 'foo')
112
113 with self.assertRaises(ValueError):
114 configure.search_config_file(args + ['--rc', path])
115
116 with self.assertRaises(ValueError):
117 with mock.patch.dict(os.environ, {configure.CONFIG_ENV_NAME: path}):
118 configure.search_config_file(args)
119
Kuang-che Wuab72da72018-01-16 18:07:54 +0800120 def test_load_sample_config(self):
121 filename = 'bisect_kit.json.sample'
Kuang-che Wu3b46aa42019-03-14 15:59:52 +0800122 path = os.path.join(common.BISECT_KIT_ROOT, filename)
Kuang-che Wuab72da72018-01-16 18:07:54 +0800123 config = configure.ConfigStore(path)
124
125 # Load succeeded, no exceptions.
126 config.load_config()
127
Kuang-che Wu385279d2017-09-27 14:48:28 +0800128 def test_include(self):
129 subdir = os.path.join(self.progdir, 'subdir')
130 os.mkdir(subdir)
131 with scoped_file(self.progdir, 'a', '''
132 {"include":["subdir/b"]}
133 ''') as path, \
134 scoped_file(subdir, 'b', '''
135 {"options": {"foo": "bar"}}'''):
136 config = configure.ConfigStore(path)
137 config.load_config()
138 self.assertEqual(config.get_option('foo'), 'bar')
139
140 def test_plugins(self):
141 subdir = os.path.join(self.progdir, 'subdir')
142 os.mkdir(subdir)
143
144 with scoped_file(self.progdir, 'a', '''
145 {"include": ["subdir/b.json"], "plugins": ["a.py"] }
146 ''') as path, \
147 scoped_file(self.progdir, 'a.py', textwrap.dedent('''
148 from bisect_kit import configure_test
149
150 def loaded():
151 configure_test.aaa = 111
152 ''')), \
153 scoped_file(subdir, 'b.json', '''
154 {"plugins": ["b.py"]}
155 '''), \
156 scoped_file(subdir, 'b.py', textwrap.dedent('''
157 from bisect_kit import configure_test
158
159 def loaded():
160 configure_test.bbb = 222
161 ''')):
162 config = configure.ConfigStore(path)
163 config.load_config()
164 config.load_plugins()
165 self.assertEqual(globals().get('aaa'), 111)
166 self.assertEqual(globals().get('bbb'), 222)
167
168
169if __name__ == '__main__':
170 unittest.main()