示例#1
0
def testDeleteVim(api, broker: Connection, reraise):
    id = str(uuid4())

    vimAdaptorResponse = {"request_status": "SUCCESS"}

    # Mock vim adaptor
    def onDeleteVimRequest(message: Message):
        with reraise(catch=True):
            assert {"id": id} == message.payload

        return vimAdaptorResponse

    broker.register_async_endpoint(onDeleteVimRequest,
                                   "infrastructure.management.compute.remove")

    # Test successful deletion
    assert 204 == api.delete("/api/v3/vims/" + id).status_code

    # Test vim adaptor error response
    vimAdaptorResponse = {
        "request_status": "ERROR",
        "message": "error message"
    }
    reply = api.delete("/api/v3/vims/" + id)
    assert 500 == reply.status_code
    assert "error message" == reply.get_json()["detail"]
示例#2
0
def test_registration_and_heartbeat(connection: Connection, reraise):
    registration_request_received = Event()

    def on_registration_request(message: Message):
        """
        When the registration request from the plugin is received, this method replies
        as if it were the plugin manager
        """
        with reraise:
            non_empty_string = All(str, Length(min=1))
            assert (S({
                "name": non_empty_string,
                "version": non_empty_string,
                "description": non_empty_string,
            }) == message.payload)
        return {"status": "OK", "uuid": PLUGIN_UUID}

    heartbeat_received = Event()

    def on_heartbeat(message: Message):
        with reraise:
            assert (S({
                "uuid": PLUGIN_UUID,
                "state": In(("READY", "RUNNING", "PAUSED", "FAILED")),
            }) == message.payload)
        heartbeat_received.set()

    connection.register_async_endpoint(on_registration_request,
                                       "platform.management.plugin.register")
    connection.subscribe(
        on_heartbeat,
        "platform.management.plugin." + PLUGIN_UUID + ".heartbeat",
    )

    plugin = ManoBasePlugin(
        use_loopback_connection=True,
        version="1.2.3",
        description="Test Plugin",
    )

    try:
        registration_request_received.wait(1)
        heartbeat_received.wait(1)

        assert plugin.uuid == PLUGIN_UUID
    finally:
        plugin.conn.close()
示例#3
0
def testGetVims(api, broker: Connection):
    # Mock vim adaptor
    broker.register_async_endpoint(
        lambda message: [{
            "id": "id",
            "name": "name",
            "country": "country",
            "city": "city",
            "type": "type",
            "cores": {
                "total": 4,
                "used": 3
            },
            "memory": {
                "total": 2,
                "used": 1
            },
        }],
        "infrastructure.management.compute.list",
    )

    response = api.get("/api/v3/vims")
    assert 200 == response.status_code
    assert [{
        "id": "id",
        "name": "name",
        "country": "country",
        "city": "city",
        "type": "type",
        "cores": {
            "total": 4,
            "used": 3
        },
        "memory": {
            "total": 2,
            "used": 1
        },
    }] == response.get_json()
示例#4
0
def testAddVim(api, broker: Connection, reraise):
    id = str(uuid4())  # VIM uuid returned by the vim-adaptor mock

    baseVimData = {
        "city": "my city",
        "country": "my country",
        "name": "my name",
    }

    vimData = {
        "aws": {
            **baseVimData,
            "type": "aws",
            "accessKey": "access key",
            "secretKey": "secret key",
            "region": "region",
        },
        "kubernetes": {
            **baseVimData,
            "type": "kubernetes",
            "serviceToken": "service token",
            "address": "address",
            "port": 1234,
            "ccc": "ccc",
        },
        "openstack": {
            **baseVimData,
            "type": "openstack",
            "address": "address",
            "tenant": {
                "id": "tenant id",
                "externalNetworkId": "tenant external network id",
                "externalRouterId": "tenant external router id",
            },
            "username": "******",
            "password": "******",
        },
    }

    vimAdaptorResponse = {"request_status": "COMPLETED", "id": id}

    # Mock vim adaptor
    def onAddVimRequest(message: Message):
        with reraise(catch=True):
            # baseVimData should be contained in the payload
            assert S(baseVimData) <= message.payload

        return vimAdaptorResponse

    broker.register_async_endpoint(onAddVimRequest,
                                   "infrastructure.management.compute.add")

    # Add all types of vims
    for data in vimData.values():
        reply = api.post("/api/v3/vims", json=data)
        assert 201 == reply.status_code
        assert {"id": id} == reply.get_json()

    # Let the mock vim adaptor reply with an error
    vimAdaptorResponse = {
        "request_status": "ERROR",
        "message": "error message"
    }
    reply = api.post("/api/v3/vims", json=vimData["aws"])
    assert 500 == reply.status_code
    assert "error message" == reply.get_json()["detail"]
示例#5
0
class testPLEXRegistration(unittest.TestCase):
    """
    Tests the registration process of the Placement Executive to the broker
    and the plugin manager, and the heartbeat process.
    """
    def setUp(self):
        #a new Placement Executive in another process for each test
        self.plex_proc = Process(target=PlacementExecutive)
        self.plex_proc.daemon = True

        if 'broker_man_host' in os.environ:
            self.man_host = os.environ['broker_man_host']
        else:
            self.man_host = 'http://localhost:15672'

        if 'sm_broker_host' in os.environ:
            self.sm_host = os.environ['sm_broker_host']
        else:
            self.sm_host = 'http://localhost:15672'
        url_user = "******".format(self.man_host)
        url_create = '{0}/api/vhosts/ssm-1234'.format(self.man_host)
        url_permission = '{0}/api/permissions/ssm-1234/specific-management'.format(
            self.man_host)
        self.headers = {'content-type': 'application/json'}
        data1 = '{"password":"******","tags":"son-sm"}'
        data2 = '{"configure":".*","write":".*","read":".*"}'
        res = requests.put(url=url_user,
                           headers=self.headers,
                           data=data1,
                           auth=('guest', 'guest'))
        LOG.info(res.content)
        res1 = requests.put(url=url_create,
                            headers=self.headers,
                            auth=('guest', 'guest'))
        LOG.info(res1.content)
        res2 = requests.put(url=url_permission,
                            headers=self.headers,
                            data=data2,
                            auth=('guest', 'guest'))
        LOG.info(res2.content)

        #make a new connection with the broker before each test
        url = "{0}/ssm-1234".format(self.sm_host)
        self.manoconn = ManoBrokerRequestResponseConnection(
            'son-plugin.SonPluginManager')
        self.sm_connection = ManoBrokerRequestResponseConnection(
            'son-plugin.SSM', url=url)

        #Some threading events that can be used during the tests
        self.wait_for_event1 = threading.Event()
        self.wait_for_event1.clear()

        self.wait_for_event2 = threading.Event()
        self.wait_for_event2.clear()

    def tearDown(self):
        #Killing the Placement Executive
        if self.plex_proc is not None:
            self.plex_proc.terminate()
        del self.plex_proc

        #Killing the connection with the broker
        try:
            self.manoconn.stop_connection()
            self.sm_connection.stop_connection()
        except Exception as e:
            LOG.exception("Stop connection exception.")

        #Clearing the threading helpers
        del self.wait_for_event1
        del self.wait_for_event2

        url_user = "******".format(self.man_host)
        url_vhost = "{0}/api/vhosts/ssm-1234".format(self.man_host)
        res1 = requests.delete(url=url_user,
                               headers=self.headers,
                               auth=('guest', 'guest'))
        LOG.info(res1.content)
        res1 = requests.delete(url=url_vhost,
                               headers=self.headers,
                               auth=('guest', 'guest'))
        LOG.info(res1.content)

    #Method that terminates the timer that waits for an event
    def eventFinished1(self):
        self.wait_for_event1.set()

    def eventFinished2(self):
        self.wait_for_event2.set()

    #Method that starts a timer, waiting for an event
    def waitForEvent1(self, timeout=5, msg="Event timed out."):
        if not self.wait_for_event1.wait(timeout):
            self.assertEqual(True, False, msg=msg)

    def waitForEvent2(self, timeout=5, msg="Event timed out."):
        if not self.wait_for_event2.wait(timeout):
            self.assertEqual(True, False, msg=msg)

    def test_1_PLEX_Registration(self):
        """
        TEST: This test verifies whether the Placement Executive is sending out a message,
        and whether it contains all the needed info on the
        platform.management.plugin.register topic to register to the plugin
        manager.
        """

        #STEP3a: When receiving the message, we need to check whether all fields present.
        def on_register_receive(ch, method, properties, message):

            msg = yaml.load(message)
            #CHECK: The message should be a dictionary.
            self.assertTrue(isinstance(msg, dict),
                            msg='message is not a dictionary')
            #CHECK: The dictionary should have a key 'name'.
            self.assertIn('name',
                          msg.keys(),
                          msg='No name provided in message.')
            if isinstance(msg['name'], str):
                #CHECK: The value of 'name' should not be an empty string.
                self.assertTrue(len(msg['name']) > 0,
                                msg='empty name provided.')
            else:
                #CHECK: The value of 'name' should be a string
                self.assertEqual(True, False, msg='name is not a string')
            #CHECK: The dictionary should have a key 'version'.
            self.assertIn('version',
                          msg.keys(),
                          msg='No version provided in message.')
            if isinstance(msg['version'], str):
                #CHECK: The value of 'version' should not be an empty string.
                self.assertTrue(len(msg['version']) > 0,
                                msg='empty version provided.')
            else:
                #CHECK: The value of 'version' should be a string
                self.assertEqual(True, False, msg='version is not a string')
            #CHECK: The dictionary should have a key 'description'
            self.assertIn('description',
                          msg.keys(),
                          msg='No description provided in message.')
            if isinstance(msg['description'], str):
                #CHECK: The value of 'description' should not be an empty string.
                self.assertTrue(len(msg['description']) > 0,
                                msg='empty description provided.')
            else:
                #CHECK: The value of 'description' should be a string
                self.assertEqual(True,
                                 False,
                                 msg='description is not a string')

            # stop waiting
            self.eventFinished1()

        #STEP1: Listen to the platform.management.plugin.register topic
        self.manoconn.subscribe(on_register_receive,
                                'platform.management.plugin.register')

        #STEP2: Start the Placement Executive
        self.plex_proc.start()

        #STEP3b: When not receiving the message, the test failed
        self.waitForEvent1(timeout=5, msg="message not received.")

    def test_2_PLEX_request_response(self):
        def on_request_send(ch, method, properties, message):

            if properties.app_id == "son-plugin.PlacementExecutive":
                msg = yaml.load(message)

                self.assertTrue(isinstance(msg, dict),
                                msg='message is not a dictionary')

                self.assertIn('uuid',
                              msg.keys(),
                              msg='No uuid provided in message.')
                if isinstance(msg['uuid'], str):
                    self.assertTrue(msg['uuid'] == '1234',
                                    msg='empty uuid provided.')

                self.assertNotIn('place', msg.keys(), msg='wrong message.')

                res_payload = yaml.dump({'uuid': '1234', 'place': '2'})

                self.eventFinished1()
                return res_payload

        def on_response_send(ch, method, properties, message):
            if properties.app_id == "son-plugin.PlacementExecutive":
                msg = yaml.load(message)

                self.assertTrue(isinstance(msg, dict),
                                msg='message is not a dictionary')

                self.assertIn('uuid',
                              msg.keys(),
                              msg='No uuid provided in message.')
                if isinstance(msg['uuid'], str):
                    self.assertTrue(msg['uuid'] == '1234',
                                    msg='empty uuid provided.')

                self.assertIn('place',
                              msg.keys(),
                              msg='No place provided in message.')
                if isinstance(msg['place'], str):
                    self.assertTrue(msg['place'] == '2',
                                    msg='empty uuid provided.')

                self.eventFinished2()

        self.plex_proc.start()

        time.sleep(2)

        self.manoconn.subscribe(on_response_send,
                                'placement.executive.request')
        self.sm_connection.register_async_endpoint(on_request_send,
                                                   'placement.ssm.1234')

        req_payload = yaml.dump({'uuid': '1234'})
        self.manoconn.publish("placement.executive.request",
                              message=req_payload)

        self.waitForEvent1(timeout=5, msg="response message not received.")
        self.waitForEvent2(timeout=5, msg="request message not received.")