def test_handle_message_verify_metadata_pass_through(self): request_id = str(uuid.uuid4()) expected_insights_id = str(uuid.uuid4()) metadata = { "request_id": request_id, "archive_url": "https://some.url" } host_data = { "display_name": "test_host", "insights_id": expected_insights_id, "account": "0000001" } message = { "operation": "add_host", "platform_metadata": metadata, "data": host_data } expected_results = {"platform_metadata": {**metadata}} mock_event_producer = mockEventProducer() with self.app.app_context(): handle_message(json.dumps(message), mock_event_producer) self.assertEqual( json.loads( mock_event_producer.get_write_event())["platform_metadata"], expected_results["platform_metadata"], )
def test_add_host_stale_timestamp_missing_culling_fields(self): """ tests to check the API will reject a host if it doesn’t have both culling fields. This should raise InventoryException. """ mock_event_producer = MockEventProducer() additional_host_data = ({ "stale_timestamp": "2019-12-16T10:10:06.754201+00:00" }, { "reporter": "puptoo" }, {}) for host_data in additional_host_data: with self.subTest(host_data=host_data): host_data = { "display_name": "test_host", "insights_id": str(uuid.uuid4()), "account": "0000001", **host_data, } message = {"operation": "add_host", "data": host_data} with self.app.app_context(): with self.assertRaises(InventoryException): handle_message(json.dumps(message), mock_event_producer)
def test_handle_message_failure_invalid_json_message(self): invalid_message = "failure {} " mock_event_producer = Mock() with self.assertRaises(json.decoder.JSONDecodeError): handle_message(invalid_message, mock_event_producer) mock_event_producer.assert_not_called()
def test_handle_message_failure_invalid_surrogates(self, add_host, build_event): raw = "\udce2\udce2" escaped = "\\udce2\\udce2" display_names = (f"{raw}", f"{escaped}", f"{raw}{escaped}") for display_name in display_names: with self.subTest(display_names=display_names): invalid_message = self._message(display_name) with self.assertRaises(UnicodeError): handle_message(invalid_message, Mock()) add_host.assert_not_called()
def test_handle_message_failure_invalid_message_format(self): invalid_message = json.dumps({ "operation": "add_host", "NOTdata": {} }) # Missing data field mock_event_producer = Mock() with self.assertRaises(marshmallow.exceptions.ValidationError): handle_message(invalid_message, mock_event_producer) mock_event_producer.assert_not_called()
def _base_add_host_test(self, host_data, expected_results, host_keys_to_check): message = {"operation": "add_host", "data": host_data} mock_event_producer = mockEventProducer() with self.app.app_context(): handle_message(json.dumps(message), mock_event_producer) for key in host_keys_to_check: self.assertEqual( json.loads(mock_event_producer.get_write_event())["host"][key], expected_results["host"][key])
def test_handle_message_verify_message_key_and_metadata_not_required( self, add_host): host_data = self._host_data() add_host.return_value = (host_data, AddHostResults.created) message = {"operation": "add_host", "data": host_data} mock_event_producer = MockEventProducer() with self.app.app_context(): handle_message(json.dumps(message), mock_event_producer) self.assertEqual(mock_event_producer.key, host_data["id"]) event = json.loads(mock_event_producer.event) self.assertEqual(event["host"], host_data)
def test_handle_message_unicode_not_damaged(self, add_host, build_event): operation_raw = "🧜🏿♂️" operation_escaped = json.dumps(operation_raw)[1:-1] messages = ( f'{{"operation": "", "data": {{"display_name": "{operation_raw}{operation_raw}"}}}}', f'{{"operation": "", "data": {{"display_name": "{operation_escaped}{operation_escaped}"}}}}', f'{{"operation": "", "data": {{"display_name": "{operation_raw}{operation_escaped}"}}}}', ) for message in messages: with self.subTest(message=message): add_host.reset_mock() handle_message(message, Mock()) add_host.assert_called_once_with( {"display_name": f"{operation_raw}{operation_raw}"})
def _base_incomplete_staleness_data_test(self, additional_host_data): expected_insights_id = str(uuid.uuid4()) host_data = { "display_name": "test_host", "insights_id": expected_insights_id, "account": "0000001", **additional_host_data, } message = {"operation": "add_host", "data": host_data} mock_event_producer = mockEventProducer() with self.app.app_context(): with self.assertRaises(InventoryException): handle_message(json.dumps(message), mock_event_producer)
def test_handle_message_verify_metadata_pass_through(self): metadata = { "request_id": str(uuid.uuid4()), "archive_url": "https://some.url" } message = { "operation": "add_host", "platform_metadata": metadata, "data": self._host_data() } mock_event_producer = MockEventProducer() with self.app.app_context(): handle_message(json.dumps(message), mock_event_producer) event = json.loads(mock_event_producer.event) self.assertEqual(event["platform_metadata"], metadata)
def test_handle_message_happy_path(self, datetime_mock): expected_insights_id = str(uuid.uuid4()) host_id = uuid.uuid4() timestamp_iso = datetime_mock.utcnow.return_value.replace( tzinfo=timezone.utc).isoformat() message = { "operation": "add_host", "data": { "insights_id": expected_insights_id, "account": "0000001", "stale_timestamp": "2019-12-16T10:10:06.754201+00:00", "reporter": "test", }, } with self.app.app_context(): with unittest.mock.patch( "app.queue.ingress.host_repository.add_host") as m: m.return_value = ({ "id": host_id, "insights_id": None }, AddHostResults.created) mock_event_producer = Mock() handle_message(json.dumps(message), mock_event_producer) mock_event_producer.write_event.assert_called_once() self.assertEquals( json.loads( mock_event_producer.write_event.call_args[0][0]), { "host": { "id": str(host_id), "insights_id": None }, "platform_metadata": {}, "timestamp": timestamp_iso, "type": "created", }, )
def test_add_host_empty_keys_facts(self, datetime_mock): insights_id = str(uuid.uuid4()) samples = ( [{ "facts": { "": "invalid" }, "namespace": "rhsm" }], [{ "facts": { "metadata": { "": "invalid" } }, "namespace": "rhsm" }], ) mock_event_producer = MockEventProducer() for facts in samples: with self.subTest(facts=facts): host_data = { "display_name": "test_host", "insights_id": insights_id, "account": "0000001", "stale_timestamp": datetime.now(timezone.utc).isoformat(), "reporter": "test", "facts": facts, } message = {"operation": "add_host", "data": host_data} with self.app.app_context(): with self.assertRaises(ValidationException): handle_message(json.dumps(message), mock_event_producer)
def test_add_host_empty_keys_system_profile(self, datetime_mock): insights_id = str(uuid.uuid4()) host_data = { "display_name": "test_host", "insights_id": insights_id, "account": "0000001", "stale_timestamp": datetime.now(timezone.utc).isoformat(), "reporter": "test", "system_profile": { "disk_devices": [{ "options": { "": "invalid" } }] }, } message = {"operation": "add_host", "data": host_data} mock_event_producer = MockEventProducer() with self.app.app_context(): with self.assertRaises(ValidationException): handle_message(json.dumps(message), mock_event_producer)
def test_handle_message_verify_metadata_is_not_required(self): expected_insights_id = str(uuid.uuid4()) host_data = { "display_name": "test_host", "insights_id": expected_insights_id, "account": "0000001" } message = {"operation": "add_host", "data": host_data} expected_results = {"host": {**host_data}} mock_event_producer = mockEventProducer() with self.app.app_context(): handle_message(json.dumps(message), mock_event_producer) host_keys_to_check = ["display_name", "insights_id", "account"] for key in host_keys_to_check: self.assertEqual( json.loads(mock_event_producer.get_write_event())["host"][key], expected_results["host"][key])