예제 #1
0
def test_evaluate_ruling_cancel_fail_state_change(
        workspace: Workspace,
        monkeypatch: _pytest.monkeypatch.MonkeyPatch) -> None:
    patch(monkeypatch, workspace, 'handle_success')

    mock_error: tft.artemis.tasks.DoerReturnType = Error(
        tft.artemis.Failure('mock error'))

    def mock_update_guest_state(*args: Any, **kwargs: Any) -> None:
        workspace.result = mock_error

    patch(monkeypatch, workspace,
          'update_guest_state').side_effect = mock_update_guest_state

    workspace.ruling = tft.artemis.routing_policies.PolicyRuling(
        cancel=True,
        allowed_pools=[MagicMock(name='pool1'),
                       MagicMock(name='pool2')])

    assert workspace.evaluate_ruling() is workspace

    assert workspace.result is mock_error
    assert workspace.new_pool is None

    cast(MagicMock, workspace.update_guest_state).assert_called_once_with(
        tft.artemis.guest.GuestState.ERROR,
        current_state=tft.artemis.guest.GuestState.ROUTING)

    cast(MagicMock,
         workspace.handle_success).assert_called_once_with('routing-cancelled')
예제 #2
0
def test_evaluate_ruling(workspace: Workspace) -> None:
    workspace.ruling = tft.artemis.routing_policies.PolicyRuling(
        allowed_pools=[MagicMock(
            name='pool1'), MagicMock(name='pool2')])

    assert workspace.evaluate_ruling() is workspace

    assert workspace.result is None
    assert workspace.new_pool is workspace.ruling.allowed_pools[0]
예제 #3
0
def test_dispatch_provisioning(
        workspace: Workspace,
        monkeypatch: _pytest.monkeypatch.MonkeyPatch) -> None:
    workspace.new_pool = MagicMock(name='pool1')

    patch(monkeypatch, workspace, 'dispatch_task')
    patch(monkeypatch, workspace, 'ungrab_guest_request')

    assert workspace.dispatch_provisioning() is workspace

    cast(MagicMock, workspace.dispatch_task).assert_called_once_with(
        tft.artemis.tasks.acquire_guest_request, workspace.guestname,
        workspace.new_pool.poolname)

    cast(MagicMock, workspace.ungrab_guest_request).assert_not_called()
예제 #4
0
def test_switch_to_provisioning(
        workspace: Workspace,
        monkeypatch: _pytest.monkeypatch.MonkeyPatch) -> None:
    workspace.gr = MagicMock(name='dummy-guest-request')
    workspace.new_pool = MagicMock(name='dummy-pool')

    patch(monkeypatch, workspace, 'update_guest_state')

    assert workspace.switch_to_provisioning() is workspace

    cast(MagicMock, workspace.update_guest_state).assert_called_once_with(
        tft.artemis.guest.GuestState.PROVISIONING,
        current_state=tft.artemis.guest.GuestState.ROUTING,
        set_values={'poolname': workspace.new_pool.poolname},
        pool=workspace.new_pool.poolname)
예제 #5
0
def test_evaluate_ruling_empty(
        workspace: Workspace,
        monkeypatch: _pytest.monkeypatch.MonkeyPatch) -> None:
    patch(monkeypatch, workspace, 'handle_success')
    patch(monkeypatch, workspace, 'update_guest_state')

    workspace.ruling = tft.artemis.routing_policies.PolicyRuling()

    assert workspace.evaluate_ruling() is workspace

    assert workspace.result is tft.artemis.tasks.RESCHEDULE
    assert workspace.new_pool is None

    cast(MagicMock, workspace.handle_success).assert_not_called()
    cast(MagicMock, workspace.update_guest_state).assert_not_called()
예제 #6
0
def fixture_workspace(logger: gluetool.log.ContextAdapter,
                      session: sqlalchemy.orm.session.Session) -> Workspace:
    return Workspace(logger,
                     session,
                     threading.Event(),
                     guestname='dummy-guest-name',
                     task='route-guest-request')
예제 #7
0
def test_query_policies(workspace: Workspace,
                        session: sqlalchemy.orm.session.Session,
                        monkeypatch: _pytest.monkeypatch.MonkeyPatch) -> None:
    workspace.gr = MagicMock(name='workspace.gr<mock>')
    workspace.pools = []

    mock_ruling = tft.artemis.routing_policies.PolicyRuling()

    patch(monkeypatch, workspace, 'run_hook').return_value = mock_ruling

    assert workspace.query_policies() is workspace

    assert workspace.result is None
    assert workspace.ruling is mock_ruling

    cast(MagicMock, workspace.run_hook).assert_called_once_with(
        'ROUTE',
        session=session,
        guest_request=workspace.gr,
        pools=workspace.pools)
예제 #8
0
def test_exit(workspace: Workspace,
              monkeypatch: _pytest.monkeypatch.MonkeyPatch) -> None:
    patch(monkeypatch,
          tft.artemis.tasks.route_guest_request.metrics.ProvisioningMetrics,
          'inc_failover')

    assert workspace.exit() is workspace

    assert workspace.result is tft.artemis.tasks.SUCCESS
    cast(
        MagicMock, tft.artemis.tasks.route_guest_request.metrics.
        ProvisioningMetrics.inc_failover).assert_not_called()
예제 #9
0
def test_exit_failover(workspace: Workspace,
                       monkeypatch: _pytest.monkeypatch.MonkeyPatch,
                       caplog: _pytest.logging.LogCaptureFixture) -> None:
    workspace.current_poolname = 'pool1'
    workspace.new_pool = MagicMock(name='pool2', poolname='pool2')

    patch(monkeypatch,
          tft.artemis.tasks.route_guest_request.metrics.ProvisioningMetrics,
          'inc_failover')

    assert workspace.exit() is workspace

    assert workspace.result is tft.artemis.tasks.SUCCESS

    cast(
        MagicMock,
        tft.artemis.tasks.route_guest_request.metrics.ProvisioningMetrics.
        inc_failover).assert_called_once_with('pool1', 'pool2')

    assert_log(caplog,
               message='failover: switched pool1 => pool2',
               levelno=logging.WARNING)
예제 #10
0
def test_entry(workspace: Workspace,
               monkeypatch: _pytest.monkeypatch.MonkeyPatch) -> None:
    patch(monkeypatch, workspace, 'handle_success')
    patch(monkeypatch, workspace, 'load_guest_request')

    assert workspace.guestname is not None
    assert workspace.entry() is workspace

    assert workspace.result is None

    cast(MagicMock,
         workspace.handle_success).assert_called_once_with('entered-task')
    cast(MagicMock, workspace.load_guest_request).assert_called_once_with(
        'dummy-guest-name', state=tft.artemis.guest.GuestState.ROUTING)
예제 #11
0
def test_doer(monkeypatch: _pytest.monkeypatch.MonkeyPatch,
              logger: gluetool.log.ContextAdapter, db: tft.artemis.db.DB,
              session: sqlalchemy.orm.session.Session) -> None:
    patch(monkeypatch, Workspace, 'entry')

    result = Workspace.route_guest_request(logger, db, session,
                                           threading.Event(), 'dummy-guest')

    # Read the full name of the the final mock, we can easily compare it and prove the sequence of calls.
    # The method is not part of the public API, it's used by `_repr__()`, therefore it's risky, but let's see.
    assert cast(MagicMock, result)._extract_mock_name() == '.'.join([
        'entry<mock>()', 'load_pools()', 'query_policies()',
        'evaluate_ruling()', 'switch_to_provisioning()',
        'dispatch_provisioning()', 'exit()', 'final_result'
    ])
예제 #12
0
def test_dispatch_provisioning_fail_dispatch(
        workspace: Workspace,
        monkeypatch: _pytest.monkeypatch.MonkeyPatch) -> None:
    workspace.new_pool = MagicMock(name='pool1')

    mock_error: tft.artemis.tasks.DoerReturnType = Error(
        tft.artemis.Failure('mock error'))

    def mock_dispatch_task(*args: Any, **kwargs: Any) -> None:
        workspace.result = mock_error

    patch(monkeypatch, workspace,
          'dispatch_task').side_effect = mock_dispatch_task
    patch(monkeypatch, workspace, 'ungrab_guest_request')

    assert workspace.dispatch_provisioning() is workspace

    cast(MagicMock, workspace.dispatch_task).assert_called_once_with(
        tft.artemis.tasks.acquire_guest_request, workspace.guestname,
        workspace.new_pool.poolname)

    cast(MagicMock, workspace.ungrab_guest_request).assert_called_once_with(
        tft.artemis.guest.GuestState.PROVISIONING,
        tft.artemis.guest.GuestState.ROUTING)
예제 #13
0
def test_evaluate_ruling_cancel(
        workspace: Workspace,
        monkeypatch: _pytest.monkeypatch.MonkeyPatch) -> None:
    patch(monkeypatch, workspace,
          'handle_success').return_value = tft.artemis.tasks.SUCCESS
    patch(monkeypatch, workspace, 'update_guest_state')

    workspace.ruling = tft.artemis.routing_policies.PolicyRuling(
        cancel=True,
        allowed_pools=[MagicMock(name='pool1'),
                       MagicMock(name='pool2')])

    assert workspace.evaluate_ruling() is workspace

    assert workspace.result is tft.artemis.tasks.SUCCESS
    assert workspace.new_pool is None

    cast(MagicMock, workspace.update_guest_state).assert_called_once_with(
        tft.artemis.guest.GuestState.ERROR,
        current_state=tft.artemis.guest.GuestState.ROUTING)

    cast(MagicMock,
         workspace.handle_success).assert_any_call('routing-cancelled')
    cast(MagicMock, workspace.handle_success).assert_any_call('finished-task')