X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=tests%2Ftest_controller.py;h=e5c3ac7e848fa76358e731c7aa5de4b6ffe4af86;hb=6b69910923309e05820706dc025e1441463906c9;hp=88d6f70c6d9ecdd0b447655682e35fd7c003651e;hpb=bfa46147cce23a46a49fb53dfae8a790b0fe34e4;p=ric-plt%2Fa1.git diff --git a/tests/test_controller.py b/tests/test_controller.py index 88d6f70..e5c3ac7 100644 --- a/tests/test_controller.py +++ b/tests/test_controller.py @@ -14,12 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # ================================================================================== -import tempfile -import os +import time from rmr.rmr_mocks import rmr_mocks -from a1 import app -import pytest +from a1 import run ADM_CTRL = "admission_control_policy" @@ -30,23 +28,8 @@ 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(): - db_fd, app.app.config["DATABASE"] = tempfile.mkstemp() - app.app.config["TESTING"] = True - cl = app.app.test_client() - - yield cl - - os.close(db_fd) - os.unlink(app.app.config["DATABASE"]) - - -def _fake_dequeue(_filter_type): - """ - for monkeypatching a1rmnr.dequeue_all_messages with a good status - """ +def _fake_dequeue(_mrc, _filter_type): + """for monkeypatching with a good status""" fake_msg = {} pay = b'{"policy_type_id": 20000, "policy_instance_id": "admission_control_policy", "handler_id": "test_receiver", "status": "OK"}' fake_msg["payload"] = pay @@ -54,27 +37,42 @@ def _fake_dequeue(_filter_type): return new_messages -def _fake_dequeue_none(_filter_type): - """ - for monkeypatching a1rmnr.dequeue_all_messages with no waiting messages - """ +def _fake_dequeue_none(_mrc, _filter_type): + """for monkeypatching with no waiting messages""" return [] -def _fake_dequeue_deleted(_filter_type): - """ - for monkeypatching a1rmnr.dequeue_all_messages with a DELETED status - """ - fake_msg = {} +def _fake_dequeue_deleted(_mrc, _filter_type): + """for monkeypatching with a DELETED status""" + new_msgs = [] + + # insert some that don't exist to make sure nothing blows up + pay = b'{"policy_type_id": 20666, "policy_instance_id": "admission_control_policy", "handler_id": "test_receiver", "status": "DELETED"}' + fake_msg = {"payload": pay} + new_msgs.append(fake_msg) + + pay = b'{"policy_type_id": 20000, "policy_instance_id": "darkness", "handler_id": "test_receiver", "status": "DELETED"}' + fake_msg = {"payload": pay} + new_msgs.append(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 + fake_msg = {"payload": pay} + new_msgs.append(fake_msg) + + return new_msgs def _test_put_patch(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 + # assert that rmr bad states don't cause problems + monkeypatch.setattr("rmr.rmr.rmr_send_msg", rmr_mocks.send_mock_generator(10)) + + # 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): @@ -91,12 +89,24 @@ def _test_put_patch(monkeypatch): monkeypatch.setattr("rmr.rmr.generate_and_set_transaction_id", fake_set_transactionid) +# Module level Hack + + +RMR_THREAD = None + + +def setup_module(): + """module level setup""" + global RMR_THREAD + RMR_THREAD = run.start_rmr_thread(real_init=False) + + # Actual Tests -def test_xapp_put_good(client, monkeypatch, adm_type_good, adm_instance_good): +def test_workflow_nothing_there_yet(client, monkeypatch, adm_type_good, adm_instance_good): """ test policy put good""" - + monkeypatch.setattr("rmr.helpers.rmr_rcvall_msgs", _fake_dequeue_none) # no type there yet res = client.get(ADM_CTRL_TYPE) assert res.status_code == 404 @@ -107,14 +117,23 @@ def test_xapp_put_good(client, monkeypatch, adm_type_good, adm_instance_good): 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_workflow(client, monkeypatch, adm_type_good, adm_instance_good): + """ + test a full A1 workflow + """ + monkeypatch.setattr("rmr.helpers.rmr_rcvall_msgs", _fake_dequeue_none) # put the type res = client.put(ADM_CTRL_TYPE, json=adm_type_good) assert res.status_code == 201 + # cant replace types + res = client.put(ADM_CTRL_TYPE, json=adm_type_good) + assert res.status_code == 400 + # type there now res = client.get(ADM_CTRL_TYPE) assert res.status_code == 200 @@ -139,6 +158,10 @@ def test_xapp_put_good(client, monkeypatch, adm_type_good, adm_instance_good): res = client.put(ADM_CTRL_INSTANCE, json=adm_instance_good) assert res.status_code == 202 + # replace is allowed on instances + 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 @@ -155,14 +178,19 @@ def test_xapp_put_good(client, monkeypatch, adm_type_good, adm_instance_good): 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) + # try a status get but we didn't get any ACKs yet to test NOT IN EFFECT + time.sleep(1) # wait for the rmr thread get_instance_good("NOT IN EFFECT") # now pretend we did get a good ACK - monkeypatch.setattr("a1.a1rmr.dequeue_all_waiting_messages", _fake_dequeue) + monkeypatch.setattr("rmr.helpers.rmr_rcvall_msgs", _fake_dequeue) + time.sleep(1) # wait for the rmr thread get_instance_good("IN EFFECT") + # cant delete type until there are no instances + res = client.delete(ADM_CTRL_TYPE) + assert res.status_code == 400 + # delete it res = client.delete(ADM_CTRL_INSTANCE) assert res.status_code == 202 @@ -170,51 +198,42 @@ def test_xapp_put_good(client, monkeypatch, adm_type_good, adm_instance_good): 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) + monkeypatch.setattr("rmr.helpers.rmr_rcvall_msgs", _fake_dequeue) + time.sleep(1) # wait for the rmr thread get_instance_good("IN EFFECT") # now pretend we deleted successfully - monkeypatch.setattr("a1.a1rmr.dequeue_all_waiting_messages", _fake_dequeue_deleted) + monkeypatch.setattr("rmr.helpers.rmr_rcvall_msgs", _fake_dequeue_deleted) + time.sleep(1) # wait for the rmr thread 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 == [] + # delete the type + res = client.delete(ADM_CTRL_TYPE) + assert res.status_code == 204 -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(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(ADM_CTRL_INSTANCE, json=adm_instance_good) - assert res.status_code == 202 + # cant touch this + res = client.get(ADM_CTRL_TYPE) + assert res.status_code == 404 + res = client.delete(ADM_CTRL_TYPE) + assert res.status_code == 404 def test_bad_instances(client, monkeypatch, adm_type_good): """ - Test bad send failures + test various failure modes """ + # put the type (needed for some of the tests below) rmr_mocks.patch_rmr(monkeypatch) - - # TODO: reenable this after delete! - # put the type - # res = client.put(ADM_CTRL_TYPE, json=adm_type_good) - # assert res.status_code == 201 - - # 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 + res = client.put(ADM_CTRL_TYPE, json=adm_type_good) + assert res.status_code == 201 # bad body res = client.put(ADM_CTRL_INSTANCE, json={"not": "expected"}) @@ -224,6 +243,30 @@ def test_bad_instances(client, monkeypatch, adm_type_good): res = client.put(ADM_CTRL_INSTANCE, data="notajson") assert res.status_code == 415 + # delete a non existent instance + res = client.delete(ADM_CTRL_INSTANCE + "DARKNESS") + assert res.status_code == 404 + + # get a non existent instance + monkeypatch.setattr("rmr.helpers.rmr_rcvall_msgs", _fake_dequeue) + time.sleep(1) + res = client.get(ADM_CTRL_INSTANCE + "DARKNESS") + assert res.status_code == 404 + + # delete the type (as cleanup) + res = client.delete(ADM_CTRL_TYPE) + assert res.status_code == 204 + + +def test_illegal_types(client, monkeypatch, adm_type_good): + """ + Test illegal types + """ + 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 + def test_healthcheck(client): """ @@ -231,3 +274,8 @@ def test_healthcheck(client): """ res = client.get("/a1-p/healthcheck") assert res.status_code == 200 + + +def teardown_module(): + """module teardown""" + RMR_THREAD.stop()