X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=tests%2Ftest_controller.py;h=2866dd8990e13b62563fb50a346d43c6c3333f01;hb=a0876efd819b43b870ba2254b34676b1a03ad326;hp=bae2ac9c2c9efc145b2826acc0464f0e3ba60220;hpb=2c94a42d6c7ce672af76eb68484d3d69710ac4d4;p=ric-plt%2Fa1.git diff --git a/tests/test_controller.py b/tests/test_controller.py index bae2ac9..2866dd8 100644 --- a/tests/test_controller.py +++ b/tests/test_controller.py @@ -16,13 +16,20 @@ # ================================================================================== import tempfile import os + from rmr.rmr_mocks import rmr_mocks from a1 import app -from a1 import exceptions -from rmr import rmr -import testing_helpers import pytest + +ADM_CTRL = "admission_control_policy" +ADM_CTRL_POLICIES = "/a1-p/policytypes/20000/policies" +ADM_CTRL_INSTANCE = ADM_CTRL_POLICIES + "/" + ADM_CTRL +ADM_CTRL_INSTANCE_STATUS = ADM_CTRL_INSTANCE + "/status" +ADM_CTRL_TYPE = "/a1-p/policytypes/20000" +TEST_TYPE = "/a1-p/policytypes/20001" + + # http://flask.pocoo.org/docs/1.0/testing/ @pytest.fixture def client(): @@ -36,42 +43,46 @@ def client(): os.unlink(app.app.config["DATABASE"]) -def _fake_dequeue( - monkeypatch, - msg_payload={"status": "SUCCESS", "foo": "bar"}, - msg_type=20001, - msg_state=0, - jsonb=True, - unexpected_first=True, -): +def _fake_dequeue(_filter_type): """ - generates a mock rmr message response (returns a function that does; uses closures to set params) + for monkeypatching a1rmnr.dequeue_all_messages with a good status """ - new_messages = [] - # stick a message we don't want at the front of the queue, then stick the message we want - if unexpected_first: - monkeypatch.setattr("rmr.rmr.rmr_torcv_msg", rmr_mocks.rcv_mock_generator(msg_payload, -1, msg_state, jsonb)) - sbuf = rmr.rmr_alloc_msg(None, None) - sbuf = rmr.rmr_torcv_msg(None, sbuf, None) - summary = rmr.message_summary(sbuf) - new_messages.append(summary) + fake_msg = {} + pay = b'{"policy_type_id": 20000, "policy_instance_id": "admission_control_policy", "handler_id": "test_receiver", "status": "OK"}' + fake_msg["payload"] = pay + new_messages = [fake_msg] + return new_messages - monkeypatch.setattr("rmr.rmr.rmr_torcv_msg", rmr_mocks.rcv_mock_generator(msg_payload, msg_type, msg_state, jsonb)) - sbuf = rmr.rmr_alloc_msg(None, None) - sbuf = rmr.rmr_torcv_msg(None, sbuf, None) - summary = rmr.message_summary(sbuf) - new_messages.append(summary) - def f(): - return new_messages +def _fake_dequeue_none(_filter_type): + """ + for monkeypatching a1rmnr.dequeue_all_messages with no waiting messages + """ + return [] - return f + +def _fake_dequeue_deleted(_filter_type): + """ + for monkeypatching a1rmnr.dequeue_all_messages with a DELETED status + """ + fake_msg = {} + pay = b'{"policy_type_id": 20000, "policy_instance_id": "admission_control_policy", "handler_id": "test_receiver", "status": "DELETED"}' + fake_msg["payload"] = pay + new_messages = [fake_msg] + return new_messages def _test_put_patch(monkeypatch): - testing_helpers.patch_all(monkeypatch) + rmr_mocks.patch_rmr(monkeypatch) monkeypatch.setattr("rmr.rmr.rmr_send_msg", rmr_mocks.send_mock_generator(0)) # good sends for this whole batch + # we need this because free expects a real sbuf + # TODO: move this into rmr_mocks + def noop(_sbuf): + pass + + monkeypatch.setattr("rmr.rmr.rmr_free_msg", noop) + # we need to repatch alloc (already patched in patch_rmr) to fix the transactionid, alloc is called in send and recieve def fake_alloc(_unused, _alsounused): sbuf = rmr_mocks.Rmr_mbuf_t() @@ -90,142 +101,135 @@ def _test_put_patch(monkeypatch): # Actual Tests -def test_policy_get(client, monkeypatch): - """ - test policy GET - """ - _test_put_patch(monkeypatch) - monkeypatch.setattr( - "a1.a1rmr._dequeue_all_waiting_messages", - _fake_dequeue(monkeypatch, msg_payload={"GET ack": "pretend policy is here"}, msg_type=20003), - ) - res = client.get("/a1-p/policies/admission_control_policy") +def test_xapp_put_good(client, monkeypatch, adm_type_good, adm_instance_good): + """ test policy put good""" + + # no type there yet + res = client.get(ADM_CTRL_TYPE) + assert res.status_code == 404 + + # no types at all + res = client.get("/a1-p/policytypes") assert res.status_code == 200 - assert res.json == {"GET ack": "pretend policy is here"} + assert res.json == [] + # instance 404 because type not there yet + monkeypatch.setattr("a1.a1rmr.dequeue_all_waiting_messages", _fake_dequeue_none) + res = client.get(ADM_CTRL_POLICIES) + assert res.status_code == 404 -def test_policy_get_unsupported(client, monkeypatch): - """ - test policy GET - """ - testing_helpers.patch_all(monkeypatch, nofetch=True) - res = client.get("/a1-p/policies/admission_control_policy") - assert res.status_code == 400 - assert res.data == b'"POLICY DOES NOT SUPPORT FETCHING"\n' + # put the type + res = client.put(ADM_CTRL_TYPE, json=adm_type_good) + assert res.status_code == 201 + # type there now + res = client.get(ADM_CTRL_TYPE) + assert res.status_code == 200 + assert res.json == adm_type_good + res = client.get("/a1-p/policytypes") + assert res.status_code == 200 + assert res.json == [20000] -def test_xapp_put_good(client, monkeypatch): - """ test policy put good""" - _test_put_patch(monkeypatch) - monkeypatch.setattr("a1.a1rmr._dequeue_all_waiting_messages", _fake_dequeue(monkeypatch)) - res = client.put("/a1-p/policies/admission_control_policy", json=testing_helpers.good_payload()) + # instance 200 but empty list + res = client.get(ADM_CTRL_POLICIES) assert res.status_code == 200 - assert res.json == {"status": "SUCCESS", "foo": "bar"} + assert res.json == [] + # no instance there yet + res = client.get(ADM_CTRL_INSTANCE) + assert res.status_code == 404 + res = client.get(ADM_CTRL_INSTANCE_STATUS) + assert res.status_code == 404 -def test_xapp_put_bad(client, monkeypatch): - """Test policy put fails""" + # create a good instance _test_put_patch(monkeypatch) - # return from policy handler has a status indicating FAIL - monkeypatch.setattr( - "a1.a1rmr._dequeue_all_waiting_messages", _fake_dequeue(monkeypatch, msg_payload={"status": "FAIL", "foo": "bar"}) - ) - res = client.put("/a1-p/policies/admission_control_policy", json=testing_helpers.good_payload()) - assert res.status_code == 502 - assert res.json["reason"] == "BAD STATUS" - assert res.json["return_payload"] == {"status": "FAIL", "foo": "bar"} - - # return from policy handler has no status field - monkeypatch.setattr("a1.a1rmr._dequeue_all_waiting_messages", _fake_dequeue(monkeypatch, msg_payload={"foo": "bar"})) - res = client.put("/a1-p/policies/admission_control_policy", json=testing_helpers.good_payload()) - assert res.status_code == 502 - assert res.json["reason"] == "NO STATUS" - assert res.json["return_payload"] == {"foo": "bar"} - - # return from policy handler not a json - monkeypatch.setattr( - "a1.a1rmr._dequeue_all_waiting_messages", _fake_dequeue(monkeypatch, msg_payload="booger", jsonb=False) - ) - res = client.put("/a1-p/policies/admission_control_policy", json=testing_helpers.good_payload()) - assert res.status_code == 502 - assert res.json["reason"] == "NOT JSON" - assert res.json["return_payload"] == "booger" - - # bad type - monkeypatch.setattr("a1.a1rmr._dequeue_all_waiting_messages", _fake_dequeue(monkeypatch, msg_type=666)) - res = client.put("/a1-p/policies/admission_control_policy", json=testing_helpers.good_payload()) - assert res.status_code == 504 - assert res.data == b"\"A1 was expecting an ACK back but it didn't receive one or didn't recieve the expected ACK\"\n" - - # bad state - monkeypatch.setattr("a1.a1rmr._dequeue_all_waiting_messages", _fake_dequeue(monkeypatch, msg_state=666)) - res = client.put("/a1-p/policies/admission_control_policy", json=testing_helpers.good_payload()) - assert res.status_code == 504 - assert res.data == b"\"A1 was expecting an ACK back but it didn't receive one or didn't recieve the expected ACK\"\n" - - -def test_xapp_put_bad_send(client, monkeypatch): - """ - Test bad send failures - """ - testing_helpers.patch_all(monkeypatch) + res = client.put(ADM_CTRL_INSTANCE, json=adm_instance_good) + assert res.status_code == 202 + + # instance 200 and in list + res = client.get(ADM_CTRL_POLICIES) + assert res.status_code == 200 + assert res.json == [ADM_CTRL] + + def get_instance_good(expected): + # get the instance + res = client.get(ADM_CTRL_INSTANCE) + assert res.status_code == 200 + assert res.json == adm_instance_good + + # get the instance status + res = client.get(ADM_CTRL_INSTANCE_STATUS) + assert res.status_code == 200 + assert res.get_data(as_text=True) == expected + + # try a status get but pretend we didn't get any ACKs yet to test NOT IN EFFECT + monkeypatch.setattr("a1.a1rmr.dequeue_all_waiting_messages", _fake_dequeue_none) + get_instance_good("NOT IN EFFECT") + + # now pretend we did get a good ACK + monkeypatch.setattr("a1.a1rmr.dequeue_all_waiting_messages", _fake_dequeue) + get_instance_good("IN EFFECT") + + # delete it + res = client.delete(ADM_CTRL_INSTANCE) + assert res.status_code == 202 + res = client.delete(ADM_CTRL_INSTANCE) # should be able to do multiple deletes + assert res.status_code == 202 + + # status after a delete, but there are no messages yet, should still return + monkeypatch.setattr("a1.a1rmr.dequeue_all_waiting_messages", _fake_dequeue) + get_instance_good("IN EFFECT") + + # now pretend we deleted successfully + monkeypatch.setattr("a1.a1rmr.dequeue_all_waiting_messages", _fake_dequeue_deleted) + res = client.get(ADM_CTRL_INSTANCE_STATUS) # cant get status + assert res.status_code == 404 + res = client.get(ADM_CTRL_INSTANCE) # cant get instance + assert res.status_code == 404 + # list still 200 but no instance + res = client.get(ADM_CTRL_POLICIES) + assert res.status_code == 200 + assert res.json == [] - monkeypatch.setattr("a1.a1rmr._dequeue_all_waiting_messages", _fake_dequeue(monkeypatch)) - res = client.put("/a1-p/policies/admission_control_policy", json={"not": "expected"}) - assert res.status_code == 400 +def test_xapp_put_good_bad_rmr(client, monkeypatch, adm_instance_good): + """ + assert that rmr bad states don't cause problems + """ + _test_put_patch(monkeypatch) monkeypatch.setattr("rmr.rmr.rmr_send_msg", rmr_mocks.send_mock_generator(10)) - res = client.put("/a1-p/policies/admission_control_policy", json=testing_helpers.good_payload()) - assert res.status_code == 504 - assert res.data == b'"A1 was unable to send a needed message to a downstream subscriber"\n' + res = client.put(ADM_CTRL_INSTANCE, json=adm_instance_good) + assert res.status_code == 202 monkeypatch.setattr("rmr.rmr.rmr_send_msg", rmr_mocks.send_mock_generator(5)) - res = client.put("/a1-p/policies/admission_control_policy", json=testing_helpers.good_payload()) - assert res.status_code == 504 - assert res.data == b'"A1 was unable to send a needed message to a downstream subscriber"\n' - + res = client.put(ADM_CTRL_INSTANCE, json=adm_instance_good) + assert res.status_code == 202 -def test_bad_requests(client, monkeypatch): - """Test bad requests""" - testing_helpers.patch_all(monkeypatch) - # test a 404 - res = client.put("/a1-p/policies/noexist", json=testing_helpers.good_payload()) - assert res.status_code == 404 - - # bad media type - res = client.put("/a1-p/policies/admission_control_policy", data="notajson") - assert res.status_code == 415 - - # test a PUT body against a poliucy not expecting one - res = client.put("/a1-p/policies/test_policy", json=testing_helpers.good_payload()) - assert res.status_code == 400 - assert res.data == b'"BODY SUPPLIED BUT POLICY HAS NO EXPECTED BODY"\n' - - -def test_missing_manifest(client, monkeypatch): +def test_bad_instances(client, monkeypatch, adm_type_good): """ - test that we get a 500 with an approrpiate message on a missing manifest + Test bad send failures """ + rmr_mocks.patch_rmr(monkeypatch) - def f(): - raise exceptions.MissingManifest() - - monkeypatch.setattr("a1.utils.get_ric_manifest", f) + # TODO: reenable this after delete! + # put the type + # res = client.put(ADM_CTRL_TYPE, json=adm_type_good) + # assert res.status_code == 201 - res = client.put("/a1-p/policies/admission_control_policy", json=testing_helpers.good_payload()) - assert res.status_code == 500 - assert res.data == b'"A1 was unable to find the required RIC manifest. report this!"\n' + # illegal type range + res = client.put("/a1-p/policytypes/19999", json=adm_type_good) + assert res.status_code == 400 + res = client.put("/a1-p/policytypes/21024", json=adm_type_good) + assert res.status_code == 400 + # bad body + res = client.put(ADM_CTRL_INSTANCE, json={"not": "expected"}) + assert res.status_code == 400 -def test_missing_rmr(client, monkeypatch): - """ - test that we get a 500 with an approrpiate message on a missing rmr rmr_string - """ - testing_helpers.patch_all(monkeypatch, nonexisting_rmr=True) - res = client.put("/a1-p/policies/admission_control_policy", json=testing_helpers.good_payload()) - assert res.status_code == 500 - assert res.data == b'"A1 does not have a mapping for the desired rmr string. report this!"\n' + # bad media type + res = client.put(ADM_CTRL_INSTANCE, data="notajson") + assert res.status_code == 415 def test_healthcheck(client):