async def test_server_warning_conflicting_poll_methods(caplog): caplog.set_level(logging.WARNING) enable_default_logging() logger = logging.getLogger('openleadr') logger.setLevel(logging.DEBUG) server = OpenADRServer(vtn_id='myvtn', requested_poll_freq=timedelta(seconds=1)) server.add_handler('on_poll', print) print("Running server") await server.run_async() await asyncio.sleep(0.1) server.add_event(ven_id='venid', signal_name='simple', signal_type='level', intervals=[{ 'dtstart': datetime.now(), 'duration': timedelta(seconds=10), 'signal_payload': 1.1 }], target={'ven_id': 'venid'}, callback=print) assert ( "You cannot use the add_event method after you assign your own on_poll " "handler. If you use your own on_poll handler, you are responsible for " "delivering events from that handler. If you want to use OpenLEADRs " "message queuing system, you should not assign an on_poll handler. " "Your Event will NOT be added.") in [ record.msg for record in caplog.records ] await server.stop() await asyncio.sleep(0)
async def test_server_add_event_with_no_callback_response_never_required( caplog): caplog.set_level(logging.WARNING) logger = logging.getLogger('openleadr') logger.setLevel(logging.DEBUG) server = OpenADRServer(vtn_id='myvtn') server.add_event( ven_id='venid', event_id= 'test_server_add_event_with_no_callback_response_never_required', signal_name='simple', signal_type='level', intervals=[{ 'dtstart': datetime.now(timezone.utc), 'duration': timedelta(seconds=1), 'signal_payload': 1.1 }], target={'ven_id': 'venid'}, response_required='never') await server.run() await server.stop() assert ( "You did not provide a 'callback', which means you won't know if the " "VEN will opt in or opt out of your event. You should consider adding " "a callback for this.") not in caplog.messages
async def test_client_event_cleanup(): now = datetime.datetime.now(datetime.timezone.utc) server = OpenADRServer(vtn_id='myvtn') server.add_handler('on_create_party_registration', on_create_party_registration) loop = asyncio.get_event_loop() event_1_callback_future = loop.create_future() event_2_callback_future = loop.create_future() server.add_event(ven_id='ven123', signal_name='simple', signal_type='level', intervals=[ objects.Interval( dtstart=now, duration=datetime.timedelta(seconds=1), signal_payload=1) ], callback=event_1_callback_future) await server.run() client = OpenADRClient( ven_name='ven123', vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b') client.add_handler('on_event', on_event_opt_in) await client.run() await asyncio.sleep(0.5) assert len(client.received_events) == 1 await asyncio.sleep(0.5) await client._event_cleanup() assert len(client.received_events) == 0 await server.stop() await client.stop()
def test_server_add_event_with_custom_signal_name(): server = OpenADRServer(vtn_id='myvtn') server.add_event(ven_id='ven123', signal_name='x-invalid', signal_type='x-loadControlCapacity', intervals=[ objects.Interval(dtstart=datetime.now(timezone.utc), duration=timedelta(seconds=10), signal_payload=1.0) ]) assert len(server.events['ven123']) == 1
def test_server_add_event_with_invalid_signal_name(): server = OpenADRServer(vtn_id='myvtn') with pytest.raises(ValueError): server.add_event(ven_id='ven123', signal_name='invalid', signal_type='x-loadControlCapacity', intervals=[ objects.Interval(dtstart=datetime.now( timezone.utc), duration=timedelta(seconds=10), signal_payload=1.0) ])
async def test_request_event(): loop = asyncio.get_event_loop() client = OpenADRClient( ven_name='myven', vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b') server = OpenADRServer(vtn_id='myvtn', requested_poll_freq=datetime.timedelta(seconds=1)) server.add_handler('on_create_party_registration', on_create_party_registration) event_id = server.add_event( ven_id='ven123', signal_name='simple', signal_type='level', intervals=[{ 'dtstart': datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(seconds=4), 'duration': datetime.timedelta(seconds=2), 'signal_payload': 1 }], ramp_up_period=datetime.timedelta(seconds=2), callback=partial(event_callback)) assert server.events['ven123'][0].event_descriptor.event_status == 'far' await server.run_async() await client.create_party_registration() message_type, message_payload = await client.request_event() assert message_type == 'oadrDistributeEvent' message_type, message_payload = await client.request_event() assert message_type == 'oadrDistributeEvent' await client.stop() await server.stop()
async def test_client_exception_event_handler(caplog): caplog.set_level(logging.WARNING) enable_default_logging() logger = logging.getLogger('openleadr') logger.setLevel(logging.DEBUG) client = OpenADRClient( ven_name='myven', vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b') client.add_handler('on_event', broken_on_event) server = OpenADRServer(vtn_id='myvtn', requested_poll_freq=timedelta(seconds=1)) server.add_handler('on_create_party_registration', on_create_party_registration) print("Running server") await server.run_async() await asyncio.sleep(0.1) print("Running client") await client.run() event_confirm_future = asyncio.get_event_loop().create_future() print("Adding event") server.add_event(ven_id='venid', signal_name='simple', signal_type='level', intervals=[{ 'dtstart': datetime.now(), 'duration': timedelta(seconds=10), 'signal_payload': 1.1 }], target={'ven_id': 'venid'}, callback=partial(on_event_accepted, future=event_confirm_future)) print("Waiting for a response to the event") result = await event_confirm_future assert result == 'optOut' err = KeyError("BOOM") assert ( "Your on_event handler encountered an error. Will Opt Out of the event. " f"The error was {err.__class__.__name__}: {str(err)}") in [ rec.message for rec in caplog.records ] await client.stop() await server.stop() await asyncio.sleep(0)
async def test_cancel_event(): async def opt_in_to_event(event, future=None): if future: future.set_result(True) return 'optIn' async def on_update_event(event, future=None): if future: future.set_result(event) return 'optIn' now = datetime.datetime.now(datetime.timezone.utc) server = OpenADRServer(vtn_id='myvtn', requested_poll_freq=datetime.timedelta(seconds=1)) server.add_handler('on_create_party_registration', on_create_party_registration) loop = asyncio.get_event_loop() event_1_callback_future = loop.create_future() event_id = server.add_event( ven_id='ven123', signal_name='simple', signal_type='level', intervals=[ objects.Interval(dtstart=now, duration=datetime.timedelta(seconds=60), signal_payload=1) ], callback=event_1_callback_future, response_required='always') await server.run() client = OpenADRClient( ven_name='ven123', vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b') client.add_handler('on_event', opt_in_to_event) cancel_future = loop.create_future() client.add_handler('on_update_event', partial(on_update_event, future=cancel_future)) await client.run() await event_1_callback_future server.cancel_event('ven123', event_id) result = await cancel_future assert utils.getmember(result, 'event_descriptor.event_status') == 'cancelled' response_type, response_payload = await client.request_event() assert response_type == 'oadrResponse' await client._event_cleanup() assert len(client.responded_events) == 0 assert len(client.received_events) == 0 await server.stop() await client.stop()
async def test_client_good_event_handler(caplog): caplog.set_level(logging.WARNING) logger = logging.getLogger('openleadr') logger.setLevel(logging.DEBUG) client = OpenADRClient( ven_name='myven', vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b') client.add_handler('on_event', good_on_event) server = OpenADRServer(vtn_id='myvtn', requested_poll_freq=timedelta(seconds=1)) server.add_handler('on_create_party_registration', on_create_party_registration) caplog.clear() print("Running server") await server.run_async() # await asyncio.sleep(0.1) print("Running client") await client.run() event_confirm_future = asyncio.get_event_loop().create_future() print("Adding event") server.add_event(ven_id='venid', event_id='test_client_good_event_handler', signal_name='simple', signal_type='level', intervals=[{ 'dtstart': datetime.now(timezone.utc), 'duration': timedelta(seconds=1), 'signal_payload': 1.1 }], target={'ven_id': 'venid'}, callback=partial(on_event_accepted, future=event_confirm_future)) print("Waiting for a response to the event") result = await event_confirm_future assert result == 'optIn' print("-" * 80) print("THE CAPLOG RECORDS ARE:") print(caplog.records) print("-" * 80) assert len(caplog.records) == 0 await client.stop() await server.stop() await asyncio.gather(*[t for t in asyncio.all_tasks()][1:])
async def test_client_warning_no_update_event_handler(caplog): caplog.set_level(logging.WARNING) logger = logging.getLogger('openleadr') logger.setLevel(logging.DEBUG) server = OpenADRServer(vtn_id='myvtn', requested_poll_freq=timedelta(seconds=1)) server.add_handler('on_create_party_registration', on_create_party_registration) event_accepted_future = asyncio.get_event_loop().create_future() server.add_event(ven_id='venid', event_id='test_client_warning_no_update_event_handler', signal_name='simple', signal_type='level', intervals=[{ 'dtstart': datetime.now(timezone.utc), 'duration': timedelta(seconds=1), 'signal_payload': 1.1 }], target={'ven_id': 'venid'}, callback=event_accepted_future) client = OpenADRClient( ven_name='myven', vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b') client.add_handler('on_event', good_on_event) print("Starting server") await server.run() await client.run() print("Waiting for first event to be accepted...") await event_accepted_future # Manually update the event server.events['venid'][0].event_descriptor.modification_number = 1 server.events_updated['venid'] = True await asyncio.sleep(1) assert ( "An Event was updated, but you don't have an on_updated_event handler configured. " "You should implement your own on_update_event handler. This handler receives " "an Event dict and should return either 'optIn' or 'optOut' based on your " "choice. Will re-use the previous opt status for this event_id for now" ) in [record.msg for record in caplog.records] await client.stop() await server.stop() await asyncio.gather(*[t for t in asyncio.all_tasks()][1:])
async def test_client_no_event_handler(caplog): caplog.set_level(logging.WARNING) enable_default_logging() logger = logging.getLogger('openleadr') logger.setLevel(logging.DEBUG) client = OpenADRClient( ven_name='myven', vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b') server = OpenADRServer(vtn_id='myvtn', requested_poll_freq=timedelta(seconds=1)) server.add_handler('on_create_party_registration', on_create_party_registration) print("Running server") await server.run_async() await asyncio.sleep(0.1) print("Running client") await client.run() event_confirm_future = asyncio.get_event_loop().create_future() print("Adding event") server.add_event(ven_id='venid', signal_name='simple', signal_type='level', intervals=[{ 'dtstart': datetime.now(), 'duration': timedelta(seconds=10), 'signal_payload': 1.1 }], target={'ven_id': 'venid'}, callback=partial(on_event_accepted, future=event_confirm_future)) print("Waiting for a response to the event") result = await event_confirm_future assert result == 'optOut' assert ( "You should implement your own on_event handler. This handler receives " "an Event dict and should return either 'optIn' or 'optOut' based on your " "choice. Will opt out of the event for now.") in [ rec.message for rec in caplog.records ] await client.stop() await server.stop() await asyncio.sleep(0)
async def test_client_faulty_event_handler(caplog): caplog.set_level(logging.WARNING) logger = logging.getLogger('openleadr') logger.setLevel(logging.DEBUG) client = OpenADRClient( ven_name='myven', vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b') client.add_handler('on_event', faulty_on_event) server = OpenADRServer(vtn_id='myvtn', requested_poll_freq=timedelta(seconds=1)) server.add_handler('on_create_party_registration', on_create_party_registration) print("Running server") await server.run_async() # await asyncio.sleep(0.1) print("Running client") await client.run() event_confirm_future = asyncio.get_event_loop().create_future() print("Adding event") server.add_event(ven_id='venid', event_id='test_client_faulty_event_handler', signal_name='simple', signal_type='level', intervals=[{ 'dtstart': datetime.now(timezone.utc), 'duration': timedelta(seconds=1), 'signal_payload': 1.1 }], target={'ven_id': 'venid'}, callback=partial(on_event_accepted, future=event_confirm_future)) print("Waiting for a response to the event") result = await event_confirm_future assert result == 'optOut' assert ( "Your on_event or on_update_event handler must return 'optIn' or 'optOut'; " f"you supplied {None}. Please fix your on_event handler.") in [ rec.message for rec in caplog.records ] await client.stop() await server.stop() await asyncio.gather(*[t for t in asyncio.all_tasks()][1:])
async def test_internal_message_queue(): loop = asyncio.get_event_loop() client = OpenADRClient( ven_name='myven', vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b') client.add_handler('on_event', on_event) server = OpenADRServer(vtn_id='myvtn', requested_poll_freq=datetime.timedelta(seconds=1)) server.add_handler('on_create_party_registration', on_create_party_registration) event_callback_future = loop.create_future() server.add_event(ven_id='ven123', signal_name='simple', signal_type='level', intervals=[{ 'dtstart': datetime.datetime.now(datetime.timezone.utc), 'duration': datetime.timedelta(seconds=3), 'signal_payload': 1 }], callback=partial(event_callback, future=event_callback_future)) await server.run_async() #await asyncio.sleep(1) await client.run() #await asyncio.sleep(1) status = await event_callback_future assert status == 'optIn' message_type, message_payload = await asyncio.wait_for(client.poll(), 0.5) assert message_type == 'oadrResponse' message_type, message_payload = await asyncio.wait_for(client.poll(), 0.5) assert message_type == 'oadrResponse' #await asyncio.sleep(1) # Wait for the event to be completed await client.stop() await server.stop()
async def test_server_add_event_with_wrong_callback_signature(caplog): def dummy_callback(some_param): pass caplog.set_level(logging.WARNING) logger = logging.getLogger('openleadr') logger.setLevel(logging.DEBUG) server = OpenADRServer(vtn_id='myvtn', requested_poll_freq=timedelta(seconds=1)) with pytest.raises(ValueError) as err: server.add_event( ven_id='venid', event_id='test_server_add_event_with_wrong_callback_signature', signal_name='simple', signal_type='level', intervals=[{ 'dtstart': datetime.now(timezone.utc), 'duration': timedelta(seconds=1), 'signal_payload': 1.1 }], target={'ven_id': 'venid'}, callback=dummy_callback)
async def test_server_warning_naive_datetimes_in_event(caplog): caplog.set_level(logging.WARNING) logger = logging.getLogger('openleadr') logger.setLevel(logging.DEBUG) server = OpenADRServer(vtn_id='myvtn', requested_poll_freq=timedelta(seconds=1)) server.add_event(ven_id='venid', event_id='test_server_warning_naive_datetimes_in_event', signal_name='simple', signal_type='level', intervals=[{ 'dtstart': datetime.now(), 'duration': timedelta(seconds=1), 'signal_payload': 1.1 }], target={'ven_id': 'venid'}, callback=on_event_accepted) assert ("You supplied a naive datetime object to your interval's dtstart. " "This will be interpreted as a timestamp in your local timezone " "and then converted to UTC before sending. Please supply timezone-" "aware timestamps like datetime.datetime.new(timezone.utc) or " "datetime.datetime(..., tzinfo=datetime.timezone.utc)") in [ record.msg for record in caplog.records ]
def test_server_add_event_with_no_intervals(): server = OpenADRServer(vtn_id='myvtn') with pytest.raises(ValueError): server.add_event(ven_id='ven123', signal_name='x-invalid', signal_type='x-loadControlCapacity', intervals=None) with pytest.raises(ValueError): server.add_event(ven_id='ven123', signal_name='x-invalid', signal_type='x-loadControlCapacity', intervals=[]) with pytest.raises(ValueError): server.add_event(ven_id='ven123', signal_name='x-invalid', signal_type='x-loadControlCapacity', intervals={"dtstart": "2021-01-01"})
async def test_multiple_events_in_queue(): now = datetime.datetime.now(datetime.timezone.utc) server = OpenADRServer(vtn_id='myvtn') server.add_handler('on_create_party_registration', on_create_party_registration) loop = asyncio.get_event_loop() event_1_callback_future = loop.create_future() event_2_callback_future = loop.create_future() server.add_event(ven_id='ven123', signal_name='simple', signal_type='level', intervals=[ objects.Interval( dtstart=now, duration=datetime.timedelta(seconds=1), signal_payload=1) ], callback=event_1_callback_future) await server.run() on_event_future = loop.create_future() client = OpenADRClient( ven_name='ven123', vtn_url='http://localhost:8080/OpenADR2/Simple/2.0b') await client.create_party_registration() response_type, response_payload = await client.request_event() assert response_type == 'oadrDistributeEvent' events = response_payload['events'] assert len(events) == 1 event_id = events[0]['event_descriptor']['event_id'] request_id = response_payload['request_id'] await client.created_event(request_id=request_id, event_id=event_id, opt_type='optIn', modification_number=0) server.add_event(ven_id='ven123', signal_name='simple', signal_type='level', intervals=[ objects.Interval( dtstart=now + datetime.timedelta(seconds=1), duration=datetime.timedelta(seconds=1), signal_payload=1) ], callback=event_2_callback_future) response_type, response_payload = await client.request_event() assert response_type == 'oadrDistributeEvent' events = response_payload['events'] # Assert that we still have two events in the response assert len(events) == 2 # Wait one second and retrieve the events again await asyncio.sleep(1) response_type, response_payload = await client.request_event() assert response_type == 'oadrDistributeEvent' events = response_payload['events'] assert len(events) == 2 assert events[1]['event_descriptor']['event_status'] == 'completed' response_type, response_payload = await client.request_event() assert response_type == 'oadrDistributeEvent' events = response_payload['events'] assert len(events) == 1 await asyncio.sleep(1) response_type, response_payload = await client.request_event() assert response_type == 'oadrDistributeEvent' response_type, response_payload = await client.request_event() assert response_type == 'oadrResponse' await server.stop()