Ejemplo n.º 1
0
 def test_calculate_period_end(self):
     period = TimePeriod(1000)
     start_time = self._get_time1()
     period.start_period(start_time)
     period_end = period.calculate_period_end()
     expected_end_time = start_time + timedelta(seconds=1000)
     assert period_end == expected_end_time
Ejemplo n.º 2
0
 def test_calculate_period_end(self):
     period = TimePeriod(1000)
     start_time = self._get_time1()
     period.start_period(start_time)
     period_end = period.calculate_period_end()
     expected_end_time = start_time + timedelta(seconds=1000)
     assert period_end == expected_end_time
Ejemplo n.º 3
0
    def test_reset(self):
        period = TimePeriod(50, time_provider=self._get_time1)
        period.start_period(self._get_time1())
        period.reset()

        assert period.period_start_time is None
        assert period.period_started is False
Ejemplo n.º 4
0
    def test_start_period(self):
        start_time = self._get_time1()
        period = TimePeriod(30, time_provider=TestTimePeriod._get_time1)
        period.start_period()

        assert period.period_start_time == start_time
        assert period.period_started is True
        assert period.period_length_in_seconds == 30
Ejemplo n.º 5
0
    def test_start_period(self):
        start_time = self._get_time1()
        period = TimePeriod(30, time_provider=TestTimePeriod._get_time1)
        period.start_period()

        assert period.period_start_time == start_time
        assert period.period_started is True
        assert period.period_length_in_seconds == 30
Ejemplo n.º 6
0
    def test_start_period_with_start_time(self):
        start_time = self._get_time1()
        period = TimePeriod(90)
        period.start_period(start_time)

        assert period.period_start_time == start_time
        assert period.period_started is True
        assert period.period_length_in_seconds == 90
Ejemplo n.º 7
0
    def test_start_period_with_start_time(self):
        start_time = self._get_time1()
        period = TimePeriod(90)
        period.start_period(start_time)

        assert period.period_start_time == start_time
        assert period.period_started is True
        assert period.period_length_in_seconds == 90
Ejemplo n.º 8
0
 def __init__(self, instance_uuid, policy):
     self._logger = logging.getLogger(__name__)
     self.state = ScalingStateUntriggered()
     threshold_period_in_seconds = policy.get_threshold_period_in_seconds()
     self._logger.debug("threshold period of policy %s is %d", policy,
                        threshold_period_in_seconds)
     self.threshold_period = TimePeriod(threshold_period_in_seconds)
     self._latest_metric_update = None
     self.instance_uuid = instance_uuid
     self.policy = policy
Ejemplo n.º 9
0
    def test_init(self):
        period_length = 464
        period = TimePeriod(period_length)

        assert period.period_started is False
        assert period.period_length_in_seconds == period_length
        assert period.period_start_time is None
Ejemplo n.º 10
0
 def __init__(self, instance_uuid, policy):
     self._logger = logging.getLogger(__name__)
     self.state = ScalingStateUntriggered()
     threshold_period_in_seconds = policy.get_threshold_period_in_seconds()
     self._logger.debug("threshold period of policy %s is %d", policy, threshold_period_in_seconds)
     self.threshold_period = TimePeriod(threshold_period_in_seconds)
     self._latest_metric_update = None
     self.instance_uuid = instance_uuid
     self.policy = policy
Ejemplo n.º 11
0
    def test_reset(self):
        period = TimePeriod(50, time_provider=self._get_time1)
        period.start_period(self._get_time1())
        period.reset()

        assert period.period_start_time is None
        assert period.period_started is False
Ejemplo n.º 12
0
 def __init__(self, scaling_policy_configuration, service,
              scaling_policy_type):
     self._logger = logging.getLogger(__name__)
     self._policy_instances = {}
     self.state = ScalingStateUntriggered()
     self._policy_config = scaling_policy_configuration
     self.service_type = self._policy_config.service_type
     self.policy_name = scaling_policy_configuration.name
     cooldown_period_in_seconds = self._calculate_period_in_seconds(
         scaling_policy_configuration.cooldown_period,
         scaling_policy_configuration.cooldown_period_unit)
     self._logger.debug("cooldown period of policy %s is %d",
                        self.policy_name, cooldown_period_in_seconds)
     self.cooldown_period = TimePeriod(cooldown_period_in_seconds)
     self.service = service
     self._last_in_period_uuid_of_service_type = {}
     self._scaling_policy_type = scaling_policy_type
Ejemplo n.º 13
0
    def test_is_in_period_with_specific_time(self):
        start_time = self._get_time2()
        period_length = timedelta(seconds=30)
        period = TimePeriod(period_length.seconds,
                            time_provider=self._get_time2)
        period.start_period()

        in_period_time_1 = start_time + timedelta(seconds=30)
        in_period_time_2 = start_time + timedelta(seconds=29)
        in_period_time_3 = start_time + timedelta(seconds=1)
        in_period_time_4 = start_time
        out_period_time_1 = start_time + timedelta(seconds=31)
        out_period_time_2 = start_time + timedelta(seconds=30, microseconds=1)

        assert period.is_in_period(time=in_period_time_1) is True
        assert period.is_in_period(time=in_period_time_2) is True
        assert period.is_in_period(time=in_period_time_3) is True
        assert period.is_in_period(time=in_period_time_4) is True
        assert period.is_in_period(time=out_period_time_1) is False
        assert period.is_in_period(time=out_period_time_2) is False
Ejemplo n.º 14
0
    def test_is_in_period_with_specific_time(self):
        start_time = self._get_time2()
        period_length = timedelta(seconds=30)
        period = TimePeriod(period_length.seconds, time_provider=self._get_time2)
        period.start_period()

        in_period_time_1 = start_time + timedelta(seconds=30)
        in_period_time_2 = start_time + timedelta(seconds=29)
        in_period_time_3 = start_time + timedelta(seconds=1)
        in_period_time_4 = start_time
        out_period_time_1 = start_time + timedelta(seconds=31)
        out_period_time_2 = start_time + timedelta(seconds=30, microseconds=1)

        assert period.is_in_period(time=in_period_time_1) is True
        assert period.is_in_period(time=in_period_time_2) is True
        assert period.is_in_period(time=in_period_time_3) is True
        assert period.is_in_period(time=in_period_time_4) is True
        assert period.is_in_period(time=out_period_time_1) is False
        assert period.is_in_period(time=out_period_time_2) is False
Ejemplo n.º 15
0
    def test_is_in_period_now(self):
        start_time = self._get_time1()
        period_length = timedelta(seconds=30)

        in_period_time_1 = start_time + timedelta(seconds=30)
        in_period_time_2 = start_time + timedelta(seconds=29)
        in_period_time_3 = start_time + timedelta(seconds=1)
        in_period_time_4 = start_time
        out_period_time_1 = start_time + timedelta(seconds=31)
        out_period_time_2 = start_time + timedelta(seconds=30, microseconds=1)

        period = TimePeriod(period_length.seconds,
                            time_provider=lambda: in_period_time_1)
        period.start_period(start_time)
        assert period.is_in_period() is True

        period = TimePeriod(period_length.seconds,
                            time_provider=lambda: in_period_time_2)
        period.start_period(start_time)
        assert period.is_in_period() is True

        period = TimePeriod(period_length.seconds,
                            time_provider=lambda: in_period_time_3)
        period.start_period(start_time)
        assert period.is_in_period() is True

        period = TimePeriod(period_length.seconds,
                            time_provider=lambda: in_period_time_4)
        period.start_period(start_time)
        assert period.is_in_period() is True

        period = TimePeriod(period_length.seconds,
                            time_provider=lambda: out_period_time_1)
        period.start_period(start_time)
        assert period.is_in_period() is False

        period = TimePeriod(period_length.seconds,
                            time_provider=lambda: out_period_time_2)
        period.start_period(start_time)
        assert period.is_in_period() is False
Ejemplo n.º 16
0
class ScalingPolicyInstance:

    _latest_metric_update = None

    state = None
    policy = None
    instance_uuid = None
    threshold_period = None

    def __init__(self, instance_uuid, policy):
        self._logger = logging.getLogger(__name__)
        self.state = ScalingStateUntriggered()
        threshold_period_in_seconds = policy.get_threshold_period_in_seconds()
        self._logger.debug("threshold period of policy %s is %d", policy, threshold_period_in_seconds)
        self.threshold_period = TimePeriod(threshold_period_in_seconds)
        self._latest_metric_update = None
        self.instance_uuid = instance_uuid
        self.policy = policy

    def update_policy_state_and_get_scaling_actions(self, metrics_message):
        scaling_actions = []

        for metric_value in metrics_message.metric_values:
            value = metric_value.value
            timestamp = dateutil.parser.parse(metric_value.timestamp)

            if not self._is_new_metric(timestamp):
                self._logger.debug("metric value %s is outdated for instance %s", repr(metric_value), self.instance_uuid)
                continue

            if self.policy.cooldown_period.is_in_period(timestamp):
                self._logger.debug("metric value %s ignored because of cooldown is active", repr(metric_value))
                continue

            predicate_satisfied = self.policy.value_exceeds_or_undercuts_threshold(float(value))
            self._logger.debug("metric value %s is %s under/over threshold",
                               repr(metric_value),
                               "" if predicate_satisfied else "not"
                               )

            cooldown_start_time = timestamp
            if self.threshold_period.period_started:
                cooldown_start_time = self.threshold_period.calculate_period_end()

            action_required = self.state.update_and_report_if_action_required(
                self,
                predicate_satisfied,
                timestamp,
                metrics_message.uuid
            )

            if action_required:
                scaling_action = self.policy.create_scaling_action(metrics_message.metric_name, self.instance_uuid)
                self.policy.cooldown_period.start_period(cooldown_start_time)
                scaling_actions.append(scaling_action)
                self._logger.info("Triggered scaling action %s, beginning cooldown", repr(scaling_action))

        return scaling_actions

    def _is_new_metric(self, timestamp):
        if self._latest_metric_update is None:
            self._latest_metric_update = timestamp
            return True

        new_metric = timestamp > self._latest_metric_update
        if new_metric:
            self._latest_metric_update = timestamp
        return new_metric

    def __repr__(self):
        return "ScalingPolicyInstance(instance_uuid={},state={},threshold_period={},policy={})".format(
            self.instance_uuid,
            repr(self.state),
            repr(self.threshold_period),
            self.policy.policy_name
        )
Ejemplo n.º 17
0
 def test_calculate_period_end_with_unstarted_period(self):
     with pytest.raises(ValueError):
         period = TimePeriod(1000)
         period_end = period.calculate_period_end()
         assert period_end is None
Ejemplo n.º 18
0
 def test_calculate_period_end_with_unstarted_period(self):
     with pytest.raises(ValueError):
         period = TimePeriod(1000)
         period_end = period.calculate_period_end()
         assert period_end is None
Ejemplo n.º 19
0
class ScalingPolicyInstance:

    _latest_metric_update = None

    state = None
    policy = None
    instance_uuid = None
    threshold_period = None

    def __init__(self, instance_uuid, policy):
        self._logger = logging.getLogger(__name__)
        self.state = ScalingStateUntriggered()
        threshold_period_in_seconds = policy.get_threshold_period_in_seconds()
        self._logger.debug("threshold period of policy %s is %d", policy,
                           threshold_period_in_seconds)
        self.threshold_period = TimePeriod(threshold_period_in_seconds)
        self._latest_metric_update = None
        self.instance_uuid = instance_uuid
        self.policy = policy

    def update_policy_state_and_get_scaling_actions(self, metrics_message):
        scaling_actions = []

        for metric_value in metrics_message.metric_values:
            value = metric_value.value
            timestamp = dateutil.parser.parse(metric_value.timestamp)

            if not self._is_new_metric(timestamp):
                self._logger.debug(
                    "metric value %s is outdated for instance %s",
                    repr(metric_value), self.instance_uuid)
                continue

            if self.policy.cooldown_period.is_in_period(timestamp):
                self._logger.debug(
                    "metric value %s ignored because of cooldown is active",
                    repr(metric_value))
                continue

            predicate_satisfied = self.policy.value_exceeds_or_undercuts_threshold(
                float(value))
            self._logger.debug("metric value %s is %s under/over threshold",
                               repr(metric_value),
                               "" if predicate_satisfied else "not")

            cooldown_start_time = timestamp
            if self.threshold_period.period_started:
                cooldown_start_time = self.threshold_period.calculate_period_end(
                )

            action_required = self.state.update_and_report_if_action_required(
                self, predicate_satisfied, timestamp, metrics_message.uuid)

            if action_required:
                scaling_action = self.policy.create_scaling_action(
                    metrics_message.metric_name, self.instance_uuid)
                self.policy.cooldown_period.start_period(cooldown_start_time)
                scaling_actions.append(scaling_action)
                self._logger.info(
                    "Triggered scaling action %s, beginning cooldown",
                    repr(scaling_action))

        return scaling_actions

    def _is_new_metric(self, timestamp):
        if self._latest_metric_update is None:
            self._latest_metric_update = timestamp
            return True

        new_metric = timestamp > self._latest_metric_update
        if new_metric:
            self._latest_metric_update = timestamp
        return new_metric

    def __repr__(self):
        return "ScalingPolicyInstance(instance_uuid={},state={},threshold_period={},policy={})".format(
            self.instance_uuid, repr(self.state), repr(self.threshold_period),
            self.policy.policy_name)
Ejemplo n.º 20
0
    def test_is_in_period_now(self):
        start_time = self._get_time1()
        period_length = timedelta(seconds=30)

        in_period_time_1 = start_time + timedelta(seconds=30)
        in_period_time_2 = start_time + timedelta(seconds=29)
        in_period_time_3 = start_time + timedelta(seconds=1)
        in_period_time_4 = start_time
        out_period_time_1 = start_time + timedelta(seconds=31)
        out_period_time_2 = start_time + timedelta(seconds=30, microseconds=1)

        period = TimePeriod(period_length.seconds, time_provider=lambda: in_period_time_1)
        period.start_period(start_time)
        assert period.is_in_period() is True

        period = TimePeriod(period_length.seconds, time_provider=lambda: in_period_time_2)
        period.start_period(start_time)
        assert period.is_in_period() is True

        period = TimePeriod(period_length.seconds, time_provider=lambda: in_period_time_3)
        period.start_period(start_time)
        assert period.is_in_period() is True

        period = TimePeriod(period_length.seconds, time_provider=lambda: in_period_time_4)
        period.start_period(start_time)
        assert period.is_in_period() is True

        period = TimePeriod(period_length.seconds, time_provider=lambda: out_period_time_1)
        period.start_period(start_time)
        assert period.is_in_period() is False

        period = TimePeriod(period_length.seconds, time_provider=lambda: out_period_time_2)
        period.start_period(start_time)
        assert period.is_in_period() is False