1 # ==================================================================================
2 # Copyright (c) 2019 Nokia
3 # Copyright (c) 2018-2019 AT&T Intellectual Property.
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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 # ==================================================================================
19 from rmr.rmr_mocks import rmr_mocks
23 ADM_CTRL = "admission_control_policy"
24 ADM_CTRL_POLICIES = "/a1-p/policytypes/20000/policies"
25 ADM_CTRL_INSTANCE = ADM_CTRL_POLICIES + "/" + ADM_CTRL
26 ADM_CTRL_INSTANCE_STATUS = ADM_CTRL_INSTANCE + "/status"
27 ADM_CTRL_TYPE = "/a1-p/policytypes/20000"
28 TEST_TYPE = "/a1-p/policytypes/20001"
31 def _fake_dequeue(_mrc, _filter_type):
32 """for monkeypatching with a good status"""
34 pay = b'{"policy_type_id": 20000, "policy_instance_id": "admission_control_policy", "handler_id": "test_receiver", "status": "OK"}'
35 fake_msg["payload"] = pay
36 new_messages = [fake_msg]
40 def _fake_dequeue_none(_mrc, _filter_type):
41 """for monkeypatching with no waiting messages"""
45 def _fake_dequeue_deleted(_mrc, _filter_type):
46 """for monkeypatching with a DELETED status"""
49 # insert some that don't exist to make sure nothing blows up
50 pay = b'{"policy_type_id": 20666, "policy_instance_id": "admission_control_policy", "handler_id": "test_receiver", "status": "DELETED"}'
51 fake_msg = {"payload": pay}
52 new_msgs.append(fake_msg)
54 pay = b'{"policy_type_id": 20000, "policy_instance_id": "darkness", "handler_id": "test_receiver", "status": "DELETED"}'
55 fake_msg = {"payload": pay}
56 new_msgs.append(fake_msg)
58 pay = b'{"policy_type_id": 20000, "policy_instance_id": "admission_control_policy", "handler_id": "test_receiver", "status": "DELETED"}'
59 fake_msg = {"payload": pay}
60 new_msgs.append(fake_msg)
65 def _test_put_patch(monkeypatch):
66 rmr_mocks.patch_rmr(monkeypatch)
67 # assert that rmr bad states don't cause problems
68 monkeypatch.setattr("rmr.rmr.rmr_send_msg", rmr_mocks.send_mock_generator(10))
70 # we need this because free expects a real sbuf
71 # TODO: move this into rmr_mocks
75 monkeypatch.setattr("rmr.rmr.rmr_free_msg", noop)
77 # we need to repatch alloc (already patched in patch_rmr) to fix the transactionid, alloc is called in send and recieve
78 def fake_alloc(_unused, _alsounused):
79 sbuf = rmr_mocks.Rmr_mbuf_t()
80 sbuf.contents.xaction = b"d49b53e478b711e9a1130242ac110002"
83 # we also need to repatch set, since in the send function, we alloc, then set a new transid
84 def fake_set_transactionid(sbuf):
85 sbuf.contents.xaction = b"d49b53e478b711e9a1130242ac110002"
87 # Note, we could have just patched summary, but this patches at a "lower level" so is a better test
88 monkeypatch.setattr("rmr.rmr.rmr_alloc_msg", fake_alloc)
89 monkeypatch.setattr("rmr.rmr.generate_and_set_transaction_id", fake_set_transactionid)
99 """module level setup"""
101 RMR_THREAD = run.start_rmr_thread(real_init=False)
107 def test_workflow_nothing_there_yet(client, monkeypatch, adm_type_good, adm_instance_good):
108 """ test policy put good"""
109 monkeypatch.setattr("rmr.helpers.rmr_rcvall_msgs", _fake_dequeue_none)
111 res = client.get(ADM_CTRL_TYPE)
112 assert res.status_code == 404
115 res = client.get("/a1-p/policytypes")
116 assert res.status_code == 200
117 assert res.json == []
119 # instance 404 because type not there yet
120 res = client.get(ADM_CTRL_POLICIES)
121 assert res.status_code == 404
124 def test_workflow(client, monkeypatch, adm_type_good, adm_instance_good):
126 test a full A1 workflow
128 monkeypatch.setattr("rmr.helpers.rmr_rcvall_msgs", _fake_dequeue_none)
130 res = client.put(ADM_CTRL_TYPE, json=adm_type_good)
131 assert res.status_code == 201
134 res = client.put(ADM_CTRL_TYPE, json=adm_type_good)
135 assert res.status_code == 400
138 res = client.get(ADM_CTRL_TYPE)
139 assert res.status_code == 200
140 assert res.json == adm_type_good
141 res = client.get("/a1-p/policytypes")
142 assert res.status_code == 200
143 assert res.json == [20000]
145 # instance 200 but empty list
146 res = client.get(ADM_CTRL_POLICIES)
147 assert res.status_code == 200
148 assert res.json == []
150 # no instance there yet
151 res = client.get(ADM_CTRL_INSTANCE)
152 assert res.status_code == 404
153 res = client.get(ADM_CTRL_INSTANCE_STATUS)
154 assert res.status_code == 404
156 # create a good instance
157 _test_put_patch(monkeypatch)
158 res = client.put(ADM_CTRL_INSTANCE, json=adm_instance_good)
159 assert res.status_code == 202
161 # replace is allowed on instances
162 res = client.put(ADM_CTRL_INSTANCE, json=adm_instance_good)
163 assert res.status_code == 202
165 # instance 200 and in list
166 res = client.get(ADM_CTRL_POLICIES)
167 assert res.status_code == 200
168 assert res.json == [ADM_CTRL]
170 def get_instance_good(expected):
172 res = client.get(ADM_CTRL_INSTANCE)
173 assert res.status_code == 200
174 assert res.json == adm_instance_good
176 # get the instance status
177 res = client.get(ADM_CTRL_INSTANCE_STATUS)
178 assert res.status_code == 200
179 assert res.get_data(as_text=True) == expected
181 # try a status get but we didn't get any ACKs yet to test NOT IN EFFECT
182 time.sleep(1) # wait for the rmr thread
183 get_instance_good("NOT IN EFFECT")
185 # now pretend we did get a good ACK
186 monkeypatch.setattr("rmr.helpers.rmr_rcvall_msgs", _fake_dequeue)
187 time.sleep(1) # wait for the rmr thread
188 get_instance_good("IN EFFECT")
190 # cant delete type until there are no instances
191 res = client.delete(ADM_CTRL_TYPE)
192 assert res.status_code == 400
195 res = client.delete(ADM_CTRL_INSTANCE)
196 assert res.status_code == 202
197 res = client.delete(ADM_CTRL_INSTANCE) # should be able to do multiple deletes
198 assert res.status_code == 202
200 # status after a delete, but there are no messages yet, should still return
201 monkeypatch.setattr("rmr.helpers.rmr_rcvall_msgs", _fake_dequeue)
202 time.sleep(1) # wait for the rmr thread
203 get_instance_good("IN EFFECT")
205 # now pretend we deleted successfully
206 monkeypatch.setattr("rmr.helpers.rmr_rcvall_msgs", _fake_dequeue_deleted)
207 time.sleep(1) # wait for the rmr thread
208 res = client.get(ADM_CTRL_INSTANCE_STATUS) # cant get status
209 assert res.status_code == 404
210 res = client.get(ADM_CTRL_INSTANCE) # cant get instance
211 assert res.status_code == 404
213 # list still 200 but no instance
214 res = client.get(ADM_CTRL_POLICIES)
215 assert res.status_code == 200
216 assert res.json == []
219 res = client.delete(ADM_CTRL_TYPE)
220 assert res.status_code == 204
223 res = client.get(ADM_CTRL_TYPE)
224 assert res.status_code == 404
225 res = client.delete(ADM_CTRL_TYPE)
226 assert res.status_code == 404
229 def test_bad_instances(client, monkeypatch, adm_type_good):
231 test various failure modes
233 # put the type (needed for some of the tests below)
234 rmr_mocks.patch_rmr(monkeypatch)
235 res = client.put(ADM_CTRL_TYPE, json=adm_type_good)
236 assert res.status_code == 201
239 res = client.put(ADM_CTRL_INSTANCE, json={"not": "expected"})
240 assert res.status_code == 400
243 res = client.put(ADM_CTRL_INSTANCE, data="notajson")
244 assert res.status_code == 415
246 # delete a non existent instance
247 res = client.delete(ADM_CTRL_INSTANCE + "DARKNESS")
248 assert res.status_code == 404
250 # get a non existent instance
251 monkeypatch.setattr("rmr.helpers.rmr_rcvall_msgs", _fake_dequeue)
253 res = client.get(ADM_CTRL_INSTANCE + "DARKNESS")
254 assert res.status_code == 404
256 # delete the type (as cleanup)
257 res = client.delete(ADM_CTRL_TYPE)
258 assert res.status_code == 204
261 def test_illegal_types(client, monkeypatch, adm_type_good):
265 res = client.put("/a1-p/policytypes/19999", json=adm_type_good)
266 assert res.status_code == 400
267 res = client.put("/a1-p/policytypes/21024", json=adm_type_good)
268 assert res.status_code == 400
271 def test_healthcheck(client):
275 res = client.get("/a1-p/healthcheck")
276 assert res.status_code == 200
279 def teardown_module():
280 """module teardown"""