Пример #1
0
 def run(self):
     rectifier = Rectifier(storage=RedisStorage(),
                           broker=RabbitMQ(),
                           infrastructure_provider=Heroku())
     while True:
         rectifier.run()
         time.sleep(settings.TIME_BETWEEN_REQUESTS)
Пример #2
0
def test_kill_only_calls_when_needed(env):
    storage = RedisStorageMock()
    infrastructure_provider = InfrastructureProviderMock(env)

    config = f'{{"rectifier":{{"mode": "kill", "q1":{{"intervals":[0,10,100],"workers":[1,2,3],"cooldown":60,"consumers_formation_name":"worker_q1"}}}}}}'
    storage.set(settings.REDIS_CONFIG_KEY, bytes(config, 'utf-8'))

    rectifier = Rectifier(
        broker=RabbitMQ(),
        storage=storage,
        infrastructure_provider=infrastructure_provider,
    )

    rectifier.run()
    assert infrastructure_provider.called_count == 0
    assert infrastructure_provider.consumers['rectifier']['worker_q1'] == 0

    env.rabbitmq.set_queue('rectifier', 'q1', 10, 200)
    rectifier.run()
    assert infrastructure_provider.called_count == 1
    assert infrastructure_provider.consumers['rectifier']['worker_q1'] == 0

    env.rabbitmq.set_queue('rectifier', 'q1', 0, 200)
    rectifier.run()
    assert infrastructure_provider.called_count == 1
    assert infrastructure_provider.consumers['rectifier']['worker_q1'] == 0
Пример #3
0
def test_monitor_with_no_config(env):
    storage = RedisStorageMock()
    infrastructure_provider = InfrastructureProviderMock(env)

    storage.set(settings.REDIS_CONFIG_KEY, None)
    rectifier = Rectifier(
        broker=RabbitMQ(),
        storage=storage,
        infrastructure_provider=infrastructure_provider,
    )

    assert not storage.get(settings.REDIS_CONFIG_KEY)
    assert not storage.get(settings.REDIS_UPDATE_TIMES)
    rectifier.run()

    assert infrastructure_provider.called_count == 0
    assert not storage.get(settings.REDIS_CONFIG_KEY)
    assert not storage.get(settings.REDIS_UPDATE_TIMES)
Пример #4
0
def test_update_time_storage(env):
    storage = RedisStorageMock()
    infrastructure_provider = InfrastructureProviderMock(env)

    rectifier = Rectifier(
        broker=RabbitMQ(),
        storage=storage,
        infrastructure_provider=infrastructure_provider,
    )

    storage.set(
        settings.REDIS_CONFIG_KEY,
        b'{"rectify":{"q1":{"intervals":[0,10,100],"workers":[1,2,3],"cooldown":60,"consumers_formation_name":"worker_q1"}}}',
    )

    with freeze_time("2012-01-14 03:00:00") as frozen_time:
        # Should scale to one consumer, because the workers count
        # for the 0 - 10 interval is 1
        env.rabbitmq.set_queue('rectify', 'q1')
        rectifier.run()

        assert infrastructure_provider.called_count == 1
        assert infrastructure_provider.consumers['rectify']['worker_q1'] == 1

        update_times = pickle.loads(storage.get(settings.REDIS_UPDATE_TIMES))
        assert update_times['rectify']['q1'] == frozen_time.time_to_freeze

        env.rabbitmq.set_queue('rectify', 'q1', 1, 11)
        frozen_time.move_to('2012-01-14 03:01:00')
        rectifier.run()
        assert infrastructure_provider.called_count == 2
        assert infrastructure_provider.consumers['rectify']['worker_q1'] == 2

        update_times = pickle.loads(storage.get(settings.REDIS_UPDATE_TIMES))
        assert update_times['rectify']['q1'] == frozen_time.time_to_freeze

        old_time = frozen_time.time_to_freeze
        env.rabbitmq.set_queue('rectify', 'q1', 1, 2)
        frozen_time.move_to('2012-01-14 03:11:00')
        rectifier.run()
        assert infrastructure_provider.called_count == 2
        assert infrastructure_provider.consumers['rectify']['worker_q1'] == 2
        update_times = pickle.loads(storage.get(settings.REDIS_UPDATE_TIMES))
        assert update_times['rectify']['q1'] == old_time
Пример #5
0
def test_monitor_with_no_broker_uri(env):
    storage = RedisStorageMock()
    infrastructure_provider = MagicMock()
    infrastructure_provider.scale = MagicMock()
    infrastructure_provider.broker_uri = MagicMock(return_value=None)

    storage.set(
        settings.REDIS_CONFIG_KEY,
        b'{"rectifier":{"q1":{"intervals":[0,10,100],"workers":[1,2,3],"cooldown":60,"consumers_formation_name":"worker_q1"}}}',
    )
    rectifier = Rectifier(
        broker=RabbitMQ(),
        storage=storage,
        infrastructure_provider=infrastructure_provider,
    )

    rectifier.run()

    assert not infrastructure_provider.scale.called
Пример #6
0
def test_monitor_paused(env, mode, expected_called_count, expected_workers):
    storage = RedisStorageMock()
    infrastructure_provider = InfrastructureProviderMock(env)

    config = f'{{"rectifier":{{"mode": "{mode}", "q1":{{"intervals":[0,10,100],"workers":[1,2,3],"cooldown":60,"consumers_formation_name":"worker_q1"}}}}}}'
    storage.set(settings.REDIS_CONFIG_KEY, bytes(config, 'utf-8'))

    rectifier = Rectifier(
        broker=RabbitMQ(),
        storage=storage,
        infrastructure_provider=infrastructure_provider,
    )

    env.rabbitmq.set_queue('rectifier', 'q1', 10, 200)
    rectifier.run()

    assert infrastructure_provider.called_count == expected_called_count
    assert (infrastructure_provider.consumers['rectifier']['worker_q1'] ==
            expected_workers)
Пример #7
0
def test_monitor_common_config(env):
    storage = RedisStorageMock()
    infrastructure_provider = InfrastructureProviderMock(env)

    storage.set(
        settings.REDIS_CONFIG_KEY,
        b'{"rectifier":{"q1+q2":{"intervals":[0,10,100],"workers":[0,2,3],"cooldown":60,"consumers_formation_name":"worker"}}}',
    )

    rectifier = Rectifier(
        broker=RabbitMQ(),
        storage=storage,
        infrastructure_provider=infrastructure_provider,
    )

    with freeze_time("2012-01-14 03:00:00") as frozen_time:
        env.rabbitmq.set_queue('rectifier', 'q1', 0, 0)
        env.rabbitmq.set_queue('rectifier', 'q2', 0, 0)
        rectifier.run()

        assert infrastructure_provider.called_count == 0
        assert infrastructure_provider.consumers['rectifier']['worker'] == 0

        env.rabbitmq.set_queue('rectifier', 'q1', 0, 0)
        env.rabbitmq.set_queue('rectifier', 'q2', 0, 20)
        rectifier.run()

        assert infrastructure_provider.called_count == 1
        assert infrastructure_provider.consumers['rectifier']['worker'] == 2

        frozen_time.move_to('2012-01-14 03:20:00')
        env.rabbitmq.set_queue('rectifier', 'q1', 2, 79)
        env.rabbitmq.set_queue('rectifier', 'q2', 2, 20)
        rectifier.run()
        assert infrastructure_provider.called_count == 1
        assert infrastructure_provider.consumers['rectifier']['worker'] == 2

        env.rabbitmq.set_queue('rectifier', 'q1', 2, 80)
        env.rabbitmq.set_queue('rectifier', 'q2', 2, 20)
        rectifier.run()
        assert infrastructure_provider.called_count == 2
        assert infrastructure_provider.consumers['rectifier']['worker'] == 3
Пример #8
0
def test_monitor(env):
    storage = RedisStorageMock()
    infrastructure_provider = InfrastructureProviderMock(env)

    storage.set(
        settings.REDIS_CONFIG_KEY,
        b'{"rectifier":{"q1":{"intervals":[0,10,100],"workers":[1,2,3],"cooldown":60,"consumers_formation_name":"worker_q1"}},'
        b'"rectifier2":{"q2":{"intervals":[0,10,100],"workers":[2,4,6],"cooldown":30,"consumers_formation_name":"worker_q2"}}}',
    )
    rectifier = Rectifier(
        broker=RabbitMQ(),
        storage=storage,
        infrastructure_provider=infrastructure_provider,
    )

    with freeze_time("2012-01-14 03:00:00") as frozen_time:
        env.rabbitmq.set_queue('rectifier', 'q1')
        env.rabbitmq.set_queue('rectifier2', 'q2')
        rectifier.run()

        assert infrastructure_provider.called_count == 2
        assert infrastructure_provider.consumers['rectifier']['worker_q1'] == 1
        assert infrastructure_provider.consumers['rectifier2'][
            'worker_q2'] == 2

        # Update the queues. Increase the messages
        env.rabbitmq.set_queue('rectifier', 'q1', 1, 10)
        env.rabbitmq.set_queue('rectifier2', 'q2', 1, 12)

        # Move 29 seconds in the future.
        # As the cooldown is not yet elapsed for either queue, nothing should happen.
        frozen_time.move_to('2012-01-14 03:00:29')
        rectifier.run()
        assert infrastructure_provider.called_count == 2
        assert infrastructure_provider.consumers['rectifier']['worker_q1'] == 1
        assert infrastructure_provider.consumers['rectifier2'][
            'worker_q2'] == 2

        # Move one more second. The CD is elapsed for q2. Check the scaling happened.
        frozen_time.move_to('2012-01-14 03:00:30')
        rectifier.run()
        assert infrastructure_provider.called_count == 3
        assert infrastructure_provider.consumers['rectifier']['worker_q1'] == 1
        assert infrastructure_provider.consumers['rectifier2'][
            'worker_q2'] == 4

        # Update the queues. Increase the messages
        env.rabbitmq.set_queue('rectifier2', 'q2', 4, 12)

        # Check that the other queue gets updated..
        frozen_time.move_to('2012-01-14 03:01:00')
        rectifier.run()
        assert infrastructure_provider.called_count == 4
        assert infrastructure_provider.consumers['rectifier']['worker_q1'] == 2
        assert infrastructure_provider.consumers['rectifier2'][
            'worker_q2'] == 4

        # Set q1 to more than 100 messages, but set the workers to 3 (to simulate a manual change)
        env.rabbitmq.set_queue('rectifier', 'q1', 3, 123)

        # Move ahead to more the 60 seconds in the future. As the workers were manually adjusted,
        # check that they're not scaled again.
        frozen_time.move_to('2012-01-14 03:02:00')
        rectifier.run()
        assert infrastructure_provider.called_count == 4
        # This is still two because scale() wasn't actually called since the balancer
        # noticed that the workers don't have to be balanced.
        assert infrastructure_provider.consumers['rectifier']['worker_q1'] == 2
        assert infrastructure_provider.consumers['rectifier2'][
            'worker_q2'] == 4

        # Consume messages from the queue
        env.rabbitmq.set_queue('rectifier', 'q1', 3, 75)

        # Check that downscaling works
        rectifier.run()
        assert infrastructure_provider.called_count == 5
        assert infrastructure_provider.consumers['rectifier']['worker_q1'] == 2

        # Check that the CD is respected for downscaling too
        env.rabbitmq.set_queue('rectifier', 'q1', 2, 7)
        env.rabbitmq.set_queue('rectifier2', 'q2', 2, 7)
        frozen_time.move_to('2012-01-14 03:02:01')
        assert infrastructure_provider.called_count == 5
        assert infrastructure_provider.consumers['rectifier']['worker_q1'] == 2
        assert infrastructure_provider.consumers['rectifier2'][
            'worker_q2'] == 4

        env.rabbitmq.set_queue('rectifier', 'q1', 2, 0)
        frozen_time.move_to('2012-01-14 03:03:00')
        rectifier.run()
        assert infrastructure_provider.called_count == 6
        assert infrastructure_provider.consumers['rectifier']['worker_q1'] == 1
        assert infrastructure_provider.consumers['rectifier2'][
            'worker_q2'] == 4

        env.rabbitmq.set_queue('rectifier', 'q1', 1, 0)
        env.rabbitmq.set_queue('rectifier2', 'q2', 3, 0)
        frozen_time.move_to('2012-01-14 03:04:00')
        rectifier.run()
        assert infrastructure_provider.called_count == 7
        assert infrastructure_provider.consumers['rectifier']['worker_q1'] == 1
        assert infrastructure_provider.consumers['rectifier2'][
            'worker_q2'] == 2