def consumed_exposed_pair(): """Returns a dict with two keys: * consumed_thing: A ConsumedThing instance. The Servient instance that contains this ConsumedThing has been patched to use the ExposedThingProxyClient Protocol Binding client. * exposed_thing: The ExposedThing behind the previous ConsumedThing (for assertion purposes).""" servient = Servient() exp_thing = ExposedThing(servient=servient, thing=Thing(id=uuid.uuid4().urn)) servient.select_client = MagicMock( return_value=ExposedThingProxyClient(exp_thing)) @tornado.gen.coroutine def lower(parameters): input_value = parameters.get("input") yield tornado.gen.sleep(0) raise tornado.gen.Return(str(input_value).lower()) exp_thing.add_property(uuid.uuid4().hex, _build_property_fragment()) exp_thing.add_action(uuid.uuid4().hex, _build_action_fragment(), lower) exp_thing.add_event(uuid.uuid4().hex, _build_event_fragment()) td = ThingDescription.from_thing(exp_thing.thing) return { "consumed_thing": ConsumedThing(servient=servient, td=td), "exposed_thing": exp_thing }
def all_protocols_servient(): """Returns a Servient configured to use all available protocol bindings.""" servient = Servient(catalogue_port=None) http_port = find_free_port() http_server = HTTPServer(port=http_port) servient.add_server(http_server) ws_port = find_free_port() ws_server = WebsocketServer(port=ws_port) servient.add_server(ws_server) if is_coap_supported(): from wotpy.protocols.coap.server import CoAPServer coap_port = find_free_port() coap_server = CoAPServer(port=coap_port) servient.add_server(coap_server) if is_mqtt_supported(): from wotpy.protocols.mqtt.server import MQTTServer from tests.protocols.mqtt.broker import get_test_broker_url, is_test_broker_online if is_test_broker_online(): mqtt_server = MQTTServer(broker_url=get_test_broker_url()) servient.add_server(mqtt_server) @tornado.gen.coroutine def start(): raise tornado.gen.Return((yield servient.start())) wot = tornado.ioloop.IOLoop.current().run_sync(start) td_dict = { "id": uuid.uuid4().urn, "title": uuid.uuid4().hex, "properties": { uuid.uuid4().hex: { "observable": True, "type": "string" } } } td = ThingDescription(td_dict) exposed_thing = wot.produce(td.to_str()) exposed_thing.expose() yield servient @tornado.gen.coroutine def shutdown(): yield servient.shutdown() tornado.ioloop.IOLoop.current().run_sync(shutdown)
def test_discovery_method_multicast_dnssd(): """Things can be discovered usin the multicast method supported by DNS-SD.""" catalogue_port_01 = find_free_port() catalogue_port_02 = find_free_port() instance_name_01 = "servient-01-{}".format(Faker().pystr()) instance_name_02 = "servient-02-{}".format(Faker().pystr()) servient_01 = Servient(catalogue_port=catalogue_port_01, dnssd_enabled=True, dnssd_instance_name=instance_name_01) servient_02 = Servient(catalogue_port=catalogue_port_02, dnssd_enabled=True, dnssd_instance_name=instance_name_02) future_done, found = tornado.concurrent.Future(), [] def resolve(): len(found) == 2 and not future_done.done() and future_done.set_result( True) @tornado.gen.coroutine def test_coroutine(): wot_01 = yield servient_01.start() wot_02 = yield servient_02.start() wot_01.produce(ThingFragment(TD_DICT_01)).expose() wot_01.produce(ThingFragment(TD_DICT_02)).expose() thing_filter = ThingFilterDict(method=DiscoveryMethod.MULTICAST) observable = wot_02.discover(thing_filter, dnssd_find_kwargs={ "min_results": 1, "timeout": 5 }) subscription = observable.subscribe( on_next=lambda td_str: found.append(ThingDescription(td_str) ) or resolve()) yield future_done assert_equal_td_sequences(found, [TD_DICT_01, TD_DICT_02]) subscription.dispose() yield servient_01.shutdown() yield servient_02.shutdown() run_test_coroutine(test_coroutine)
def main(): LOGGER.info("Creating COAP server on: {}".format(COAP_PORT)) coap_server = CoAPServer(port=COAP_PORT) LOGGER.info("Creating servient with TD catalogue on: {}".format(CATALOGUE_PORT)) servient = Servient(catalogue_port=CATALOGUE_PORT) servient.add_server(coap_server) LOGGER.info("Starting servient") wot = yield servient.start() LOGGER.info("Exposing and configuring Thing") exposed_thing = wot.produce(json.dumps(DESCRIPTION)) exposed_thing.expose()
def test_coroutine(): service_history = asyncio_zeroconf.pop("service_history") port_catalogue = find_free_port() servient = Servient(catalogue_port=port_catalogue) instance_name = Faker().sentence() instance_name = instance_name.strip('.')[:32] yield dnssd_discovery.start() yield dnssd_discovery.register(servient, instance_name=instance_name) while _num_service_instance_items(servient, service_history, instance_name) < 1: yield tornado.gen.sleep(0.1) yield dnssd_discovery.stop() while _num_service_instance_items(servient, service_history, instance_name) < 2: yield tornado.gen.sleep(0.1) assert len([ item[1].startswith(instance_name) for item in service_history ]) == 2 with pytest.raises(Exception): _assert_service_added_removed(servient, service_history) _assert_service_added_removed(servient, service_history, instance_name)
def test_clients_config(): """Custom configuration arguments can be passed to the Servient default protocol clients.""" connect_timeout = random.random() servient = Servient(clients_config={Protocols.HTTP: {"connect_timeout": connect_timeout}}) assert servient.clients[Protocols.HTTP].connect_timeout == connect_timeout
def test_produce_model_str(): """Things can be produced from TD documents serialized to JSON-LD string.""" td_str = json.dumps(TD_EXAMPLE) thing_id = TD_EXAMPLE.get("id") servient = Servient() wot = WoT(servient=servient) assert wot.servient is servient exp_thing = wot.produce(td_str) assert servient.get_exposed_thing(thing_id) assert exp_thing.thing.id == thing_id assert_exposed_thing_equal(exp_thing, TD_EXAMPLE)
async def main(td_url, sleep_time): """Subscribes to all events and properties on the remote Thing.""" wot = WoT(servient=Servient()) consumed_thing = await wot.consume_from_url(td_url) LOGGER.info("ConsumedThing: {}".format(consumed_thing)) subscriptions = [] def subscribe(intrct): LOGGER.info("Subscribing to: {}".format(intrct)) sub = intrct.subscribe( on_next=lambda item: LOGGER.info("{} :: Next :: {}".format(intrct, item)), on_completed=lambda: LOGGER.info("{} :: Completed".format(intrct)), on_error=lambda error: LOGGER.warning("{} :: Error :: {}".format(intrct, error))) subscriptions.append(sub) for name in consumed_thing.properties: if consumed_thing.properties[name].observable: subscribe(consumed_thing.properties[name]) for name in consumed_thing.events: subscribe(consumed_thing.events[name]) await asyncio.sleep(sleep_time) for subscription in subscriptions: LOGGER.info("Disposing: {}".format(subscription)) subscription.dispose()
def http_server(): """Builds an HTTPServer instance that contains an ExposedThing.""" exposed_thing = ExposedThing(servient=Servient(), thing=Thing(id=uuid.uuid4().urn)) exposed_thing.add_property(uuid.uuid4().hex, PropertyFragmentDict({ "type": "number", "observable": True }), value=Faker().pyint()) exposed_thing.add_property(uuid.uuid4().hex, PropertyFragmentDict({ "type": "number", "observable": True }), value=Faker().pyint()) exposed_thing.add_event(uuid.uuid4().hex, EventFragmentDict({"type": "object"})) action_name = uuid.uuid4().hex @tornado.gen.coroutine def triple(parameters): input_value = parameters.get("input") yield tornado.gen.sleep(0) raise tornado.gen.Return(input_value * 3) exposed_thing.add_action( action_name, ActionFragmentDict({ "input": { "type": "number" }, "output": { "type": "number" } }), triple) port = find_free_port() server = HTTPServer(port=port) server.add_exposed_thing(exposed_thing) @tornado.gen.coroutine def start(): yield server.start() tornado.ioloop.IOLoop.current().run_sync(start) yield server @tornado.gen.coroutine def stop(): yield server.stop() tornado.ioloop.IOLoop.current().run_sync(stop)
def test_produce_model_thing_template(): """Things can be produced from ThingTemplate instances.""" thing_id = Faker().url() thing_name = Faker().sentence() thing_template = ThingFragment({"id": thing_id, "name": thing_name}) servient = Servient() wot = WoT(servient=servient) exp_thing = wot.produce(thing_template) assert servient.get_exposed_thing(thing_id) assert exp_thing.id == thing_id assert exp_thing.name == thing_name
def test_discovery_method_local(): """All TDs contained in the Servient are returned when using the local discovery method without defining the fragment nor the query fields.""" servient = Servient(dnssd_enabled=False) wot = WoT(servient=servient) wot.produce(ThingFragment(TD_DICT_01)) wot.produce(ThingFragment(TD_DICT_02)) future_done, found = tornado.concurrent.Future(), [] def resolve(): len(found) == 2 and not future_done.done() and future_done.set_result( True) @tornado.gen.coroutine def test_coroutine(): thing_filter = ThingFilterDict(method=DiscoveryMethod.LOCAL) observable = wot.discover(thing_filter) subscription = observable.subscribe( on_next=lambda td_str: found.append(ThingDescription(td_str) ) or resolve()) yield future_done assert_equal_td_sequences(found, [TD_DICT_01, TD_DICT_02]) subscription.dispose() run_test_coroutine(test_coroutine)
def test_ssl_context(self_signed_ssl_context): """An SSL context can be passed to the WebSockets server to enable encryption.""" exposed_thing = ExposedThing(servient=Servient(), thing=Thing(id=uuid.uuid4().urn)) prop_name = uuid.uuid4().hex exposed_thing.add_property(prop_name, PropertyFragmentDict({ "type": "string", "observable": True }), value=Faker().pystr()) port = find_free_port() server = WebsocketServer(port=port, ssl_context=self_signed_ssl_context) server.add_exposed_thing(exposed_thing) @tornado.gen.coroutine def test_coroutine(): yield server.start() ws_url = build_websocket_url(exposed_thing, server, port) assert WebsocketSchemes.WSS in ws_url with pytest.raises(ssl.SSLError): http_req = tornado.httpclient.HTTPRequest(ws_url, method="GET") yield tornado.websocket.websocket_connect(http_req) http_req = tornado.httpclient.HTTPRequest(ws_url, method="GET", validate_cert=False) conn = yield tornado.websocket.websocket_connect(http_req) request_id = Faker().pyint() msg_req = WebsocketMessageRequest( method=WebsocketMethods.READ_PROPERTY, params={"name": prop_name}, msg_id=request_id) conn.write_message(msg_req.to_json()) msg_resp_raw = yield conn.read_message() msg_resp = WebsocketMessageResponse.from_raw(msg_resp_raw) assert msg_resp.id == request_id value = yield exposed_thing.read_property(prop_name) assert value == msg_resp.result yield conn.close() yield server.stop() run_test_coroutine(test_coroutine)
async def fetch_consumed_thing(td_url, protocol): """Gets the remote Thing Description and returns a ConsumedThing.""" clients = [build_protocol_client(protocol)] wot = WoT(servient=Servient(clients=clients)) consumed_thing = await wot.consume_from_url(td_url) return consumed_thing
def build_servient(parsed_args, clients_config=None): """Factory function to build a Servient with a set of servers depending on the input arguments.""" logger = logging.getLogger() logger.info("Creating servient with TD catalogue on: {}".format( parsed_args.port_catalogue)) servient = Servient(catalogue_port=parsed_args.port_catalogue, hostname=parsed_args.hostname, clients_config=clients_config) if parsed_args.port_ws > 0: logger.info("Creating WebSocket server on: {}".format( parsed_args.port_ws)) servient.add_server(WebsocketServer(port=parsed_args.port_ws)) if parsed_args.port_http > 0: logger.info("Creating HTTP server on: {}".format( parsed_args.port_http)) servient.add_server(HTTPServer(port=parsed_args.port_http)) if parsed_args.mqtt_broker: try: from wotpy.protocols.mqtt.server import MQTTServer logger.info("Creating MQTT server on broker: {}".format( parsed_args.mqtt_broker)) mqtt_server = MQTTServer(parsed_args.mqtt_broker, servient_id=servient.hostname) servient.add_server(mqtt_server) logger.info("MQTT server created with ID: {}".format( mqtt_server.servient_id)) except NotImplementedError as ex: logger.warning(ex) if parsed_args.port_coap > 0: try: from wotpy.protocols.coap.server import CoAPServer logger.info("Creating CoAP server on: {}".format( parsed_args.port_coap)) servient.add_server(CoAPServer(port=parsed_args.port_coap)) except NotImplementedError as ex: logger.warning(ex) return servient
def main(): ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.load_cert_chain(certfile="../rsa.crt", keyfile="../rsa.key") LOGGER.info("Creating HTTPs server on: {}".format(HTTP_PORT)) http_server = HTTPServer(port=HTTP_PORT, ssl_context=ssl_context) LOGGER.info( "Creating servient with TD catalogue on: {}".format(CATALOGUE_PORT)) servient = Servient(catalogue_port=CATALOGUE_PORT) servient.add_server(http_server) LOGGER.info("Starting servient") wot = yield servient.start() LOGGER.info("Exposing and configuring Thing") exposed_thing = wot.produce(json.dumps(DESCRIPTION)) exposed_thing.expose()
def mqtt_server(request): """Builds a MQTTServer instance that contains an ExposedThing.""" from wotpy.protocols.mqtt.server import MQTTServer from tests.protocols.mqtt.broker import get_test_broker_url exposed_thing = ExposedThing(servient=Servient(), thing=Thing(id=uuid.uuid4().urn)) exposed_thing.add_property(uuid.uuid4().hex, PropertyFragmentDict({ "type": "string", "observable": True }), value=Faker().sentence()) exposed_thing.add_event(uuid.uuid4().hex, EventFragmentDict({"type": "number"})) action_name = uuid.uuid4().hex @tornado.gen.coroutine def handler(parameters): input_value = parameters.get("input") yield tornado.gen.sleep(random.random() * 0.1) raise tornado.gen.Return("{:f}".format(input_value)) exposed_thing.add_action( action_name, ActionFragmentDict({ "input": { "type": "number" }, "output": { "type": "string" } }), handler) server = MQTTServer(broker_url=get_test_broker_url(), **request.param) server.add_exposed_thing(exposed_thing) @tornado.gen.coroutine def start(): yield server.start() tornado.ioloop.IOLoop.current().run_sync(start) yield server @tornado.gen.coroutine def stop(): yield server.stop() tornado.ioloop.IOLoop.current().run_sync(stop)
def main(): global buf LOGGER.info("Creating HTTP server on: {}".format(HTTP_PORT)) http_server = HTTPServer(port=HTTP_PORT) LOGGER.info("Creating servient with TD catalogue on: {}".format(CATALOGUE_PORT)) servient = Servient(catalogue_port=CATALOGUE_PORT) servient.add_server(http_server) while len(buf) < int(sys.argv[1]): r = random.random() c = math.floor(r*256) buf += format(c, 'x') LOGGER.info("Starting servient") wot = yield servient.start() LOGGER.info("Exposing and configuring Thing") exposed_thing = wot.produce(json.dumps(DESCRIPTION)) exposed_thing.set_property_read_handler("bench", bench_handler) exposed_thing.expose()
def test_discovery_fragment(): """The Thing filter fragment attribute enables discovering Things by matching TD fields.""" servient = Servient(dnssd_enabled=False) wot = WoT(servient=servient) wot.produce(ThingFragment(TD_DICT_01)) wot.produce(ThingFragment(TD_DICT_02)) def first(thing_filter): """Returns the first TD discovery for the given Thing filter.""" future_done, found = tornado.concurrent.Future(), [] def resolve(): not future_done.done() and future_done.set_result(True) @tornado.gen.coroutine def discover_first(): observable = wot.discover(thing_filter) subscription = observable.subscribe( on_next=lambda td_str: found.append(ThingDescription(td_str) ) or resolve()) yield future_done subscription.dispose() assert len(found) raise tornado.gen.Return(found[0]) return tornado.ioloop.IOLoop.current().run_sync( discover_first, timeout=TIMEOUT_DISCOVER) fragment_td_pairs = [({ "name": TD_DICT_01.get("name") }, TD_DICT_01), ({ "version": { "instance": "2.0.0" } }, TD_DICT_02), ({ "id": TD_DICT_02.get("id") }, TD_DICT_02), ({ "security": [{ "scheme": "psk" }] }, TD_DICT_01)] for fragment, td_expected in fragment_td_pairs: td_found = first( ThingFilterDict(method=DiscoveryMethod.LOCAL, fragment=fragment)) assert_equal_tds(td_found, td_expected)
async def main(): """Main entrypoint.""" LOGGER.info("Creating WebSocket server on: {}".format(PORT_WS)) ws_server = WebsocketServer(port=PORT_WS) LOGGER.info("Creating HTTP server on: {}".format(PORT_HTTP)) http_server = HTTPServer(port=PORT_HTTP) LOGGER.info("Creating MQTT server on broker: {}".format(MQTT_BROKER)) mqtt_server = MQTTServer(MQTT_BROKER) LOGGER.info( "Creating servient with TD catalogue on: {}".format(PORT_CATALOGUE)) servient = Servient(catalogue_port=PORT_CATALOGUE) servient.add_server(ws_server) servient.add_server(http_server) servient.add_server(mqtt_server) LOGGER.info("Starting servient") wot = await servient.start() LOGGER.info("Exposing System Monitor Thing") exposed_thing = wot.produce(json.dumps(DESCRIPTION)) exposed_thing.set_property_read_handler("cpuPercent", cpu_percent_handler) exposed_thing.properties["cpuThreshold"].write(DEFAULT_CPU_THRESHOLD) exposed_thing.expose() create_cpu_check_task(exposed_thing)
def test_thing_fragment_getters_setters(): """ThingFragment attributes can be get and set from the ExposedThing.""" thing_fragment = ThingFragment({ "id": uuid.uuid4().urn, "name": Faker().pystr(), "description": Faker().pystr(), "properties": { uuid.uuid4().hex: { "description": Faker().pystr(), "type": DataType.STRING } } }) thing = Thing(thing_fragment=thing_fragment) exp_thing = ExposedThing(servient=Servient(), thing=thing) assert exp_thing.name == thing_fragment.name assert exp_thing.description == thing_fragment.description assert list(exp_thing.properties) == list( six.iterkeys(thing_fragment.properties)) name_original = thing_fragment.name name_updated = Faker().pystr() description_original = thing_fragment.description description_updated = Faker().pystr() exp_thing.name = name_updated exp_thing.description = description_updated assert exp_thing.name == name_updated assert exp_thing.name != name_original assert exp_thing.description == description_updated assert exp_thing.description != description_original with pytest.raises(AttributeError): # noinspection PyPropertyAccess exp_thing.id = Faker().pystr() with pytest.raises(AttributeError): # noinspection PyPropertyAccess exp_thing.properties = Faker().pylist() with pytest.raises(AttributeError): # noinspection PyPropertyAccess exp_thing.actions = Faker().pylist() with pytest.raises(AttributeError): # noinspection PyPropertyAccess exp_thing.events = Faker().pylist()
def main(): global buf ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.load_cert_chain(certfile="../rsa.crt", keyfile="../rsa.key") LOGGER.info("Creating HTTPs server on: {}".format(HTTP_PORT)) http_server = HTTPServer(port=HTTP_PORT, ssl_context=ssl_context) LOGGER.info("Creating servient with TD catalogue on: {}".format(CATALOGUE_PORT)) servient = Servient(catalogue_port=CATALOGUE_PORT) servient.add_server(http_server) while len(buf) < int(sys.argv[1]): r = random.random() c = math.floor(r*256) buf += format(c, 'x') LOGGER.info("Starting servient") wot = yield servient.start() LOGGER.info("Exposing and configuring Thing") exposed_thing = wot.produce(json.dumps(DESCRIPTION)) exposed_thing.set_property_read_handler("bench", bench_handler) exposed_thing.expose()
def test_coroutine(): service_history = asyncio_zeroconf.pop("service_history") port_catalogue = find_free_port() servient = Servient(catalogue_port=port_catalogue) yield dnssd_discovery.start() yield dnssd_discovery.register(servient) yield dnssd_discovery.unregister(servient) while _num_service_instance_items(servient, service_history) < 2: yield tornado.gen.sleep(0.1) _assert_service_added_removed(servient, service_history)
def dnssd_servient(): """Builds a Servient with both the TD catalogue and the DNS-SD service enabled.""" servient = Servient(catalogue_port=find_free_port(), dnssd_enabled=True, dnssd_instance_name=Faker().pystr()) yield servient @tornado.gen.coroutine def shutdown(): yield servient.shutdown() tornado.ioloop.IOLoop.current().run_sync(shutdown)
def test_produce_model_consumed_thing(): """Things can be produced from ConsumedThing instances.""" servient = Servient() wot = WoT(servient=servient) td_str = json.dumps(TD_EXAMPLE) consumed_thing = wot.consume(td_str) exposed_thing = wot.produce(consumed_thing) assert exposed_thing.id == consumed_thing.td.id assert exposed_thing.name == consumed_thing.td.name assert len(exposed_thing.properties) == len(consumed_thing.td.properties) assert len(exposed_thing.actions) == len(consumed_thing.td.actions) assert len(exposed_thing.events) == len(consumed_thing.td.events)
def _test_equivalent_interaction_names(base_name, transform_name): """Helper function to test that interaction names are equivalent given a certain transformation function.""" thing = Thing(id=uuid.uuid4().urn) exp_thing = ExposedThing(servient=Servient(), thing=thing) prop_name = "property" + base_name prop_name_transform = transform_name(prop_name) prop_default_value = Faker().pybool() exp_thing.add_property(prop_name, {"type": DataType.BOOLEAN}, value=prop_default_value) with pytest.raises(ValueError): exp_thing.add_property(prop_name_transform, {"type": DataType.BOOLEAN}) @tornado.gen.coroutine def assert_prop_read(): assert (yield exp_thing.properties[prop_name].read()) is prop_default_value assert (yield exp_thing.properties[prop_name_transform].read() ) is prop_default_value tornado.ioloop.IOLoop.current().run_sync(assert_prop_read) action_name = "action" + base_name action_name_transform = transform_name(action_name) exp_thing.add_action(action_name, {}) with pytest.raises(ValueError): exp_thing.add_action(action_name_transform, {}) assert exp_thing.actions[action_name] assert exp_thing.actions[action_name_transform] event_name = "event" + base_name event_name_transform = transform_name(event_name) exp_thing.add_event(event_name, {}) with pytest.raises(ValueError): exp_thing.add_event(event_name_transform, {}) assert exp_thing.events[event_name] assert exp_thing.events[event_name_transform]
def test_clients_subset(): """Although all clients are enabled by default, the user may only enable a subset.""" ws_client = WebsocketClient() servient_01 = Servient() servient_02 = Servient(clients=[ws_client]) td = ThingDescription(TD_DICT_01) prop_name = next(six.iterkeys(TD_DICT_01["properties"])) assert servient_01.select_client(td, prop_name) is not ws_client assert servient_02.select_client(td, prop_name) is ws_client
def test_ssl_context(self_signed_ssl_context): """An SSL context can be passed to the HTTP server to enable encryption.""" exposed_thing = ExposedThing(servient=Servient(), thing=Thing(id=uuid.uuid4().urn)) prop_name = uuid.uuid4().hex exposed_thing.add_property(prop_name, PropertyFragmentDict({ "type": "string", "observable": True }), value=Faker().pystr()) port = find_free_port() server = HTTPServer(port=port, ssl_context=self_signed_ssl_context) server.add_exposed_thing(exposed_thing) href = _get_property_href(exposed_thing, prop_name, server) assert HTTPSchemes.HTTPS in href @tornado.gen.coroutine def test_coroutine(): yield server.start() prop_value = Faker().pystr() yield exposed_thing.properties[prop_name].write(prop_value) http_client = tornado.httpclient.AsyncHTTPClient() with pytest.raises(ssl.SSLError): yield http_client.fetch( tornado.httpclient.HTTPRequest(href, method="GET")) http_request = tornado.httpclient.HTTPRequest(href, method="GET", validate_cert=False) response = yield http_client.fetch(http_request) assert json.loads(response.body).get("value") == prop_value yield server.stop() run_test_coroutine(test_coroutine)
def test_discovery_method_multicast_dnssd_unsupported(): """Attempting to discover other Things using multicast DNS-SD in an unsupported platform raises a warning.""" servient = Servient(catalogue_port=None, dnssd_enabled=True) @tornado.gen.coroutine def test_coroutine(): wot = yield servient.start() with warnings.catch_warnings(record=True) as warns: wot.discover(ThingFilterDict(method=DiscoveryMethod.MULTICAST)) assert len(warns) yield servient.shutdown() run_test_coroutine(test_coroutine)
def servient(request): """Returns an empty WoT Servient.""" catalogue_port = find_free_port() if request.param.get( 'catalogue_enabled') else None servient = Servient(catalogue_port=catalogue_port) @tornado.gen.coroutine def start(): yield servient.start() tornado.ioloop.IOLoop.current().run_sync(start) yield servient @tornado.gen.coroutine def shutdown(): yield servient.shutdown() tornado.ioloop.IOLoop.current().run_sync(shutdown)
def test_produce_from_url(td_example_tornado_app): """ExposedThings can be created from URLs that provide Thing Description documents.""" app_port = find_free_port() td_example_tornado_app.listen(app_port) url_valid = "http://localhost:{}/".format(app_port) url_error = "http://localhost:{}/{}".format(app_port, Faker().pystr()) wot = WoT(servient=Servient()) @tornado.gen.coroutine def test_coroutine(): exposed_thing = yield wot.produce_from_url(url_valid) assert exposed_thing.thing.id == TD_EXAMPLE.get("id") with pytest.raises(Exception): yield wot.produce_from_url(url_error) run_test_coroutine(test_coroutine)