def test_parallel_operations(client_server): """Make sure operations run in parallel. This unit test will deadlock if parallel operations are not supported. """ loop, client, server = client_server event = loop.create_event() async def _set_event(payload, context): event.set() async def _wait_event(payload, context): await event.wait() server.register_command('set', _set_event, Verifier()) server.register_command('wait', _wait_event, Verifier()) async def deadlock_if_not_parallel(): wait_task = loop.add_task( client.send_command('wait', {}, Verifier(), timeout=1)) set_task = loop.add_task( client.send_command('set', {}, Verifier(), timeout=1)) await wait_task.task await set_task.task loop.run_coroutine(deadlock_if_not_parallel())
def test_event_sending(client_server): """Make sure we can send and receive events.""" loop, client, server = client_server shared = [0] async def _send_event(payload, context): server = context.server con = context.connection await server.send_event(con, payload, 5) def event_callback(payload): shared[0] += payload server.register_command('send_event', _send_event, StringVerifier()) client.register_event('event1', event_callback, IntVerifier()) loop.run_coroutine(client.send_command('send_event', 'event1', Verifier())) assert shared[0] == 5 loop.run_coroutine(client.send_command('send_event', 'event1', Verifier())) assert shared[0] == 10 loop.run_coroutine(client.send_command('send_event', 'event2', Verifier())) assert shared[0] == 10
async def deadlock_if_not_parallel(): wait_task = loop.add_task( client.send_command('wait', {}, Verifier(), timeout=1)) set_task = loop.add_task( client.send_command('set', {}, Verifier(), timeout=1)) await wait_task.task await set_task.task
def test_format_short_only(): """ Make sure names are properly formatted with short descs """ short_only_desc = "this is a short desc" ver = Verifier(short_only_desc) val = ver.format_name('Test') assert val == 'Test: this is a short desc\n'
def test_format_short_long(): """Make sure names with both short and long desc are formatted correctly """ short_long = "short desc\n\nthis is a longer desc\nhello, this is line 2" ver = Verifier(short_long) val = ver.format_name('Test') assert val == 'Test: short desc\n' + ' ' + 'this is a longer desc\n' + ' ' + 'hello, this is line 2\n'
def test_format_long_only(): """ Make sure names are properly formatted """ long_only_desc = "this is a longer desc\nhello, this is line 2" ver = Verifier(long_only_desc) val = ver.format_name('Test') assert val == 'Test\n' + ' ' + 'this is a longer desc\n' + ' ' + 'hello, this is line 2\n'
def test_desc_cleanup(): """Make sure descriptions are properly cleaned of whitespace """ desc = """ short desc long form desc starts here """ ver = Verifier(desc) val = ver.format_name('Test') assert val == 'Test: short desc\n' + ' ' + 'long form desc starts here\n'
def post_command(self, command, args): """Post a command asynchronously and don't wait for a response. There is no notification of any error that could happen during command execution. A log message will be generated if an error occurred. The command's response is discarded. This method is thread-safe and may be called from inside or ouside of the background event loop. If there is no connection, no error will be raised (though an error will be logged). Args: command (string): The command name args (dict): Optional arguments """ self._loop.log_coroutine(self.send_command(command, args, Verifier()))
from ws4py.client.threadedclient import WebSocketClient from future.utils import viewitems import threading import msgpack import datetime import logging import uuid from iotile.core.exceptions import IOTileException, InternalError, ValidationError, TimeoutExpiredError from iotile.core.utilities.schema_verify import Verifier, DictionaryVerifier, StringVerifier, LiteralVerifier, OptionsVerifier # The prescribed schema of command response messages # Messages with this format are automatically processed inside the ValidatingWSClient SuccessfulResponseSchema = DictionaryVerifier() SuccessfulResponseSchema.add_required('type', LiteralVerifier('response')) SuccessfulResponseSchema.add_required('success', LiteralVerifier(True)) SuccessfulResponseSchema.add_optional('payload', Verifier()) FailureResponseSchema = DictionaryVerifier() FailureResponseSchema.add_required('type', LiteralVerifier('response')) FailureResponseSchema.add_required('success', LiteralVerifier(False)) FailureResponseSchema.add_required('reason', StringVerifier()) ResponseSchema = OptionsVerifier(SuccessfulResponseSchema, FailureResponseSchema) class ValidatingWSClient(WebSocketClient): """A threaded websocket client that validates messages received. Messages are assumed to be packed using msgpack in a binary format and are decoded and validated against message type schema. Matching messages are dispatched to the appropriate handler and messages that
"description", StringVerifier("A short description for what the action is doing")) ActionItem.add_optional( "use", ListVerifier(StringVerifier("The name of a resource"), desc="A list of used resources")) ActionItem.add_optional( "open_before", ListVerifier(StringVerifier("The name of a resource"), desc="A list of resources to open before this step")) ActionItem.add_optional( "close_after", ListVerifier(StringVerifier("The name of a resource"), desc="A list of resources to close after this step")) ActionItem.key_rule(None, Verifier("A parameter passed into the underlying action") ) # Allow any additional values ResourceItem = DictionaryVerifier( desc="A shared resource that can be used by one or more action steps") ResourceItem.add_required( "name", StringVerifier( "The name of the resource so it can be referenced in a step")) ResourceItem.add_required( "type", StringVerifier( "A unique string identifying what type of resource should be created")) ResourceItem.add_optional( "autocreate", BooleanVerifier(
ProbeCommand = NoneVerifier() ProbeResponse = NoneVerifier() # Send RPC SendRPCCommand = DictionaryVerifier() SendRPCCommand.add_required('connection_string', StringVerifier()) SendRPCCommand.add_required('address', IntVerifier()) SendRPCCommand.add_required('rpc_id', IntVerifier()) SendRPCCommand.add_required('timeout', FloatVerifier()) SendRPCCommand.add_required('payload', BytesVerifier(encoding="base64")) SendRPCResponse = DictionaryVerifier() SendRPCResponse.add_required('status', IntVerifier()) SendRPCResponse.add_required('payload', BytesVerifier(encoding="base64")) # Send script SendScriptCommand = DictionaryVerifier() SendScriptCommand.add_required('connection_string', StringVerifier()) SendScriptCommand.add_required('fragment_count', IntVerifier()) SendScriptCommand.add_required('fragment_index', IntVerifier()) SendScriptCommand.add_required('script', BytesVerifier(encoding="base64")) SendScriptResponse = NoneVerifier() SendDebugCommand = DictionaryVerifier() SendScriptCommand.add_required('connection_string', StringVerifier()) SendDebugCommand.add_required('command', StringVerifier()) SendDebugCommand.add_required('args', Verifier()) SendDebugResponse = Verifier()
SuccessfulCommandResponse = DictionaryVerifier() # pylint: disable=C0103 SuccessfulCommandResponse.add_required('type', LiteralVerifier('response')) SuccessfulCommandResponse.add_required('client', StringVerifier()) SuccessfulCommandResponse.add_required('success', LiteralVerifier(True)) FailedCommandResponse = DictionaryVerifier() # pylint: disable=C0103 FailedCommandResponse.add_required('type', LiteralVerifier('response')) FailedCommandResponse.add_required('client', StringVerifier()) FailedCommandResponse.add_required('success', LiteralVerifier(False)) FailedCommandResponse.add_required('failure_reason', StringVerifier()) ProbeResponse = DictionaryVerifier() # pylint: disable=C0103 ProbeResponse.add_required('type', LiteralVerifier('response')) ProbeResponse.add_required('client', StringVerifier()) ProbeResponse.add_required('success', LiteralVerifier(True)) ProbeResponse.add_required('devices', ListVerifier(Verifier())) # Possible Responses to a Connect Command SuccessfulConnectionResponse = DictionaryVerifier() # pylint: disable=C0103 SuccessfulConnectionResponse.add_required('type', LiteralVerifier('response')) SuccessfulConnectionResponse.add_required('operation', LiteralVerifier('connect')) SuccessfulConnectionResponse.add_required('client', StringVerifier()) SuccessfulConnectionResponse.add_required('success', LiteralVerifier(True)) FailedConnectionResponse = DictionaryVerifier() # pylint: disable=C0103 FailedConnectionResponse.add_required('type', LiteralVerifier('response')) FailedConnectionResponse.add_required('operation', LiteralVerifier('connect')) FailedConnectionResponse.add_required('client', StringVerifier()) FailedConnectionResponse.add_required('success', LiteralVerifier(False)) FailedConnectionResponse.add_required('failure_reason', StringVerifier())
"""List of notifications handled by the WebSocket plugin.""" from iotile.core.utilities.schema_verify import BytesVerifier, DictionaryVerifier, Verifier, IntVerifier,\ LiteralVerifier, StringVerifier from . import operations Basic = DictionaryVerifier() Basic.add_required('type', LiteralVerifier('notification')) # Device found while scanning DeviceFound = Basic.clone() DeviceFound.add_required('operation', LiteralVerifier(operations.NOTIFY_DEVICE_FOUND)) DeviceFound.add_required('device', Verifier()) # Report Report = Basic.clone() Report.add_required('operation', LiteralVerifier(operations.NOTIFY_REPORT)) Report.add_required('connection_string', StringVerifier()) Report.add_required('payload', BytesVerifier(encoding="base64")) # Trace Trace = Basic.clone() Trace.add_required('operation', LiteralVerifier(operations.NOTIFY_TRACE)) Trace.add_required('connection_string', StringVerifier()) Trace.add_required('payload', BytesVerifier(encoding="base64")) # Script progress Progress = Basic.clone() Progress.add_required('operation', LiteralVerifier(operations.NOTIFY_PROGRESS)) Progress.add_required('connection_string', StringVerifier())
"""List of notifications handled by the Socket plugin.""" from iotile.core.utilities.schema_verify import BytesVerifier, DictionaryVerifier, Verifier, BooleanVerifier, IntVerifier,\ StringVerifier # Device found while scanning ScanEvent = Verifier() # Report SerializedReport = DictionaryVerifier() SerializedReport.add_required('encoded_report', BytesVerifier(encoding="base64")) SerializedReport.add_required('received_time', Verifier()) SerializedReport.add_required('report_format', IntVerifier()) SerializedReport.add_required('origin', IntVerifier()) ReportEvent = DictionaryVerifier() ReportEvent.add_required('connection_string', StringVerifier()) ReportEvent.add_required('serialized_report', SerializedReport) DisconnectionEvent = DictionaryVerifier() DisconnectionEvent.add_required('connection_string', StringVerifier()) DisconnectionEvent.add_required('reason', StringVerifier()) DisconnectionEvent.add_required('expected', BooleanVerifier()) # Trace TraceEvent = DictionaryVerifier() TraceEvent.add_required('connection_string', StringVerifier()) TraceEvent.add_required('payload', BytesVerifier(encoding="base64")) # Script and debug progress
"""The classes of messages supported by this socket impementation.""" from iotile.core.utilities.schema_verify import Verifier, NoneVerifier, DictionaryVerifier, StringVerifier from iotile.core.utilities.schema_verify import LiteralVerifier, OptionsVerifier # The prescribed schema of command response messages # Messages with this format are automatically processed inside the Client COMMAND = DictionaryVerifier() COMMAND.add_required('type', LiteralVerifier('command')) COMMAND.add_required('operation', StringVerifier()) COMMAND.add_required('uuid', StringVerifier()) COMMAND.add_optional('payload', Verifier()) SUCCESSFUL_RESPONSE = DictionaryVerifier() SUCCESSFUL_RESPONSE.add_required('uuid', StringVerifier()) SUCCESSFUL_RESPONSE.add_required('type', LiteralVerifier('response')) SUCCESSFUL_RESPONSE.add_required('success', LiteralVerifier(True)) SUCCESSFUL_RESPONSE.add_optional('payload', Verifier()) FAILURE_RESPONSE = DictionaryVerifier() FAILURE_RESPONSE.add_required('type', LiteralVerifier('response')) FAILURE_RESPONSE.add_required('uuid', StringVerifier()) FAILURE_RESPONSE.add_required('success', LiteralVerifier(False)) FAILURE_RESPONSE.add_required('reason', StringVerifier()) FAILURE_RESPONSE.add_required( 'exception_class', OptionsVerifier(StringVerifier(), NoneVerifier())) RESPONSE = OptionsVerifier(SUCCESSFUL_RESPONSE, FAILURE_RESPONSE) EVENT = DictionaryVerifier() EVENT.add_required('type', LiteralVerifier('event'))