Example #1
0
    def __init__(self, event_config, control_opts={}, client_id=None):
        '''
        base class initializer, creates an `event.EventHandler` as
        `self.event_handler` and a `control.EventController` as
        `self.event_controller

        event_config -- A dictionary containing keyword arugments for the
                        EventHandler
        control_opts -- a dict of opts for `control.EventController` init
        '''

        # Get an EventHandler and an EventController
        self.event_handler = event.EventHandler(**event_config)
        self.event_controller = controller.EventController(
            self.event_handler, **control_opts)

        # Add an exit thread for the module
        self._exit = threading.Event()
        self._exit.clear()

        logger.addFilter(IdFilter(client_id=client_id))

        logger.info('Created base handler.')

        pass
def test_60_new_cancelled_event(tmpdir):
    """
    VEN, EiEvent Service, oadrDistributeEvent, oadrCreatedEvent Payload
    If the VTN sends an oadrEvent with the eventStatus set to cancelled and
    has an eventID that the VEN is not aware of then the VEN should ignore
    the event since it is not currently in its list of known events, but still must
    respond with the createdEvent if required to do so by oadrResponseRequired
    """
    test_event = AdrEvent(
        id="FooEvent",
        start=datetime.utcnow() - timedelta(seconds=60),
        signals=[dict(index=0, duration=timedelta(minutes=10), level=1.0)],
        status=AdrEventStatus.CANCELLED, mod_number=1
    )

    event_handler = event.EventHandler("VEN_ID", db_path=TEST_DB_ADDR % tmpdir)
    event_controller = controller.EventController(event_handler)

    reply = event_handler.handle_payload(generate_payload([test_event]))

    assert reply.findtext(
        responseCode,
        namespaces=NS_A
    ) == "200"
    assert reply.findtext(
        optType,
        namespaces=NS_A
    ) == "optIn"

    active_event = event_handler.get_active_events()[0]

    signal_level, evt_id, remove_events = event_controller._calculate_current_event_status([active_event])
    assert (signal_level, evt_id, remove_events) == (0, None, ["FooEvent"])
def test_65_cancellation_time_randomization(tmpdir):
    """
    VEN, EiEvent Service, oadrDistributeEvent, oadrCreatedEvent Payload
    When an event containing a randomization value in the startafter element is
    cancelled, either explicitly or implicitly, the VEN MUST randomize its
    termination of the event. The randomization window should be between 0
    and a duration equal to the value specified in startafter.
    """
    test_event = AdrEvent(
        id="FooEvent",
        start=datetime.utcnow() - timedelta(minutes=5),
        signals=[dict(index=0, duration=timedelta(minutes=10), level=1.0)],
        status=AdrEventStatus.ACTIVE, start_after=timedelta(minutes=2)
    )
    event_handler = event.EventHandler("VEN_ID", db_path=TEST_DB_ADDR % tmpdir)
    event_controller = controller.EventController(event_handler)

    event_handler.handle_payload(generate_payload([test_event]))

    with freeze_time():
        test_event.mod_number += 1
        test_event.status = AdrEventStatus.CANCELLED

        event_handler.handle_payload(generate_payload([test_event]))

        active_event = event_handler.get_active_events()[0]

        assert active_event.end != datetime.utcnow()
        assert (active_event.start - datetime.utcnow()) < timedelta(minutes=2)
def test_59_event_cancellation(tmpdir):
    """
    VEN, EiEvent Service, oadrDistributeEvent Payload
    If the VTN sends an oadrEvent with the eventStatus set to cancelled and
    has an eventID that the VEN is aware of then the VEN should cancel the
    existing event and delete it from its list of known events.
    """
    test_event = AdrEvent(
        id="FooEvent",
        start=datetime.utcnow() + timedelta(seconds=60),
        signals=[dict(index=0, duration=timedelta(minutes=10), level=1.0)],
        status=AdrEventStatus.PENDING, mod_number=1
    )

    event_handler = event.EventHandler("VEN_ID", db_path=TEST_DB_ADDR % tmpdir)
    event_controller = controller.EventController(event_handler)

    event_handler.handle_payload(generate_payload([test_event]))

    active_event = event_handler.get_active_events()[0]
    assert active_event == test_event.to_obj()

    with freeze_time():
        test_event.status = AdrEventStatus.CANCELLED
        test_event.mod_number += 1
        test_event.end = datetime.utcnow()

        event_handler.handle_payload(generate_payload([test_event]))

        active_event = event_handler.get_active_events()[0]
        assert active_event == test_event.to_obj()

    signal_level, evt_id, remove_events = event_controller._calculate_current_event_status([test_event.to_obj()])
    assert (signal_level, evt_id, remove_events) == (0, None, ["FooEvent"])
def test_56_new_event(tmpdir):
    """
    VEN, EiEvent Service, oadrDistributeEvent Payload
    If the VTN sends an oadrEvent with an eventID that the VEN is not aware
    then it should process the event and add it to its list of known events
    """
    test_event = AdrEvent(
        id="FooEvent",
        start=datetime.utcnow()+timedelta(seconds=60),
        signals=[dict(index=0, duration=timedelta(minutes=10), level=1.0)],
        status=AdrEventStatus.PENDING
    )
    event_handler = event.EventHandler("VEN_ID", db_path=TEST_DB_ADDR % tmpdir)
    event_controller = controller.EventController(event_handler)

    event_handler.handle_payload(generate_payload([test_event]))

    signal_level, evt_id, remove_events = event_controller._calculate_current_event_status([test_event.to_obj()])
    assert (signal_level, evt_id, remove_events) == (0, None, [])

    active_event = event_handler.get_active_events()[0]
    expected_event = test_event.to_obj()
    assert active_event == expected_event

    with freeze_time(datetime.utcnow()+timedelta(seconds=70)):
        signal_level, evt_id, remove_events = event_controller._calculate_current_event_status([test_event.to_obj()])
        assert (signal_level, evt_id, remove_events) == (1.0, "FooEvent", [])
Example #6
0
def test_calculate_current_event_status(event_list, expected, tmpdir):
    event_handler = event.EventHandler("VEN_ID", db_path=TEST_DB_ADDR % tmpdir)
    event_controller = controller.EventController(event_handler)

    signal_level, evt_id, remove_events = event_controller._calculate_current_event_status([evt.to_obj() for evt in event_list])

    assert (signal_level, evt_id, remove_events) == expected
def test_18_overlaping_events(tmpdir):
    """
    VEN/VTN, EiEvent Service
    The VEN/VTN must honor the following rules with regards to overlapping
    active periods...
    DR events with overlapping active periods may be issued, but only if they
    are from different marketContexts and only if the programs have a priority
    associated with them. DR events for programs with higher priorities
    supersede the events of programs with lower priorities. If two programs with
    overlapping events have the same priority then the program whose event
    was activated first takes priority.
    The behavior of a VEN is undefined with respect to the receipt on an
    overlapping event in the same market context. The VTN shall not send
    overlapping events in the same market context, including events that could
    potentially overlap a randomized event cancellation. Nothing in this rule
    should preclude a VEN from opting into overlapping events in different
    market contexts.
    """
    expected_events = [
        AdrEvent(
            id="FooEvent1",
            start=datetime.utcnow() - timedelta(seconds=60),
            signals=[dict(index=0, duration=timedelta(minutes=10), level=1.0)],
            status=AdrEventStatus.ACTIVE, market_context="context1", priority=1
        ),
        AdrEvent(
            id="FooEvent2",
            start=datetime.utcnow() - timedelta(seconds=60),
            signals=[dict(index=0, duration=timedelta(minutes=10), level=2.0)],
            status=AdrEventStatus.ACTIVE, market_context="context2", priority=2
        ),
    ]

    event_handler = event.EventHandler(
        "VEN_ID",
        db_path=TEST_DB_ADDR % tmpdir,
        vtn_ids="TH_VTN",
        market_contexts="context1,context2"
    )
    event_controller = controller.EventController(event_handler)

    event_handler.handle_payload(generate_payload(expected_events))

    active_events = event_handler.get_active_events()

    signal_level, evt_id, remove_events = event_controller._calculate_current_event_status(active_events)
    assert (signal_level, evt_id, remove_events) == (2.0, "FooEvent2", [])
Example #8
0
def test_calculate_update_control(event_list, expected_level, expected_removed, tmpdir):
    db_mock = mock.MagicMock()
    event_handler = event.EventHandler("VEN_ID", db_path=TEST_DB_ADDR % tmpdir)
    event_handler.db.remove_events = db_mock
    event_controller = controller.EventController(event_handler)

    signal_level = event_controller._update_control([evt.to_obj() for evt in event_list])

    assert signal_level == expected_level

    if expected_removed:
        parsed_events = db_mock.call_args[0][0]
        for evt in expected_removed:
            assert evt in parsed_events
            parsed_events.remove(evt)

        assert parsed_events == []
    else:
        db_mock.assert_not_called()
def test_47_unending_event(tmpdir):
    """
    VEN/VTN, EiEvent Service, oadrDistributeEvent Payload
    An event with an overall duration of 0 indicates an event with no defined
    end time and will remain active until explicitly cancelled.
    """
    test_event = AdrEvent(
        id="FooEvent",
        start=datetime.utcnow() + timedelta(seconds=60),
        signals=[dict(index=0, duration=timedelta(minutes=0), level=1.0)],
        status=AdrEventStatus.ACTIVE
    )
    event_handler = event.EventHandler("VEN_ID", db_path=TEST_DB_ADDR % tmpdir)
    event_controller = controller.EventController(event_handler)

    event_handler.handle_payload(generate_payload([test_event]))

    active_event = event_handler.get_active_events()[0]

    signal_level, evt_id, remove_events = event_controller._calculate_current_event_status([active_event])
    assert (signal_level, evt_id, remove_events) == (0, None, [])

    with freeze_time(datetime.utcnow() + timedelta(seconds=70)):
        signal_level, evt_id, remove_events = event_controller._calculate_current_event_status([active_event])
        assert (signal_level, evt_id, remove_events) == (1.0, "FooEvent", [])

    with freeze_time(datetime.utcnow() + timedelta(minutes=70)):
        signal_level, evt_id, remove_events = event_controller._calculate_current_event_status([active_event])
        assert (signal_level, evt_id, remove_events) == (1.0, "FooEvent", [])

    with freeze_time(datetime.utcnow() + timedelta(hours=70)):
        signal_level, evt_id, remove_events = event_controller._calculate_current_event_status([active_event])
        assert (signal_level, evt_id, remove_events) == (1.0, "FooEvent", [])

    test_event.status = AdrEventStatus.CANCELLED
    test_event.mod_number += 1

    event_handler.handle_payload(generate_payload([test_event]))
    active_event = event_handler.get_active_events()[0]

    signal_level, evt_id, remove_events = event_controller._calculate_current_event_status([active_event])
    assert (signal_level, evt_id, remove_events) == (0, None, ["FooEvent"])
def test_6_test_event(tmpdir):
    """
    VEN, EiEvent Service, oadrDistributeEvent Payload
    The presence of any string except “false” in the oadrDisributeEvent
    testEvent element is treated as a trigger for a test event.
    """
    test_event = AdrEvent(
        id="FooEvent",
        start=datetime.utcnow()-timedelta(seconds=60),
        signals=[dict(index=0, duration=timedelta(minutes=10), level=1.0)],
        status=AdrEventStatus.ACTIVE, test_event=True
    )
    event_handler = event.EventHandler("VEN_ID", db_path=TEST_DB_ADDR % tmpdir)
    event_controller = controller.EventController(event_handler)

    event_handler.handle_payload(generate_payload([test_event]))

    signal_level, evt_id, remove_events = event_controller._calculate_current_event_status([test_event.to_obj()])
    assert (signal_level, evt_id, remove_events) == (0, None, [])

    active_event = event_handler.get_active_events()[0]
    expected_event = test_event.to_obj()
    assert active_event == expected_event