def test_start_stop(): """The MQTT server may be started and stopped.""" mqtt_server = MQTTServer(broker_url=get_test_broker_url()) @tornado.gen.coroutine def test_coroutine(): assert not (yield _ping(mqtt_server, timeout=DEFAULT_PING_TIMEOUT)) yield mqtt_server.start() assert (yield _ping(mqtt_server)) assert (yield _ping(mqtt_server)) yield mqtt_server.stop() yield mqtt_server.start() yield mqtt_server.stop() assert not (yield _ping(mqtt_server, timeout=DEFAULT_PING_TIMEOUT)) yield mqtt_server.stop() yield mqtt_server.start() yield mqtt_server.start() assert (yield _ping(mqtt_server)) run_test_coroutine(test_coroutine)
def test_servient_id(): """An MQTT server may be identified by a unique Servient ID to avoid topic collisions.""" broker_url = get_test_broker_url() mqtt_srv_01 = MQTTServer(broker_url=broker_url) mqtt_srv_02 = MQTTServer(broker_url=broker_url) mqtt_srv_03 = MQTTServer(broker_url=broker_url, servient_id=Faker().pystr()) assert mqtt_srv_01.servient_id and mqtt_srv_02.servient_id and mqtt_srv_03.servient_id assert mqtt_srv_01.servient_id == mqtt_srv_02.servient_id assert mqtt_srv_01.servient_id != mqtt_srv_03.servient_id @tornado.gen.coroutine def assert_ping_loop(srv, num_iters=10): for _ in range(num_iters): assert (yield _ping(srv, timeout=DEFAULT_PING_TIMEOUT)) yield tornado.gen.sleep(random.uniform(0.1, 0.3)) @tornado.gen.coroutine def test_coroutine(): yield [mqtt_srv_01.start(), mqtt_srv_03.start()] yield [assert_ping_loop(mqtt_srv_01), assert_ping_loop(mqtt_srv_03)] run_test_coroutine(test_coroutine)
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 connect_broker(topics): """Connects to the test MQTT broker and subscribes to the topics.""" topics = [(topics, QOS_0)] if isinstance(topics, six.string_types) else topics hbmqtt_client = MQTTClient() yield hbmqtt_client.connect(get_test_broker_url()) yield hbmqtt_client.subscribe(topics) raise tornado.gen.Return(hbmqtt_client)
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 _ping(mqtt_server, timeout=None): """Returns True if the given MQTT server has answered to a PING request.""" broker_url = get_test_broker_url() topic_ping = "{}/ping".format(mqtt_server.servient_id) topic_pong = "{}/pong".format(mqtt_server.servient_id) try: hbmqtt_client = MQTTClient() yield hbmqtt_client.connect(broker_url) yield hbmqtt_client.subscribe([(topic_pong, QOS_2)]) bytes_payload = bytes(uuid.uuid4().hex, "utf8") yield hbmqtt_client.publish(topic_ping, bytes_payload, qos=QOS_2) message = yield hbmqtt_client.deliver_message(timeout=timeout) assert message.data == bytes_payload yield hbmqtt_client.disconnect() except TimeoutError: raise tornado.gen.Return(False) raise tornado.gen.Return(True)
def mqtt_servient(): """Returns a Servient that exposes a CoAP server and one ExposedThing.""" from wotpy.protocols.mqtt.server import MQTTServer from tests.protocols.mqtt.broker import get_test_broker_url server = MQTTServer(broker_url=get_test_broker_url()) servient = Servient(catalogue_port=None) servient.add_server(server) @tornado.gen.coroutine def start(): raise tornado.gen.Return((yield servient.start())) wot = tornado.ioloop.IOLoop.current().run_sync(start) property_name_01 = uuid.uuid4().hex action_name_01 = uuid.uuid4().hex event_name_01 = uuid.uuid4().hex td_dict = { "id": uuid.uuid4().urn, "name": uuid.uuid4().hex, "properties": { property_name_01: { "observable": True, "type": "string" } }, "actions": { action_name_01: { "input": { "type": "number" }, "output": { "type": "number" }, } }, "events": { event_name_01: { "type": "string" } }, } td = ThingDescription(td_dict) exposed_thing = wot.produce(td.to_str()) exposed_thing.expose() @tornado.gen.coroutine def action_handler(parameters): input_value = parameters.get("input") raise tornado.gen.Return(int(input_value) * 2) exposed_thing.set_action_handler(action_name_01, action_handler) yield servient @tornado.gen.coroutine def shutdown(): yield servient.shutdown() tornado.ioloop.IOLoop.current().run_sync(shutdown)