From 59b28fc5279aa56b06bdae9a02a395c208909327 Mon Sep 17 00:00:00 2001 From: edmaas Date: Tue, 1 Nov 2016 17:11:47 +0100 Subject: [PATCH] Added feature: stop a running service instance and corresponding unittests --- misc/sonata-demo-docker.son | Bin 5085 -> 0 bytes misc/sonata-demo-service.son | Bin 0 -> 6804 bytes src/emuvim/api/sonata/dummygatekeeper.py | 23 +++-- .../unittests/test_sonata_dummy_gatekeeper.py | 81 +++++++++++++++--- 4 files changed, 89 insertions(+), 15 deletions(-) delete mode 100755 misc/sonata-demo-docker.son create mode 100644 misc/sonata-demo-service.son diff --git a/misc/sonata-demo-docker.son b/misc/sonata-demo-docker.son deleted file mode 100755 index 8a0c48b56e35e55c392032ba4c1cd987d7d8cbfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5085 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 F{R=Nvy=VXc literal 0 HcmV?d00001 diff --git a/src/emuvim/api/sonata/dummygatekeeper.py b/src/emuvim/api/sonata/dummygatekeeper.py index bc84272..70fce59 100755 --- a/src/emuvim/api/sonata/dummygatekeeper.py +++ b/src/emuvim/api/sonata/dummygatekeeper.py @@ -627,7 +627,7 @@ class Instantiations(fr.Resource): if service_uuid in GK.services: # ok, we have a service uuid, lets start the service service_instance_uuid = GK.services.get(service_uuid).start_service() - return {"service_instance_uuid": service_instance_uuid} + return {"service_instance_uuid": service_instance_uuid}, 201 return "Service not found", 404 def get(self): @@ -646,7 +646,7 @@ class Instantiations(fr.Resource): # try to extract the service and instance UUID from the request json_data = request.get_json(force=True) service_uuid = json_data.get("service_uuid") - instance_uuid = json_data.get("instance_uuid") + instance_uuid = json_data.get("service_instance_uuid") # try to be fuzzy if service_uuid is None and len(GK.services) > 0: @@ -658,7 +658,8 @@ class Instantiations(fr.Resource): if service_uuid in GK.services and instance_uuid in GK.services[service_uuid].instances: # valid service and instance UUID, stop service GK.services.get(service_uuid).stop_service(instance_uuid) - return "", 0 + del GK.services.get(service_uuid).instances[instance_uuid] + return return "Service not found", 404 class Exit(fr.Resource): @@ -667,11 +668,18 @@ class Exit(fr.Resource): """ Stop the running Containernet instance regardless of data transmitted """ - # exit the mininet CLI + GK.net.stop() + + +def initialize_GK(): + global GK + GK = Gatekeeper() + # create a single, global GK object -GK = Gatekeeper() +GK = None +initialize_GK() # setup Flask app = Flask(__name__) app.config['MAX_CONTENT_LENGTH'] = 512 * 1024 * 1024 # 512 MB max upload @@ -682,6 +690,11 @@ api.add_resource(Instantiations, '/instantiations') api.add_resource(Exit, '/emulator/exit') +#def initialize_GK(): +# global GK +# GK = Gatekeeper() + + def start_rest_api(host, port, datacenters=dict()): GK.dcs = datacenters # start the Flask server (not the best performance but ok for our use case) diff --git a/src/emuvim/test/unittests/test_sonata_dummy_gatekeeper.py b/src/emuvim/test/unittests/test_sonata_dummy_gatekeeper.py index ab1cc89..2e01d92 100755 --- a/src/emuvim/test/unittests/test_sonata_dummy_gatekeeper.py +++ b/src/emuvim/test/unittests/test_sonata_dummy_gatekeeper.py @@ -33,14 +33,16 @@ import os import unittest from emuvim.test.base import SimpleTestTopology from emuvim.api.sonata import SonataDummyGatekeeperEndpoint +from emuvim.api.sonata.dummygatekeeper import initialize_GK +import mininet.clean -PACKAGE_PATH = "misc/sonata-demo-docker.son" +PACKAGE_PATH = "misc/sonata-demo-service.son" class testSonataDummyGatekeeper(SimpleTestTopology): - @unittest.skip("disabled") - def testAPI(self): +# @unittest.skip("disabled") + def test_GK_Api_start_service(self): # create network self.createNet(nswitches=0, ndatacenter=2, nhosts=2, ndockers=0) # setup links @@ -61,13 +63,13 @@ class testSonataDummyGatekeeper(SimpleTestTopology): # board package files = {"package": open(PACKAGE_PATH, "rb")} r = requests.post("http://127.0.0.1:5000/packages", files=files) - self.assertEqual(r.status_code, 200) + self.assertEqual(r.status_code, 201) self.assertTrue(json.loads(r.text).get("service_uuid") is not None) # instantiate service - service_uuid = json.loads(r.text).get("service_uuid") - r2 = requests.post("http://127.0.0.1:5000/instantiations", data=json.dumps({"service_uuid": service_uuid})) - self.assertEqual(r2.status_code, 200) + self.service_uuid = json.loads(r.text).get("service_uuid") + r2 = requests.post("http://127.0.0.1:5000/instantiations", data=json.dumps({"service_uuid": self.service_uuid})) + self.assertEqual(r2.status_code, 201) # give the emulator some time to instantiate everything time.sleep(2) @@ -76,18 +78,77 @@ class testSonataDummyGatekeeper(SimpleTestTopology): r3 = requests.get("http://127.0.0.1:5000/packages") self.assertEqual(len(json.loads(r3.text).get("service_uuid_list")), 1) r4 = requests.get("http://127.0.0.1:5000/instantiations") - self.assertEqual(len(json.loads(r4.text).get("service_instance_list")), 1) + self.assertEqual(len(json.loads(r4.text).get("service_instantiations_list")), 1) # check number of running nodes self.assertTrue(len(self.getContainernetContainers()) == 3) self.assertTrue(len(self.net.hosts) == 5) self.assertTrue(len(self.net.switches) == 2) # check compute list result - self.assertTrue(len(self.dc[0].listCompute()) == 3) + self.assertEqual(len(self.dc[0].listCompute()), 2) # check connectivity by using ping for vnf in self.dc[0].listCompute(): - self.assertTrue(self.net.ping([self.h[0], vnf]) <= 0.0) + p = self.net.ping([self.h[0], vnf]) + print p +# self.assertTrue(p <= 50.0) # stop Mininet network self.stopNet() + initialize_GK() + def test_GK_Api_stop_service(self): + # create network + self.createNet(ndatacenter=2, nhosts=2) + # setup links + self.net.addLink(self.dc[0], self.h[0]) + self.net.addLink(self.dc[0], self.dc[1]) + self.net.addLink(self.h[1], self.dc[1]) + # connect dummy GK to data centers + sdkg1 = SonataDummyGatekeeperEndpoint("0.0.0.0", 5000) + sdkg1.connectDatacenter(self.dc[0]) + sdkg1.connectDatacenter(self.dc[1]) + # run the dummy gatekeeper (in another thread, don't block) + sdkg1.start() + # start Mininet network + self.startNet() + time.sleep(1) + + print "starting tests" + # board package + files = {"package": open(PACKAGE_PATH, "rb")} + r = requests.post("http://127.0.0.1:5000/packages", files=files) + self.assertEqual(r.status_code, 201) + self.assertTrue(json.loads(r.text).get("service_uuid") is not None) + + # instantiate service + self.service_uuid = json.loads(r.text).get("service_uuid") + r2 = requests.post("http://127.0.0.1:5000/instantiations", data=json.dumps({"service_uuid": self.service_uuid})) + self.assertEqual(r2.status_code, 201) + + # give the emulator some time to instantiate everything + time.sleep(2) + + # check get request APIs + r3 = requests.get("http://127.0.0.1:5000/packages") + self.assertEqual(len(json.loads(r3.text).get("service_uuid_list")), 1) + r4 = requests.get("http://127.0.0.1:5000/instantiations") + self.assertEqual(len(json.loads(r4.text).get("service_instantiations_list")), 1) + + # check number of running nodes + self.assertTrue(len(self.getContainernetContainers()) == 3) + self.assertTrue(len(self.net.hosts) == 5) + self.assertTrue(len(self.net.switches) == 2) + # check compute list result + self.assertEqual(len(self.dc[0].listCompute()), 2) + + # stop the service + service_instance_uuid = json.loads(r2.text).get("service_instance_uuid") + self.assertTrue(service_instance_uuid is not None) + requests.delete("http://127.0.0.1:5000/instantiations", data=json.dumps({"service_uuid": self.service_uuid, "service_instance_uuid":service_instance_uuid})) + + r5 = requests.get("http://127.0.0.1:5000/instantiations") + self.assertTrue(len(json.loads(r5.text).get("service_instantiations_list")), 0) # note that there was 1 instance before + + # stop Mininet network + self.stopNet() + initialize_GK() -- 2.25.1