def setUp(self):
        self.vm_id1 = "vm_id1"
        self.vm_id2 = "vm_id2"

        self.host_ip1 = "host_ip1"
        self.host_ip2 = "host_ip2"

        self.cap1 = 50
        self.cap2 = 78
        self.io_cap = 75

        self.bigsea_username = "******"
        self.bigsea_password = "******"
        self.authorization_url = "authorization_url"
        # self.authorization_data = dict(authorization_url=self.authorization_url,
        #                                bigsea_username=self.bigsea_username,
        #                                bigsea_password=self.bigsea_password)

        compute_nodes = []
        compute_nodes_key = "key"
        self.instance_locator = InstanceLocator(SSHUtils({}), compute_nodes,
                                                compute_nodes_key)
        self.remote_kvm = RemoteKVM(SSHUtils({}), compute_nodes_key)
        self.actuator = KVMActuator(
            self.instance_locator,
            self.remote_kvm,  # self.authorization_data,
            self.io_cap)
    def setUp(self):
        self.application_id_0 = "app-00"
        self.application_id_1 = "app-01"
        self.application_id_2 = "app-02"
        self.application_id_3 = "app-03"
        self.application_id_4 = "app-04"

        self.timestamp_1 = datetime.datetime.strptime("2000-01-01T00:00:00.0Z",
                                                      '%Y-%m-%dT%H:%M:%S.%fZ')
        self.timestamp_2 = datetime.datetime.strptime("2000-01-01T00:05:00.0Z",
                                                      '%Y-%m-%dT%H:%M:%S.%fZ')
        self.timestamp_3 = datetime.datetime.strptime("2000-01-01T00:10:00.0Z",
                                                      '%Y-%m-%dT%H:%M:%S.%fZ')
        self.timestamp_4 = datetime.datetime.strptime("2000-01-01T00:15:00.0Z",
                                                      '%Y-%m-%dT%H:%M:%S.%fZ')

        self.instance_name_1 = "instance1"
        self.instance_name_2 = "instance2"

        self.bigsea_username = "******"
        self.bigsea_password = "******"
        self.authorization_url = "authorization_url"
        # self.authorization_data = dict(
        #                                authorization_url=self.authorization_url,
        #                                bigsea_username=self.bigsea_username,
        #                                bigsea_password=self.bigsea_password)

        self.trigger_down = 30.0
        self.trigger_up = 10.0
        self.min_cap = 10.0
        self.max_cap = 100.0
        self.actuation_size = 10.0
        self.allocated_resources = 50
        self.metric_round = 2
        self.default_io_cap = 56

        compute_nodes = []
        compute_nodes_key = "key"
        self.instances = [self.instance_name_1, self.instance_name_2]
        self.metric_source = MetricSourceBuilder().get_metric_source("nop", {})
        self.instance_locator = InstanceLocator(SSHUtils({}), compute_nodes,
                                                compute_nodes_key)
        self.remote_kvm = RemoteKVM(SSHUtils({}), compute_nodes_key)
        self.actuator = KVMActuator(
            self.instance_locator,
            self.remote_kvm,
            # self.authorization_data,
            self.default_io_cap)

        self.alarm = BasicAlarm(self.actuator, self.metric_source,
                                self.trigger_down, self.trigger_up,
                                self.min_cap, self.max_cap,
                                self.actuation_size, self.metric_round)

        self.timestamps = [
            self.timestamp_1, self.timestamp_2, self.timestamp_3,
            self.timestamp_4
        ]
Esempio n. 3
0
    def get_actuator(self, name, parameters={}):
        if name == "kvm":
            keypair = api.compute_nodes_keypair

            iops_reference = api.iops_reference
            bs_reference = api.bs_reference
            default_io_cap = api.default_io_cap
            tunelling = api.tunelling

            compute_nodes = [
                x.strip() for x in api.compute_nodes_str.split(",")
            ]

            if tunelling == "True":
                instance_locator = InstanceLocator(SSHUtils({}), compute_nodes,
                                                   keypair)

                remote_kvm = RemoteKVM(SSHUtils({}), keypair, iops_reference,
                                       bs_reference)

            else:
                ports = [x.strip() for x in api.ports_str.split(",")]

                hosts_ports = dict(zip(compute_nodes, ports))

                instance_locator = InstanceTunnelLocator(
                    SSHUtils(hosts_ports), compute_nodes, keypair)

                remote_kvm = RemoteKVMTunnel(SSHUtils(hosts_ports), keypair,
                                             iops_reference, bs_reference)

            return KVMActuator(instance_locator, remote_kvm, default_io_cap)

        elif name == "kvm_io":
            keypair = api.compute_nodes_keypair

            iops_reference = api.iops_reference
            bs_reference = api.bs_reference
            default_io_cap = api.default_io_cap
            tunelling = api.tunelling

            compute_nodes = [
                x.strip() for x in api.compute_nodes_str.split(",")
            ]

            if tunelling == "False":
                instance_locator = InstanceLocator(SSHUtils({}), compute_nodes,
                                                   keypair)

                remote_kvm = RemoteKVM(SSHUtils({}), keypair, iops_reference,
                                       bs_reference)

            else:
                ports = [x.strip() for x in api.ports_str.split(",")]

                hosts_ports = dict(zip(compute_nodes, ports))

                instance_locator = InstanceTunnelLocator(
                    SSHUtils(hosts_ports), compute_nodes, keypair)

                remote_kvm = RemoteKVMTunnel(SSHUtils(hosts_ports), keypair,
                                             iops_reference, bs_reference)

            return KVMIOActuator(instance_locator, remote_kvm)

        elif name == "kvm_upv":
            iops_reference = api.iops_reference
            bs_reference = api.bs_reference

            return KVMUPVActuator(iops_reference, bs_reference)

        elif name == "k8s_replicas":
            try:
                actuator = K8sActuator(parameters['app_id'], api.k8s_manifest)
            except Exception as e:
                raise e

            return actuator

        elif name == "service":
            actuator_port = api.actuator_port
            compute_nodes = [
                x.strip() for x in api.compute_nodes_str.split(",")
            ]

            instance_locator = ServiceInstanceLocator(compute_nodes,
                                                      actuator_port)

            return ServiceActuator(actuator_port, instance_locator)

        elif name == "external_api":
            actuator_metric = api.actuator_metric
            try:
                actuator = ExternalApi(parameters['app_id'], actuator_metric,
                                       api.k8s_manifest)
            except Exception as e:
                raise e

            return actuator

        elif name == "nop":
            return NopActuator()

        else:
            # FIXME: review this exception type
            raise Exception("Unknown actuator type")
    def setUp(self):
        self.application_id_0 = "app-00"
        self.application_id_1 = "app-01"
        self.application_id_2 = "app-02"

        self.timestamp_1 = datetime.datetime.strptime("2000-01-01T00:00:00.0Z",
                                                      '%Y-%m-%dT%H:%M:%S.%fZ')
        self.timestamp_2 = datetime.datetime.strptime("2000-01-01T00:05:00.0Z",
                                                      '%Y-%m-%dT%H:%M:%S.%fZ')
        self.timestamp_3 = datetime.datetime.strptime("2000-01-01T00:10:00.0Z",
                                                      '%Y-%m-%dT%H:%M:%S.%fZ')
        self.timestamp_4 = datetime.datetime.strptime("2000-01-01T00:15:00.0Z",
                                                      '%Y-%m-%dT%H:%M:%S.%fZ')

        self.instance_name_1 = "instance1"
        self.instance_name_2 = "instance2"
        self.instances = [self.instance_name_1, self.instance_name_2]

        self.trigger_down = 30.0
        self.trigger_up = 10.0
        self.min_cap = 10.0
        self.max_cap = 100.0
        self.actuation_size = 10.0
        self.allocated_resources = 50
        self.metric_round = 2
        self.default_io_cap = 78

        self.bigsea_username = "******"
        self.bigsea_password = "******"
        # self.authorization_url = "authorization_url"
        # self.authorization_data = dict(
        #                                authorization_url=self.authorization_url,
        #                                bigsea_username=self.bigsea_username,
        #                                bigsea_password=self.bigsea_password)

        compute_nodes = []
        compute_nodes_key = "key"
        self.instances = [self.instance_name_1, self.instance_name_2]
        self.metric_source = MetricSourceBuilder().get_metric_source("nop", {})
        self.instance_locator = InstanceLocator(SSHUtils({}), compute_nodes,
                                                compute_nodes_key)
        self.remote_kvm = RemoteKVM(SSHUtils({}), compute_nodes_key)
        self.actuator = KVMActuator(
            self.instance_locator,
            self.remote_kvm,
            # self.authorization_data,
            self.default_io_cap)

        self.proportional_factor = 1
        self.factor_up = 1
        self.factor_down = 0.5
        self.heuristic_options_error_proportional = {
            "heuristic_name": "error_proportional",
            "proportional_factor": self.proportional_factor
        }
        self.heuristic_options_error_proportional_up_down = \
            {"heuristic_name": "error_proportional_up_down",
             "factor_up": self.factor_up,
             "factor_down": self.factor_down}

        self.progress_error = {
            self.application_id_0: -20.0,
            self.application_id_1: 0.00,
            self.application_id_2: 30.0
        }

        self.timestamps = [
            self.timestamp_1, self.timestamp_2, self.timestamp_3,
            self.timestamp_4
        ]
    def get_actuator(self, name):
        if name == "kvm":
            keypair = api.compute_nodes_keypair

            iops_reference = api.iops_reference
            bs_reference = api.bs_reference
            default_io_cap = api.default_io_cap
            tunelling = api.tunelling

            compute_nodes = [x.strip()
                             for x in api.compute_nodes_str.split(",")]

            if tunelling == "True": 
                instance_locator = InstanceLocator(SSHUtils({}),
                                                   compute_nodes,
                                                   keypair)

                remote_kvm = RemoteKVM(SSHUtils({}),
                                       keypair,
                                       iops_reference,
                                       bs_reference)

            else:
                ports = [x.strip() for x in api.ports_str.split(",")]

                hosts_ports = dict(zip(compute_nodes, ports))

                instance_locator = InstanceTunnelLocator(
                                       SSHUtils(hosts_ports),
                                       compute_nodes,
                                       keypair)

                remote_kvm = RemoteKVMTunnel(SSHUtils(hosts_ports),
                                             keypair,
                                             iops_reference,
                                             bs_reference)

            return KVMActuator(instance_locator, remote_kvm,
                               authorization_data, default_io_cap)

        elif name == "kvm_io":
            keypair = api.compute_nodes_keypair

            iops_reference = api.iops_reference
            bs_reference = api.bs_reference
            default_io_cap = api.default_io_cap
            tunelling = api.tunelling

            compute_nodes = [x.strip()
                             for x in api.compute_nodes_str.split(",")]

            if tunelling == "False":
                instance_locator = InstanceLocator(SSHUtils({}),
                                                   compute_nodes,
                                                   keypair)
     
                remote_kvm = RemoteKVM(SSHUtils({}),
                                       keypair,
                                       iops_reference,
                                       bs_reference)

            else:
                ports = [x.strip() for x in api.ports_str.split(",")]

                hosts_ports = dict(zip(compute_nodes, ports))

                instance_locator = InstanceTunnelLocator(
                                       SSHUtils(hosts_ports),
                                       compute_nodes,
                                       keypair)

                remote_kvm = RemoteKVMTunnel(SSHUtils(hosts_ports),
                                             keypair,
                                             iops_reference,
                                             bs_reference)

            return KVMIOActuator(instance_locator, remote_kvm)

        elif name == "kvm_upv":
            iops_reference = api.iops_reference
            bs_reference = api.bs_reference

            return KVMUPVActuator(iops_reference, bs_reference)

        elif name == "service":
            actuator_port = api.actuator_port
            compute_nodes = [x.strip()
                             for x in api.compute_nodes_str.split(",")]

            instance_locator = ServiceInstanceLocator(compute_nodes,
                                                      actuator_port)

            return ServiceActuator(actuator_port, instance_locator)

        elif name == "nop":
            return NopActuator()

        else:
            # FIXME: review this exception type
            raise Exception("Unknown actuator type")
class TestBasicActuator(unittest.TestCase):
    def setUp(self):
        self.vm_id1 = "vm_id1"
        self.vm_id2 = "vm_id2"

        self.host_ip1 = "host_ip1"
        self.host_ip2 = "host_ip2"

        self.cap1 = 50
        self.cap2 = 78
        self.io_cap = 75

        self.bigsea_username = "******"
        self.bigsea_password = "******"
        self.authorization_url = "authorization_url"
        # self.authorization_data = dict(authorization_url=self.authorization_url,
        #                                bigsea_username=self.bigsea_username,
        #                                bigsea_password=self.bigsea_password)

        compute_nodes = []
        compute_nodes_key = "key"
        self.instance_locator = InstanceLocator(SSHUtils({}), compute_nodes,
                                                compute_nodes_key)
        self.remote_kvm = RemoteKVM(SSHUtils({}), compute_nodes_key)
        self.actuator = KVMActuator(
            self.instance_locator,
            self.remote_kvm,  # self.authorization_data,
            self.io_cap)

    def locator(self, vm_id):
        return {self.vm_id1: self.host_ip1, self.vm_id2: self.host_ip2}[vm_id]

    def locator_instance_does_not_exist(self, vm_id):
        if vm_id == self.vm_id1:
            return self.host_ip1
        else:
            raise InstanceNotFoundException(vm_id)

    @unittest.skip("Authorization isn't working")
    def test_authorization(self):
        self.actuator.authorizer.get_authorization = MagicMock(
            return_value={'success': True})

        # Actuator tries to authenticate
        self.actuator.authorizer.get_authorization.assert_called_once_with(
            self.authorization_url, self.bigsea_username, self.bigsea_password)

    def test_adjust_resources_locates_and_acts_correctly_1_instance(self):
        vm_data = {self.vm_id1: self.cap1}

        self.instance_locator.locate = MagicMock(return_value=self.host_ip1)
        self.remote_kvm.change_vcpu_quota = MagicMock(return_value=None)
        self.remote_kvm.change_io_quota = MagicMock(return_value=None)

        self.actuator.adjust_resources(vm_data)

        # Actuator tries to locate the instances
        self.instance_locator.locate.assert_called_once_with(self.vm_id1)

        # Actuator tries to change the cap
        self.remote_kvm.change_vcpu_quota.assert_called_once_with(
            self.host_ip1, self.vm_id1, self.cap1)
        self.remote_kvm.change_io_quota.assert_called_once_with(
            self.host_ip1, self.vm_id1, self.io_cap)

    def test_adjust_resources_locates_and_acts_correctly_n_instances(self):
        vm_data = {self.vm_id1: self.cap1, self.vm_id2: self.cap2}

        self.instance_locator.locate = MagicMock()
        self.instance_locator.locate.side_effect = self.locator
        self.remote_kvm.change_vcpu_quota = MagicMock(return_value=None)
        self.remote_kvm.change_io_quota = MagicMock(return_value=None)

        self.actuator.adjust_resources(vm_data)

        # Actuator tries to locate the instances
        self.instance_locator.locate.assert_any_call(self.vm_id1)
        self.instance_locator.locate.assert_any_call(self.vm_id2)

        # Actuator tries to locate only the given instances
        self.assertEqual(self.instance_locator.locate.call_count, 2)

        # Actuator tries to change the cap
        self.remote_kvm.change_vcpu_quota.assert_any_call(
            self.host_ip1, self.vm_id1, self.cap1)
        self.remote_kvm.change_io_quota.assert_any_call(
            self.host_ip1, self.vm_id1, self.io_cap)

        self.remote_kvm.change_vcpu_quota.assert_any_call(
            self.host_ip2, self.vm_id2, self.cap2)
        self.remote_kvm.change_io_quota.assert_any_call(
            self.host_ip2, self.vm_id2, self.io_cap)

        # Actuator tries to change the cap of only the given instances
        self.assertEqual(self.remote_kvm.change_vcpu_quota.call_count, 2)

    def test_adjust_resources_one_instance_does_not_exist(self):
        vm_data = {self.vm_id1: self.cap1, self.vm_id2: self.cap2}

        self.instance_locator.locate = MagicMock()
        self.instance_locator.locate.side_effect = self.locator_instance_does_not_exist

        self.remote_kvm.change_vcpu_quota = MagicMock(return_value=None)
        self.remote_kvm.change_io_quota = MagicMock(return_value=None)

        self.actuator.adjust_resources(vm_data)

        # Actuator tries to locate the instances
        self.instance_locator.locate.assert_any_call(self.vm_id1)
        self.instance_locator.locate.assert_any_call(self.vm_id2)

        # Actuator tries to change the cap
        self.remote_kvm.change_vcpu_quota.assert_called_once_with(
            self.host_ip1, self.vm_id1, self.cap1)
        self.remote_kvm.change_io_quota.assert_called_once_with(
            self.host_ip1, self.vm_id1, self.io_cap)

    def test_get_allocated_resources(self):
        self.instance_locator.locate = MagicMock()
        self.instance_locator.locate.side_effect = self.locator
        self.remote_kvm.get_allocated_resources = MagicMock(return_value=50)

        cap = self.actuator.get_allocated_resources(self.vm_id1)

        # Actuator returns the correct cap value
        self.assertEquals(cap, 50)

        # Actuator tries to locate the instance
        self.instance_locator.locate.assert_called_once_with(self.vm_id1)

        # Actuator tries to get the resources allocated to the given instance
        self.remote_kvm.get_allocated_resources.assert_called_once_with(
            self.host_ip1, self.vm_id1)

    def test_get_allocated_resources_to_cluster(self):
        vms_ids = [self.vm_id1, self.vm_id2]

        self.instance_locator.locate = MagicMock()
        self.instance_locator.locate.side_effect = self.locator
        self.remote_kvm.get_allocated_resources = MagicMock(return_value=50)

        self.actuator.get_allocated_resources_to_cluster(vms_ids)

        # Actuator tries to locate the first instance
        self.instance_locator.locate.assert_called_once_with(self.vm_id1)

        # Actuator tries to get the resources allocated to the given instance
        self.remote_kvm.get_allocated_resources.assert_called_once_with(
            self.host_ip1, self.vm_id1)

    def test_get_allocated_resources_to_cluster_instance_does_not_exist(self):
        vms_ids = [self.vm_id2, self.vm_id1]

        self.instance_locator.locate = MagicMock()
        self.instance_locator.locate.side_effect = self.locator_instance_does_not_exist
        self.remote_kvm.get_allocated_resources = MagicMock(return_value=50)

        self.actuator.get_allocated_resources_to_cluster(vms_ids)

        # Actuator tries to locate the first instance
        self.instance_locator.locate.assert_any_call(self.vm_id1)
        self.instance_locator.locate.assert_any_call(self.vm_id2)

        # Actuator tries to get the resources allocated to the given instance
        self.remote_kvm.get_allocated_resources.assert_called_once_with(
            self.host_ip1, self.vm_id1)

    @unittest.skip("Authorization isn't working")
    def test_adjust_resources_raises_exception_if_not_authorized(self):
        vm_data = {self.vm_id1: self.cap1, self.vm_id2: self.cap2}

        self.instance_locator.locate = MagicMock()
        self.instance_locator.locate.side_effect = self.locator_instance_does_not_exist

        self.remote_kvm.change_vcpu_quota = MagicMock(return_value=None)
        self.actuator.authorizer.get_authorization = MagicMock(
            return_value={'success': False})

        self.assertRaises(AuthorizationFailedException,
                          self.actuator.adjust_resources, vm_data)

    @unittest.skip("Authorization isn't working")
    def test_get_allocated_resources_raises_exception_if_not_authorized(self):
        vms_ids = [self.vm_id2, self.vm_id1]

        self.instance_locator.locate = MagicMock()
        self.instance_locator.locate.side_effect = self.locator_instance_does_not_exist
        self.remote_kvm.get_allocated_resources = MagicMock(return_value=50)
        self.actuator.authorizer.get_authorization = MagicMock(
            return_value={'success': False})

        self.assertRaises(AuthorizationFailedException,
                          self.actuator.get_allocated_resources_to_cluster,
                          vms_ids)
    def setUp(self):
        self.application_id_0 = "app-00"
        self.application_id_1 = "app-01"
        self.application_id_2 = "app-02"
        self.application_id_3 = "app-03"
        self.application_id_4 = "app-04"
        self.application_id_5 = "app-05"
        self.application_id_6 = "app-06"
        self.application_id_7 = "app-07"
        self.application_id_8 = "app-08"
        self.application_id_9 = "app-09"

        self.timestamp_1 = datetime.datetime.strptime("2000-01-01T00:00:00.0Z",
                                                      "%Y-%m-%dT%H:%M:%S.%fZ")
        self.timestamp_2 = datetime.datetime.strptime("2000-01-01T00:05:00.0Z",
                                                      "%Y-%m-%dT%H:%M:%S.%fZ")
        self.timestamp_3 = datetime.datetime.strptime("2000-01-01T00:10:00.0Z",
                                                      "%Y-%m-%dT%H:%M:%S.%fZ")
        self.timestamp_4 = datetime.datetime.strptime("2000-01-01T00:15:00.0Z",
                                                      "%Y-%m-%dT%H:%M:%S.%fZ")

        self.timestamps = [
            self.timestamp_1, self.timestamp_2, self.timestamp_3,
            self.timestamp_4
        ]

        self.instance_name_1 = "instance1"
        self.instance_name_2 = "instance2"
        self.instances = [self.instance_name_1, self.instance_name_2]

        self.trigger_down = 0.0
        self.trigger_up = 0.0
        self.min_cap = 10.0
        self.max_cap = 100.0
        self.actuation_size = 10.0
        self.allocated_resources_scale_down = 100
        self.allocated_resources_scale_up = 10
        self.metric_round = 2
        self.default_io_cap = 34

        self.bigsea_username = "******"
        self.bigsea_password = "******"
        # self.authorization_url = "authorization_url"
        # self.authorization_data = dict(
        #                                authorization_url=self.authorization_url,
        #                                bigsea_username=self.bigsea_username,
        #                                bigsea_password=self.bigsea_password)

        compute_nodes = []
        compute_nodes_key = "key"
        self.instances = [self.instance_name_1, self.instance_name_2]
        self.metric_source = MetricSourceBuilder().get_metric_source("nop", {})
        self.instance_locator = InstanceLocator(SSHUtils({}), compute_nodes,
                                                compute_nodes_key)
        self.remote_kvm = RemoteKVM(SSHUtils({}), compute_nodes_key)
        self.actuator = KVMActuator(
            self.instance_locator,
            self.remote_kvm,
            # self.authorization_data,
            self.default_io_cap)

        self.proportional_factor = 1.5
        self.derivative_factor = 0.5
        self.integrative_factor = 1.5

        self.heuristic_options = {
            "heuristic_name": "error_pid",
            "proportional_factor": self.proportional_factor,
            "derivative_factor": self.derivative_factor,
            "integrative_factor": self.integrative_factor
        }

        self.progress_error = {
            # CASE 1
            self.application_id_0: {
                self.timestamp_1: -30.0,
                self.timestamp_2: -20.0,
                self.timestamp_3: -15.0
            },

            # CASE 2
            self.application_id_1: {
                self.timestamp_1: -30.0,
                self.timestamp_2: -40.0,
                self.timestamp_3: -60.0
            },

            # CASE 3
            self.application_id_2: {
                self.timestamp_1: 30.0,
                self.timestamp_2: 20.0,
                self.timestamp_3: 15.0
            },

            # CASE 4
            self.application_id_3: {
                self.timestamp_1: 30.0,
                self.timestamp_2: 40.0,
                self.timestamp_3: 55.0
            },

            # CASE 5
            self.application_id_4: {
                self.timestamp_1: 100.0,
                self.timestamp_2: 100.0,
                self.timestamp_3: 100.0
            },

            # CASE 6
            self.application_id_5: {
                self.timestamp_1: -100.0,
                self.timestamp_2: -100.0,
                self.timestamp_3: -100.0
            },

            # CASE 7
            self.application_id_6: {
                self.timestamp_1: -30.0,
                self.timestamp_2: 10.0,
                self.timestamp_3: 30.0
            },

            # CASE 8
            self.application_id_7: {
                self.timestamp_1: -5.0,
                self.timestamp_2: -1.0,
                self.timestamp_3: 2.0
            },

            # CASE 9
            self.application_id_8: {
                self.timestamp_1: -10.0,
                self.timestamp_2: -5.0,
                self.timestamp_3: 20.0,
                self.timestamp_4: -5.0
            },

            # CASE 10
            self.application_id_9: {
                self.timestamp_1: -10.0,
                self.timestamp_2: 0.0,
                self.timestamp_3: 10.0,
                self.timestamp_4: 5.0
            }
        }