Пример #1
0
def test_host_model_default_timestamps(db_create_host):
    host = Host(account=ACCOUNT, canonical_facts={"fqdn": "fqdn"})

    before_commit = now()
    db_create_host(host)
    after_commit = now()

    assert isinstance(host.created_on, datetime)
    assert before_commit < host.created_on < after_commit
    assert isinstance(host.modified_on, datetime)
    assert before_commit < host.modified_on < after_commit
Пример #2
0
def test_host_model_updated_timestamp(db_create_host):
    host = Host(account=ACCOUNT, canonical_facts={"fqdn": "fqdn"})

    before_insert_commit = now()
    db_create_host(host)
    after_insert_commit = now()

    host.canonical_facts = {"fqdn": "ndqf"}

    before_update_commit = now()
    db.session.commit()
    after_update_commit = now()

    assert before_insert_commit < host.created_on < after_insert_commit
    assert before_update_commit < host.modified_on < after_update_commit
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
Пример #4
0
def db_host(**values):
    data = {
        "account": USER_IDENTITY["account_number"],
        "display_name": "test-display-name",
        "ansible_host": "test-ansible-host",
        "canonical_facts": {
            "insights_id": generate_uuid(),
            "subscription_manager_id": generate_uuid(),
            "bios_uuid": generate_uuid(),
            "fqdn": "test-fqdn",
            "satellite_id": generate_uuid(),
            "rhel_machine_id": generate_uuid(),
            "ip_addresses": ["10.0.0.1"],
            "mac_addresses": ["aa:bb:cc:dd:ee:ff"],
        },
        "facts": {
            "ns1": {
                "key1": "value1"
            }
        },
        "tags": {
            "ns1": {
                "key1": ["val1", "val2"],
                "key2": ["val1"]
            },
            "SPECIAL": {
                "tag": ["ToFind"]
            }
        },
        "stale_timestamp": (now() + timedelta(days=randint(1, 7))).isoformat(),
        "reporter": "test-reporter",
        **values,
    }
    return Host(**data)
Пример #5
0
def test_add_host_stale_timestamp(event_datetime_mock,
                                  mq_create_or_update_host):
    """
    Tests to see if the host is successfully created with both reporter
    and stale_timestamp set.
    """
    expected_insights_id = generate_uuid()
    timestamp_iso = event_datetime_mock.isoformat()
    stale_timestamp = now()

    host = minimal_host(insights_id=expected_insights_id,
                        stale_timestamp=stale_timestamp.isoformat())

    expected_results = {
        "host": {
            **host.data(),
            "stale_warning_timestamp":
            (stale_timestamp + timedelta(weeks=1)).isoformat(),
            "culled_timestamp":
            (stale_timestamp + timedelta(weeks=2)).isoformat(),
        },
        "platform_metadata": {},
        "timestamp": timestamp_iso,
        "type": "created",
    }

    host_keys_to_check = ["reporter", "stale_timestamp", "culled_timestamp"]

    key, event, headers = mq_create_or_update_host(host, return_all_data=True)

    assert_mq_host_data(key, event, expected_results, host_keys_to_check)
def _test_order_by_id_desc(inventory_config, api_get, subtests, created_hosts, specifications, order_by, order_how):
    for updates, expected_added_hosts in specifications:
        # Update hosts to they have a same modified_on timestamp, but different IDs.
        # New modified_on value must be set explicitly so it’s saved the same to all
        # records. Otherwise SQLAlchemy would consider it unchanged and update it
        # automatically to its own "now" only for records whose ID changed.
        new_modified_on = now()

        for added_host_index, new_id in updates:
            host = update_host_in_db(created_hosts[added_host_index].id, id=new_id, modified_on=new_modified_on)
            created_hosts[added_host_index] = serialize_db_host(host, inventory_config)

        # Check the order in the response against the expected order. Only indexes
        # are passed, because self.added_hosts values were replaced during the
        # update.
        expected_hosts = tuple(created_hosts[added_host_index] for added_host_index in expected_added_hosts)

        urls = (HOST_URL, build_hosts_url(created_hosts), build_system_profile_url(created_hosts))
        for url in urls:
            with subtests.test(url=url, updates=updates):
                order_query_parameters = build_order_query_parameters(order_by=order_by, order_how=order_how)
                response_status, response_data = api_get(url, query_parameters=order_query_parameters)

                assert_response_status(response_status, expected_status=200)
                assert_host_ids_in_response(response_data, expected_hosts)
Пример #7
0
def test_ignore_culled_host_on_update_by_elevated_id(
        api_create_or_update_host):
    # Culled host
    host = minimal_host(insights_id=generate_uuid(),
                        stale_timestamp=(now() -
                                         timedelta(weeks=3)).isoformat())

    # Create the host
    multi_response_status, multi_response_data = api_create_or_update_host(
        [host])

    assert_response_status(multi_response_status, 207)

    create_host_response = get_host_from_multi_response(multi_response_data)

    assert_host_was_created(create_host_response)

    # Update the host
    host.ip_addresses = ["10.10.0.2"]

    multi_response_status, multi_response_data = api_create_or_update_host(
        [host])

    assert_response_status(multi_response_status, 207)

    update_host_response = get_host_from_multi_response(multi_response_data)

    assert_host_was_created(update_host_response)

    assert create_host_response["host"]["id"] != update_host_response["host"][
        "id"]
Пример #8
0
def test_ignore_culled_host_on_update_by_canonical_facts(
        api_create_or_update_host):
    # Culled host
    host = minimal_host(fqdn="my awesome fqdn",
                        stale_timestamp=(now() -
                                         timedelta(weeks=3)).isoformat())

    # Create the host
    multi_response_status, multi_response_data = api_create_or_update_host(
        [host])

    assert_response_status(multi_response_status, 207)

    create_host_response = get_host_from_multi_response(multi_response_data)

    assert_host_was_created(create_host_response)

    # Update the host
    multi_response_status, multi_response_data = api_create_or_update_host(
        [host])

    assert_response_status(multi_response_status, 207)

    update_host_response = get_host_from_multi_response(multi_response_data)

    assert_host_was_created(update_host_response)

    assert create_host_response["host"]["id"] != update_host_response["host"][
        "id"]
Пример #9
0
def test_update_existing_host_fix_display_name_using_input_fqdn(
        db_create_host):
    # Create an "existing" host
    fqdn = "host1.domain1.com"

    existing_host = db_create_host(extra_data={
        "canonical_facts": {
            "fqdn": fqdn
        },
        "display_name": None
    })

    # Clear the display_name
    existing_host.display_name = None
    db.session.commit()
    assert existing_host.display_name is None

    # Update the host
    expected_fqdn = "different.domain1.com"
    input_host = Host({"fqdn": expected_fqdn},
                      display_name="",
                      reporter="puptoo",
                      stale_timestamp=now())
    existing_host.update(input_host)

    assert existing_host.display_name == expected_fqdn
Пример #10
0
def test_update_existing_host_fix_display_name_using_existing_fqdn(
        db_create_host):
    expected_fqdn = "host1.domain1.com"
    insights_id = generate_uuid()

    existing_host = db_create_host(
        extra_data={
            "canonical_facts": {
                "fqdn": expected_fqdn,
                "insights_id": insights_id
            },
            "display_name": None
        })

    # Clear the display_name
    existing_host.display_name = None
    db.session.commit()
    assert existing_host.display_name is None

    # Update the host
    input_host = Host({"insights_id": insights_id},
                      display_name="",
                      reporter="puptoo",
                      stale_timestamp=now())
    existing_host.update(input_host)

    assert existing_host.display_name == expected_fqdn
Пример #11
0
def test_host_model_assigned_values(db_create_host, db_get_host):
    values = {
        "account": USER_IDENTITY["account_number"],
        "display_name": "display_name",
        "ansible_host": "ansible_host",
        "facts": [{
            "namespace": "namespace",
            "facts": {
                "key": "value"
            }
        }],
        "tags": {
            "namespace": {
                "key": ["value"]
            }
        },
        "canonical_facts": {
            "fqdn": "fqdn"
        },
        "system_profile_facts": {
            "number_of_cpus": 1
        },
        "stale_timestamp": now(),
        "reporter": "reporter",
    }

    inserted_host = Host(**values)
    db_create_host(inserted_host)

    selected_host = db_get_host(inserted_host.id)
    for key, value in values.items():
        assert getattr(selected_host, key) == value
Пример #12
0
def test_host_model_default_timestamps(db_create_host):
    host = Host(
        account=USER_IDENTITY["account_number"],
        canonical_facts={"fqdn": "fqdn"},
        reporter="yupana",
        stale_timestamp=now(),
    )

    before_commit = now()
    db_create_host(host=host)
    after_commit = now()

    assert isinstance(host.created_on, datetime)
    assert before_commit < host.created_on < after_commit
    assert isinstance(host.modified_on, datetime)
    assert before_commit < host.modified_on < after_commit
Пример #13
0
def test_host_model_timestamp_timezones(db_create_host):
    host = Host(account=ACCOUNT, canonical_facts={"fqdn": "fqdn"}, stale_timestamp=now(), reporter="ingress")

    db_create_host(host)

    assert host.created_on.tzinfo
    assert host.modified_on.tzinfo
    assert host.stale_timestamp.tzinfo
Пример #14
0
def test_host_model_constraints(field, value, db_create_host):
    values = {"account": ACCOUNT, "canonical_facts": {"fqdn": "fqdn"}, **{field: value}}
    if field == "reporter":
        values["stale_timestamp"] = now()

    host = Host(**values)

    with pytest.raises(DataError):
        db_create_host(host)
def minimal_db_host(**values):
    data = {
        "account": ACCOUNT,
        "canonical_facts": {"insights_id": generate_uuid()},
        "stale_timestamp": (now() + timedelta(days=randint(1, 7))).isoformat(),
        "reporter": "test-reporter",
        **values,
    }
    return Host(**data)
Пример #16
0
def test_host_model_default_id(db_create_host):
    host = Host(
        account=USER_IDENTITY["account_number"],
        canonical_facts={"fqdn": "fqdn"},
        reporter="yupana",
        stale_timestamp=now(),
    )
    db_create_host(host=host)

    assert isinstance(host.id, uuid.UUID)
Пример #17
0
def test_host_model_updated_timestamp(db_create_host):
    host = Host(
        account=USER_IDENTITY["account_number"],
        canonical_facts={"fqdn": "fqdn"},
        reporter="yupana",
        stale_timestamp=now(),
    )

    before_insert_commit = now()
    db_create_host(host=host)
    after_insert_commit = now()

    host.canonical_facts = {"fqdn": "ndqf"}

    before_update_commit = now()
    db.session.commit()
    after_update_commit = now()

    assert before_insert_commit < host.created_on < after_insert_commit
    assert before_update_commit < host.modified_on < after_update_commit
Пример #18
0
def test_host_schema_ignored_tags(tags):
    host = {
        "fqdn": "fred.flintstone.com",
        "display_name": "display_name",
        "account": ACCOUNT,
        "tags": tags,
        "stale_timestamp": now().isoformat(),
        "reporter": "test",
    }

    validated_host = HttpHostSchema(strict=True).load(host)
    assert "tags" not in validated_host.data
Пример #19
0
def test_host_schema_valid_tags(tags):
    host = {
        "fqdn": "fred.flintstone.com",
        "display_name": "display_name",
        "account": USER_IDENTITY["account_number"],
        "tags": tags,
        "stale_timestamp": now().isoformat(),
        "reporter": "test",
    }
    validated_host = HostSchema().load(host)

    assert validated_host["tags"] == tags
Пример #20
0
def test_host_schema_timezone_enforced():
    host = {
        "fqdn": "scooby.doo.com",
        "display_name": "display_name",
        "account": USER_IDENTITY["account_number"],
        "stale_timestamp": now().replace(tzinfo=None).isoformat(),
        "reporter": "test",
    }
    with pytest.raises(MarshmallowValidationError) as exception:
        HostSchema().load(host)

    assert "Timestamp must contain timezone info" in str(exception.value)
Пример #21
0
def test_host_schema_timezone_enforced(schema):
    host = {
        "fqdn": "scooby.doo.com",
        "display_name": "display_name",
        "account": ACCOUNT,
        "stale_timestamp": now().replace(tzinfo=None).isoformat(),
        "reporter": "test",
    }
    with pytest.raises(ValidationError) as exception:
        schema(strict=True).load(host)

    assert "Timestamp must contain timezone info" in str(exception.value)
def test_culled_timestamp(culling_culled_offset_days, inventory_config, mq_create_or_update_host, api_get):
    inventory_config.culling_culled_offset_days = culling_culled_offset_days

    stale_timestamp = now() + timedelta(hours=1)
    host = minimal_host(stale_timestamp=stale_timestamp.isoformat())
    created_host = mq_create_or_update_host(host)

    url = build_hosts_url(created_host.id)
    response_status, response_data = api_get(url)
    assert response_status == 200

    culled_timestamp = stale_timestamp + timedelta(days=culling_culled_offset_days)
    assert culled_timestamp.isoformat() == response_data["results"][0]["culled_timestamp"]
Пример #23
0
def test_host_model_timestamp_timezones(db_create_host):
    host = Host(
        account=USER_IDENTITY["account_number"],
        canonical_facts={"fqdn": "fqdn"},
        stale_timestamp=now(),
        reporter="ingress",
    )

    db_create_host(host=host)

    assert host.created_on.tzinfo
    assert host.modified_on.tzinfo
    assert host.stale_timestamp.tzinfo
def minimal_db_host(**values):
    data = {
        "account": USER_IDENTITY["account_number"],
        "canonical_facts": {
            "insights_id": generate_uuid()
        },
        "stale_timestamp": (now() + timedelta(days=randint(1, 7))),
        "reporter": "test-reporter",
        **values,
    }
    if "account" in values:
        data["account"] = values.get("account")

    return Host(**data)
Пример #25
0
def test_host_schema_invalid_tags(tags):
    host = {
        "fqdn": "fred.flintstone.com",
        "display_name": "display_name",
        "account": ACCOUNT,
        "tags": tags,
        "stale_timestamp": now().isoformat(),
        "reporter": "test",
    }
    with pytest.raises(ValidationError) as exception:
        MqHostSchema(strict=True).load(host)

    error_messages = exception.value.normalized_messages()
    assert "tags" in error_messages
    assert error_messages["tags"] == {0: {"key": ["Missing data for required field."]}}
Пример #26
0
def test_host_model_constraints(field, value, db_create_host):
    values = {
        "account": USER_IDENTITY["account_number"],
        "canonical_facts": {"fqdn": "fqdn"},
        "stale_timestamp": now(),
        **{field: value},
    }
    # add reporter if it's missing because it is now required all the time
    if not values.get("reporter"):
        values["reporter"] = "yupana"

    host = Host(**values)

    with pytest.raises(DataError):
        db_create_host(host=host)
Пример #27
0
def test_host_models_missing_fields(missing_field):
    limited_values = {
        "account": USER_IDENTITY["account_number"],
        "canonical_facts": {"fqdn": "foo.qoo.doo.noo"},
        "system_profile_facts": {"number_of_cpus": 1},
    }
    if missing_field in limited_values:
        limited_values[missing_field] = None

    # LimitedHost should be fine with these missing values
    LimitedHost(**limited_values)

    values = {**limited_values, "stale_timestamp": now(), "reporter": "reporter"}
    if missing_field in values:
        values[missing_field] = None

    # Host should complain about the missing values
    with pytest.raises(InventoryException):
        Host(**values)
def test_with_stale_timestamp(mq_create_or_update_host, api_get):
    stale_timestamp = now()
    reporter = "some reporter"

    host = minimal_host(fqdn="matching fqdn", stale_timestamp=stale_timestamp.isoformat(), reporter=reporter)

    created_host = mq_create_or_update_host(host)
    assert_system_culling_data(created_host.data(), stale_timestamp, reporter)

    updated_host = mq_create_or_update_host(host)
    assert_system_culling_data(updated_host.data(), stale_timestamp, reporter)

    response_status, response_data = api_get(HOST_URL)
    assert response_status == 200
    assert_system_culling_data(response_data["results"][0], stale_timestamp, reporter)

    response_status, response_data = api_get(build_hosts_url(created_host.id))
    assert response_status == 200
    assert_system_culling_data(response_data["results"][0], stale_timestamp, reporter)
Пример #29
0
def test_always_update_stale_timestamp_from_next_reporter(
        api_create_or_update_host, db_get_host, new_stale_timestamp,
        new_reporter):
    old_stale_timestamp = now() + timedelta(days=2)
    old_reporter = "old reporter"

    host = minimal_host(stale_timestamp=old_stale_timestamp.isoformat(),
                        reporter=old_reporter)

    multi_response_status, multi_response_data = api_create_or_update_host(
        [host])

    assert_response_status(multi_response_status, 207)

    create_host_response = get_host_from_multi_response(multi_response_data)

    assert_host_was_created(create_host_response)

    created_host_id = create_host_response["host"]["id"]

    retrieved_host = db_get_host(created_host_id)

    assert old_stale_timestamp == retrieved_host.stale_timestamp
    assert old_reporter == retrieved_host.reporter

    host.stale_timestamp = new_stale_timestamp.isoformat()
    host.reporter = new_reporter

    multi_response_status, multi_response_data = api_create_or_update_host(
        [host])

    assert_response_status(multi_response_status, 207)

    update_host_response = get_host_from_multi_response(multi_response_data)

    assert_host_was_updated(create_host_response, update_host_response)

    retrieved_host = db_get_host(created_host_id)

    assert new_stale_timestamp == retrieved_host.stale_timestamp
    assert new_reporter == retrieved_host.reporter
Пример #30
0
def test_update_existing_host_dont_change_display_name(db_create_host):
    # Create an "existing" host
    fqdn = "host1.domain1.com"
    display_name = "foo"
    existing_host = db_create_host(extra_data={
        "canonical_facts": {
            "fqdn": fqdn
        },
        "display_name": display_name
    })

    # Attempt to update the display name from Satellite reporter (shouldn't change)
    expected_fqdn = "different.domain1.com"
    input_host = Host({"fqdn": expected_fqdn},
                      display_name="dont_change_me",
                      reporter="yupana",
                      stale_timestamp=now())
    existing_host.update(input_host)

    # assert display name hasn't changed
    assert existing_host.display_name == display_name