blob: 377c6930b8bd1bdeb37c92b4a1e2babe60074e1f [file] [log] [blame]
James E. Blair6f27fca2017-11-21 17:05:43 -08001# Copyright (C) 2017 Red Hat, Inc.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12# implied.
13#
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import os
18import shutil
19import tempfile
20import unittest
21
22from devstack_local_conf import LocalConf
23from collections import OrderedDict
24
25class TestDevstackLocalConf(unittest.TestCase):
Luigi Toscano70d043d2019-03-12 22:25:44 +010026
27 @staticmethod
28 def _init_localconf(p):
29 lc = LocalConf(p.get('localrc'),
30 p.get('local_conf'),
31 p.get('base_services'),
32 p.get('services'),
33 p.get('plugins'),
34 p.get('base_dir'),
35 p.get('projects'),
36 p.get('project'),
37 p.get('tempest_plugins'))
38 return lc
39
James E. Blair6f27fca2017-11-21 17:05:43 -080040 def setUp(self):
41 self.tmpdir = tempfile.mkdtemp()
42
43 def tearDown(self):
44 shutil.rmtree(self.tmpdir)
45
46 def test_plugins(self):
47 "Test that plugins without dependencies work"
48 localrc = {'test_localrc': '1'}
49 local_conf = {'install':
50 {'nova.conf':
51 {'main':
52 {'test_conf': '2'}}}}
53 services = {'cinder': True}
54 # We use ordereddict here to make sure the plugins are in the
55 # *wrong* order for testing.
56 plugins = OrderedDict([
57 ('bar', 'git://git.openstack.org/openstack/bar-plugin'),
58 ('foo', 'git://git.openstack.org/openstack/foo-plugin'),
59 ('baz', 'git://git.openstack.org/openstack/baz-plugin'),
60 ])
61 p = dict(localrc=localrc,
62 local_conf=local_conf,
63 base_services=[],
64 services=services,
65 plugins=plugins,
66 base_dir='./test',
67 path=os.path.join(self.tmpdir, 'test.local.conf'))
Luigi Toscano70d043d2019-03-12 22:25:44 +010068 lc = self._init_localconf(p)
James E. Blair6f27fca2017-11-21 17:05:43 -080069 lc.write(p['path'])
70
71 plugins = []
72 with open(p['path']) as f:
73 for line in f:
74 if line.startswith('enable_plugin'):
75 plugins.append(line.split()[1])
76 self.assertEqual(['bar', 'baz', 'foo'], plugins)
77
James E. Blaire1edde32018-03-02 15:05:14 +000078
James E. Blair6f27fca2017-11-21 17:05:43 -080079 def test_plugin_deps(self):
80 "Test that plugins with dependencies work"
81 os.makedirs(os.path.join(self.tmpdir, 'foo-plugin', 'devstack'))
82 os.makedirs(os.path.join(self.tmpdir, 'foo-plugin', '.git'))
83 os.makedirs(os.path.join(self.tmpdir, 'bar-plugin', 'devstack'))
84 os.makedirs(os.path.join(self.tmpdir, 'bar-plugin', '.git'))
85 with open(os.path.join(
86 self.tmpdir,
87 'foo-plugin', 'devstack', 'settings'), 'w') as f:
Jens Harbott0b855002018-12-19 12:20:51 +000088 f.write('define_plugin foo-plugin\n')
James E. Blair6f27fca2017-11-21 17:05:43 -080089 with open(os.path.join(
90 self.tmpdir,
91 'bar-plugin', 'devstack', 'settings'), 'w') as f:
Jens Harbott0b855002018-12-19 12:20:51 +000092 f.write('define_plugin bar-plugin\n')
93 f.write('plugin_requires bar-plugin foo-plugin\n')
James E. Blair6f27fca2017-11-21 17:05:43 -080094
95 localrc = {'test_localrc': '1'}
96 local_conf = {'install':
97 {'nova.conf':
98 {'main':
99 {'test_conf': '2'}}}}
100 services = {'cinder': True}
101 # We use ordereddict here to make sure the plugins are in the
102 # *wrong* order for testing.
103 plugins = OrderedDict([
Jens Harbott0b855002018-12-19 12:20:51 +0000104 ('bar-plugin', 'git://git.openstack.org/openstack/bar-plugin'),
105 ('foo-plugin', 'git://git.openstack.org/openstack/foo-plugin'),
James E. Blair6f27fca2017-11-21 17:05:43 -0800106 ])
107 p = dict(localrc=localrc,
108 local_conf=local_conf,
109 base_services=[],
110 services=services,
111 plugins=plugins,
112 base_dir=self.tmpdir,
113 path=os.path.join(self.tmpdir, 'test.local.conf'))
Luigi Toscano70d043d2019-03-12 22:25:44 +0100114 lc = self._init_localconf(p)
Jens Harbott6d103a72018-12-19 11:53:16 +0000115 lc.write(p['path'])
116
117 plugins = []
118 with open(p['path']) as f:
119 for line in f:
120 if line.startswith('enable_plugin'):
121 plugins.append(line.split()[1])
Jens Harbott0b855002018-12-19 12:20:51 +0000122 self.assertEqual(['foo-plugin', 'bar-plugin'], plugins)
James E. Blaire1edde32018-03-02 15:05:14 +0000123
124 def test_libs_from_git(self):
125 "Test that LIBS_FROM_GIT is auto-generated"
126 projects = {
127 'git.openstack.org/openstack/nova': {
128 'required': True,
129 'short_name': 'nova',
130 },
131 'git.openstack.org/openstack/oslo.messaging': {
132 'required': True,
133 'short_name': 'oslo.messaging',
134 },
135 'git.openstack.org/openstack/devstack-plugin': {
136 'required': False,
137 'short_name': 'devstack-plugin',
138 },
139 }
James E. Blair8e5f8c22018-06-15 10:10:35 -0700140 project = {
141 'short_name': 'glance',
142 }
James E. Blaire1edde32018-03-02 15:05:14 +0000143 p = dict(base_services=[],
144 base_dir='./test',
145 path=os.path.join(self.tmpdir, 'test.local.conf'),
James E. Blair8e5f8c22018-06-15 10:10:35 -0700146 projects=projects,
147 project=project)
Luigi Toscano70d043d2019-03-12 22:25:44 +0100148 lc = self._init_localconf(p)
James E. Blair6f27fca2017-11-21 17:05:43 -0800149 lc.write(p['path'])
150
James E. Blaire1edde32018-03-02 15:05:14 +0000151 lfg = None
James E. Blair6f27fca2017-11-21 17:05:43 -0800152 with open(p['path']) as f:
153 for line in f:
James E. Blaire1edde32018-03-02 15:05:14 +0000154 if line.startswith('LIBS_FROM_GIT'):
155 lfg = line.strip().split('=')[1]
James E. Blair8e5f8c22018-06-15 10:10:35 -0700156 self.assertEqual('nova,oslo.messaging,glance', lfg)
James E. Blaire1edde32018-03-02 15:05:14 +0000157
158 def test_overridelibs_from_git(self):
159 "Test that LIBS_FROM_GIT can be overridden"
160 localrc = {'LIBS_FROM_GIT': 'oslo.db'}
161 projects = {
162 'git.openstack.org/openstack/nova': {
163 'required': True,
164 'short_name': 'nova',
165 },
166 'git.openstack.org/openstack/oslo.messaging': {
167 'required': True,
168 'short_name': 'oslo.messaging',
169 },
170 'git.openstack.org/openstack/devstack-plugin': {
171 'required': False,
172 'short_name': 'devstack-plugin',
173 },
174 }
175 p = dict(localrc=localrc,
176 base_services=[],
177 base_dir='./test',
178 path=os.path.join(self.tmpdir, 'test.local.conf'),
179 projects=projects)
Luigi Toscano70d043d2019-03-12 22:25:44 +0100180 lc = self._init_localconf(p)
James E. Blaire1edde32018-03-02 15:05:14 +0000181 lc.write(p['path'])
182
183 lfg = None
184 with open(p['path']) as f:
185 for line in f:
186 if line.startswith('LIBS_FROM_GIT'):
187 lfg = line.strip().split('=')[1]
188 self.assertEqual('oslo.db', lfg)
James E. Blair6f27fca2017-11-21 17:05:43 -0800189
190 def test_plugin_circular_deps(self):
191 "Test that plugins with circular dependencies fail"
192 os.makedirs(os.path.join(self.tmpdir, 'foo-plugin', 'devstack'))
193 os.makedirs(os.path.join(self.tmpdir, 'foo-plugin', '.git'))
194 os.makedirs(os.path.join(self.tmpdir, 'bar-plugin', 'devstack'))
195 os.makedirs(os.path.join(self.tmpdir, 'bar-plugin', '.git'))
196 with open(os.path.join(
197 self.tmpdir,
198 'foo-plugin', 'devstack', 'settings'), 'w') as f:
199 f.write('define_plugin foo\n')
200 f.write('plugin_requires foo bar\n')
201 with open(os.path.join(
202 self.tmpdir,
203 'bar-plugin', 'devstack', 'settings'), 'w') as f:
204 f.write('define_plugin bar\n')
205 f.write('plugin_requires bar foo\n')
206
207 localrc = {'test_localrc': '1'}
208 local_conf = {'install':
209 {'nova.conf':
210 {'main':
211 {'test_conf': '2'}}}}
212 services = {'cinder': True}
213 # We use ordereddict here to make sure the plugins are in the
214 # *wrong* order for testing.
215 plugins = OrderedDict([
216 ('bar', 'git://git.openstack.org/openstack/bar-plugin'),
217 ('foo', 'git://git.openstack.org/openstack/foo-plugin'),
218 ])
219 p = dict(localrc=localrc,
220 local_conf=local_conf,
221 base_services=[],
222 services=services,
223 plugins=plugins,
224 base_dir=self.tmpdir,
225 path=os.path.join(self.tmpdir, 'test.local.conf'))
226 with self.assertRaises(Exception):
Luigi Toscano70d043d2019-03-12 22:25:44 +0100227 lc = self._init_localconf(p)
James E. Blair6f27fca2017-11-21 17:05:43 -0800228 lc.write(p['path'])
229
Luigi Toscano70d043d2019-03-12 22:25:44 +0100230 def _find_tempest_plugins_value(self, file_path):
231 tp = None
232 with open(file_path) as f:
233 for line in f:
234 if line.startswith('TEMPEST_PLUGINS'):
235 found = line.strip().split('=')[1]
236 self.assertIsNone(tp,
237 "TEMPEST_PLUGIN ({}) found again ({})".format(
238 tp, found))
239 tp = found
240 return tp
241
242 def test_tempest_plugins(self):
243 "Test that TEMPEST_PLUGINS is correctly populated."
244 p = dict(base_services=[],
245 base_dir='./test',
246 path=os.path.join(self.tmpdir, 'test.local.conf'),
247 tempest_plugins=['heat-tempest-plugin', 'sahara-tests'])
248 lc = self._init_localconf(p)
249 lc.write(p['path'])
250
251 tp = self._find_tempest_plugins_value(p['path'])
252 self.assertEqual('"./test/heat-tempest-plugin ./test/sahara-tests"', tp)
253 self.assertEqual(len(lc.warnings), 0)
254
255 def test_tempest_plugins_not_overridden(self):
256 """Test that the existing value of TEMPEST_PLUGINS is not overridden
257 by the user-provided value, but a warning is emitted."""
258 localrc = {'TEMPEST_PLUGINS': 'someplugin'}
259 p = dict(localrc=localrc,
260 base_services=[],
261 base_dir='./test',
262 path=os.path.join(self.tmpdir, 'test.local.conf'),
263 tempest_plugins=['heat-tempest-plugin', 'sahara-tests'])
264 lc = self._init_localconf(p)
265 lc.write(p['path'])
266
267 tp = self._find_tempest_plugins_value(p['path'])
268 self.assertEqual('someplugin', tp)
269 self.assertEqual(len(lc.warnings), 1)
270
James E. Blair6f27fca2017-11-21 17:05:43 -0800271
272if __name__ == '__main__':
273 unittest.main()