From 7cf97412a3e8059c4ddd0a471bc3095a7b5a266b Mon Sep 17 00:00:00 2001 From: ReemMahmoud Date: Thu, 22 Mar 2018 12:06:48 +0200 Subject: Add more tests and fix bug in moon_orchestrator adding more validation adding more test cases covering pods, slaves applying comments mentioned Change-Id: I7e58f184a3f216fc3740097244a5538c184bd940 Signed-off-by: ReemMahmoud --- moon_orchestrator/moon_orchestrator/api/pods.py | 38 +++--- moon_orchestrator/moon_orchestrator/drivers.py | 28 +++-- moon_orchestrator/tests/unit_python/mock_pods.py | 13 ++ moon_orchestrator/tests/unit_python/test_pods.py | 154 ++++++++++++++++++++++- 4 files changed, 196 insertions(+), 37 deletions(-) diff --git a/moon_orchestrator/moon_orchestrator/api/pods.py b/moon_orchestrator/moon_orchestrator/api/pods.py index 3a01c3a9..389fa5b0 100644 --- a/moon_orchestrator/moon_orchestrator/api/pods.py +++ b/moon_orchestrator/moon_orchestrator/api/pods.py @@ -52,27 +52,29 @@ class Pods(Resource): for _pod_key, _pod_values in self.driver.get_pods().items(): pods[_pod_key] = [] for _pod_value in _pod_values: - if _pod_value['namespace'] != "moon": + if "namespace" in _pod_value and _pod_value['namespace'] != "moon": continue pods[_pod_key].append(_pod_value) return {"pods": pods} except Exception as e: return {"result": False, "message": str(e)}, 500 - def __get_pod_with_keystone_pid(self, keystone_pid): + def __validate_pod_with_keystone_pid(self, keystone_pid): for pod_key, pod_values in self.driver.get_pods().items(): - if pod_values[0]['keystone_project_id'] == keystone_pid: + if pod_values and "keystone_project_id" in pod_values[0] \ + and pod_values[0]['keystone_project_id'] == keystone_pid: return True - def __get_wrapper(self, slave_name): + def __is_slave_exist(self, slave_name): for slave in self.driver.get_slaves(): - if slave_name == slave["name"] \ - and slave["configured"]: + if "name" in slave and "configured" in slave \ + and slave_name == slave["name"] and slave["configured"]: return True def __get_slave_names(self): for slave in self.driver.get_slaves(): - yield slave["name"] + if "name" in slave : + yield slave["name"] @check_auth def post(self, uuid=None, user_id=None): @@ -98,27 +100,24 @@ class Pods(Resource): } } """ - pods = {} if "security_pipeline" in request.json: - if self.__get_pod_with_keystone_pid(request.json.get("keystone_project_id")): + if self.__validate_pod_with_keystone_pid(request.json.get("keystone_project_id")): raise exceptions.PipelineConflict + if not request.json.get("pdp_id"): + raise exceptions.PdpUnknown + if not request.json.get("security_pipeline"): + raise exceptions.PolicyUnknown self.driver.create_pipeline( request.json.get("keystone_project_id"), request.json.get("pdp_id"), request.json.get("security_pipeline"), manager_data=request.json, slave_name=request.json.get("slave_name")) - for _pod_key, _pod_values in self.driver.get_pods().items(): - pods[_pod_key] = [] - for _pod_value in _pod_values: - if _pod_value['namespace'] != "moon": - continue - pods[_pod_key].append(_pod_value) else: logger.info("------------------------------------") logger.info(list(self.__get_slave_names())) logger.info("------------------------------------") - if self.__get_wrapper(request.json.get("slave_name")): + if self.__is_slave_exist(request.json.get("slave_name")): raise exceptions.WrapperConflict if request.json.get("slave_name") not in self.__get_slave_names(): raise exceptions.SlaveNameUnknown @@ -144,8 +143,11 @@ class Pods(Resource): return {'result': True} except exceptions.PipelineUnknown: for slave in self.driver.get_slaves(): - if uuid in (slave['name'], slave["wrapper_name"]): - self.driver.delete_wrapper(name=slave["wrapper_name"]) + if "name" in slave and "wrapper_name" in slave: + if uuid in (slave['name'], slave["wrapper_name"]): + self.driver.delete_wrapper(name=slave["wrapper_name"]) + else : + raise exceptions.SlaveNameUnknown except Exception as e: return {"result": False, "message": str(e)}, 500 diff --git a/moon_orchestrator/moon_orchestrator/drivers.py b/moon_orchestrator/moon_orchestrator/drivers.py index bb0d0c2c..4519f3aa 100644 --- a/moon_orchestrator/moon_orchestrator/drivers.py +++ b/moon_orchestrator/moon_orchestrator/drivers.py @@ -203,13 +203,14 @@ class K8S(Driver): for key, value in pods.items(): # logger.info("ctx={}".format(active_context)) # logger.info("value={}".format(value)) - if active_context["name"] == value[0].get('slave_name'): - data = dict(active_context) - data["wrapper_name"] = value[0]['name'] - data["ip"] = value[0].get("ip", "NC") - data["port"] = value[0].get("external_port", "NC") - slaves.append(data) - break + if "name" in active_context and value and "name" in value[0]: + if active_context["name"] == value[0].get('slave_name'): + data = dict(active_context) + data["wrapper_name"] = value[0]['name'] + data["ip"] = value[0].get("ip", "NC") + data["port"] = value[0].get("external_port", "NC") + slaves.append(data) + break return slaves for ctx in contexts: data = dict(ctx) @@ -217,12 +218,13 @@ class K8S(Driver): for key, value in pods.items(): # logger.info("ctx={}".format(ctx)) # logger.info("value={}".format(value)) - if ctx["name"] == value[0].get('slave_name'): - data["wrapper_name"] = value[0]['name'] - data["ip"] = value[0].get("ip", "NC") - data["port"] = value[0].get("external_port", "NC") - data["configured"] = True - break + if "name" in ctx and value and "name" in value[0]: + if ctx["name"] == value[0].get('slave_name'): + data["wrapper_name"] = value[0]['name'] + data["ip"] = value[0].get("ip", "NC") + data["port"] = value[0].get("external_port", "NC") + data["configured"] = True + break slaves.append(data) return slaves diff --git a/moon_orchestrator/tests/unit_python/mock_pods.py b/moon_orchestrator/tests/unit_python/mock_pods.py index 84e6c7ea..59e1b3c0 100644 --- a/moon_orchestrator/tests/unit_python/mock_pods.py +++ b/moon_orchestrator/tests/unit_python/mock_pods.py @@ -208,12 +208,25 @@ def patch_k8s(monkeypatch): 'create_namespaced_deployment', create_namespaced_deployment_mockreturn) + def delete_namespaced_deployment_mockreturn(*args, **kwargs): + return None + + monkeypatch.setattr(client.ExtensionsV1beta1Api, + 'delete_namespaced_deployment', + delete_namespaced_deployment_mockreturn) + def create_namespaced_service_mockreturn(*args, **kwargs): return {} monkeypatch.setattr(client.CoreV1Api, 'create_namespaced_service', create_namespaced_service_mockreturn) + def delete_namespaced_service_mockreturn(*args, **kwargs): + return {} + monkeypatch.setattr(client.CoreV1Api, + 'delete_namespaced_service', + delete_namespaced_service_mockreturn) + def register_pods(m): """ Modify the response from Requests module diff --git a/moon_orchestrator/tests/unit_python/test_pods.py b/moon_orchestrator/tests/unit_python/test_pods.py index 678645be..5e1b3767 100644 --- a/moon_orchestrator/tests/unit_python/test_pods.py +++ b/moon_orchestrator/tests/unit_python/test_pods.py @@ -15,6 +15,7 @@ def test_get_pods(context, monkeypatch): data = get_json(req.data) assert isinstance(data, dict) assert "pods" in data + assert data["pods"] def test_get_pods_failure(context, monkeypatch): @@ -30,6 +31,7 @@ def test_get_pods_failure(context, monkeypatch): assert isinstance(data, dict) assert not data["pods"] +############################ /post ############################ def test_add_pods_with_pipeline(context, monkeypatch): patch_k8s(monkeypatch) @@ -52,7 +54,7 @@ def test_add_pods_with_pipeline(context, monkeypatch): assert data["pods"] -def test_add_pods_without_pipeline_with_bad_slave_name(context, monkeypatch): +def test_add_pods_without_pipeline_with_bad_slave_name_failure(context, monkeypatch): patch_k8s(monkeypatch) import moon_orchestrator.server @@ -89,7 +91,7 @@ def test_add_pods_without_pipeline_with_good_slave_name(context, monkeypatch): assert data["pods"] -def test_add_pods_without_pipeline_without_slave_name(context, monkeypatch): +def test_add_pods_without_pipeline_without_slave_name_failure(context, monkeypatch): patch_k8s(monkeypatch) import moon_orchestrator.server @@ -106,7 +108,7 @@ def test_add_pods_without_pipeline_without_slave_name(context, monkeypatch): assert 'The slave is unknown.' in data['message'] -def test_add_pods_with_no_data(context, monkeypatch): +def test_add_pods_with_no_data_failure(context, monkeypatch): patch_k8s(monkeypatch) import moon_orchestrator.server server = moon_orchestrator.server.create_server() @@ -140,6 +142,146 @@ def test_add_pods_with_no_policies_no_models(context, monkeypatch, no_requests): assert req.status_code == 200 -def test_delete_pods(context, monkeypatch): - # TODO - pass +def test_add_pods_with_empty_pdp_id_and_keystone_project_id_failure(context, monkeypatch): + patch_k8s(monkeypatch) + + import moon_orchestrator.server + server = moon_orchestrator.server.create_server() + _client = server.app.test_client() + data = { + "keystone_project_id": "", + "pdp_id": "", + "security_pipeline": context.get('security_pipeline'), + } + req = _client.post("/pods", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert req.data + data = get_json(req.data) + assert "The pdp is unknown." in data['message'] + + +def test_add_pods_with_empty_security_pipeline_failure(context, monkeypatch): + patch_k8s(monkeypatch) + + import moon_orchestrator.server + server = moon_orchestrator.server.create_server() + _client = server.app.test_client() + data = { + "keystone_project_id": context.get('project_id'), + "pdp_id": context.get('pdp_id'), + "security_pipeline": "", + } + req = _client.post("/pods", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert req.data + data = get_json(req.data) + assert 'The policy is unknown.' in data['message'] + + +def test_add_different_pods_with_same_pdp_id(context, monkeypatch): + patch_k8s(monkeypatch) + + import moon_orchestrator.server + server = moon_orchestrator.server.create_server() + _client = server.app.test_client() + data = { + "keystone_project_id": context.get('project_id'), + "pdp_id": context.get('pdp_id'), + "security_pipeline": context.get('security_pipeline'), + } + req = _client.post("/pods", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + data["keystone_project_id"] = data["keystone_project_id"] + "x" + req = _client.post("/pods", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 200 + + +def test_add_different_pods_with_same_keystone_project_id_failure(context, monkeypatch): + patch_k8s(monkeypatch) + + import moon_orchestrator.server + server = moon_orchestrator.server.create_server() + _client = server.app.test_client() + data = { + "keystone_project_id": context.get('project_id'), + "pdp_id": context.get('pdp_id'), + "security_pipeline": context.get('security_pipeline'), + } + req = _client.post("/pods", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + data["pdp_id"] = data["pdp_id"] + "xyz" + req = _client.post("/pods", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 409 + data = get_json(req.data) + assert isinstance(data, dict) + assert 'A Pipeline already exist for the specified slave.' in data['message'] + + +def test_add_pod_with_slave_more_than_once_failure(context, monkeypatch): + patch_k8s(monkeypatch) + + import moon_orchestrator.server + server = moon_orchestrator.server.create_server() + _client = server.app.test_client() + data = { + "slave_name": "active_context", + } + req = _client.post("/pods", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + req = _client.post("/pods", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 409 + assert req.data + data = get_json(req.data) + assert isinstance(data, dict) + assert 'A Wrapper already exist for the specified slave.' in data['message'] + +############################ /delete ############################ + +def test_delete_pod_valid_uuid(context, monkeypatch): + patch_k8s(monkeypatch) + + import moon_orchestrator.server + server = moon_orchestrator.server.create_server() + _client = server.app.test_client() + data = { + "keystone_project_id": context.get('project_id'), + "pdp_id": context.get('pdp_id'), + "security_pipeline": context.get('security_pipeline'), + } + req = _client.post("/pods", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 200 + assert req.data + data = get_json(req.data) + for key in data["pods"]: + req = _client.delete("/pods/{}".format(key)) + assert req.status_code == 200 + +def test_delete_pod_Invalid_uuid_failure(context, monkeypatch): + patch_k8s(monkeypatch) + + import moon_orchestrator.server + server = moon_orchestrator.server.create_server() + _client = server.app.test_client() + + req = _client.delete("/pods/invalid") + assert req.status_code == 400 + data = get_json(req.data) + assert 'The slave is unknown.' in data['message'] + +def test_delete_pod_without_uuid_failure(context, monkeypatch): + patch_k8s(monkeypatch) + + import moon_orchestrator.server + server = moon_orchestrator.server.create_server() + _client = server.app.test_client() + + req = _client.delete("/pods/") + assert req.status_code == 400 + data = get_json(req.data) + assert 'The slave is unknown.' in data['message'] \ No newline at end of file -- cgit 1.2.3-korg