def test_swim_client_with_statement_exception_callback_and_terminate( self, mock_exit, mock_warn_tb, mock_warn): # Given mock_callback = mock_exception_callback # When with SwimClient(terminate_on_exception=True, execute_on_exception=mock_callback, debug=True) as swim_client: # Then self.assertIsInstance(swim_client, SwimClient) self.assertIsInstance(swim_client.loop, asyncio.events.AbstractEventLoop) self.assertFalse(swim_client.loop.is_closed()) self.assertTrue(swim_client.loop_thread.is_alive()) self.assertIsInstance(swim_client.loop_thread, Thread) swim_client.task_with_exception = lambda: (_ for _ in ()).throw( Exception, Exception('Mock exception in task')) swim_client.task_with_exception() mock_exit.assert_called_once_with(1) self.assertTrue(swim_client.loop.is_closed()) self.assertEqual('Mock exception in task', mock_warn.call_args_list[0][0][0]) mock_warn_tb.assert_called_once() mock_warn.assert_called_once() self.assertFalse(swim_client.loop_thread.is_alive())
async def test_downlink_view_open(self, mock_websocket_connect): message = '@event(node:"boo/bar",lane:shop)' MockWebsocket.get_mock_websocket().messages_to_send.append(message) loop_class = ReceiveLoop() MockWebsocket.get_mock_websocket( ).custom_recv_func = loop_class.recv_loop # Given with SwimClient(debug=True) as client: downlink = ValueDownlinkView(client) downlink.set_host_uri('ws://127.0.0.1') downlink.set_node_uri('boo/bar') downlink.set_lane_uri('shop') downlink.did_set(mock_did_set_confirmation) # When actual = downlink.open() while loop_class.call_count == 0: pass # Then self.assertTrue(actual.is_open) # await asyncio.sleep(2) # self.assertFalse(actual.is_open) self.assertTrue(mock_websocket_connect.called) self.assertIsInstance(actual.model, DownlinkModel)
async def test_downlink_model_receive_message_unlinked(self, mock_warn): # Given with SwimClient(execute_on_exception=MockExecuteOnException. get_mock_execute_on_exception()) as client: downlink = EventDownlinkModel(client) downlink.connection = MockConnection.get_mock_connection() downlink.connection.owner = downlink body = RecordMap.create() body.add(Attr.create_attr('laneNotFound', 'foo')) unlinked_message = UnlinkedResponse('unlinked_node', 'unlinked_lane', body=body) downlink.connection.messages_to_receive.append(unlinked_message) # When actual = downlink.open() while not MockExecuteOnException.get_mock_execute_on_exception( ).called: pass # Then self.assertEqual(downlink, actual) self.assertEqual('Lane "None" was not found on the remote agent!', mock_warn.call_args_list[0][0][0])
def test_swim_client_command_before_open(self): # Given swim_client = SwimClient() # When downlink_event = swim_client.downlink_event() # Then self.assertIsInstance(downlink_event, _EventDownlinkView) self.assertEqual(downlink_event._client, swim_client)
def test_swim_client_downlink_value_open_before_client_started(self, mock_warn): # Given swim_client = SwimClient() # When downlink_value = swim_client.downlink_value() downlink_value.open() # Then self.assertEqual('Cannot execute "_add_downlink_view" before the client has been started!', mock_warn.call_args_list[0][0][0])
def test_swim_client_test_schedule_task_that_is_cancelled(self): # Given mock_task = MockScheduleTask.get_mock_schedule_task() with SwimClient() as swim_client: # When actual = swim_client._schedule_task(mock_task.async_infinite_cancel_execute) # Then self.assertIsInstance(actual, futures.Future) self.assertTrue(actual.cancelled())
def test_swim_client_downlink_event(self): # Given with SwimClient() as swim_client: # When downlink_event = swim_client.downlink_event() # Then self.assertIsInstance(downlink_event, EventDownlinkView) self.assertEqual(downlink_event.client, swim_client)
def test_swim_client_downlink_map(self): # Given with SwimClient() as swim_client: # When downlink_map = swim_client.downlink_map() # Then self.assertIsInstance(downlink_map, MapDownlinkView) self.assertEqual(downlink_map.client, swim_client)
def test_swim_client_downlink_value(self): # Given with SwimClient() as swim_client: # When downlink_view = swim_client.downlink_value() # Then self.assertIsInstance(downlink_view, ValueDownlinkView) self.assertEqual(downlink_view.client, swim_client)
async def test_downlink_view_set_lane_uri(self): # Given with SwimClient() as client: downlink = EventDownlinkView(client) lane_uri = 'shop' # When actual = downlink.set_lane_uri(lane_uri) # Then self.assertEqual(downlink, actual) self.assertEqual(lane_uri, actual.lane_uri)
async def test_create_event_downlink_model(self): # Given with SwimClient() as client: # When actual = EventDownlinkModel(client) # Then self.assertIsInstance(actual, EventDownlinkModel) self.assertIsInstance(actual, DownlinkModel) self.assertEqual(client, actual.client) self.assertFalse(actual.linked.is_set())
async def test_downlink_view_set_node_uri(self): # Given with SwimClient() as client: downlink = EventDownlinkView(client) node_uri = 'boo/bar' # When actual = downlink.set_node_uri(node_uri) # Then self.assertEqual(downlink, actual) self.assertEqual(node_uri, actual.node_uri)
async def test_downlink_view_set_host_uri_warp(self): # Given with SwimClient() as client: downlink = EventDownlinkView(client) host_uri = 'warp://127.0.0.1' # When actual = downlink.set_host_uri(host_uri) # Then self.assertEqual(downlink, actual) self.assertEqual('ws://127.0.0.1', actual.host_uri)
def test_swim_client_stop(self): # Given client = SwimClient() client.start() # When actual = client.stop() # Then self.assertEqual(client, actual) self.assertIsInstance(actual.loop, asyncio.events.AbstractEventLoop) self.assertIsInstance(actual.loop_thread, Thread) self.assertTrue(actual.loop.is_closed()) self.assertFalse(actual.loop_thread.is_alive())
async def test_create_event_downlink_view(self): # Given with SwimClient() as client: # When actual = EventDownlinkView(client) # Then self.assertIsInstance(actual, EventDownlinkView) self.assertIsInstance(actual, DownlinkView) self.assertEqual(client, actual.client) self.assertFalse(actual.is_open) self.assertFalse(actual.strict)
async def test_downlink_view_route(self): # Given with SwimClient() as client: downlink = EventDownlinkView(client) node_uri = 'boo/bar' lane_uri = 'shop' downlink.set_node_uri(node_uri) downlink.set_lane_uri(lane_uri) # When actual = downlink.route # Then self.assertEqual(f'{node_uri}/{lane_uri}', actual)
async def test_swim_client_test_schedule_task(self): # Given mock_task = MockScheduleTask.get_mock_schedule_task() with SwimClient() as swim_client: # When actual = swim_client.schedule_task(mock_task.async_execute, 'foo') while not actual.done(): pass # Then self.assertEqual(1, mock_task.call_count) self.assertEqual('foo', mock_task.message) self.assertIsInstance(actual, futures.Future)
async def test_open_downlink_model(self): # Given with SwimClient() as client: downlink = EventDownlinkModel(client) downlink.connection = MockConnection.get_mock_connection() # When actual = downlink.open() # Then self.assertFalse(actual.task.done()) self.assertTrue(actual.task.done()) self.assertEqual(downlink, actual) self.assertIsInstance(actual.task, Future)
def test_swim_client_with_statement(self): # When with SwimClient() as swim_client: # Then self.assertIsInstance(swim_client, SwimClient) self.assertIsInstance(swim_client.loop, asyncio.events.AbstractEventLoop) self.assertIsInstance(swim_client.loop_thread, Thread) self.assertFalse(swim_client.loop.is_closed()) self.assertIsInstance(swim_client.loop, asyncio.events.AbstractEventLoop) self.assertIsInstance(swim_client.loop_thread, Thread) self.assertTrue(swim_client.loop.is_closed()) self.assertFalse(swim_client.loop_thread.is_alive())
def test_swim_client_test_schedule_task_that_raises_exception(self, mock_warn_tb, mock_warn): # Given mock_task = MockScheduleTask.get_mock_schedule_task() with SwimClient(debug=True) as swim_client: # When actual = swim_client._schedule_task(mock_task.async_exception_execute, 'foo') while not actual.done(): pass # Then mock_warn_tb.assert_called_once() mock_warn.assert_called_once() self.assertEqual('Mock async execute exception', mock_warn.call_args_list[0][0][0]) self.assertEqual(1, mock_task.call_count) self.assertEqual('foo', mock_task.message) self.assertIsInstance(actual, futures.Future)
def test_swim_client_command(self, mock_websocket_connect): # Given host_uri = 'ws://*****:*****@command(node:moo,lane:cow)"Hello, World!"' with SwimClient() as swim_client: # When actual = swim_client.command(host_uri, node_uri, lane_uri, Text.create_from('Hello, World!')) while not actual.done(): pass # Then self.assertIsInstance(actual, futures.Future) mock_websocket_connect.assert_called_once_with(host_uri) self.assertEqual(expected, MockWebsocket.get_mock_websocket().sent_messages[0])
def test_swim_client_test_schedule_task_exception_debug(self, mock_print_tb, mock_warn): # Given mock_task = MockScheduleTask.get_mock_schedule_task() original_run = asyncio.run_coroutine_threadsafe with patch('asyncio.run_coroutine_threadsafe', new_callable=MockRunWithExceptionOnce) as mock_run: mock_exception_once = MockExceptionOnce.get_mock_exception_once() mock_exception_once.actual_function = original_run mock_run.side_effect = mock_exception_once.side_effect # When with SwimClient(debug=True) as swim_client: actual = swim_client._schedule_task(mock_task.sync_execute, 'foo') self.assertEqual('Mock exception', mock_warn.call_args_list[0][0][0]) mock_print_tb.assert_called_once() self.assertIsNone(actual)
async def test_downlink_model_receive_message_linked(self): # Given with SwimClient() as client: downlink = EventDownlinkModel(client) downlink.connection = MockConnection.get_mock_connection() downlink.connection.owner = downlink linked_message = LinkedResponse('linked_node', 'linked_lane') downlink.connection.messages_to_receive.append(linked_message) # When actual = downlink.open() while not actual.linked.is_set(): pass # Then self.assertEqual(downlink, actual) self.assertTrue(actual.linked.is_set())
async def test_swim_client_get_connection(self, mock_get_connection): # Given host_uri = 'ws://*****:*****@synced(node:"moo",lane:"cow")') with SwimClient() as swim_client: downlink_view = swim_client.downlink_value() downlink_view._host_uri = host_uri downlink_view._node_uri = node_uri downlink_view._lane_uri = lane_uri # When await swim_client._get_connection(host_uri) # Then mock_get_connection.assert_called_once_with(host_uri)
def test_swim_client_with_statement_exception_no_handler(self, mock_warn_tb, mock_warn): # When with SwimClient(debug=True) as swim_client: # Then self.assertIsInstance(swim_client, SwimClient) self.assertIsInstance(swim_client._loop, asyncio.events.AbstractEventLoop) self.assertIsInstance(swim_client._loop_thread, Thread) self.assertFalse(swim_client._loop.is_closed()) self.assertTrue(swim_client._loop_thread.is_alive()) swim_client.task_with_exception = lambda: (_ for _ in ()).throw(Exception, Exception('Mock exception in task')) swim_client.task_with_exception() mock_warn.assert_called_once() mock_warn_tb.assert_called_once() self.assertEqual('Mock exception in task', mock_warn.call_args_list[0][0][0]) self.assertTrue(swim_client._loop.is_closed()) self.assertFalse(swim_client._loop_thread.is_alive())
async def test_downlink_model_receive_message_event(self): # Given with SwimClient() as client: downlink = ValueDownlinkModel(client) downlink.connection = MockConnection.get_mock_connection() downlink.connection.owner = downlink downlink_manager = DownlinkManager(downlink.connection) downlink.downlink_manager = downlink_manager event_message = EventMessage( 'event_node', 'event_lane', Record.create_from(Text.create_from('event_body'))) downlink.connection.messages_to_receive.append(event_message) # When actual = downlink.open() while not actual.value: pass # Then self.assertEqual(downlink, actual) self.assertEqual('event_body', actual.value.value)
async def test_swim_client_remove_downlink_view(self, mock_remove_downlink, mock_add_downlink): # Given host_uri = 'ws://*****:*****@synced(node:"moo",lane:"cow")') with SwimClient() as swim_client: downlink_view = swim_client.downlink_value() downlink_view.host_uri = host_uri downlink_view.node_uri = node_uri downlink_view.lane_uri = lane_uri await swim_client.add_downlink_view(downlink_view) # When await swim_client.remove_downlink_view(downlink_view) # Then mock_add_downlink.assert_called_once_with(downlink_view) mock_remove_downlink.assert_called_once_with(downlink_view)
# Copyright 2015-2020 SWIM.AI inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import time from swimai import SwimClient from swimai.structures import Value if __name__ == '__main__': with SwimClient() as swim_client: host_uri = 'ws://localhost:9001' node_uri = '/unit/foo' for i in range(0, 10): swim_client.command(host_uri, node_uri, 'publish', Value.absent()) time.sleep(5) print('Stopping the client in 2 seconds') time.sleep(2)
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Setting the value of a value lane on a remote agent. import time from swimai import SwimClient from swimai.structures import Num async def custom_on_event_callback(event): print(f'link received event: {event}') with SwimClient(debug=True) as swim_client: host_uri = 'ws://localhost:9001' node_uri = '/unit/foo' lane_uri = 'publishValue' event_downlink = swim_client.downlink_event() event_downlink.set_host_uri('ws://localhost:9001') event_downlink.set_node_uri(node_uri) event_downlink.set_lane_uri(lane_uri) event_downlink.on_event(custom_on_event_callback) event_downlink.open() new_value = 'Hello from Python!' swim_client.command(host_uri, node_uri, "publish", Num.create_from(13)) print('Stopping the client in 5 seconds')