Ejemplo n.º 1
0
def test_handle_message_unicode_not_damaged(mocker, flask_app, subtests):
    mocker.patch("app.queue.queue.build_event")
    add_host = mocker.patch("app.queue.queue.add_host",
                            return_value=(mocker.MagicMock(), None, None,
                                          None))

    operation_raw = "🧜🏿‍♂️"
    operation_escaped = json.dumps(operation_raw)[1:-1]

    messages = (
        f'{{"operation": "", "data": {{"display_name": "{operation_raw}{operation_raw}", "account": "test"}}}}',
        f'{{"operation": "", "data": {{"display_name": "{operation_escaped}{operation_escaped}","account": "test"}}}}',
        f'{{"operation": "", "data": {{"display_name": "{operation_raw}{operation_escaped}", "account": "test"}}}}',
    )

    for message in messages:
        with subtests.test(message=message):
            host_id = generate_uuid()
            add_host.reset_mock()
            add_host.return_value = ({
                "id": host_id
            }, host_id, None, AddHostResult.updated)
            handle_message(message, mocker.Mock())
            add_host.assert_called_once_with(
                {
                    "display_name": f"{operation_raw}{operation_raw}",
                    "account": "test"
                }, Identity(USER_IDENTITY))
Ejemplo n.º 2
0
    def test_update_host_with_tags_doesnt_change_tags(self):
        create_host_data = HostWrapper(
            test_data(tags=[{"namespace": "ns", "key": "some_key", "value": "val"}], fqdn="fqdn")
        )

        message = {"operation": "add_host", "data": create_host_data.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)
        host_id = event["host"]["id"]

        # attempt to update
        update_host_data = HostWrapper(
            test_data(tags=[{"namespace": "other_ns", "key": "other_key", "value": "other_val"}], fqdn="fqdn")
        )
        update_response = self.post(HOST_URL, [update_host_data.data()], 207)
        self._verify_host_status(update_response, 0, 200)

        tags_response = self.get(f"{HOST_URL}/{host_id}/tags")

        # check the tags haven't updated
        self.assertEqual(create_host_data.tags, tags_response["results"][host_id])
Ejemplo n.º 3
0
def test_handle_message_with_different_account(mocker, flask_app, subtests):
    mocker.patch("app.queue.queue.build_event")
    add_host = mocker.patch("app.queue.queue.add_host",
                            return_value=(mocker.MagicMock(), None, None,
                                          None))

    operation_raw = "🧜🏿‍♂️"
    messages = (
        f'{{"operation": "", "data": {{"display_name": "{operation_raw}{operation_raw}", "account": "dummy"}}}}',
    )

    identity = Identity(SYSTEM_IDENTITY)
    identity.account_number = "dummy"

    for message in messages:
        with subtests.test(message=message):
            host_id = generate_uuid()
            add_host.reset_mock()
            add_host.return_value = ({
                "id": host_id
            }, host_id, None, AddHostResult.updated)
            handle_message(message, mocker.Mock())
            add_host.assert_called_once_with(
                {
                    "display_name": f"{operation_raw}{operation_raw}",
                    "account": "dummy"
                }, identity)
def test_handle_message_happy_path(mocker, event_datetime_mock, flask_app):
    expected_insights_id = generate_uuid()
    host_id = generate_uuid()
    timestamp_iso = event_datetime_mock.isoformat()

    mocker.patch(
        "app.queue.queue.add_host",
        return_value=(
            {"id": host_id, "insights_id": expected_insights_id},
            host_id,
            expected_insights_id,
            AddHostResult.created,
        ),
    )
    mock_event_producer = mocker.Mock()

    host = minimal_host(insights_id=expected_insights_id)
    message = wrap_message(host.data())
    handle_message(json.dumps(message), mock_event_producer)

    mock_event_producer.write_event.assert_called_once()

    assert json.loads(mock_event_producer.write_event.call_args[0][0]) == {
        "timestamp": timestamp_iso,
        "type": "created",
        "host": {"id": host_id, "insights_id": expected_insights_id},
        "platform_metadata": {},
        "metadata": {"request_id": "-1"},
    }
def test_events_sent_to_correct_topic(mocker, flask_app, secondary_topic_enabled):
    host_id = generate_uuid()
    insights_id = generate_uuid()

    host = minimal_host(id=host_id, insights_id=insights_id)

    add_host = mocker.patch(
        "app.queue.queue.add_host", return_value=({"id": host_id}, host_id, insights_id, AddHostResult.created)
    )
    mock_event_producer = mocker.Mock()

    message = wrap_message(host.data())
    handle_message(json.dumps(message), mock_event_producer)

    # checking events sent to both egress and events topic
    assert mock_event_producer.write_event.call_count == 2
    assert mock_event_producer.write_event.call_args_list[0][0][3] == Topic.egress
    assert mock_event_producer.write_event.call_args_list[1][0][3] == Topic.events

    mock_event_producer.reset_mock()

    # for host update events
    add_host.return_value = ({"id": host_id}, host_id, insights_id, AddHostResult.updated)

    message["data"].update(stale_timestamp=(now() + timedelta(hours=26)).isoformat())
    handle_message(json.dumps(message), mock_event_producer)

    # checking events sent to both egress and events topic
    assert mock_event_producer.write_event.call_count == 2
    assert mock_event_producer.write_event.call_args_list[0][0][3] == Topic.egress
    assert mock_event_producer.write_event.call_args_list[1][0][3] == Topic.events
Ejemplo n.º 6
0
def test_handle_message_failure_invalid_json_message(mocker):
    invalid_message = "failure {} "

    mock_event_producer = mocker.Mock()

    with pytest.raises(json.decoder.JSONDecodeError):
        handle_message(invalid_message, mock_event_producer)

    mock_event_producer.assert_not_called()
def test_handle_message_failure_invalid_message_format(mocker):
    invalid_message = json.dumps({"operation": "add_host", "NOTdata": {}})  # Missing data field

    mock_event_producer = mocker.Mock()

    with pytest.raises(marshmallow.exceptions.ValidationError):
        handle_message(invalid_message, mock_event_producer)

    mock_event_producer.assert_not_called()
def test_handle_message_failure_invalid_surrogates(mocker, display_name):
    mocker.patch("app.queue.queue.build_event")
    add_host = mocker.patch("app.queue.queue.add_host", return_value=(mocker.MagicMock(), None))

    invalid_message = f'{{"operation": "", "data": {{"display_name": "hello{display_name}"}}}}'

    with pytest.raises(UnicodeError):
        handle_message(invalid_message, mocker.Mock())

    add_host.assert_not_called()
    def _mq_create_or_update_host(
        host_data, platform_metadata=None, return_all_data=False, event_producer=event_producer_mock
    ):
        message = wrap_message(host_data.data(), platform_metadata=platform_metadata)
        handle_message(json.dumps(message), event_producer)
        event = json.loads(event_producer.event)

        if return_all_data:
            return event_producer_mock.key, event, event_producer.headers

        # add facts object since it's not returned by event message
        return HostWrapper({**event["host"], **{"facts": host_data.facts}})
Ejemplo n.º 10
0
def test_handle_message_side_effect(mocker, flask_app):
    fake_add_host = mocker.patch("lib.host_repository.add_host",
                                 side_effect=OperationalError(
                                     "DB Problem", "fake_param", "fake_orig"))

    expected_insights_id = generate_uuid()
    host = minimal_host(insights_id=expected_insights_id)

    fake_add_host.reset_mock()
    message = json.dumps(wrap_message(host.data()))

    with pytest.raises(expected_exception=OperationalError):
        handle_message(message, mocker.MagicMock())
    def test_get_host_with_escaped_special_characters(self):
        host_wrapper = HostWrapper({
            "account":
            ACCOUNT,
            "insights_id":
            generate_uuid(),
            "stale_timestamp":
            now().isoformat(),
            "reporter":
            "test",
            "tags": [
                {
                    "namespace": ";,/?:@&=+$",
                    "key": "-_.!~*'()",
                    "value": "#"
                },
                {
                    "namespace": " \t\n\r\f\v",
                    "key": " \t\n\r\f\v",
                    "value": " \t\n\r\f\v"
                },
            ],
        })
        message = {"operation": "add_host", "data": host_wrapper.data()}

        with self.app.app_context():
            mock_event_producer = MockEventProducer()
            handle_message(json.dumps(message), mock_event_producer)
            response_data = json.loads(mock_event_producer.event)
            created_host = response_data["host"]

        for namespace, key, value in ((";,/?:@&=+$", "-_.!~*'()", "#"),
                                      (" \t\n\r\f\v", " \t\n\r\f\v",
                                       " \t\n\r\f\v")):
            with self.subTest(namespace=namespace, key=key, value=value):
                tags_query = url_quote(
                    f"{quote_everything(namespace)}/{quote_everything(key)}={quote_everything(value)}"
                )
                get_response = self.get(f"{HOST_URL}?tags={tags_query}", 200)

                self.assertEqual(get_response["count"], 1)
                self.assertEqual(get_response["results"][0]["id"],
                                 created_host["id"])
Ejemplo n.º 12
0
    def _mq_create_or_update_host(
        host_data,
        platform_metadata=None,
        return_all_data=False,
        event_producer=event_producer_mock,
        message_operation=add_host,
    ):
        if not platform_metadata:
            platform_metadata = get_platform_metadata()
        host_data.data()["account"] = SYSTEM_IDENTITY.get("account_number")
        message = wrap_message(host_data.data(),
                               platform_metadata=platform_metadata)
        handle_message(json.dumps(message), event_producer, message_operation)
        event = json.loads(event_producer.event)

        if return_all_data:
            return event_producer_mock.key, event, event_producer.headers

        # add facts object since it's not returned by event message
        return HostWrapper({**event["host"], **{"facts": host_data.facts}})
Ejemplo n.º 13
0
    def create_hosts(self):
        hosts_to_create = [
            (
                "host1",
                generate_uuid(),
                "host1.domain.test",
                [
                    {
                        "namespace": "NS1",
                        "key": "key1",
                        "value": "val1"
                    },
                    {
                        "namespace": "NS1",
                        "key": "key2",
                        "value": "val1"
                    },
                    {
                        "namespace": "SPECIAL",
                        "key": "tag",
                        "value": "ToFind"
                    },
                    {
                        "namespace": "no",
                        "key": "key",
                        "value": None
                    },
                ],
            ),
            (
                "host2",
                generate_uuid(),
                "host1.domain.test",
                [
                    {
                        "namespace": "NS1",
                        "key": "key1",
                        "value": "val1"
                    },
                    {
                        "namespace": "NS2",
                        "key": "key2",
                        "value": "val2"
                    },
                    {
                        "namespace": "NS3",
                        "key": "key3",
                        "value": "val3"
                    },
                ],
            ),  # the same fqdn is intentional
            (
                "host3",
                generate_uuid(),
                "host2.domain.test",
                [
                    {
                        "namespace": "NS2",
                        "key": "key2",
                        "value": "val2"
                    },
                    {
                        "namespace": "NS3",
                        "key": "key3",
                        "value": "val3"
                    },
                    {
                        "namespace": "NS1",
                        "key": "key3",
                        "value": "val3"
                    },
                    {
                        "namespace": None,
                        "key": "key4",
                        "value": "val4"
                    },
                    {
                        "namespace": None,
                        "key": "key5",
                        "value": None
                    },
                ],
            ),
        ]

        if hasattr(self, "hosts_to_create"):
            self.hosts_to_create = hosts_to_create + self.hosts_to_create
        else:
            self.hosts_to_create = hosts_to_create

        host_list = []

        mock_event_producer = MockEventProducer()

        for host in self.hosts_to_create:
            host_wrapper = HostWrapper()
            host_wrapper.account = ACCOUNT
            host_wrapper.display_name = host[0]
            host_wrapper.insights_id = generate_uuid()
            host_wrapper.rhel_machine_id = generate_uuid()
            host_wrapper.subscription_manager_id = generate_uuid()
            host_wrapper.satellite_id = generate_uuid()
            host_wrapper.bios_uuid = generate_uuid()
            host_wrapper.ip_addresses = ["10.0.0.2"]
            host_wrapper.fqdn = host[2]
            host_wrapper.mac_addresses = ["aa:bb:cc:dd:ee:ff"]
            host_wrapper.external_id = generate_uuid()
            host_wrapper.facts = [{
                "namespace": "ns1",
                "facts": {
                    "key1": "value1"
                }
            }]
            host_wrapper.tags = host[3]
            host_wrapper.stale_timestamp = now().isoformat()
            host_wrapper.reporter = "test"
            message = {"operation": "add_host", "data": host_wrapper.data()}

            with self.app.app_context():
                handle_message(json.dumps(message), mock_event_producer)

            response_data = json.loads(mock_event_producer.event)

            # add facts object since it's not returned by message
            host_data = {
                **response_data["host"], "facts": message["data"]["facts"]
            }
            host_list.append(HostWrapper(host_data))

        return host_list