Esempio n. 1
0
def test_schedule_with_completed_activity(monkeypatch):
    """Test the scheduling of an activity.
    """

    mock(monkeypatch)
    from tests.fixtures.flows import example

    monkeypatch.setattr(decider, 'schedule_activity_task', MagicMock())

    decisions = MagicMock()
    schedule_context = decider.ScheduleContext()
    instance_state = activity.ActivityState('activity_1')
    instance_state.add_state(activity.ACTIVITY_COMPLETED)
    current_activity = example.activity_1
    history = {
        current_activity.name: {
            'workflow_name_activity_1-1-schedule_id': instance_state
        }
    }

    resp = decider.schedule(decisions, schedule_context, history, {},
                            'schedule_id', current_activity)

    assert not decider.schedule_activity_task.called
    assert resp.get_last_state() == activity.ACTIVITY_COMPLETED
    assert schedule_context.completed
    resp.result.get('foo')
Esempio n. 2
0
def test_schedule_requires_with_incomplete_activities():
    """Test the scheduler.
    """

    activity_state = activity.ActivityState('activity_name')
    with pytest.raises(activity.ActivityInstanceNotReadyException):
        decider.ensure_requirements([activity_state])

    with pytest.raises(activity.ActivityInstanceNotReadyException):
        decider.ensure_requirements([None])

    activity_state.add_state(activity.ACTIVITY_COMPLETED)
    decider.ensure_requirements(requires=[activity_state])
Esempio n. 3
0
def test_activity_state():
    """Test the creation of the activity state.
    """

    activity_id = 'id'
    state = activity.ActivityState(activity_id)
    assert state.activity_id is activity_id
    assert not state.get_last_state()

    state.add_state(activity.ACTIVITY_FAILED)
    state.add_state(activity.ACTIVITY_COMPLETED)
    assert len(state.states) == 2
    assert state.get_last_state() is activity.ACTIVITY_COMPLETED

    result = 'foobar'
    state.set_result(result)
    assert state.result == result

    with pytest.raises(Exception):
        state.set_result('shouldnt reset')

    assert state.result == result
Esempio n. 4
0
def schedule(decisions,
             schedule_context,
             history,
             context,
             schedule_id,
             current_activity,
             requires=None,
             input=None,
             version='1.0'):
    """Schedule an activity.

    Scheduling an activity requires all the requirements to be completed (all
    activities should be marked as completed). The scheduler also mixes the
    input with the full execution context to send the data to the activity.

    Args:
        decisions (Layer1Decisions): the layer decision for swf.
        schedule_context (dict): information about the schedule.
        history (dict): history of the execution.
        context (dict): context of the execution.
        schedule_id (str): the id of the activity to schedule.
        current_activity (Activity): the activity to run.
        requires (list): list of all requirements.
        input (dict): additional input for the context.

    Throws:
        ActivityInstanceNotReadyException: if one of the activity in the
            requirements is not ready.

    Return:
        State: the state of the schedule (contains the response).
    """

    ensure_requirements(requires)
    activity_completed = set()
    result = dict()

    instance_context = dict()
    instance_context.update(context or {})
    instance_context.update(input or {})

    for current in current_activity.instances(instance_context):
        current_id = '{}-{}'.format(current.id, schedule_id)
        states = history.get(current.activity_name, {}).get(current_id)

        if states:
            if states.get_last_state() == activity.ACTIVITY_COMPLETED:
                result.update(states.result or dict())
                activity_completed.add(True)
                continue

            activity_completed.add(False)
            schedule_context.mark_uncompleted()

            if states.get_last_state() != activity.ACTIVITY_FAILED:
                continue
            elif (not current.retry
                  or current.retry < activity.count_activity_failures(states)):
                raise Exception(
                    'The activity failures has exceeded its retry limit.')

        activity_completed.add(False)
        schedule_context.mark_uncompleted()
        schedule_activity_task(decisions,
                               current,
                               id=current_id,
                               version=version)

    state = activity.ActivityState(current_activity.name)
    state.add_state(activity.ACTIVITY_SCHEDULED)

    if len(activity_completed) == 1 and True in activity_completed:
        state.add_state(activity.ACTIVITY_COMPLETED)
        state.set_result(result)
    return state
Esempio n. 5
0
def activity_states_from_events(events):
    """Get activity states from a list of events.

    The workflow events contains the different states of our activities. This
    method consumes the logs, and regenerates a dictionnary with the list of
    all the activities and their states.

    Note:
        Please note: from the list of events, only activities that have been
        registered are accessible. For all the others that have not yet
        started, they won't be part of this list.

    Args:
        events (dict): list of all the events.
    Return:
        `dict`: the activities and their state.
    """

    events = sorted(events, key=lambda item: item.get('eventId'))
    event_id_info = dict()
    activity_events = dict()

    for event in events:
        event_id = event.get('eventId')
        event_type = event.get('eventType')

        if event_type == 'ActivityTaskScheduled':
            activity_info = event.get('activityTaskScheduledEventAttributes')
            activity_id = activity_info.get('activityId')
            activity_name = activity_info.get('activityType').get('name')
            event_id_info.update({
                event_id: {
                    'activity_name': activity_name,
                    'activity_id': activity_id
                }
            })

            activity_events.setdefault(activity_name, {}).setdefault(
                activity_id, activity.ActivityState(activity_id)).add_state(
                    activity.ACTIVITY_SCHEDULED)

        elif event_type == 'ActivityTaskFailed':
            activity_info = event.get('activityTaskFailedEventAttributes')
            activity_event = event_id_info.get(
                activity_info.get('scheduledEventId'))
            activity_id = activity_event.get('activity_id')

            activity_events.setdefault(
                activity_event.get('activity_name'),
                {}).setdefault(activity_id,
                               activity.ActivityState(activity_id)).add_state(
                                   activity.ACTIVITY_FAILED)

        elif event_type == 'ActivityTaskCompleted':
            activity_info = event.get('activityTaskCompletedEventAttributes')
            activity_event = event_id_info.get(
                activity_info.get('scheduledEventId'))
            activity_id = activity_event.get('activity_id')

            activity_events.setdefault(
                activity_event.get('activity_name'),
                {}).setdefault(activity_id,
                               activity.ActivityState(activity_id)).add_state(
                                   activity.ACTIVITY_COMPLETED)

            result = json.loads(activity_info.get('result') or '{}')
            activity_events.get(activity_event.get('activity_name')).get(
                activity_id).set_result(result)

    return activity_events