def setUp(self): self.host = 'foobar.baz' self.port = 8080 self.device_id = 'DFDS44' self.meta = {} self.meta['foo'] = mock.Mock(units="F", sampleRate="10", min=0, max=100) self.meta['bar'] = mock.Mock(units="C", sampleRate="1", min=-100, max=200) self.meta['baz'] = mock.Mock(units="C", sampleRate="1", min=-100, max=200) # Mock's constructor treats 'name' in a special way, it won't return a string self.meta['foo'].configure_mock(name='foo') self.meta['bar'].configure_mock(name='bar') self.meta['baz'].configure_mock(name='baz') self.data_bus = None self.telemetry_connection = None self.status_function = mock.Mock() self.data_bus = mock.Mock() self.telemetry_connection = TelemetryConnection(self.host, self.port, self.device_id, self.meta, self.data_bus, self.status_function) # We mock these functions because we don't want to really connect to anything # This is a unit test, not integration! self.telemetry_connection.create_socket = mock.Mock() self.telemetry_connection.connect = mock.Mock() self.telemetry_connection.push = mock.Mock()
class TelemetryConnectionTest(unittest.TestCase): def setUp(self): self.host = 'foobar.baz' self.port = 8080 self.device_id = 'DFDS44' self.meta = {} self.meta['foo'] = mock.Mock(units="F", sampleRate="10", min=0, max=100) self.meta['bar'] = mock.Mock(units="C", sampleRate="1", min=-100, max=200) self.meta['baz'] = mock.Mock(units="C", sampleRate="1", min=-100, max=200) # Mock's constructor treats 'name' in a special way, it won't return a string self.meta['foo'].configure_mock(name='foo') self.meta['bar'].configure_mock(name='bar') self.meta['baz'].configure_mock(name='baz') self.data_bus = None self.telemetry_connection = None self.status_function = mock.Mock() self.data_bus = mock.Mock() self.telemetry_connection = TelemetryConnection( self.host, self.port, self.device_id, self.meta, self.data_bus, self.status_function) # We mock these functions because we don't want to really connect to anything # This is a unit test, not integration! self.telemetry_connection.create_socket = mock.Mock() self.telemetry_connection.connect = mock.Mock() self.telemetry_connection.push = mock.Mock() def test_run(self, asyncore_loop_mock): self.telemetry_connection.run() self.telemetry_connection.create_socket.assert_called_with( socket.AF_INET, socket.SOCK_STREAM) self.telemetry_connection.connect.assert_called_with( (self.host, self.port)) self.assertTrue(asyncore_loop_mock.called) self.assertTrue(self.data_bus.add_sample_listener.called) self.assertTrue(self.data_bus.addMetaListener.called) def test_sends_auth(self, asyncore_loop_mock): self.telemetry_connection.run() self.telemetry_connection.handle_connect() self.telemetry_connection.push.assert_called_with( '{"cmd":{"schemaVer":2,"auth":{"deviceId":"' + self.device_id + '"}}}' + "\n") def test_sends_authorized_status(self, asyncore_loop_mock): self.telemetry_connection.run() self.telemetry_connection.handle_connect() args, kwargs = self.status_function.call_args status, message, status_code = args self.assertEqual(status_code, TelemetryConnection.STATUS_CONNECTED) self.telemetry_connection.collect_incoming_data('{"status":"ok"}') self.telemetry_connection.found_terminator() args, kwargs = self.status_function.call_args status, message, status_code = args self.assertEqual(status_code, TelemetryConnection.STATUS_STREAMING) def test_sends_error_authenticating_status(self, asyncore_loop_mock): self.telemetry_connection.run() self.telemetry_connection.handle_connect() self.telemetry_connection.collect_incoming_data( '{"status":"error","message":"invalid serial number"}') self.telemetry_connection.found_terminator() args, kwargs = self.status_function.call_args status, message, status_code = args self.assertEqual(status_code, TelemetryConnection.ERROR_AUTHENTICATING) def test_sends_unknown_error(self, asyncore_loop_mock): self.telemetry_connection.run() self.telemetry_connection.handle_connect() self.telemetry_connection.collect_incoming_data('{"foo":"bar"}') self.telemetry_connection.found_terminator() args, kwargs = self.status_function.call_args status, message, status_code = args self.assertEqual(status_code, TelemetryConnection.ERROR_UNKNOWN_MESSAGE) def test_sends_meta(self, asyncore_loop_mock): self.telemetry_connection.run() self.telemetry_connection.handle_connect() args, kwargs = self.status_function.call_args status, message, status_code = args self.assertEqual(status_code, TelemetryConnection.STATUS_CONNECTED) self.telemetry_connection.collect_incoming_data('{"status":"ok"}') self.telemetry_connection.found_terminator() args, kwargs = self.telemetry_connection.push.call_args message, = args meta_json = json.loads(message) self.assertTrue("s" in meta_json, "Sends 's'") self.assertTrue("meta" in meta_json["s"], "Sends meta property") for name, info in self.meta.iteritems(): # Verify all the channels were sent with correct info channel_info = next( (item for item in meta_json["s"]["meta"] if item["nm"] == name), None) self.assertIsNotNone(channel_info, "Channel found") self.assertEqual(channel_info["ut"], info.units, "Units are sent") self.assertEqual(channel_info["sr"], info.sampleRate, "Sample rate is sent") self.assertEqual(channel_info["min"], info.min, "Min is sent") self.assertEqual(channel_info["max"], info.max, "Max is sent") def test_sends_line_break(self, asyncore_loop_mock): self.telemetry_connection.send_msg("foo") args, kwargs = self.telemetry_connection.push.call_args message, = args self.assertEqual(message, "foo\n", "Newline added to end of message") @patch('threading.Timer') def test_sends_bitmask(self, timer_mock, asyncore_loop_mock): sample = {} sample['bar'] = 3.0 bitmask = '' # Compute our own bitmask to verify for channel_name, value in self.meta.iteritems(): if channel_name == 'bar': bitmask = "1" + bitmask else: bitmask = "0" + bitmask bitmask = int(bitmask, 2) self.telemetry_connection._on_sample(sample) self.telemetry_connection._send_sample() args, kwargs = self.telemetry_connection.push.call_args message, = args message_json = json.loads(message) self.assertEqual( bitmask, message_json["s"]["d"][len(message_json["s"]["d"]) - 1]) @patch('threading.Timer') def test_sends_multiple_bitmasks(self, timer_mock, asyncore_loop_mock): sample = {} meta = {} for i in range(1, 40): meta['sensor' + str(i)] = mock.Mock(units="F", sampleRate="10", min=random.randint(-100, 0), max=random.randint(0, 100)) meta['sensor' + str(i)].configure_mock(name='sensor' + str(i)) # Manually doing this to aid debugging if this test breaks sample['sensor2'] = random.randint(-50, 50) sample['sensor3'] = random.randint(-50, 50) sample['sensor4'] = random.randint(-50, 50) sample['sensor5'] = random.randint(-50, 50) sample['sensor6'] = random.randint(-50, 50) sample['sensor7'] = random.randint(-50, 50) sample['sensor8'] = random.randint(-50, 50) sample['sensor10'] = random.randint(-50, 50) sample['sensor11'] = random.randint(-50, 50) sample['sensor12'] = random.randint(-50, 50) sample['sensor21'] = random.randint(-50, 50) sample['sensor25'] = random.randint(-50, 50) sample['sensor26'] = random.randint(-50, 50) sample['sensor29'] = random.randint(-50, 50) sample['sensor33'] = random.randint(-50, 50) sample['sensor35'] = random.randint(-50, 50) sample['sensor37'] = random.randint(-50, 50) sample['sensor38'] = random.randint(-50, 50) sample['sensor39'] = random.randint(-50, 50) self.telemetry_connection.authorized = True self.telemetry_connection._on_meta(meta) self.telemetry_connection._on_sample(sample) self.telemetry_connection._send_sample() bitmasks = [] bitmask = '' bit_count = 0 # Compute our own bitmask to verify for channel_name, value in self.telemetry_connection._channel_metas.iteritems( ): if sample.get(channel_name): bitmask = "1" + bitmask else: bitmask = "0" + bitmask bit_count += 1 if bit_count > 31: bitmasks.append(bitmask) bitmask = '' bit_count = 0 bitmasks.append(bitmask) args, kwargs = self.telemetry_connection.push.call_args message, = args message_json = json.loads(message) expected1 = int(bitmasks[0], 2) actual1 = message_json["s"]["d"][len(message_json["s"]["d"]) - 2] expected2 = int(bitmasks[1], 2) actual2 = message_json["s"]["d"][len(message_json["s"]["d"]) - 1] self.assertEqual(expected1, actual1) self.assertEqual(expected2, actual2) @patch('threading.Timer') def resends_meta(self, timer_mock, asyncore_loop_mock): meta = {} for i in range(1, 5): meta['sensor' + str(i)] = mock.Mock(units="F", sampleRate="10", min=random.randint(-100, 0), max=random.randint(0, 100)) meta['sensor' + str(i)].configure_mock(name='sensor' + str(i)) self.telemetry_connection._on_meta(meta) args, kwargs = self.telemetry_connection.push.call_args message, = args message_json = json.loads(message) self.assertEqual(len(message_json["s"]["meta"]), 5)
class TelemetryConnectionTest(unittest.TestCase): def setUp(self): self.host = 'foobar.baz' self.port = 8080 self.device_id = 'DFDS44' self.meta = {} self.meta['foo'] = mock.Mock(units="F", sampleRate="10", min=0, max=100) self.meta['bar'] = mock.Mock(units="C", sampleRate="1", min=-100, max=200) self.meta['baz'] = mock.Mock(units="C", sampleRate="1", min=-100, max=200) # Mock's constructor treats 'name' in a special way, it won't return a string self.meta['foo'].configure_mock(name='foo') self.meta['bar'].configure_mock(name='bar') self.meta['baz'].configure_mock(name='baz') self.data_bus = None self.telemetry_connection = None self.status_function = mock.Mock() self.data_bus = mock.Mock() self.telemetry_connection = TelemetryConnection(self.host, self.port, self.device_id, self.meta, self.data_bus, self.status_function) # We mock these functions because we don't want to really connect to anything # This is a unit test, not integration! self.telemetry_connection.create_socket = mock.Mock() self.telemetry_connection.connect = mock.Mock() self.telemetry_connection.push = mock.Mock() def test_run(self, asyncore_loop_mock): self.telemetry_connection.run() self.telemetry_connection.create_socket.assert_called_with(socket.AF_INET, socket.SOCK_STREAM) self.telemetry_connection.connect.assert_called_with((self.host, self.port)) self.assertTrue(asyncore_loop_mock.called) self.assertTrue(self.data_bus.add_sample_listener.called) self.assertTrue(self.data_bus.addMetaListener.called) def test_sends_auth(self, asyncore_loop_mock): self.telemetry_connection.run() self.telemetry_connection.handle_connect() self.telemetry_connection.push.assert_called_with('{"cmd":{"schemaVer":2,"auth":{"deviceId":"' + self.device_id + '"}}}' + "\n") def test_sends_authorized_status(self, asyncore_loop_mock): self.telemetry_connection.run() self.telemetry_connection.handle_connect() args, kwargs = self.status_function.call_args status, message, status_code = args self.assertEqual(status_code, TelemetryConnection.STATUS_CONNECTED) self.telemetry_connection.collect_incoming_data('{"status":"ok"}') self.telemetry_connection.found_terminator() args, kwargs = self.status_function.call_args status, message, status_code = args self.assertEqual(status_code, TelemetryConnection.STATUS_STREAMING) def test_sends_error_authenticating_status(self, asyncore_loop_mock): self.telemetry_connection.run() self.telemetry_connection.handle_connect() self.telemetry_connection.collect_incoming_data('{"status":"error","message":"invalid serial number"}') self.telemetry_connection.found_terminator() args, kwargs = self.status_function.call_args status, message, status_code = args self.assertEqual(status_code, TelemetryConnection.ERROR_AUTHENTICATING) def test_sends_unknown_error(self, asyncore_loop_mock): self.telemetry_connection.run() self.telemetry_connection.handle_connect() self.telemetry_connection.collect_incoming_data('{"foo":"bar"}') self.telemetry_connection.found_terminator() args, kwargs = self.status_function.call_args status, message, status_code = args self.assertEqual(status_code, TelemetryConnection.ERROR_UNKNOWN_MESSAGE) def test_sends_meta(self, asyncore_loop_mock): self.telemetry_connection.run() self.telemetry_connection.handle_connect() args, kwargs = self.status_function.call_args status, message, status_code = args self.assertEqual(status_code, TelemetryConnection.STATUS_CONNECTED) self.telemetry_connection.collect_incoming_data('{"status":"ok"}') self.telemetry_connection.found_terminator() args, kwargs = self.telemetry_connection.push.call_args message, = args meta_json = json.loads(message) self.assertTrue("s" in meta_json, "Sends 's'") self.assertTrue("meta" in meta_json["s"], "Sends meta property") for name, info in self.meta.iteritems(): # Verify all the channels were sent with correct info channel_info = next((item for item in meta_json["s"]["meta"] if item["nm"] == name), None) self.assertIsNotNone(channel_info, "Channel found") self.assertEqual(channel_info["ut"], info.units, "Units are sent") self.assertEqual(channel_info["sr"], info.sampleRate, "Sample rate is sent") self.assertEqual(channel_info["min"], info.min, "Min is sent") self.assertEqual(channel_info["max"], info.max, "Max is sent") def test_sends_line_break(self, asyncore_loop_mock): self.telemetry_connection.send_msg("foo") args, kwargs = self.telemetry_connection.push.call_args message, = args self.assertEqual(message, "foo\n", "Newline added to end of message") @patch('threading.Timer') def test_sends_bitmask(self, timer_mock, asyncore_loop_mock): sample = {} sample['bar'] = 3.0 bitmask = '' # Compute our own bitmask to verify for channel_name, value in self.meta.iteritems(): if channel_name == 'bar': bitmask = "1" + bitmask else: bitmask = "0" + bitmask bitmask = int(bitmask, 2) self.telemetry_connection._on_sample(sample) self.telemetry_connection._send_sample() args, kwargs = self.telemetry_connection.push.call_args message, = args message_json = json.loads(message) self.assertEqual(bitmask, message_json["s"]["d"][len(message_json["s"]["d"]) - 1]) @patch('threading.Timer') def test_sends_multiple_bitmasks(self, timer_mock, asyncore_loop_mock): sample = {} meta = {} for i in range(1, 40): meta['sensor' + str(i)] = mock.Mock(units="F", sampleRate="10", min=random.randint(-100, 0), max=random.randint(0, 100)) meta['sensor' + str(i)].configure_mock(name='sensor' + str(i)) # Manually doing this to aid debugging if this test breaks sample['sensor2'] = random.randint(-50, 50) sample['sensor3'] = random.randint(-50, 50) sample['sensor4'] = random.randint(-50, 50) sample['sensor5'] = random.randint(-50, 50) sample['sensor6'] = random.randint(-50, 50) sample['sensor7'] = random.randint(-50, 50) sample['sensor8'] = random.randint(-50, 50) sample['sensor10'] = random.randint(-50, 50) sample['sensor11'] = random.randint(-50, 50) sample['sensor12'] = random.randint(-50, 50) sample['sensor21'] = random.randint(-50, 50) sample['sensor25'] = random.randint(-50, 50) sample['sensor26'] = random.randint(-50, 50) sample['sensor29'] = random.randint(-50, 50) sample['sensor33'] = random.randint(-50, 50) sample['sensor35'] = random.randint(-50, 50) sample['sensor37'] = random.randint(-50, 50) sample['sensor38'] = random.randint(-50, 50) sample['sensor39'] = random.randint(-50, 50) self.telemetry_connection.authorized = True self.telemetry_connection._on_meta(meta) self.telemetry_connection._on_sample(sample) self.telemetry_connection._send_sample() bitmasks = [] bitmask = '' bit_count = 0 # Compute our own bitmask to verify for channel_name, value in self.telemetry_connection._channel_metas.iteritems(): if sample.get(channel_name): bitmask = "1" + bitmask else: bitmask = "0" + bitmask bit_count += 1 if bit_count > 31: bitmasks.append(bitmask) bitmask = '' bit_count = 0 bitmasks.append(bitmask) args, kwargs = self.telemetry_connection.push.call_args message, = args message_json = json.loads(message) expected1 = int(bitmasks[0], 2) actual1 = message_json["s"]["d"][len(message_json["s"]["d"]) - 2] expected2 = int(bitmasks[1], 2) actual2 = message_json["s"]["d"][len(message_json["s"]["d"]) - 1] self.assertEqual(expected1, actual1) self.assertEqual(expected2, actual2) @patch('threading.Timer') def resends_meta(self, timer_mock, asyncore_loop_mock): meta = {} for i in range(1, 5): meta['sensor' + str(i)] = mock.Mock(units="F", sampleRate="10", min=random.randint(-100, 0), max=random.randint(0, 100)) meta['sensor' + str(i)].configure_mock(name='sensor' + str(i)) self.telemetry_connection._on_meta(meta) args, kwargs = self.telemetry_connection.push.call_args message, = args message_json = json.loads(message) self.assertEqual(len(message_json["s"]["meta"]), 5)