def test_build_throughput(): m = Model(builds_per_hour=0.0, build_run_time=10, sec_per_tick=1, initial_builder_count=1, builder_boot_time=0) builds = [Build(m.ticks, m.build_run_time), Build(m.ticks, m.build_run_time)] m.build_queue.extend(builds) m.advance(20) assert (builds[1].started_time - builds[1].queued_time) == m.build_run_time
def test_utilization(): m = Model(build_run_time=100, builder_boot_time=100, builds_per_hour=0.0, sec_per_tick=1, initial_builder_count=2) m.advance(200) m.build_queue.append(Build(m.ticks, m.build_run_time)) m.advance(200) assert m.mean_percent_utilization() == 12.5 assert m.mean_unused_builders() == 1.75
def test_dynamic_builds_per_hour(): m = Model(builds_per_hour=100.0, build_run_time=10, sec_per_tick=3600, initial_builder_count=100, builder_boot_time=0, builds_per_hour_fn=Model.SINE) assert m.current_builds_per_hour() == 0.0 m.advance(12) print 'ticks:', m.ticks print 'per hour:', m.current_builds_per_hour() assert m.current_builds_per_hour() == 100.0 m.advance(12) assert m.current_builds_per_hour() == 0.0
def test_graceful_shutdown(): m = Model(build_run_time=10, builder_boot_time=0, builds_per_hour=0.0, sec_per_tick=1, initial_builder_count=2) assert len(m.builders) == 2 m.build_queue.append(Build(m.ticks, m.build_run_time)) m.advance(5) m.shutdown_builders(2) m.advance(6) assert len(m.builders) == 0 finished = m.finished_builds[0] assert (finished.finished_time - finished.started_time) == m.build_run_time
def test_build_throughput(): m = Model(builds_per_hour=0.0, build_run_time=10, sec_per_tick=1, initial_builder_count=1, builder_boot_time=0) builds = [ Build(m.ticks, m.build_run_time), Build(m.ticks, m.build_run_time) ] m.build_queue.extend(builds) m.advance(20) assert (builds[1].started_time - builds[1].queued_time) == m.build_run_time
def test_scale_up(): m = Model(build_run_time=50, builder_boot_time=100, builds_per_hour=0.0, sec_per_tick=10, initial_builder_count=2, autoscale=True, alarm_period_duration=10, scale_up_alarm_period_count=3, scale_down_alarm_period_count=1000, scale_up_threshold=5, scale_up_change=2, scale_down_threshold=8, scale_down_change=1) assert len(m.builders) == 2 m.advance(3) # No scaling until alarm has enough data assert len(m.builders) == 2 m.advance(1) assert len(m.builders) == 4 # Scale after one cooldown # (ideal cooldown of builder_boot_time + alarm_period_duration) m.advance(11) assert len(m.builders) == 6 # But no more m.advance(11) assert len(m.builders) == 6
def test_scale_down(): m = Model(build_run_time=50, builder_boot_time=0, builds_per_hour=0.0, sec_per_tick=1, initial_builder_count=10, autoscale=True, alarm_period_duration=10, scale_up_alarm_period_count=1000, scale_down_alarm_period_count=3, scale_up_threshold=5, scale_up_change=2, scale_down_threshold=8, scale_down_change=1) # opposite of test_scale_up assert len(m.builders) == 10 m.advance(30) assert len(m.builders) == 10 m.advance(1) assert len(m.builders) == 9 m.advance(60) assert len(m.builders) == 8 m.advance(60) assert len(m.builders) == 8
def test_dynamic_builds_per_hour_e2e(): # This test is not deterministic, but random fails should be extremely rare m = Model(builds_per_hour=6000.0, build_run_time=10, sec_per_tick=60, initial_builder_count=100, builder_boot_time=0, builds_per_hour_fn=Model.SINE) m.advance(1) assert len(m.finished_builds) < 10 m.advance(720) # 12 hrs initial =len(m.finished_builds) m.advance(1) final = len(m.finished_builds) assert 90 < final - initial < 110
def test_dynamic_builds_per_hour_e2e(): # This test is not deterministic, but random fails should be extremely rare m = Model(builds_per_hour=6000.0, build_run_time=10, sec_per_tick=60, initial_builder_count=100, builder_boot_time=0, builds_per_hour_fn=Model.SINE) m.advance(1) assert len(m.finished_builds) < 10 m.advance(720) # 12 hrs initial = len(m.finished_builds) m.advance(1) final = len(m.finished_builds) assert 90 < final - initial < 110