def test_alarm_does_nothing(self): proportional_factor = 1 heuristic_options = {"heuristic_name": "error_proportional", "proportional_factor": proportional_factor} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_1, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_1}) # The method doesn't try to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_not_called() # The method doesn't try to adjust the amount of resources self.actuator.adjust_resources.assert_not_called()
def test_alarm_does_not_reuse_metrics_with_same_timestamp(self): proportional_factor = 1 heuristic_options = {"heuristic_name": "error_proportional", "proportional_factor": proportional_factor} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_0, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Add resources error = self.metrics(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0})[1] new_cap = self.allocated_resources + proportional_factor * abs(error) # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) # # 2nd call. The method checks if the metric is new and does not act # # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0}) # The method doesn't try to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_not_called() # The method doesn't try to adjust the amount of resources self.actuator.adjust_resources.assert_not_called()
def test_alarm_gets_metrics_and_scales_up_error_proportional_up_down(self): # # Case 1: normal scale up # heuristic_options = {"heuristic_name": "error_proportional_up_down", "factor_up": self.factor_up, "factor_down": self.factor_down} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_0, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Add resources error = self.metrics(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0})[1] new_cap = self.allocated_resources + self.factor_up * abs(error) # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) # # Case 2: calculated cap is too high. Use max cap instead # factor_up = 5 heuristic_options = {"heuristic_name": "error_proportional_up_down", "factor_up": factor_up, "factor_down": self.factor_down} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_0, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Add resources new_cap = self.max_cap # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap})
class Test_Proportional_Alarm(unittest.TestCase): 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 = Metric_Source_Builder().get_metric_source("nop", {}) self.instance_locator = Instance_Locator( SSH_Utils({}), compute_nodes, compute_nodes_key) self.remote_kvm = Remote_KVM(SSH_Utils({}), compute_nodes_key) self.actuator = KVM_Actuator(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] # normal cases # application 0 -> job progress < time progress -> scale up # application 1 -> job progress = time progress -> do nothing # application 2 -> job progress > time progress -> scale down def metrics(self, metric_name, options): application_id = options["application_id"] if metric_name == Proportional_Alarm.ERROR_METRIC_NAME: return self.timestamp_1, self.progress_error[application_id] def metrics_different_timestamps(self, metric_name, options): application_id = options["application_id"] timestamp = self.timestamps.pop(0) if metric_name == Proportional_Alarm.ERROR_METRIC_NAME: return timestamp, self.progress_error[application_id] def test_alarm_gets_metrics_and_scales_down_error_proportional(self): # # Case 1: normal scale down # proportional_factor = 1 heuristic_options = {"heuristic_name": "error_proportional", "proportional_factor": proportional_factor} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_2, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Remove resources error = self.metrics(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2})[1] new_cap = self.allocated_resources - self.proportional_factor * error # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) # # Case 2: calculated cap is too low. Use min cap instead # proportional_factor = 3 heuristic_options = {"heuristic_name": "error_proportional", "proportional_factor": proportional_factor} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_2, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Remove resources new_cap = self.min_cap # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) def test_alarm_gets_metrics_and_scales_up_error_proportional(self): # # Case 1: normal scale up # proportional_factor = 1 heuristic_options = {"heuristic_name": "error_proportional", "proportional_factor": proportional_factor} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_0, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Add resources error = self.metrics(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0})[1] new_cap = self.allocated_resources + proportional_factor * abs(error) # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) # # Case 2: calculated cap is too high. Use max cap instead # proportional_factor = 3 heuristic_options = {"heuristic_name": "error_proportional", "proportional_factor": proportional_factor} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_0, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Add resources new_cap = self.max_cap # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) def test_alarm_does_nothing(self): proportional_factor = 1 heuristic_options = {"heuristic_name": "error_proportional", "proportional_factor": proportional_factor} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_1, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_1}) # The method doesn't try to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_not_called() # The method doesn't try to adjust the amount of resources self.actuator.adjust_resources.assert_not_called() def test_alarm_does_not_reuse_metrics_with_same_timestamp(self): proportional_factor = 1 heuristic_options = {"heuristic_name": "error_proportional", "proportional_factor": proportional_factor} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_0, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Add resources error = self.metrics(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0})[1] new_cap = self.allocated_resources + proportional_factor * abs(error) # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) # # 2nd call. The method checks if the metric is new and does not act # # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0}) # The method doesn't try to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_not_called() # The method doesn't try to adjust the amount of resources self.actuator.adjust_resources.assert_not_called() def test_alarm_metrics_with_different_timestamps(self): proportional_factor = 1 heuristic_options = {"heuristic_name": "error_proportional", "proportional_factor": proportional_factor} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_2, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics_different_timestamps self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Remove resources error = self.metrics(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2})[1] new_cap = self.allocated_resources - self.proportional_factor * error # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) # # 2nd call. The method checks if the metric is new and acts # # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics_different_timestamps self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Remove resources error = self.metrics(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2})[1] new_cap = self.allocated_resources - self.proportional_factor * error # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) def test_alarm_gets_metrics_and_scales_down_error_proportional_up_down(self): # # Case 1: normal scale down # heuristic_options = {"heuristic_name": "error_proportional_up_down", "factor_up": self.factor_up, "factor_down": self.factor_down} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_2, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Remove resources error = self.metrics(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2})[1] new_cap = self.allocated_resources - self.factor_down * error # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) # # Case 2: calculated cap is too low. Use min cap instead # factor_down = 5 heuristic_options = {"heuristic_name": "error_proportional_up_down", "factor_up": self.factor_up, "factor_down": factor_down} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_2, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Remove resources new_cap = self.min_cap # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) def test_alarm_gets_metrics_and_scales_up_error_proportional_up_down(self): # # Case 1: normal scale up # heuristic_options = {"heuristic_name": "error_proportional_up_down", "factor_up": self.factor_up, "factor_down": self.factor_down} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_0, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Add resources error = self.metrics(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0})[1] new_cap = self.allocated_resources + self.factor_up * abs(error) # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) # # Case 2: calculated cap is too high. Use max cap instead # factor_up = 5 heuristic_options = {"heuristic_name": "error_proportional_up_down", "factor_up": factor_up, "factor_down": self.factor_down} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_0, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_0}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Add resources new_cap = self.max_cap # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap})
def test_alarm_gets_metrics_and_scales_down_error_proportional(self): # # Case 1: normal scale down # proportional_factor = 1 heuristic_options = {"heuristic_name": "error_proportional", "proportional_factor": proportional_factor} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_2, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Remove resources error = self.metrics(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2})[1] new_cap = self.allocated_resources - self.proportional_factor * error # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap}) # # Case 2: calculated cap is too low. Use min cap instead # proportional_factor = 3 heuristic_options = {"heuristic_name": "error_proportional", "proportional_factor": proportional_factor} self.alarm = Proportional_Alarm(self.actuator, self.metric_source, self.trigger_down, self.trigger_up, self.min_cap, self.max_cap, self.metric_round, heuristic_options, self.application_id_2, self.instances) # Set up mocks self.metric_source.get_most_recent_value = MagicMock() self.metric_source.get_most_recent_value.side_effect = self.metrics self.actuator.adjust_resources = MagicMock(return_value=None) self.actuator.get_allocated_resources_to_cluster = MagicMock( return_value=self.allocated_resources) self.alarm.check_application_state() # The method tries to get the metrics correctly self.metric_source.get_most_recent_value.\ assert_any_call(Proportional_Alarm.ERROR_METRIC_NAME, {"application_id": self.application_id_2}) # The method tries to get the amount of allocated resources self.actuator.get_allocated_resources_to_cluster.assert_called_once_with( self.instances) # Remove resources new_cap = self.min_cap # The method tries to adjust the amount of resources self.actuator.adjust_resources.assert_called_once_with({self.instance_name_1: new_cap, self.instance_name_2: new_cap})