Add multi-cluster support
[dcaegen2/platform/plugins.git] / k8s / tests / test_tasks.py
1 # ============LICENSE_START=======================================================
2 # org.onap.dcae
3 # ================================================================================
4 # Copyright (c) 2017-2019 AT&T Intellectual Property. All rights reserved.
5 # ================================================================================
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 #      http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 # ============LICENSE_END=========================================================
18 #
19 # ECOMP is a trademark and service mark of AT&T Intellectual Property.
20
21 import copy
22 import pytest
23 from cloudify.exceptions import NonRecoverableError, RecoverableError
24
25
26 def test_generate_component_name(mockconfig):
27     from k8splugin import tasks
28     kwargs = { "service_component_type": "doodle",
29             "service_component_name_override": None }
30
31     assert "doodle" in tasks._generate_component_name(**kwargs)["name"]
32
33     kwargs["service_component_name_override"] = "yankee"
34
35     assert "yankee" == tasks._generate_component_name(**kwargs)["name"]
36
37
38 def test_parse_streams(monkeypatch, mockconfig):
39     import k8splugin
40     from k8splugin import tasks
41     # Good case for streams_publishes
42     test_input = { "streams_publishes": [{"name": "topic00", "type": "message_router"},
43             {"name": "feed00", "type": "data_router"}],
44             "streams_subscribes": {} }
45
46     expected = {'feed00': {'type': 'data_router', 'name': 'feed00'},
47             'streams_publishes': [{'type': 'message_router', 'name': 'topic00'},
48                 {'type': 'data_router', 'name': 'feed00'}],
49             'streams_subscribes': {},
50             'topic00': {'type': 'message_router', 'name': 'topic00'}
51             }
52
53     assert expected == tasks._parse_streams(**test_input)
54
55     # Good case for streams_subscribes (password provided)
56     test_input = { "streams_publishes": {},
57             "streams_subscribes": [{"name": "topic01", "type": "message_router"},
58                 {"name": "feed01", "type": "data_router", "username": "hero",
59                     "password": "123456"}] }
60
61     expected = {'feed01': {'type': 'data_router', 'name': 'feed01',
62                     'username': 'hero', 'password': '123456'},
63             'streams_publishes': {},
64             'streams_subscribes': [{'type': 'message_router', 'name': 'topic01'},
65                 {'type': 'data_router', 'name': 'feed01', 'username': 'hero',
66                     'password': '123456'}],
67             'topic01': {'type': 'message_router', 'name': 'topic01'}}
68
69     assert expected == tasks._parse_streams(**test_input)
70
71     # Good case for streams_subscribes (password generated)
72     test_input = { "streams_publishes": {},
73             "streams_subscribes": [{"name": "topic01", "type": "message_router"},
74                 {"name": "feed01", "type": "data_router", "username": None,
75                     "password": None}] }
76
77     def not_so_random(n):
78         return "nosurprise"
79
80     monkeypatch.setattr(k8splugin.utils, "random_string", not_so_random)
81
82     expected = {'feed01': {'type': 'data_router', 'name': 'feed01',
83                     'username': 'nosurprise', 'password': 'nosurprise'},
84             'streams_publishes': {},
85             'streams_subscribes': [{'type': 'message_router', 'name': 'topic01'},
86                 {'type': 'data_router', 'name': 'feed01', 'username': None,
87                     'password': None}],
88             'topic01': {'type': 'message_router', 'name': 'topic01'}}
89
90     assert expected == tasks._parse_streams(**test_input)
91
92
93 def test_setup_for_discovery(monkeypatch, mockconfig):
94     import k8splugin
95     from k8splugin import tasks
96
97     test_input = { "name": "some-name",
98             "application_config": { "one": "a", "two": "b" } }
99
100     def fake_push_config(conn, name, application_config):
101         return
102
103     monkeypatch.setattr(k8splugin.discovery, "push_service_component_config",
104             fake_push_config)
105
106     assert test_input == tasks._setup_for_discovery(**test_input)
107
108     def fake_push_config_connection_error(conn, name, application_config):
109         raise k8splugin.discovery.DiscoveryConnectionError("Boom")
110
111     monkeypatch.setattr(k8splugin.discovery, "push_service_component_config",
112             fake_push_config_connection_error)
113
114     with pytest.raises(RecoverableError):
115         tasks._setup_for_discovery(**test_input)
116
117
118 def test_setup_for_discovery_streams(monkeypatch, mockconfig):
119     import k8splugin
120     from k8splugin import tasks
121     test_input = {'feed01': {'type': 'data_router', 'name': 'feed01',
122                 'username': 'hero', 'password': '123456', 'location': 'Bedminster'},
123             'streams_publishes': {},
124             'streams_subscribes': [{'type': 'message_router', 'name': 'topic01'},
125                 {'type': 'data_router', 'name': 'feed01', 'username': 'hero',
126                     'password': '123456', 'location': 'Bedminster'}],
127             'topic01': {'type': 'message_router', 'name': 'topic01'}}
128     test_input["name"] = "some-foo-service-component"
129
130     # Good case
131     def fake_add_to_entry(conn, key, add_name, add_value):
132         """
133         This fake method will check all the pieces that are used to make store
134         details in Consul
135         """
136         if key != test_input["name"] + ":dmaap":
137             return None
138         if add_name != "feed01":
139             return None
140         if add_value != {"location": "Bedminster", "delivery_url": None,
141                 "username": "hero", "password": "123456", "subscriber_id": None}:
142             return None
143
144         return "SUCCESS!"
145
146     monkeypatch.setattr(k8splugin.discovery, "add_to_entry",
147             fake_add_to_entry)
148
149     assert tasks._setup_for_discovery_streams(**test_input) == test_input
150
151     # Good case - no data router subscribers
152     test_input = {"streams_publishes": [{"name": "topic00", "type": "message_router"}],
153             'streams_subscribes': [{'type': 'message_router', 'name': 'topic01'}]}
154     test_input["name"] = "some-foo-service-component"
155
156     assert tasks._setup_for_discovery_streams(**test_input) == test_input
157
158     # Bad case - something happened from the Consul call
159     test_input = {'feed01': {'type': 'data_router', 'name': 'feed01',
160                 'username': 'hero', 'password': '123456', 'location': 'Bedminster'},
161             'streams_publishes': {},
162             'streams_subscribes': [{'type': 'message_router', 'name': 'topic01'},
163                 {'type': 'data_router', 'name': 'feed01', 'username': 'hero',
164                     'password': '123456', 'location': 'Bedminster'}],
165             'topic01': {'type': 'message_router', 'name': 'topic01'}}
166     test_input["name"] = "some-foo-service-component"
167
168     def barf(conn, key, add_name, add_value):
169         raise RuntimeError("Barf")
170
171     monkeypatch.setattr(k8splugin.discovery, "add_to_entry",
172             barf)
173
174     with pytest.raises(NonRecoverableError):
175         tasks._setup_for_discovery_streams(**test_input)
176
177
178 def test_lookup_service(monkeypatch, mockconfig):
179     import k8splugin
180     from k8splugin import tasks
181     def fake_lookup(conn, scn):
182         return [{"ServiceAddress": "192.168.1.1", "ServicePort": "80"}]
183
184     monkeypatch.setattr(k8splugin.discovery, "lookup_service",
185             fake_lookup)
186
187     assert "192.168.1.1" == tasks._lookup_service("some-component")
188     assert "192.168.1.1:80" == tasks._lookup_service("some-component",
189             with_port=True)
190
191
192 def test_verify_container(monkeypatch, mockconfig):
193     import k8sclient
194     from k8splugin import tasks
195     from k8splugin.exceptions import DockerPluginDeploymentError
196
197     def fake_is_available_success(loc, ch, scn):
198         return True
199
200     monkeypatch.setattr(k8sclient, "is_available",
201             fake_is_available_success)
202
203     assert tasks._verify_k8s_deployment("some-location","some-name", 3)
204
205     def fake_is_available_never_good(loc, ch, scn):
206         return False
207
208     monkeypatch.setattr(k8sclient, "is_available",
209             fake_is_available_never_good)
210
211     assert not tasks._verify_k8s_deployment("some-location", "some-name", 2)
212
213
214 def test_update_delivery_url(monkeypatch, mockconfig):
215     import k8splugin
216     from k8splugin import tasks
217     test_input = {'feed01': {'type': 'data_router', 'name': 'feed01',
218                 'username': 'hero', 'password': '123456', 'location': 'Bedminster',
219                 'route': 'some-path'},
220             'streams_publishes': {},
221             'streams_subscribes': [{'type': 'message_router', 'name': 'topic01'},
222                 {'type': 'data_router', 'name': 'feed01', 'username': 'hero',
223                     'password': '123456', 'location': 'Bedminster',
224                     'route': 'some-path'}],
225             'topic01': {'type': 'message_router', 'name': 'topic01'}}
226     test_input["service_component_name"] = "some-foo-service-component"
227
228     def fake_lookup_service(name, with_port=False):
229         if with_port:
230             return "10.100.1.100:8080"
231         else:
232             return
233
234     monkeypatch.setattr(k8splugin.tasks, "_lookup_service",
235             fake_lookup_service)
236
237     expected = copy.deepcopy(test_input)
238     expected["feed01"]["delivery_url"] = "http://10.100.1.100:8080/some-path"
239
240     assert tasks._update_delivery_url(**test_input) == expected
241
242
243 def test_enhance_docker_params(mockconfig):
244     from k8splugin import tasks
245     # Good - Test empty docker config
246
247     test_kwargs = { "docker_config": {}, "service_id": None }
248     actual = tasks._enhance_docker_params(**test_kwargs)
249
250     assert actual == {'envs': {"SERVICE_TAGS": ""}, 'docker_config': {}, 'ports': [], 'volumes': [], "service_id": None }
251
252     # Good - Test just docker config ports and volumes
253
254     test_kwargs = { "docker_config": { "ports": ["1:1", "2:2"],
255         "volumes": [{"container": "somewhere", "host": "somewhere else"}] },
256         "service_id": None }
257     actual = tasks._enhance_docker_params(**test_kwargs)
258
259     assert actual == {'envs': {"SERVICE_TAGS": ""}, 'docker_config': {'ports': ['1:1', '2:2'],
260         'volumes': [{'host': 'somewhere else', 'container': 'somewhere'}]},
261         'ports': ['1:1', '2:2'], 'volumes': [{'host': 'somewhere else',
262             'container': 'somewhere'}], "service_id": None}
263
264     # Good - Test just docker config ports and volumes with overrrides
265
266     test_kwargs = { "docker_config": { "ports": ["1:1", "2:2"],
267         "volumes": [{"container": "somewhere", "host": "somewhere else"}] },
268         "ports": ["3:3", "4:4"], "volumes": [{"container": "nowhere", "host":
269         "nowhere else"}],
270         "service_id": None }
271     actual = tasks._enhance_docker_params(**test_kwargs)
272
273     assert actual == {'envs': {"SERVICE_TAGS": ""}, 'docker_config': {'ports': ['1:1', '2:2'],
274         'volumes': [{'host': 'somewhere else', 'container': 'somewhere'}]},
275         'ports': ['1:1', '2:2', '3:3', '4:4'], 'volumes': [{'host': 'somewhere else',
276             'container': 'somewhere'}, {'host': 'nowhere else', 'container':
277             'nowhere'}], "service_id": None}
278
279     # Good
280
281     test_kwargs = { "docker_config": {}, "service_id": "zed",
282             "deployment_id": "abc" }
283     actual = tasks._enhance_docker_params(**test_kwargs)
284
285     assert actual["envs"] == {"SERVICE_TAGS": "abc,zed"}
286
287
288 def test_notify_container(mockconfig):
289     from k8splugin import tasks
290
291     test_input = { "docker_config": { "policy": { "trigger_type": "unknown" } } }
292     assert [] == tasks._notify_container(**test_input)