blob: 27a0c53e3d042af5c7eb023ed8de9ea41f262e37 [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
Kuang-che Wua5723492019-11-25 20:59:34 +080015try:
16 from unittest import mock
17except ImportError:
18 # TODO(kcwu): remove once migrated to python3
19 import mock
Kuang-che Wu385279d2017-09-27 14:48:28 +080020
Kuang-che Wu3b46aa42019-03-14 15:59:52 +080021from bisect_kit import common
Kuang-che Wu385279d2017-09-27 14:48:28 +080022from bisect_kit import configure
23
24
25@contextlib.contextmanager
26def scoped_file(folder, filename, content=''):
27 """Helper to create file and auto delete after use.
28
29 This is with-context manager. It creates file with given content when at
30 start. After the context finished, it will delete the created file.
31
32 Args:
33 folder: where to put the file.
34 filename: filename to create.
35 content: file content.
36
37 Yields:
38 full path of created file.
39 """
40 full_path = os.path.join(folder, filename)
Kuang-che Wuae6824b2019-08-27 22:20:01 +080041 with open(full_path, 'w') as f:
Kuang-che Wu385279d2017-09-27 14:48:28 +080042 f.write(content)
43 yield full_path
44 os.unlink(full_path)
45
46
47class TestConfigure(unittest.TestCase):
48 """Test configure.Configure class."""
49
50 def setUp(self):
51 assert configure.CONFIG_ENV_NAME not in os.environ, (
52 '"%s" should not be set during unittest' % configure.CONFIG_ENV_NAME)
53 self.oldcwd = os.getcwd()
54 self.cwddir = tempfile.mkdtemp()
55 self.progdir = tempfile.mkdtemp()
56 # Make sure current working directory and is clean.
57 os.chdir(self.cwddir)
58
59 def tearDown(self):
60 os.chdir(self.oldcwd)
61 shutil.rmtree(self.progdir)
62 shutil.rmtree(self.cwddir)
63
64 def test_scoped_file(self):
65 with scoped_file(self.cwddir, 'foo', 'abc') as path:
66 assert os.path.exists(path)
Kuang-che Wua5723492019-11-25 20:59:34 +080067 with open(path) as f:
68 self.assertEqual(f.read(), 'abc')
Kuang-che Wu385279d2017-09-27 14:48:28 +080069 assert not os.path.exists(path)
70
71 def test_search_config_file(self):
72 args = [os.path.join(self.progdir, 'foo.py')]
73
74 self.assertEqual(configure.search_config_file(args), None)
75
76 with scoped_file(self.cwddir, 'foo') as path:
77 self.assertEqual(
78 configure.search_config_file(args + ['--rc', path]), path)
79
80 with scoped_file(self.cwddir, 'bar') as path:
81 with mock.patch.dict(os.environ, {configure.CONFIG_ENV_NAME: path}):
82 self.assertEqual(configure.search_config_file(args), path)
83
84 with scoped_file(self.cwddir, configure.DEFAULT_CONFIG_FILENAME) as path:
85 self.assertEqual(configure.search_config_file(args), path)
86
87 with scoped_file(self.progdir, configure.DEFAULT_CONFIG_FILENAME) as path:
88 self.assertEqual(configure.search_config_file(args), path)
89
90 def test_search_config_file_precedence(self):
91 args = [os.path.join(self.progdir, 'foo.py')]
92
93 self.assertEqual(configure.search_config_file(args), None)
94
95 with scoped_file(self.progdir, configure.DEFAULT_CONFIG_FILENAME) as path1:
96 self.assertEqual(configure.search_config_file(args), path1)
97
98 with scoped_file(self.cwddir, configure.DEFAULT_CONFIG_FILENAME) as path2:
99 self.assertEqual(configure.search_config_file(args), path2)
100
101 with scoped_file(self.cwddir, 'bar') as path3:
102 with mock.patch.dict(os.environ, {configure.CONFIG_ENV_NAME: 'none'}):
103 self.assertEqual(configure.search_config_file(args), None)
104
105 with mock.patch.dict(os.environ, {configure.CONFIG_ENV_NAME: path3}):
106 self.assertEqual(configure.search_config_file(args), path3)
107
108 with scoped_file(self.cwddir, 'foo') as path4:
109 self.assertEqual(
110 configure.search_config_file(args + ['--rc', path4]), path4)
111 self.assertEqual(
112 configure.search_config_file(args + ['--rc', 'none']), None)
113
114 def test_search_config_file_not_found(self):
115 args = [os.path.join(self.progdir, 'foo.py')]
116 path = os.path.join(self.cwddir, 'foo')
117
118 with self.assertRaises(ValueError):
119 configure.search_config_file(args + ['--rc', path])
120
121 with self.assertRaises(ValueError):
122 with mock.patch.dict(os.environ, {configure.CONFIG_ENV_NAME: path}):
123 configure.search_config_file(args)
124
Kuang-che Wuab72da72018-01-16 18:07:54 +0800125 def test_load_sample_config(self):
126 filename = 'bisect_kit.json.sample'
Kuang-che Wu3b46aa42019-03-14 15:59:52 +0800127 path = os.path.join(common.BISECT_KIT_ROOT, filename)
Kuang-che Wuab72da72018-01-16 18:07:54 +0800128 config = configure.ConfigStore(path)
129
130 # Load succeeded, no exceptions.
131 config.load_config()
132
Kuang-che Wu385279d2017-09-27 14:48:28 +0800133 def test_include(self):
134 subdir = os.path.join(self.progdir, 'subdir')
135 os.mkdir(subdir)
Kuang-che Wuae6824b2019-08-27 22:20:01 +0800136 with scoped_file(self.progdir, 'a', """
Kuang-che Wu385279d2017-09-27 14:48:28 +0800137 {"include":["subdir/b"]}
Kuang-che Wuae6824b2019-08-27 22:20:01 +0800138 """) as path, \
139 scoped_file(subdir, 'b', """
140 {"options": {"foo": "bar"}}"""):
Kuang-che Wu385279d2017-09-27 14:48:28 +0800141 config = configure.ConfigStore(path)
142 config.load_config()
143 self.assertEqual(config.get_option('foo'), 'bar')
144
145 def test_plugins(self):
146 subdir = os.path.join(self.progdir, 'subdir')
147 os.mkdir(subdir)
148
Kuang-che Wuae6824b2019-08-27 22:20:01 +0800149 with scoped_file(self.progdir, 'a', """
Kuang-che Wu385279d2017-09-27 14:48:28 +0800150 {"include": ["subdir/b.json"], "plugins": ["a.py"] }
Kuang-che Wuae6824b2019-08-27 22:20:01 +0800151 """) as path, \
152 scoped_file(self.progdir, 'a.py', textwrap.dedent("""
Kuang-che Wu385279d2017-09-27 14:48:28 +0800153 from bisect_kit import configure_test
154
155 def loaded():
156 configure_test.aaa = 111
Kuang-che Wuae6824b2019-08-27 22:20:01 +0800157 """)), \
158 scoped_file(subdir, 'b.json', """
Kuang-che Wu385279d2017-09-27 14:48:28 +0800159 {"plugins": ["b.py"]}
Kuang-che Wuae6824b2019-08-27 22:20:01 +0800160 """), \
161 scoped_file(subdir, 'b.py', textwrap.dedent("""
Kuang-che Wu385279d2017-09-27 14:48:28 +0800162 from bisect_kit import configure_test
163
164 def loaded():
165 configure_test.bbb = 222
Kuang-che Wuae6824b2019-08-27 22:20:01 +0800166 """)):
Kuang-che Wu385279d2017-09-27 14:48:28 +0800167 config = configure.ConfigStore(path)
168 config.load_config()
169 config.load_plugins()
170 self.assertEqual(globals().get('aaa'), 111)
171 self.assertEqual(globals().get('bbb'), 222)
172
173
174if __name__ == '__main__':
175 unittest.main()