Exemplo n.º 1
0
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
    }
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
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()
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
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()
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
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
Exemplo n.º 11
0
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)
Exemplo n.º 12
0
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)
Exemplo n.º 13
0
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
Exemplo n.º 14
0
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
Exemplo n.º 15
0
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()
Exemplo n.º 16
0
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)
Exemplo n.º 17
0
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()
Exemplo n.º 18
0
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)
Exemplo n.º 19
0
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)
Exemplo n.º 20
0
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()
Exemplo n.º 21
0
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()
Exemplo n.º 22
0
    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)
Exemplo n.º 23
0
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)
Exemplo n.º 24
0
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)
Exemplo n.º 25
0
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]
Exemplo n.º 26
0
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
Exemplo n.º 27
0
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)
Exemplo n.º 28
0
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)
Exemplo n.º 29
0
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)
Exemplo n.º 30
0
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)