blob: a3a89ded4ef0cd253444f90286b4484322a7761f [file] [log] [blame]
Matteo Scandolod2044a42017-08-07 16:08:28 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
Matteo Scandolo56879722017-05-17 21:39:54 -070017import unittest
18from mock import patch
19import os
20from xosconfig import Config
21from xosconfig import Config as Config2
22
23basic_conf = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/confs/basic_conf.yaml")
24yaml_not_valid = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/confs/yaml_not_valid.yaml")
25invalid_format = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/confs/invalid_format.yaml")
26sample_conf = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/confs/sample_conf.yaml")
27
Matteo Scandolo1879ce72017-05-30 15:45:26 -070028small_schema = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/schemas/small_schema.yaml")
29
Matteo Scandolo56879722017-05-17 21:39:54 -070030services_list = {
31 "xos-ws": [],
32 "xos-db": [],
33}
34
35db_service = [
36 {
37 "ModifyIndex": 6,
38 "CreateIndex": 6,
39 "Node": "0152982c3159",
40 "Address": "172.19.0.2",
41 "ServiceID": "0d53ce210785:frontend_xos_db_1:5432",
42 "ServiceName": "xos-db",
43 "ServiceTags": [],
44 "ServiceAddress": "172.18.0.4",
45 "ServicePort": 5432,
46 "ServiceEnableTagOverride": "false"
47 }
48 ]
49
50class XOSConfigTest(unittest.TestCase):
51 """
52 Testing the XOS Config Module
53 """
54
55 def tearDown(self):
56 # NOTE clear the config after each test
57 Config.clear()
58
59 def test_initialize_only_once(self):
60 """
61 [XOS-Config] Raise if initialized twice
62 """
63 with self.assertRaises(Exception) as e:
64 Config.init(sample_conf)
65 Config2.init(sample_conf)
66 self.assertEqual(e.exception.message, "[XOS-Config] Module already initialized")
67
68 def test_config_not_initialized(self):
69 """
70 [XOS-Config] Raise if accessing properties without initialization
71 """
72 with self.assertRaises(Exception) as e:
73 Config.get("database")
74 self.assertEqual(e.exception.message, "[XOS-Config] Module has not been initialized")
75
76 def test_missing_file_exception(self):
77 """
78 [XOS-Config] Raise if file not found
79 """
80 with self.assertRaises(Exception) as e:
81 Config.init("missing_conf")
82 self.assertEqual(e.exception.message, "[XOS-Config] Config file not found at: missing_conf")
83
84 def test_yaml_not_valid(self):
85 """
86 [XOS-Config] Raise if yaml is not valid
87 """
88 with self.assertRaises(Exception) as e:
89 Config.init(yaml_not_valid)
90 self.assertEqual(e.exception.message, "[XOS-Config] The config format is wrong: Unable to load any data from source yaml file")
91
92 def test_invalid_format(self):
93 """
94 [XOS-Config] Raise if format is not valid (we expect a dictionary)
95 """
96 with self.assertRaises(Exception) as e:
97 Config.init(invalid_format)
98 self.assertEqual(e.exception.message, "[XOS-Config] The config format is wrong: Schema validation failed:\n - Value '['I am', 'a yaml', 'but the', 'format is not', 'correct']' is not a dict. Value path: ''.")
99
100 def test_env_override(self):
101 """
Matteo Scandolo1879ce72017-05-30 15:45:26 -0700102 [XOS-Config] the XOS_CONFIG_FILE environment variable should override the config_file
Matteo Scandolo56879722017-05-17 21:39:54 -0700103 """
Matteo Scandolo1879ce72017-05-30 15:45:26 -0700104 os.environ["XOS_CONFIG_FILE"] = "env.yaml"
Matteo Scandolo56879722017-05-17 21:39:54 -0700105 with self.assertRaises(Exception) as e:
106 Config.init("missing_conf")
107 self.assertEqual(e.exception.message, "[XOS-Config] Config file not found at: env.yaml")
Matteo Scandolo1879ce72017-05-30 15:45:26 -0700108 del os.environ["XOS_CONFIG_FILE"]
109
110 def test_schema_override(self):
111 """
112 [XOS-Config] the XOS_CONFIG_SCHEMA environment variable should override the config_schema
113 """
114 os.environ["XOS_CONFIG_SCHEMA"] = "env-schema.yaml"
115 with self.assertRaises(Exception) as e:
116 Config.init(basic_conf)
117 self.assertRegexpMatches(e.exception.message, '\[XOS\-Config\] Config schema not found at: (.+)env-schema\.yaml')
118 # self.assertEqual(e.exception.message, "[XOS-Config] Config schema not found at: env-schema.yaml")
119 del os.environ["XOS_CONFIG_SCHEMA"]
120
121 def test_schema_override_usage(self):
122 """
123 [XOS-Config] the XOS_CONFIG_SCHEMA should be used to validate a config
124 """
125 os.environ["XOS_CONFIG_SCHEMA"] = small_schema
126 with self.assertRaises(Exception) as e:
127 Config.init(basic_conf)
128 self.assertEqual(e.exception.message, "[XOS-Config] The config format is wrong: Schema validation failed:\n - Key 'database' was not defined. Path: ''.")
129 del os.environ["XOS_CONFIG_SCHEMA"]
Matteo Scandolo56879722017-05-17 21:39:54 -0700130
131 def test_get_cli_param(self):
132 """
133 [XOS-Config] Should read CLI -C param
134 """
135 args = ["-A", "Foo", "-c", "Bar", "-C", "config.yaml"]
136 res = Config.get_cli_param(args)
137 self.assertEqual(res, "config.yaml")
138
139 def test_get_default_val_for_missing_param(self):
140 """
Matteo Scandolo1879ce72017-05-30 15:45:26 -0700141 [XOS-Config] Should get the default value if nothing is specified
Matteo Scandolo56879722017-05-17 21:39:54 -0700142 """
143 Config.init(basic_conf)
144 log = Config.get("logging")
145 self.assertEqual(log, {
146 "level": "info",
Matteo Scandolo1879ce72017-05-30 15:45:26 -0700147 "channels": ["file", "console"],
148 "logstash_hostport": "cordloghost:5617",
149 "file": "/var/log/xos.log",
Matteo Scandolo56879722017-05-17 21:39:54 -0700150 })
151
Matteo Scandoloe0fc6852017-06-07 16:01:54 -0700152 def test_get_config_file(self):
153 """
154 [XOS-Config] Should return the config file in use
155 """
156 Config.init(sample_conf)
157 res = Config.get_config_file()
158 self.assertEqual(res, sample_conf)
159
160 def test_get_missing_param(self):
Matteo Scandolo56879722017-05-17 21:39:54 -0700161 """
162 [XOS-Config] Should raise reading a missing param
163 """
164 Config.init(sample_conf)
Matteo Scandolo1879ce72017-05-30 15:45:26 -0700165 res = Config.get("foo")
166 self.assertEqual(res, None)
Matteo Scandolo56879722017-05-17 21:39:54 -0700167
168 def test_get_first_level(self):
169 """
170 [XOS-Config] Should return a first level param
171 """
172 Config.init(sample_conf)
173 # NOTE we are using Config2 here to be sure that the configuration is readable from any import,
174 # not only from the one that has been used to initialize it
175 res = Config2.get("database")
176 self.assertEqual(res, {
Matteo Scandolo6bc017c2017-05-25 18:37:42 -0700177 "name": "xos",
Matteo Scandolo56879722017-05-17 21:39:54 -0700178 "username": "test",
179 "password": "safe"
180 })
181
182 def _test_get_child_level(self):
183 """
184 [XOS-Config] Should return a child level param
185 """
186 Config.init(sample_conf)
187 res = Config.get("nested.parameter.for")
188 self.assertEqual(res, "testing")
189
190 def test_get_service_list(self):
191 """
192 [XOS-Config] Should query registrator and return a list of services
193 """
194 with patch("xosconfig.config.requests.get") as mock_get:
195 mock_get.return_value.json.return_value = services_list
196 res = Config.get_service_list()
197 self.assertEqual(res, [
198 "xos-ws",
199 "xos-db",
200 ])
201
202 def test_get_service_info(self):
203 """
204 [XOS-Config] Should query registrator and return service info
205 """
206 with patch("xosconfig.config.requests.get") as mock_get:
207 mock_get.return_value.json.return_value = db_service
208 info = Config.get_service_info("xos-db")
209 self.assertEqual(info, {
210 "name": "xos-db",
211 "url": "172.18.0.4",
212 "port": 5432
213 })
214
215 def test_fail_get_service_info(self):
216 """
217 [XOS-Config] Should query registrator and return an exception if it"s down
218 """
219 with patch("xosconfig.config.requests.get") as mock_get:
220 mock_get.return_value.ok = False
221 with self.assertRaises(Exception) as e:
222 Config.get_service_info("missing-service")
223 self.assertEqual(e.exception.message, "[XOS-Config] Registrator is down")
224
225 def test_missing_get_service_info(self):
226 """
227 [XOS-Config] Should query registrator and return an exception if service is not there
228 """
229 with patch("xosconfig.config.requests.get") as mock_get:
230 mock_get.return_value.json.return_value = []
231 with self.assertRaises(Exception) as e:
232 Config.get_service_info("missing-service")
233 self.assertEqual(e.exception.message, "[XOS-Config] The service missing-service looking for does not exist")
234
235
236 def test_get_service_endpoint(self):
237 """
238 [XOS-Config] Should query registrator and return service endpoint
239 """
240 with patch("xosconfig.config.requests.get") as mock_get:
241 mock_get.return_value.json.return_value = db_service
242 endpoint = Config.get_service_endpoint("xos-db")
Matteo Scandolo1879ce72017-05-30 15:45:26 -0700243 self.assertEqual(endpoint, "http://172.18.0.4:5432")
244
245
246if __name__ == '__main__':
247 unittest.main()