Fix logging of autoscaling lambda, add test for effective_capacity

This commit is contained in:
Mikhail f. Shiryaev 2024-03-20 17:07:32 +01:00
parent 661161695f
commit aa1a210d5d
No known key found for this signature in database
GPG Key ID: 4B02ED204C7D93F4
2 changed files with 41 additions and 14 deletions

View File

@ -120,13 +120,13 @@ def set_capacity(
# Let's calculate a new desired capacity
# (capacity_deficit + scale_up - 1) // scale_up : will increase min by 1
# if there is any capacity_deficit
desired_capacity = (
new_capacity = (
asg["DesiredCapacity"] + (capacity_deficit + scale_up - 1) // scale_up
)
desired_capacity = max(desired_capacity, asg["MinSize"])
desired_capacity = min(desired_capacity, asg["MaxSize"])
new_capacity = max(new_capacity, asg["MinSize"])
new_capacity = min(new_capacity, asg["MaxSize"])
# Finally, should the capacity be even changed
stop = stop or asg["DesiredCapacity"] == desired_capacity
stop = stop or asg["DesiredCapacity"] == new_capacity
if stop:
logging.info(
"Do not increase ASG %s capacity, current capacity=%s, effective "
@ -144,9 +144,9 @@ def set_capacity(
"The ASG %s capacity will be increased to %s, current capacity=%s, "
"effective capacity=%s, maximum capacity=%s, running jobs=%s, queue size=%s",
asg["AutoScalingGroupName"],
desired_capacity,
effective_capacity,
new_capacity,
asg["DesiredCapacity"],
effective_capacity,
asg["MaxSize"],
running,
queued,
@ -154,16 +154,16 @@ def set_capacity(
if not dry_run:
client.set_desired_capacity(
AutoScalingGroupName=asg["AutoScalingGroupName"],
DesiredCapacity=desired_capacity,
DesiredCapacity=new_capacity,
)
return
# Now we will calculate if we need to scale down
stop = stop or asg["DesiredCapacity"] == asg["MinSize"]
desired_capacity = asg["DesiredCapacity"] - (capacity_reserve // scale_down)
desired_capacity = max(desired_capacity, asg["MinSize"])
desired_capacity = min(desired_capacity, asg["MaxSize"])
stop = stop or asg["DesiredCapacity"] == desired_capacity
new_capacity = asg["DesiredCapacity"] - (capacity_reserve // scale_down)
new_capacity = max(new_capacity, asg["MinSize"])
new_capacity = min(new_capacity, asg["MaxSize"])
stop = stop or asg["DesiredCapacity"] == new_capacity
if stop:
logging.info(
"Do not decrease ASG %s capacity, current capacity=%s, effective "
@ -181,7 +181,7 @@ def set_capacity(
"The ASG %s capacity will be decreased to %s, current capacity=%s, effective "
"capacity=%s, minimum capacity=%s, running jobs=%s, queue size=%s",
asg["AutoScalingGroupName"],
desired_capacity,
new_capacity,
asg["DesiredCapacity"],
effective_capacity,
asg["MinSize"],
@ -191,7 +191,7 @@ def set_capacity(
if not dry_run:
client.set_desired_capacity(
AutoScalingGroupName=asg["AutoScalingGroupName"],
DesiredCapacity=desired_capacity,
DesiredCapacity=new_capacity,
)

View File

@ -35,7 +35,7 @@ class TestSetCapacity(unittest.TestCase):
@property
def expected_capacity(self) -> int:
"""one-time property"""
"""a one-time property"""
capacity, self._expected_capacity = self._expected_capacity, -1
return capacity
@ -117,6 +117,33 @@ class TestSetCapacity(unittest.TestCase):
set_capacity(t.name, t.queues, self.client, False)
self.assertEqual(t.expected_capacity, self.client.expected_capacity, t.name)
def test_effective_capacity(self):
"""Normal cases test increasing w/o considering
effective_capacity much lower than DesiredCapacity"""
test_cases = (
TestCase(
"desired-overwritten",
1,
20, # DesiredCapacity, overwritten by effective_capacity
50,
[
Queue("in_progress", 30, "desired-overwritten"),
Queue("queued", 60, "desired-overwritten"),
],
40,
),
)
for t in test_cases:
self.client.data_helper(t.name, t.min_size, t.desired_capacity, t.max_size)
# we test that effective_capacity is 30 (a half of 60)
data_with_instances = self.client.expected_data
data_with_instances["AutoScalingGroups"][0]["Instances"] = [
{"HealthStatus": "Healthy" if i % 2 else "Unhealthy"} for i in range(60)
]
self.client.expected_data = data_with_instances
set_capacity(t.name, t.queues, self.client, False)
self.assertEqual(t.expected_capacity, self.client.expected_capacity, t.name)
def test_exceptions(self):
test_cases = (
(