blob: 36817afab499b4ad92a209837e18867c960618c5 [file] [log] [blame]
Tommy Carpenter81b9ed72017-08-23 11:21:44 -04001# org.onap.dcae
2# ================================================================================
3# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
4# ================================================================================
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16# ============LICENSE_END=========================================================
17#
18# ECOMP is a trademark and service mark of AT&T Intellectual Property.
19
Michael Hwange11be5d2017-09-21 12:19:32 -040020import six, json, logging
Tommy Carpenter81b9ed72017-08-23 11:21:44 -040021# http://stackoverflow.com/questions/9623114/check-if-two-unordered-lists-are-equal
22from collections import Counter
23from functools import partial
24import pytest
25import requests
26from discovery_client import discovery as dis
27
28
29def test_get_connection_types():
30 config = { "x": "say something", "y": 123, "z": "{{some-analytics}}" }
31 expected = [(("z", ), "some-analytics"), ]
32 actual = dis._get_connection_types(config)
33 assert Counter(expected) == Counter(actual)
34
35 # Whitespaces ok
36 config = { "x": "say something", "y": 123, "z": "{{ some-analytics }}" }
37 expected = [(("z", ), "some-analytics"), ]
38 actual = dis._get_connection_types(config)
39 assert Counter(expected) == Counter(actual)
40
41 # Paul wanted the ability to include version so match on more than just one
42 # subfield
43 config = { "x": "say something", "y": 123, "z": "{{1-0-0.some-analytics}}" }
44 expected = [(("z", ), "1-0-0.some-analytics"), ]
45 actual = dis._get_connection_types(config)
46 assert Counter(expected) == Counter(actual)
47
48 # Need double parantheses
49 config = { "x": "say something", "y": 123, "z": "{some-analytics}" }
50 actual = dis._get_connection_types(config)
51 assert Counter([]) == Counter(actual)
52
53 # Nested in dict dict
54 config = { "x": "say something", "y": 123,
55 "z": { "aa": { "bbb": "{{some-analytics}}" } } }
56 expected = [(("z", "aa", "bbb"), "some-analytics"), ]
57 actual = dis._get_connection_types(config)
58 assert Counter(expected) == Counter(actual)
59
60 # Nested in list dict
61 config = { "x": "say something", "y": 123,
62 "z": [ "no-op", { "bbb": "{{some-analytics}}" } ] }
63 expected = [(("z", 1, "bbb"), "some-analytics"), ]
64 actual = dis._get_connection_types(config)
65 assert Counter(expected) == Counter(actual)
66
67 # Force strings to be unicode, test for Python2 compatibility
Michael Hwange11be5d2017-09-21 12:19:32 -040068 config = { "x": six.u("say something"), "y": 123,
69 "z": six.u("{{some-analytics}}") }
Tommy Carpenter81b9ed72017-08-23 11:21:44 -040070 expected = [(("z", ), "some-analytics"), ]
71 actual = dis._get_connection_types(config)
72 assert Counter(expected) == Counter(actual)
73
74
75def test_resolve_connection_types():
76 upstream = "b243b0b8-8a24-4f88-add7-9b530c578149.laika.foobar.rework-central.dcae.ecomp.com"
77 downstream = "839b0b31-f13d-4bfc-9adf-450d34071304.laika.foobar.rework-central.dcae.ecomp.com"
78
79 connection_types = [("downstream-laika", "laika"),]
80 relationships = [downstream]
81 expected = [("downstream-laika", [downstream])]
82 actual = dis._resolve_connection_types(upstream, connection_types, relationships)
83 assert sorted(actual) == sorted(expected)
84
85 # NOTE: Removed test that tested the scenario where the name stems don't
86 # match up. This name stem matching was causing grief to others so lifted the
87 # constraint.
88
89
90def test_resolve_name_for_platform():
91 def fake_lookup(fixture, service_name):
92 if service_name == fixture["ServiceName"]:
93 return [fixture]
94
95 # Good case. Grabbed from Consul call
96 fixture = { 'Node': 'agent-one', 'ModifyIndex': 2892, 'Address': '127.0.0.1',
97 'ServiceName': 'e9526e08-f9b8-42c4-99a3-443cd4deeac1.platform-laika.foobar.rework-central.dcae.ecomp.com',
98 'ServicePort': 12708, 'CreateIndex': 2825, 'ServiceAddress': '196.207.143.67',
99 'ServiceTags': [], 'ServiceEnableTagOverride': False,
100 'ServiceID': 'e9526e08-f9b8-42c4-99a3-443cd4deeac1.platform-laika.foobar.rework-central.dcae.ecomp.com'}
101
102 expected = ["{0}:{1}".format(fixture["ServiceAddress"],
103 fixture["ServicePort"])]
104 assert dis._resolve_name(partial(fake_lookup, fixture), fixture["ServiceName"]) == expected
105
106 # Fail case. When Registrator is misconfigured and ServiceAddress is not set
107 fixture = { 'Node': 'agent-one', 'ModifyIndex': 2892, 'Address': '127.0.0.1',
108 'ServiceName': 'e9526e08-f9b8-42c4-99a3-443cd4deeac1.platform-laika.foobar.rework-central.dcae.ecomp.com',
109 'ServicePort': 12708, 'CreateIndex': 2825, 'ServiceAddress': '',
110 'ServiceTags': [], 'ServiceEnableTagOverride': False,
111 'ServiceID': 'e9526e08-f9b8-42c4-99a3-443cd4deeac1.platform-laika.foobar.rework-central.dcae.ecomp.com'}
112
113 with pytest.raises(dis.DiscoveryResolvingNameError):
114 dis._resolve_name(partial(fake_lookup, fixture), fixture["ServiceName"])
115
116 # Fail case. When lookup just blows up for some reason
117 def fake_lookup_blows(service_name):
118 raise RuntimeError("Thar she blows")
119
120 with pytest.raises(dis.DiscoveryResolvingNameError):
121 dis._resolve_name(fake_lookup_blows, fixture["ServiceName"])
122
123
124def test_resolve_name_for_docker():
125 def fake_lookup(fixture, service_name):
126 if service_name == fixture["ServiceName"]:
127 return [fixture]
128
129 # Good case. Grabbed from Consul call
130 fixture = { 'Node': 'agent-one', 'ModifyIndex': 2892, 'Address': '127.0.0.1',
131 'ServiceName': 'e9526e08-f9b8-42c4-99a3-443cd4deeac1.laika.foobar.rework-central.dcae.ecomp.com',
132 'ServicePort': 12708, 'CreateIndex': 2825, 'ServiceAddress': '196.207.143.67',
133 'ServiceTags': [], 'ServiceEnableTagOverride': False,
134 'ServiceID': 'e9526e08-f9b8-42c4-99a3-443cd4deeac1.laika.foobar.rework-central.dcae.ecomp.com'}
135
136 expected = ["{0}:{1}".format(fixture["ServiceAddress"],
137 fixture["ServicePort"])]
138 assert dis._resolve_name(partial(fake_lookup, fixture), fixture["ServiceName"]) == expected
139
140 # Fail case. When Registrator is misconfigured and ServiceAddress is not set
141 fixture = { 'Node': 'agent-one', 'ModifyIndex': 2892, 'Address': '127.0.0.1',
142 'ServiceName': 'e9526e08-f9b8-42c4-99a3-443cd4deeac1.laika.foobar.rework-central.dcae.ecomp.com',
143 'ServicePort': 12708, 'CreateIndex': 2825, 'ServiceAddress': '',
144 'ServiceTags': [], 'ServiceEnableTagOverride': False,
145 'ServiceID': 'e9526e08-f9b8-42c4-99a3-443cd4deeac1.laika.foobar.rework-central.dcae.ecomp.com'}
146
147 with pytest.raises(dis.DiscoveryResolvingNameError):
148 dis._resolve_name(partial(fake_lookup, fixture), fixture["ServiceName"])
149
150 # Fail case. When lookup just blows up for some reason
151 def fake_lookup_blows(service_name):
152 raise RuntimeError("Thar she blows")
153
154 with pytest.raises(dis.DiscoveryResolvingNameError):
155 dis._resolve_name(fake_lookup_blows, fixture["ServiceName"])
156
157
158def test_resolve_name_for_cdap(monkeypatch):
159 def fake_lookup(fixture, service_name):
160 if service_name == fixture["ServiceName"]:
161 return [fixture]
162
163 # Good case. Handle CDAP apps
164 fixture = {
165 "Node":"agent-one", "Address":"10.170.2.17",
166 "ServiceID": "00b6210b71e445cdaadf76e620ebffcfhelloworldcdapappfoobardcaereworkdcaeecompcom",
167 "ServiceName": "00b6210b71e445cdaadf76e620ebffcfhelloworldcdapappfoobardcaereworkdcaeecompcom",
168 "ServiceTags":[],
169 "ServiceAddress": "196.207.143.116",
170 "ServicePort": 7777, "ServiceEnableTagOverride": False, "CreateIndex": 144733, "ModifyIndex":145169 }
171
172 class FakeRequestsResponse(object):
173 def __init__(self, url, broker_json):
174 self.url = url
175 self.broker_json = broker_json
176
177 def raise_for_status(self):
178 expected_broker_url = "http://{0}:{1}/application/{2}".format(
179 fixture["ServiceAddress"], fixture["ServicePort"],
180 fixture["ServiceName"])
181 if self.url == expected_broker_url:
182 return True
183 else:
184 raise RuntimeError("Mismatching address")
185
186 def json(self):
187 return self.broker_json
188
189 # Simulate the call to the CDAP broker
190 broker_json = {
191 "appname":"00b6210b71e445cdaadf76e620ebffcfhelloworldcdapappfoobardcaereworkdcaeecompcom",
192 "healthcheckurl":"http://196.207.143.116:7777/application/00b6210b71e445cdaadf76e620ebffcfhelloworldcdapappfoobardcaereworkdcaeecompcom/healthcheck",
193 "metricsurl":"http://196.207.143.116:7777/application/00b6210b71e445cdaadf76e620ebffcfhelloworldcdapappfoobardcaereworkdcaeecompcom/metrics",
194 "url":"http://196.207.143.116:7777/application/00b6210b71e445cdaadf76e620ebffcfhelloworldcdapappfoobardcaereworkdcaeecompcom",
195 "connectionurl":"http://196.207.160.159:10000/v3/namespaces/default/streams/foo",
196 "serviceendpoints": "something" }
197
198 monkeypatch.setattr(requests, "get", lambda url: FakeRequestsResponse(url, broker_json))
199
200 expected = [{ key: broker_json[key]
201 for key in ["connectionurl", "serviceendpoints"] }]
202 assert dis._resolve_name(partial(fake_lookup, fixture), fixture["ServiceName"]) == expected
203
204
205def test_resolve_configuration_dict(monkeypatch):
206 service_name = "123.current-node-type.some-service.some-location.com"
207 target_service_name = "456.target-node-type.some-service.some-location.com"
208
209 # Fake the Consul calls
210
211 def fake_get_relationship(ch, service_name):
212 return [ target_service_name ]
213
214 monkeypatch.setattr(dis, "_get_relationships_from_consul",
215 fake_get_relationship)
216
217 fixture = [{ 'Node': 'agent-one', 'ModifyIndex': 2892, 'Address': '127.0.0.1',
218 'ServiceName': target_service_name,
219 'ServicePort': 12708, 'CreateIndex': 2825, 'ServiceAddress': '196.207.143.67',
220 'ServiceTags': [], 'ServiceEnableTagOverride': False,
221 'ServiceID': target_service_name }]
222
223 def fake_lookup(ch, service_name):
224 return fixture
225
226 monkeypatch.setattr(dis, "_lookup_with_consul", fake_lookup)
227
228 # Simple config case
229 test_config = { "target-node": "{{ target-node-type }}", "other-param": 123 }
230
231 expected = dict(test_config)
232 expected["target-node"] = ["196.207.143.67:12708"]
233 actual = dis._resolve_configuration_dict(None, service_name, test_config)
234 assert Counter(actual) == Counter(expected)
235
236 # Nested config case
237 test_config = { "output_formats": { "target-node": "{{ target-node-type }}" },
238 "other-param": 123 }
239
240 expected = dict(test_config)
241 expected["output_formats"]["target-node"] = "196.207.143.67:12708"
242 actual = dis._resolve_configuration_dict(None, service_name, test_config)
243 assert Counter(actual) == Counter(expected)
244
245
246def test_get_consul_host(monkeypatch):
247 with pytest.raises(dis.DiscoveryInitError):
248 dis.get_consul_hostname()
249
250 monkeypatch.setenv("CONSUL_HOST", "i-am-consul-host")
251 assert "i-am-consul-host" == dis.get_consul_hostname()
252
253 assert "no-i-am" == dis.get_consul_hostname("no-i-am")