def test_get_from_collector_returns_data(self): mock_logger = mock.Mock(spec=Logger) collected_data = self.create_queue_data() with mock.patch('user.MQTTSubscribe.CollectData') as mock_CollectData: type(mock_CollectData.return_value).get_data = mock.Mock( return_value=collected_data) type(mock_CollectData.return_value).add_data = mock.Mock( return_value={}) SUT = TopicManager(self.config, mock_logger) SUT.append_data(self.topic, self.create_queue_data(), fieldname=self.fieldname) gen = SUT.get_data(self.topic) data = next(gen, None) self.assertEqual(data, collected_data) data = next(gen, None) self.assertIsNone(data)
def test_queue_empty(self): mock_logger = mock.Mock(spec=Logger) with mock.patch('user.MQTTSubscribe.weewx.accum.Accum') as mock_Accum: with mock.patch('user.MQTTSubscribe.weewx.units.to_std_system' ) as mock_to_std_system: type(mock_Accum.return_value).isEmpty = mock.PropertyMock( return_value=True) SUT = TopicManager(None, self.config, mock_logger) accumulated_data = SUT.get_accumulated_data( SUT.subscribed_topics[self.topic]['queue'], 0, time.time(), 0) self.assertDictEqual(accumulated_data, {}) mock_Accum.assert_not_called() mock_Accum.addRecord.assert_not_called() mock_Accum.getRecord.assert_not_called() mock_to_std_system.assert_not_called()
def test_missing_topic(self): mock_logger = mock.Mock(spec=Logger) config_dict = {} config = configobj.ConfigObj(config_dict) with self.assertRaises(ValueError) as error: TopicManager(None, config, mock_logger) self.assertEqual(error.exception.args[0], "At least one topic must be configured.")
def test_queue_element_before_start(self): mock_logger = mock.Mock(spec=Logger) queue_data = self.create_queue_data() with mock.patch('user.MQTTSubscribe.weewx.accum.Accum') as mock_Accum: with mock.patch('user.MQTTSubscribe.weewx.units.to_std_system' ) as mock_to_std_system: type(mock_Accum.return_value).addRecord = \ mock.Mock(side_effect=test_weewx_stubs.weewx.accum.OutOfSpan("Attempt to add out-of-interval record")) SUT = TopicManager(self.config, mock_logger) SUT.append_data(self.topic, queue_data) mock_logger.reset_mock() accumulated_data = SUT.get_accumulated_data( self.topic, 0, time.time(), 0) self.assertDictEqual(accumulated_data, {}) mock_logger.info.assert_called_once() mock_Accum.getRecord.assert_not_called() mock_to_std_system.assert_not_called()
def runit(self, payload, file_pointer, check_results=True): test_data = json.load(file_pointer, object_hook=utils.byteify) config_dict = configobj.ConfigObj(test_data['config'])['MQTTSubscribeService'] testruns = test_data['testruns'] logger = Logger('IntegTest') topics_dict = config_dict.get('topics', {}) manager = TopicManager(None, topics_dict, logger) on_message = utils.get_callback(payload, config_dict, manager, logger) for testrun in testruns: for topics in testrun['messages']: for topic in topics: topic_info = topics[topic] utils.send_msg(utils.send_direct_msg, payload, on_message, topic, topic_info) records = [] for queue in manager.queues: for data in manager.get_data(queue): if data: records.append(data) else: break if check_results: results = testrun['results'] result = {} found = False for result in results: if 'single' in result['test']: if payload in result['payloads']: found = True break self.assertTrue(found, "No results for %s" %payload) utils.check(self, payload, records, result['records']) else: for record in records: print(record)
def runit(self, payload, file_pointer): test_data = json.load(file_pointer, object_hook=utils.byteify) config_dict = configobj.ConfigObj( test_data['config'])['MQTTSubscribeService'] testruns = test_data['testruns'] logger = Logger() topics_dict = config_dict.get('topics', {}) manager = TopicManager(topics_dict, logger) on_message = utils.get_callback(payload, config_dict, manager, logger) for testrun in testruns: start_ts = time.time() for topics in testrun['messages']: for topic in topics: topic_info = topics[topic] utils.send_msg(utils.send_direct_msg, payload, on_message, topic, topic_info) end_ts = time.time() results = testrun['results'] result = {} found = False for result in results: if 'accumulate' in result['test']: if payload in result['payloads']: found = True break self.assertTrue(found, "No results for %s" % payload) records = [] for topic in sorted( manager.subscribed_topics ): # todo - dependent on topic names - not great data = manager.get_accumulated_data(topic, start_ts, end_ts, result['units']) records.append(data) utils.check(self, payload, records, result['records'])
def test_add_to_collector_returns_data(self): mock_logger = mock.Mock(spec=Logger) collected_data = self.create_queue_data() with mock.patch('user.MQTTSubscribe.CollectData') as mock_CollectData: type(mock_CollectData.return_value).get_data = mock.Mock( return_value={}) type(mock_CollectData.return_value).add_data = mock.Mock( return_value=collected_data) SUT = TopicManager(self.config, mock_logger) SUT.append_data(self.topic, self.create_queue_data(), fieldname=self.fieldname) # ToDo - need to get the topic a better way # perhaps find it by searching on subscribed topic 'type' gen = SUT.get_data(SUT.collected_topic) data = next(gen, None) self.assertEqual(data, collected_data) data = next(gen, None) self.assertIsNone(data)
def test_ignore_start_set_and_adjusted(self): mock_logger = mock.Mock(spec=Logger) final_record_data = { 'inTemp': random.uniform(1, 100), 'outTemp': random.uniform(1, 100), 'usUnits': random.uniform(0, 2), 'interval': 5, 'dateTime': time.time() } start_ts = time.time() end_ts = time.time() adjust_start_time = random.randint(2, 9) config = copy.deepcopy(self.config) config['ignore_start_time'] = True config['adjust_start_time'] = adjust_start_time with mock.patch('user.MQTTSubscribe.weewx.accum.Accum') as mock_Accum: with mock.patch('user.MQTTSubscribe.weewx.units.to_std_system' ) as mock_to_std_system: type(mock_Accum.return_value).isEmpty = mock.PropertyMock( return_value=False) mock_to_std_system.return_value = final_record_data SUT = TopicManager(None, config, mock_logger) SUT.append_data(self.topic, {'dateTime': start_ts}) accumulated_data = SUT.get_accumulated_data( SUT.subscribed_topics[self.topic]['queue'], 0, end_ts, 0) mock_Accum.assert_called_once_with( test_weewx_stubs.weeutil.weeutil.TimeSpan( start_ts - adjust_start_time, end_ts)) self.assertDictEqual(accumulated_data, final_record_data)
def test_configure_field(self): mock_logger = mock.Mock(spec=Logger) topic = ''.join([ random.choice(string.ascii_letters + string.digits) for n in range(32) ]) # pylint: disable=unused-variable config_dict = {} config_dict[topic] = {} fieldname = ''.join([ random.choice(string.ascii_letters + string.digits) for n in range(32) ]) config_dict[topic][fieldname] = {} config_dict[topic][fieldname]['ignore'] = 'true' config_dict[topic][fieldname]['ignore_msg_id_field'] = 'true' config_dict[topic][fieldname]['contains_total'] = 'true' config_dict[topic][fieldname]['conversion_type'] = 'int' weewx_name = 'barfoo' config_dict[topic][fieldname]['name'] = weewx_name config_dict[topic][fieldname]['expires_after'] = 'none' unit_name = 'unit_name' config_dict[topic][fieldname]['units'] = unit_name config = configobj.ConfigObj(config_dict) SUT = TopicManager(None, config, mock_logger) self.assertTrue( SUT.subscribed_topics[topic]['fields'][fieldname]['ignore']) self.assertEqual(SUT.subscribed_topics[topic]['ignore_msg_id_field'], [fieldname]) self.assertTrue(SUT.subscribed_topics[topic]['fields'][fieldname] ['contains_total']) self.assertEqual( SUT.subscribed_topics[topic]['fields'][fieldname] ['conversion_func']['source'], 'lambda x: to_int(x)') self.assertEqual( SUT.subscribed_topics[topic]['fields'][fieldname]['name'], weewx_name) self.assertEqual( SUT.subscribed_topics[topic]['fields'][fieldname]['units'], unit_name) self.assertIsNone(SUT.cached_fields[weewx_name]['expires_after'])
def test_invalid_unit_system_topic(self): mock_logger = mock.Mock(spec=Logger) config_dict = {} topic = random_string() unit_system_name = random_string() config_dict[topic] = {} config_dict[topic]['unit_system'] = unit_system_name config = configobj.ConfigObj(config_dict) with self.assertRaises(ValueError) as error: TopicManager(None, config, mock_logger) self.assertEqual( error.exception.args[0], "MQTTSubscribe: Unknown unit system: %s" % unit_system_name.upper())
def test_no_default_setting(self): mock_logger = mock.Mock(spec=Logger) topic = random_string() config_key = random_string(10) config_dict = {} config_dict['message'] = {} config_dict['message']['type'] = random_string(10) config_dict['message']['flatten_delimiter'] = random_string(5) config_dict['message']['keyword_delimiter'] = random_string(5) config_dict['message']['keyword_separator'] = random_string(5) config_dict[topic] = {} config_dict[topic]['message'] = {} config_dict[topic]['message']['type'] = random_string(10) config_dict[topic]['message']['flatten_delimiter'] = random_string(5) config_dict[topic]['message']['keyword_delimiter'] = random_string(5) config_dict[topic]['message']['keyword_separator'] = random_string(5) config_dict[topic]['message'][config_key] = random_string() config = configobj.ConfigObj(config_dict) SUT = TopicManager(None, config, mock_logger) self.assertIn(SUT.message_config_name, SUT.subscribed_topics[topic]) self.assertEqual( SUT.subscribed_topics[topic][SUT.message_config_name]['type'], config_dict[topic]['message']['type']) self.assertEqual( SUT.subscribed_topics[topic][ SUT.message_config_name]['flatten_delimiter'], config_dict[topic]['message']['flatten_delimiter']) self.assertEqual( SUT.subscribed_topics[topic][ SUT.message_config_name]['keyword_delimiter'], config_dict[topic]['message']['keyword_delimiter']) self.assertEqual( SUT.subscribed_topics[topic][ SUT.message_config_name]['keyword_separator'], config_dict[topic]['message']['keyword_separator']) self.assertEqual( SUT.subscribed_topics[topic][SUT.message_config_name][config_key], config_dict[topic]['message'][config_key])
def test_configure_subfields(self): mock_logger = mock.Mock(spec=Logger) topic = random_string() config_dict = {} config_dict[topic] = {} fieldname = random_string() config_dict[topic][fieldname] = {} config_dict[topic][fieldname]['ignore'] = 'true' config_dict[topic][fieldname]['ignore_msg_id_field'] = 'true' config_dict[topic][fieldname]['contains_total'] = 'true' config_dict[topic][fieldname]['conversion_type'] = 'int' weewx_name = 'barfoo' config_dict[topic][fieldname]['name'] = weewx_name config_dict[topic][fieldname]['expires_after'] = 'none' unit_name = 'unit_name' config_dict[topic][fieldname]['units'] = unit_name config_dict[topic][fieldname]['subfields'] = {} subfield_name = 'subfield1' config_dict[topic][fieldname]['subfields'][subfield_name] = {} config = configobj.ConfigObj(config_dict) SUT = TopicManager(None, config, mock_logger) self.assertNotIn(fieldname, SUT.subscribed_topics[topic]['fields']) self.assertTrue( SUT.subscribed_topics[topic]['fields'][subfield_name]['ignore']) self.assertEqual(SUT.subscribed_topics[topic]['ignore_msg_id_field'], [subfield_name]) self.assertTrue(SUT.subscribed_topics[topic]['fields'][subfield_name] ['contains_total']) self.assertEqual( SUT.subscribed_topics[topic]['fields'][subfield_name] ['conversion_func']['source'], 'lambda x: to_int(x)') self.assertEqual( SUT.subscribed_topics[topic]['fields'][subfield_name]['units'], unit_name) self.assertIsNone(SUT.cached_fields[weewx_name]['expires_after'])
def test_field_conversion_type_unknown(self): mock_logger = mock.Mock(spec=Logger) topic = random_string() config_dict = {} config_dict[topic] = {} fieldname = random_string() config_dict[topic][fieldname] = {} config_dict[topic][fieldname]['conversion_type'] = 'unknown' config = configobj.ConfigObj(config_dict) SUT = TopicManager(None, config, mock_logger) self.assertEqual( SUT.subscribed_topics[topic]['fields'][fieldname] ['conversion_func']['source'], 'lambda x: x')
def test_topic_named_message(self): mock_logger = mock.Mock(spec=Logger) topic = random_string() config_dict = {} config_dict['message'] = {} config_dict['message']['flatten_delimiter'] = random_string(5) config_dict['message']['keyword_delimiter'] = random_string(5) config_dict['message']['keyword_separator'] = random_string(5) config_dict[topic] = {} config = configobj.ConfigObj(config_dict) SUT = TopicManager(None, config, mock_logger) self.assertIn('message', SUT.subscribed_topics) self.assertIn(SUT.message_config_name, SUT.subscribed_topics['message']) self.assertNotIn('type', SUT.subscribed_topics['message'])
def test_queue_good(self): mock_logger = mock.Mock(spec=Logger) with mock.patch('user.MQTTSubscribe.CollectData') as mock_CollectData: type(mock_CollectData.return_value).get_data = mock.Mock( return_value={}) SUT = TopicManager(self.config, mock_logger) elem_one = self.create_queue_data() elem_two = self.create_queue_data() elem_three = self.create_queue_data() SUT.append_data(self.topic, elem_one) SUT.append_data(self.topic, elem_two) SUT.append_data(self.topic, elem_three) elements = [] for data in SUT.get_data(self.topic): elements.append(data) self.assertEqual(len(elements), 3) self.assertDictEqual(elements[0], elem_one) self.assertDictEqual(elements[1], elem_two) self.assertDictEqual(elements[2], elem_three)
def test_invalid_unit_system_topic(self): mock_logger = mock.Mock(spec=Logger) config_dict = {} topic = ''.join([ random.choice(string.ascii_letters + string.digits) for n in range(32) ]) # pylint: disable=unused-variable unit_system_name = ''.join([ random.choice(string.ascii_letters + string.digits) for n in range(32) ]) # pylint: disable=unused-variable config_dict[topic] = {} config_dict[topic]['unit_system'] = unit_system_name config = configobj.ConfigObj(config_dict) with self.assertRaises(ValueError) as error: TopicManager(None, config, mock_logger) self.assertEqual( error.exception.args[0], "MQTTSubscribe: Unknown unit system: %s" % unit_system_name.upper())