示例#1
0
def test_subrefs_added_to_preexisting_subrefs(storage, handler):
    body = {
        'status': {
            'kopf': {
                'progress': {
                    'some-id': {
                        'subrefs': ['sub9/2', 'sub9/1']
                    }
                }
            }
        }
    }
    patch = Patch()
    outcome_subrefs = ['sub2/b', 'sub2/a', 'sub2', 'sub1', 'sub3']
    expected_subrefs = [
        'sub1', 'sub2', 'sub2/a', 'sub2/b', 'sub3', 'sub9/1', 'sub9/2'
    ]
    outcome = HandlerOutcome(final=True, subrefs=outcome_subrefs)
    state = State.from_storage(body=Body(body),
                               handlers=[handler],
                               storage=storage)
    state = state.with_handlers([handler])
    state = state.with_outcomes(outcomes={handler.id: outcome})
    state.store(patch=patch, body=Body(body), storage=storage)
    assert patch['status']['kopf']['progress']['some-id'][
        'subrefs'] == expected_subrefs
示例#2
0
def test_activity_error_exception():
    outcome = HandlerOutcome(final=True)
    outcomes: Mapping[HandlerId, HandlerOutcome]
    outcomes = {HandlerId('id'): outcome}
    error = ActivityError("message", outcomes=outcomes)
    assert str(error) == "message"
    assert error.outcomes == outcomes
示例#3
0
def test_creation_for_permanent_errors():
    error = Exception()
    outcome = HandlerOutcome(final=True, exception=error)
    assert outcome.final
    assert outcome.delay is None
    assert outcome.result is None
    assert outcome.exception is error
示例#4
0
def test_creation_for_temporary_errors():
    error = Exception()
    outcome = HandlerOutcome(final=False, exception=error, delay=123)
    assert not outcome.final
    assert outcome.delay == 123
    assert outcome.result is None
    assert outcome.exception is error
示例#5
0
def test_creation_for_results():
    result = Result(object())
    outcome = HandlerOutcome(final=True, result=result)
    assert outcome.final
    assert outcome.delay is None
    assert outcome.result is result
    assert outcome.exception is None
示例#6
0
def test_set_awake_time(storage, handler, expected, body, delay):
    origbody = copy.deepcopy(body)
    patch = Patch()
    state = State.from_storage(body=Body(body), handlers=[handler], storage=storage)
    state = state.with_outcomes(outcomes={handler.id: HandlerOutcome(final=False, delay=delay)})
    state.store(patch=patch, body=Body(body), storage=storage)
    assert patch['status']['kopf']['progress']['some-id'].get('delayed') == expected
    assert body == origbody  # not modified
示例#7
0
def test_asap_takes_the_least_retried(mocker):
    handler1 = mocker.Mock(id='id1', spec_set=['id'])
    handler2 = mocker.Mock(id='id2', spec_set=['id'])
    handler3 = mocker.Mock(id='id3', spec_set=['id'])

    # Set the pre-existing state, and verify that it was set properly.
    state = State.from_scratch().with_handlers([handler1, handler2, handler3])
    state = state.with_outcomes({handler1.id: HandlerOutcome(final=False)})
    state = state.with_outcomes({handler1.id: HandlerOutcome(final=False)})
    state = state.with_outcomes({handler3.id: HandlerOutcome(final=False)})
    assert state[handler1.id].retries == 2
    assert state[handler2.id].retries == 0
    assert state[handler3.id].retries == 1

    handlers = [handler1, handler2, handler3]
    selected = kopf.lifecycles.asap(handlers, state=state)
    assert isinstance(selected, (tuple, list))
    assert len(selected) == 1
    assert selected[0] is handler2
示例#8
0
def test_subrefs_ignored_when_not_specified(storage, handler):
    body = {}
    patch = Patch()
    outcome = HandlerOutcome(final=True, subrefs=[])
    state = State.from_storage(body=Body(body),
                               handlers=[handler],
                               storage=storage)
    state = state.with_outcomes(outcomes={handler.id: outcome})
    state.store(patch=patch, body=Body(body), storage=storage)
    assert patch['status']['kopf']['progress']['some-id']['subrefs'] is None
示例#9
0
def test_store_success(storage, handler, expected_retries, expected_stopped, body):
    origbody = copy.deepcopy(body)
    patch = Patch()
    state = State.from_storage(body=Body(body), handlers=[handler], storage=storage)
    state = state.with_outcomes(outcomes={handler.id: HandlerOutcome(final=True)})
    state.store(patch=patch, body=Body(body), storage=storage)
    assert patch['status']['kopf']['progress']['some-id']['success'] is True
    assert patch['status']['kopf']['progress']['some-id']['failure'] is False
    assert patch['status']['kopf']['progress']['some-id']['retries'] == expected_retries
    assert patch['status']['kopf']['progress']['some-id']['stopped'] == expected_stopped
    assert patch['status']['kopf']['progress']['some-id']['message'] is None
    assert body == origbody  # not modified
示例#10
0
def test_issue_601_deletion_supersedes_other_processing(storage, reason):

    body = {
        'status': {
            'kopf': {
                'progress': {
                    'fn1': {
                        'purpose': reason.value,
                        'failure': True
                    },
                    'fn2': {
                        'purpose': reason.value,
                        'success': True
                    },
                    'fn3': {
                        'purpose': reason.value,
                        'delayed': TS1_ISO
                    },
                }
            }
        }
    }
    create_handler1 = Mock(id='fn1', spec_set=['id'])
    create_handler2 = Mock(id='fn2', spec_set=['id'])
    create_handler3 = Mock(id='fn3', spec_set=['id'])
    delete_handler9 = Mock(id='delete_fn', spec_set=['id'])
    owned_handlers = [
        create_handler1, create_handler2, create_handler3, delete_handler9
    ]
    cause_handlers = [delete_handler9]

    state = State.from_storage(body=Body(body),
                               handlers=owned_handlers,
                               storage=storage)
    state = state.with_purpose(Reason.DELETE)
    state = state.with_handlers(cause_handlers)

    assert len(state) == 4
    assert state.extras == {
        reason: StateCounters(success=1, failure=1, running=1)
    }
    assert state.counts == StateCounters(success=0, failure=0, running=1)
    assert state.done == False
    assert state.delays == [0.0]

    state = state.with_outcomes({'delete_fn': HandlerOutcome(final=True)})

    assert state.extras == {
        reason: StateCounters(success=1, failure=1, running=1)
    }
    assert state.counts == StateCounters(success=1, failure=0, running=0)
    assert state.done == True
    assert state.delays == []
示例#11
0
def test_set_retry_time(storage, handler, expected_retries, expected_delayed,
                        body, delay):
    patch = Patch()
    state = State.from_storage(body=Body(body),
                               handlers=[handler],
                               storage=storage)
    state = state.with_handlers([handler])
    state = state.with_outcomes(
        outcomes={handler.id: HandlerOutcome(final=False, delay=delay)})
    state.store(patch=patch, body=Body(body), storage=storage)
    assert patch['status']['kopf']['progress']['some-id'][
        'retries'] == expected_retries
    assert patch['status']['kopf']['progress']['some-id'][
        'delayed'] == expected_delayed
示例#12
0
def test_store_failure(storage, handler, expected_retries, expected_stopped,
                       body):
    error = Exception('some-error')
    patch = Patch()
    state = State.from_storage(body=Body(body),
                               handlers=[handler],
                               storage=storage)
    state = state.with_handlers([handler])
    state = state.with_outcomes(
        outcomes={handler.id: HandlerOutcome(final=True, exception=error)})
    state.store(patch=patch, body=Body(body), storage=storage)
    assert patch['status']['kopf']['progress']['some-id']['success'] is False
    assert patch['status']['kopf']['progress']['some-id']['failure'] is True
    assert patch['status']['kopf']['progress']['some-id'][
        'retries'] == expected_retries
    assert patch['status']['kopf']['progress']['some-id'][
        'stopped'] == expected_stopped
    assert patch['status']['kopf']['progress']['some-id'][
        'message'] == 'some-error'
示例#13
0
def test_store_result(handler, expected_patch, result):
    patch = Patch()
    outcomes = {handler.id: HandlerOutcome(final=True, result=result)}
    deliver_results(outcomes=outcomes, patch=patch)
    assert patch == expected_patch
示例#14
0
def test_creation_for_ignored_handlers():
    outcome = HandlerOutcome(final=True)
    assert outcome.final
    assert outcome.delay is None
    assert outcome.result is None
    assert outcome.exception is None