class test_KATCPClientResource_IntegratedTimewarp(TimewarpAsyncTestCase): def setUp(self): super(test_KATCPClientResource_IntegratedTimewarp, self).setUp() self.server = DeviceTestServer('', 0) start_thread_with_cleanup(self, self.server) self.host, self.port = self.server.bind_address self.default_resource_spec = dict( name='thething', address=self.server.bind_address, controlled=True) @tornado.gen.coroutine def _get_DUT_and_sync(self, resource_spec): DUT = resource_client.KATCPClientResource(self.default_resource_spec) DUT.start() yield DUT.until_state('synced') raise tornado.gen.Return(DUT) @tornado.testing.gen_test def test_disconnect(self): # Test that a device disconnect / reconnect is correctly handled DUT = yield self._get_DUT_and_sync(self.default_resource_spec) initial_reqs = set(DUT.req) initial_sensors = set(DUT.sensor) self.server.stop() self.server.join(timeout=1) yield DUT.until_state('disconnected') # Test that requests fail rep = yield DUT.req.watchdog() self.assertFalse(rep.succeeded) # Restart device so that we can reconnect self.server.start() # timewarp beyond reconect delay self.set_ioloop_time(self.ioloop_time + 1) yield DUT.until_state('syncing') yield DUT.until_state('synced') # check that sensors / requests are unchanged self.assertEqual(set(DUT.req), initial_reqs) self.assertEqual(set(DUT.sensor), initial_sensors) # Now disconnect and change the device, to check that it is properly resynced. self.server.stop() self.server.join(timeout=1) yield DUT.until_state('disconnected') # Add a new request to the server def request_sparkling_new(self, req, msg): """A new command.""" return Message.reply(msg.name, "ok", "bling1", "bling2") self.server._request_handlers['sparkling-new'] = request_sparkling_new # Check that the request does not exist currently self.assertNotIn('sparkling_new', initial_reqs) # Add a new sensor to the server sensor = DeviceTestSensor(DeviceTestSensor.INTEGER, "another.int", "An Integer.", "count", [-5, 5], timestamp=self.io_loop.time(), status=DeviceTestSensor.NOMINAL, value=3) self.server.add_sensor(sensor) # Check that the sensor does not exist currently escaped_new_sensor = resource.escape_name(sensor.name) self.assertNotIn(resource.escape_name(sensor.name), initial_sensors) # Restart device so that we can reconnect self.server.start() # timewarp beyond reconect delay self.set_ioloop_time(self.ioloop_time + 1) yield DUT.until_state('syncing') yield DUT.until_state('synced') # check that sensors / requests are correctly updated self.assertEqual(set(DUT.req), initial_reqs | set(['sparkling_new'])) self.assertEqual(set(DUT.sensor), initial_sensors | set([escaped_new_sensor])) @tornado.testing.gen_test(timeout=1000) def test_set_sensor_sampling(self): self.server.stop() self.server.join() DUT = resource_client.KATCPClientResource(self.default_resource_spec) DUT.start() yield tornado.gen.moment test_strategy = ('period', '2.5') yield DUT.set_sensor_strategy('an_int', test_strategy) # Double-check that the sensor does not yet exist self.assertNotIn('an_int', DUT.sensor) self.server.start() self.server.wait_running(timeout=1) advancer = TimewarpAsyncTestCaseTimeAdvancer(self, quantum=0.55) advancer.start() yield DUT.until_synced() self.assertEqual(DUT.sensor.an_int.sampling_strategy, test_strategy) # Now call set_sensor_strategy with a different strategy and check that it is # applied to the real sensor new_test_strategy = ('event',) yield DUT.set_sensor_strategy('an_int', new_test_strategy) self.assertEqual(DUT.sensor.an_int.sampling_strategy, new_test_strategy) @tornado.testing.gen_test(timeout=1000) def test_set_sensor_listener(self): self.server.stop() self.server.join() resource_spec = self.default_resource_spec DUT = resource_client.KATCPClientResource(resource_spec) DUT.start() yield tornado.gen.moment test_listener1 = lambda *x : None test_listener2 = lambda *y : None DUT.set_sensor_listener('an_int', test_listener1) # Double-check that the sensor does not yet exist self.assertNotIn('an_int', DUT.sensor) self.server.start() self.server.wait_running(timeout=1) advancer = TimewarpAsyncTestCaseTimeAdvancer(self, quantum=0.55) advancer.start() yield DUT.until_synced() self.assertTrue(DUT.sensor.an_int.is_listener, test_listener1) # Now call set_sensor_lister with a different listener and check that it is # also subscribed DUT.set_sensor_listener('an_int', test_listener2) self.assertTrue(DUT.sensor.an_int.is_listener, test_listener2)