def test_registry_client_connect_disconnect_fi(): log_message("registry_client = connections.connect_registry_client()") registry_client = connections.connect_registry_client() disconnect_edgehub() connect_edgehub() log_message("registry_client.disconnect()") registry_client.disconnect()
def fin(): print("") log_message("Preforming post-session cleanup") adapters.cleanup_test_objects() log_message("HORTON: post-session cleanup complete") if log_watcher: log_watcher.terminate()
def test_service_client_connect_disconnect_fi(): log_message("service_client = connections.connect_service_client()") service_client = connections.connect_service_client() disconnect_edgehub() connect_edgehub() log_message("service_client.disconnect()") service_client.disconnect()
def restart_edgehub(hard=False): log_message("restarting edgehub") sleep(5) client = docker.from_env() edgeHub = client.containers.get(EDGEHUB_NAME) try: if hard: client = docker.from_env() containerList = list( map(lambda x: x.name, client.containers.list())) for containerName in containerList: if "Mod" or "edgeHub" in containerName: currentContainer = client.containers.get(containerName) currentContainer.restart() while EDGEHUB_NAME not in list( map(lambda x: x.name, client.containers.list())): print("waiting for edge daemon to revive edgehub...") sleep(1) print("updating pointer to edgehub container") edgeHub.reload() else: edgeHub.restart() sleep(5) except Exception as e: log_message("Error: {}".format(sys.exc_info()[0])) raise e
def test_module_client_connect_enable_input_messages_disconnect_fi(): module_client = connections.connect_test_module_client() log_message("Enable Input Messages on Module Client") module_client.enable_input_messages() disconnect_edgehub() # Disconnecting Edgehub connect_edgehub() # Reconnecting EdgeHub log_message("Disconnect Module Client") module_client.disconnect()
def test_module_client_connect_enable_methods_disconnect_fi(): log_message("Connect Test Module Client") module_client = connections.connect_test_module_client() log_message("Enable Methods on Module Client") module_client.enable_methods() disconnect_edgehub() connect_edgehub() module_client.disconnect()
def module_log_fixture(request): print("") log_message("HORTON: Entering module {}".format(request.module.__name__)) def fin(): print("") log_message("HORTON: Exiting module {}".format(request.module.__name__)) request.addfinalizer(fin)
def fin(): print("") if hasattr(request.node, "rep_setup"): log_message("setup: " + str(request.node.rep_setup.outcome)) if hasattr(request.node, "rep_call"): log_message("call: " + str(request.node.rep_call.outcome)) if hasattr(request.node, "rep_teardown"): log_message("teardown: " + str(request.node.rep_call.outcome)) log_message("HORTON: Cleaning up after function {}".format( request.function.__name__)) adapters.cleanup_test_objects() log_message("HORTON: Exiting function {}".format( request.function.__name__)) log_watcher.flush_and_disable()
def restart_edgehub(hard=False): log_message("restarting edgehub") client = docker.from_env() edgeHub = client.containers.get(EDGEHUB_NAME) try: if hard: # cwd = os.getcwd() # clean_script = cwd + "/../scripts/force-restart-iotedge-clean.sh" # log_message(clean_script) # os.system(clean_script) client = docker.from_env() cMod = client.containers.get("cMod") friendMod = client.containers.get("friendMod") edgeHub = client.containers.get("edgeHub") cMod.restart() friendMod.restart() edgeHub.restart() # edgeHub.remove(force=True) while EDGEHUB_NAME not in list( map(lambda x: x.name, client.containers.list()) ): log_message("waiting for edge daemon to revive edgehub...") sleep(1) log_message("updating pointer to edgehub container") edgeHub.reload() else: edgeHub.restart() sleep(5) except Exception as e: log_message("Error: {}".format(sys.exc_info()[0])) raise e
def session_log_fixture(request): print("") log_message("HORTON: Preforming pre-session cleanup") adapters.cleanup_test_objects() log_message("HORTON: pre-session cleanup complete") def fin(): print("") log_message("Preforming post-session cleanup") adapters.cleanup_test_objects() log_message("HORTON: post-session cleanup complete") if log_watcher: log_watcher.terminate() request.addfinalizer(fin)
def test_module_output_routed_upstream(): module_client = connections.connect_test_module_client() eventhub_client = connections.connect_eventhub_client() sent_message = test_utilities.random_string_in_json() module_client.send_output_event(output_name, sent_message) received_message = eventhub_client.wait_for_next_event( environment.edge_device_id, test_utilities.default_eventhub_timeout, expected=sent_message, ) if not received_message: log_message("Message not received") assert False module_client.disconnect() eventhub_client.disconnect()
def test_device_send_event_to_iothub(): device_client = connections.connect_test_device_client() eventhub_client = connections.connect_eventhub_client() sent_message = test_utilities.random_string_in_json() log_message("sending event: " + str(sent_message)) device_client.send_event(sent_message) received_message = eventhub_client.wait_for_next_event( get_current_config().test_device.device_id, test_utilities.default_eventhub_timeout, expected=sent_message, ) if not received_message: log_message("Message not received") assert False device_client.disconnect() eventhub_client.disconnect()
def test_module_output_routed_upstream_fi(): try: module_client = connections.connect_test_module_client() eventhub_client = connections.connect_eventhub_client() disconnect_edgehub() connect_edgehub() sent_message = test_utilities.random_string_in_json() module_client.send_output_event(output_name, sent_message) received_message = eventhub_client.wait_for_next_event( get_current_config().test_module.device_id, test_utilities.default_eventhub_timeout, expected=sent_message, ) if not received_message: log_message("Message not received") assert False module_client.disconnect() eventhub_client.disconnect() finally: restart_edgehub(hard=False)
def test_module_client_connect_enable_twin_disconnect_fi(): log_message("Connect Test Module Client") module_client = connections.connect_test_module_client() log_message("Enable Twin on Module Client") module_client.enable_twin() disconnect_edgehub() connect_edgehub() log_message("Disconnect Module Client") module_client.disconnect()
def disconnect_edgehub(network=True): log_message("disconnecting edgehub from network") try: edgeHub = client.containers.get(EDGEHUB_NAME) if network: if EDGEHUB_NAME in get_network_list(): edge_network.disconnect(EDGEHUB_NAME) sleep(10) else: # Edge Network alreday contains EdgeHub log_message("Note: {} not in IoT Edge Network".format(EDGEHUB_NAME)) else: if EDGEHUB_NAME in list(map(lambda x: x.name, client.containers.list())): edgeHub.restart() else: # Edge Network alreday contains EdgeHub log_message("Note: {} not in IoT Edge Network".format(EDGEHUB_NAME)) except Exception as e: log_message("Error: {}".format(sys.exc_info()[0])) raise e
def do_device_method_call(source_module, destination_module, destination_device_id): """ Helper function which invokes a method call on one module and responds to it from another module """ try: log_message("enabling methods on the destination") destination_module.enable_methods() # start listening for method calls on the destination side log_message("starting to listen from destination module") receiver_thread = destination_module.roundtrip_method_async( method_name, status_code, method_invoke_parameters, method_response_body) time.sleep(time_for_method_to_fully_register) disconnect_edgehub() # invoking the call from caller side time.sleep(5) connect_edgehub() log_message("invoking method call") request_thread = source_module.call_device_method_async( destination_device_id, method_invoke_parameters) response = request_thread.get() print("method call complete. Response is:") print(str(response)) # wait for that response to arrive back at the source and verify that it's all good. log_message("response = " + str(response) + "\n") assert response["status"] == status_code # edge bug: the response that edge returns is stringified. The same response that comes back from an iothub service call is not stringified if isinstance(response["payload"], str): response["payload"] = json.loads(response["payload"]) assert response["payload"] == method_response_body receiver_thread.wait() finally: connect_edgehub() restart_edgehub(hard=False)
def test_module_send_event_to_iothub(): log_message("connecting module client") module_client = connections.connect_test_module_client() log_message("connecting eventhub client") eventhub_client = connections.connect_eventhub_client() sent_message = test_utilities.random_string_in_json() log_message("sending event: " + str(sent_message)) module_client.send_event(sent_message) log_message("wait for event to arrive at eventhub") received_message = eventhub_client.wait_for_next_event( runtime_config.test_module.device_id, test_utilities.default_eventhub_timeout, expected=sent_message, ) if not received_message: log_message("Message not received") assert False log_message("disconnecting module client") module_client.disconnect() log_message("disconnecting eventhub client") eventhub_client.disconnect()
def test_module_input_output_loopback(): log_message("connecting module client") module_client = connections.connect_test_module_client() log_message("enabling input messages") module_client.enable_input_messages() log_message("listening for input messages") input_thread = module_client.wait_for_input_event_async(input_name) sent_message = test_utilities.max_random_string() log_message("sending output event: " + str(sent_message)) module_client.send_output_event(output_name, sent_message) log_message("waiting for input message to arrive") received_message = input_thread.get(receive_timeout) log_message("input message arrived") log_message("expected message: " + str(sent_message)) log_message("received message: " + str(received_message)) assert received_message == sent_message module_client.disconnect()
def test_module_can_set_reported_properties_and_service_can_retrieve_them(): reported_properties_sent = {"foo": random.randint(1, 9999)} log_message("connecting module client") module_client = connections.connect_test_module_client() log_message("enabling twin") module_client.enable_twin() log_message("patching twin") module_client.patch_twin(reported_properties_sent) log_message("disconnecting module client") module_client.disconnect() log_message("module client disconnected") log_message("connecting registry client") registry_client = connections.connect_registry_client() log_message("getting twin") twin_received = registry_client.get_module_twin( runtime_config.test_module.device_id, runtime_config.test_module.module_id) log_message("disconnecting registry client") registry_client.disconnect() log_message("registry client disconnected") reported_properties_received = twin_received["properties"]["reported"] if "$version" in reported_properties_received: del reported_properties_received["$version"] if "$metadata" in reported_properties_received: del reported_properties_received["$metadata"] log_message("expected:" + str(reported_properties_sent)) log_message("received:" + str(reported_properties_received)) assert reported_properties_sent == reported_properties_received
def do_module_method_call( source_module, destination_module, destination_device_id, destination_module_id, registration_sleep=time_for_method_to_fully_register, ): """ Helper function which invokes a method call on one module and responds to it from another module """ log_message("enabling methods on the destination") destination_module.enable_methods() # start listening for method calls on the destination side log_message("starting to listen from destination module") receiver_thread = destination_module.roundtrip_method_async( method_name, status_code, method_invoke_parameters, method_response_body) log_message( "sleeping for {} seconds to make sure all registration is complete". format(registration_sleep)) time.sleep(registration_sleep) disconnect_edgehub() # One point that could be good to disconnect edgeHub # time.sleep(1) connect_edgehub() log_message("Sleeping") time.sleep(30) log_message(" Done Sleeping") # invoking the call from caller side log_message("invoking method call") response = source_module.call_module_method_async( destination_device_id, destination_module_id, method_invoke_parameters).get() log_message("method call complete. Response is:") log_message(str(response)) # wait for that response to arrive back at the source and verify that it's all good. assert response["status"] == status_code # edge bug: the response that edge returns is stringified. The same response that comes back from an iothub service call is not stringified if isinstance(response["payload"], str): response["payload"] = json.loads(response["payload"]) assert response["payload"] == method_response_body receiver_thread.wait()
def test_service_can_set_multiple_desired_property_patches_and_module_can_retrieve_them_as_events_fi( ): log_message("connecting registry client") registry_client = connections.connect_registry_client() log_message("connecting module client") module_client = connections.connect_test_module_client() log_message("enabling twin") module_client.enable_twin() base = random.randint(1, 9999) * 100 for i in range(1, 4): log_message("sending patch #" + str(i) + " through registry client") # Send patch twin_sent = {"properties": {"desired": {"foo": base + i}}} registry_client.patch_module_twin(environment.edge_device_id, environment.module_id, twin_sent) log_message("patch " + str(i) + " sent") log_message("start waiting for patch #" + str(i)) patch_thread = module_client.wait_for_desired_property_patch_async( ) # Set Twin Callback log_message("Fault Injection: disconnecting edgehub") disconnect_edgehub() # DISCONNECTING EGEHUB log_message("Fault Injection: reconnecting edgehub") connect_edgehub() # CONNECTING EDGEHUB sleep(2) log_message("Tringgering patch #" + str(i) + " through registry client") # Trigger Twin Callback registry_client.patch_module_twin(environment.edge_device_id, environment.module_id, twin_sent) log_message("patch " + str(i) + " triggered") log_message("waiting for patch " + str(i) + " to arrive at module client") patch_received = patch_thread.get() # Get twin from patch received log_message("patch received:" + json.dumps(patch_received)) log_message("desired properties sent: " + str(twin_sent["properties"]["desired"]["foo"])) foo_val = get_patch_received(patch_received) if (foo_val == -1): log_message("patch received of invalid format!") assert 0 log_message("desired properties recieved: " + str(foo_val)) assert twin_sent["properties"]["desired"]["foo"] == foo_val registry_client.disconnect() module_client.disconnect()
def fin(): print("") log_message("HORTON: Exiting module {}".format( request.module.__name__))
def test_module_send_multiple_event_iothub_fi(): try: log_message("connecting module client") module_client = connections.connect_test_module_client() log_message("connecting eventhub client") eventhub_client = connections.connect_eventhub_client() log_message("enabling telemetry on eventhub client") eventhub_client.enable_telemetry() log_message("start waiting for events on eventhub") input_thread = eventhub_client.wait_for_event_async( environment.edge_device_id) sent_message = test_utilities.random_string_in_json() log_message("disconnecting edgehub") disconnect_edgehub() # DISCONNECT EDGEHUB print("PYTEST FAKE: begin sending events async...") # Send String of Messages Asynchronously to create a queue for i in range(5): print("PYTEST FAKE: sending event " + str(i) + " async: " + str(sent_message)) thread = module_client.send_event_async(sent_message) connect_edgehub() # RECONNECT EDGEHUB log_message("getting result with timeout: " + str(local_timeout)) thread.wait(local_timeout) # Result is None if successful log_message("wait for event to arrive at eventhub") received_message = input_thread.get( test_utilities.default_eventhub_timeout) log_message("expected event: " + str(sent_message)) log_message("received event: " + str(received_message)) test_utilities.assert_json_equality(received_message, sent_message) log_message("disconnecting module client") module_client.disconnect() log_message("disconnecting eventhub client") eventhub_client.disconnect() finally: restart_edgehub(hard=False)
def test_module_can_set_reported_properties_and_service_can_retrieve_them_fi(): try: reported_properties_sent = {"foo": random.randint(1, 9999)} log_message("connecting module client") module_client = connections.connect_test_module_client() log_message("enabling twin") module_client.enable_twin() log_message("disabling edgehub") sleep(2) disconnect_edgehub() connect_edgehub() module_client.patch_twin(reported_properties_sent) sleep(2) log_message("patched twin") log_message("disconnecting module client") module_client.disconnect() log_message("module client disconnected") log_message("connecting registry client") registry_client = connections.connect_registry_client() log_message("disabling edgehub") sleep(2) disconnect_edgehub() connect_edgehub() sleep(2) log_message("reconnected edgehub") log_message("getting twin") twin_received = registry_client.get_module_twin( get_current_config().test_module.device_id, get_current_config().test_module.module_id, ) log_message("disconnecting registry client") registry_client.disconnect() log_message("registry client disconnected") reported_properties_received = twin_received["properties"]["reported"] if "$version" in reported_properties_received: del reported_properties_received["$version"] if "$metadata" in reported_properties_received: del reported_properties_received["$metadata"] log_message("expected:" + str(reported_properties_sent)) log_message("received:" + str(reported_properties_received)) assert reported_properties_sent == reported_properties_received finally: restart_edgehub() sleep(5)
def test_service_can_set_multiple_desired_property_patches_and_module_can_retrieve_them_as_events(): log_message("connecting registry client") registry_client = connections.connect_registry_client() log_message("connecting module client") module_client = connections.connect_test_module_client() log_message("enabling twin") module_client.enable_twin() base = random.randint(1, 9999) * 100 for i in range(1, 4): log_message("sending patch #" + str(i) + " through registry client") twin_sent = {"properties": {"desired": {"foo": base + i}}} registry_client.patch_module_twin( environment.edge_device_id, environment.module_id, twin_sent ) log_message("patch " + str(i) + " sent") log_message("start waiting for patch #" + str(i)) patch_thread = module_client.wait_for_desired_property_patch_async() log_message("Tringgering patch #" + str(i) + " through registry client") twin_sent = {"properties": {"desired": {"foo": base + i}}} registry_client.patch_module_twin( environment.edge_device_id, environment.module_id, twin_sent ) log_message("patch " + str(i) + " triggered") log_message("getting patch " + str(i) + " on module client") patch_received = patch_thread.get() log_message("patch received:" + json.dumps(patch_received)) log_message( "desired properties sent: " + str(twin_sent["properties"]["desired"]["foo"]) ) # Most of the time, the C wrapper returns a patch with "foo" at the root. Sometimes it # returns a patch with "properties/desired" at the root. I know that this has to do with timing and # the difference between the code that handles the initial GET and the code that handles # the PATCH that arrives later. I suspect it has something to do with the handling for # DEVICE_TWIN_UPDATE_COMPLETE and maybe we occasionally get a full twin when we're waiting # for a patch, but that's just an educated guess. # # I don't know if this is happening in the SDK or in the glue. # this happens relatively rarely. Maybe 1/20, maybe 1/100 times foo_val = get_patch_received(patch_received) if (foo_val == -1): log_message("patch received of invalid format!") assert 0 log_message("desired properties recieved: " + str(foo_val)) assert twin_sent["properties"]["desired"]["foo"] == foo_val registry_client.disconnect() module_client.disconnect()
def test_service_can_set_desired_properties_and_module_can_retrieve_them(): twin_sent = {"properties": {"desired": {"foo": random.randint(1, 9999)}}} log_message("connecting registry client") registry_client = connections.connect_registry_client() log_message("patching twin") registry_client.patch_module_twin( environment.edge_device_id, environment.module_id, twin_sent ) log_message("disconnecting registry client") registry_client.disconnect() log_message("connecting module client") module_client = connections.connect_test_module_client() log_message("enabling twin") module_client.enable_twin() log_message("getting module twin") twin_received = module_client.get_twin() log_message("disconnecting module client") module_client.disconnect() log_message("module client disconnected") log_message("twin sent: " + str(twin_sent)) log_message("twin received:" + str(twin_received)) assert ( twin_sent["properties"]["desired"]["foo"] == twin_received["properties"]["desired"]["foo"] )
def connect_edgehub(network=True): log_message("connecting edgehub to network") try: log_message(" edgeHub = client.containers.get(EDGEHUB_NAME)") edgeHub = client.containers.get(EDGEHUB_NAME) if network: if EDGEHUB_NAME not in get_network_list(): log_message("edge_network.connect(EDGEHUB_NAME)") edge_network.connect(EDGEHUB_NAME) else: # Edge Network alreday contains EdgeHub log_message("Note: {} already in IoT Edge Network".format(EDGEHUB_NAME)) else: log_message("network=False") while edgeHub.status != "running": log_message("edgehub not running") edgeHub.start() log_message("Waiting for edgeHub to come back online...") sleep(1) edgeHub = client.containers.get(EDGEHUB_NAME) log_message("EXITED WHILE LOOP") if edgeHub.status == "running": log_message( "~~~~~~~~~~~~~~~~~~edgeHub started~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ) log_message("sleeping...") sleep(5) log_message("done sleeping!") except Exception as e: log_message( "THIS IS AN EXCEPTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ) log_message("Error: {}".format(sys.exc_info()[0])) raise e
def test_module_send_event_iothub_fi(): try: log_message("connecting module client") module_client = connections.connect_test_module_client() log_message("connecting eventhub client") eventhub_client = connections.connect_eventhub_client() sent_message = test_utilities.random_string_in_json() disconnect_edgehub() # DISCONNECT EDGEHUB log_message("sending event " + " async: " + str(sent_message)) thread = module_client.send_event_async(sent_message) connect_edgehub() # RECONNECT EDGEHUB log_message("getting result with timeout: " + str(local_timeout)) thread.wait(local_timeout) # Result is None if successful log_message("wait for event to arrive at eventhub") received_message = eventhub_client.wait_for_next_event( runtime_config.test_module.device_id, test_utilities.default_eventhub_timeout, expected=sent_message, ) if not received_message: log_message("Message not received") assert False log_message("disconnecting module client") module_client.disconnect() log_message("disconnecting eventhub client") eventhub_client.disconnect() finally: restart_edgehub(hard=False)
def test_module_send_event_iothub_fi(): """ Sends event through Edge Hub to IoT Hub and validates the message is received using the Event Hub API. The module client is in the langauge being tested, and the eventhub client is directly connected to Azure to receive the event. """ log_message("connecting module client") module_client = connections.connect_test_module_client() log_message("connecting eventhub client") eventhub_client = connections.connect_eventhub_client() sent_message = test_utilities.random_string_in_json() log_message("sending event " + " async: " + str(sent_message)) module_client.send_event_async(sent_message) log_message("wait for event to arrive at eventhub") received_message = eventhub_client.wait_for_next_event( get_current_config().test_module.device_id, test_utilities.default_eventhub_timeout, expected=sent_message, ) if not received_message: log_message("Intial message not received") assert False disconnect_edgehub() # DISCONNECT EDGEHUB module_client.send_event_async(sent_message) connect_edgehub() # RECONNECT EDGEHUB received_message = eventhub_client.wait_for_next_event( get_current_config().test_module.device_id, test_utilities.default_eventhub_timeout, expected=sent_message, ) if not received_message: log_message("Second message not received") assert False log_message("disconnecting module client") module_client.disconnect() log_message("disconnecting eventhub client") eventhub_client.disconnect()
def test_service_can_set_desired_properties_and_module_can_retrieve_them_fi(): try: twin_sent = { "properties": { "desired": { "foo": random.randint(1, 9999) } } } log_message("connecting registry client") registry_client = connections.connect_registry_client() log_message("disconnecting edgehub") sleep(2) disconnect_edgehub() # DISCONNECTING EGEHUB connect_edgehub() # CONNECTING EDGEHUB registry_client.patch_module_twin(environment.edge_device_id, environment.module_id, twin_sent) log_message("patching twin") log_message("disconnecting registry client") registry_client.disconnect() log_message("connecting module client") module_client = connections.connect_test_module_client() log_message("enabling twin") module_client.enable_twin() log_message("disconnecting edgehub") sleep(2) disconnect_edgehub() # DISCONNECTING EGEHUB sleep(5) connect_edgehub() # CONNECTING EDGEHUB twin_received = module_client.get_twin() log_message("getting module twin") log_message("disconnecting module client") module_client.disconnect() log_message("module client disconnected") log_message("twin sent: " + str(twin_sent)) log_message("twin received:" + str(twin_received)) assert (twin_sent["properties"]["desired"]["foo"] == twin_received["properties"]["desired"]["foo"]) finally: cMod = client.containers.get("cMod") friendMod = client.containers.get("friendMod") edgeHub = client.containers.get("edgeHub") edgeHub.restart() friendMod.restart() cMod.restart()