def test_topic_creation_raises_for_wrong_config(
        topic_controller: TopicController,
        confluent_admin_client: confluent_kafka.admin.AdminClient,
        topic_id: str):
    topics = confluent_admin_client.list_topics(timeout=5).topics.keys()
    assert topic_id not in topics
    # We only have 1 broker for tests, so a higher replication should fail
    with pytest.raises(KafkaException):
        topic_controller.create_topics([Topic(topic_id, replication_factor=2)])
def test_topic_deletion_works(
        topic_controller: TopicController,
        confluent_admin_client: confluent_kafka.admin.AdminClient, topic: str):
    topics = confluent_admin_client.list_topics(timeout=5).topics.keys()
    assert topic in topics
    topic_controller.delete_topic(Topic(topic))
    # Invalidate cache
    confluent_admin_client.poll(timeout=1)
    topics = confluent_admin_client.list_topics(timeout=5).topics.keys()
    assert topic not in topics
def test_topic_creation_works(
        topic_controller: TopicController,
        confluent_admin_client: confluent_kafka.admin.AdminClient,
        topic_id: str):
    topics = confluent_admin_client.list_topics(timeout=5).topics.keys()
    assert topic_id not in topics
    topic_controller.create_topics([Topic(topic_id, replication_factor=1)])

    # invalidate cache
    confluent_admin_client.poll(timeout=1)
    topics = confluent_admin_client.list_topics(timeout=5).topics.keys()
    assert topic_id in topics
def test_topic_diff(topic_controller: TopicController, topic_id: str):
    # the value we get from cluster configs is as string
    # testing against this is important to ensure consistency
    default_delete_retention = "86400000"
    topic_conf = {
        "name": topic_id,
        "replication_factor": 1,
        "num_partitions": 50,
        "config": {
            "cleanup.policy": "compact"
        },
    }
    get_diff = topic_controller.diff_with_cluster

    conf = json.loads(json.dumps(topic_conf))
    topic = Topic.from_dict(conf)
    topic_controller.create_topics([topic])
    assert not get_diff(
        topic).has_changes, "Shouldn't have diff on just created topic"

    conf = json.loads(json.dumps(topic_conf))
    conf["config"]["cleanup.policy"] = "delete"
    topic = Topic.from_dict(conf)
    diff = TopicDiff().set_diff("cleanup.policy", "compact", "delete")
    assert get_diff(topic) == diff, "Should have a diff on cleanup.policy"

    conf = json.loads(json.dumps(topic_conf))
    conf["config"]["delete.retention.ms"] = 1500
    topic = Topic.from_dict(conf)
    diff = TopicDiff().set_diff("delete.retention.ms",
                                default_delete_retention, 1500)
    assert get_diff(topic) == diff, "Should have a diff on delete.retention.ms"

    # the same as before, but this time with string values
    conf = json.loads(json.dumps(topic_conf))
    conf["config"]["delete.retention.ms"] = "1500"
    topic = Topic.from_dict(conf)
    diff = TopicDiff().set_diff("delete.retention.ms",
                                default_delete_retention, "1500")
    assert get_diff(topic) == diff, "Should have a diff on delete.retention.ms"

    conf = json.loads(json.dumps(topic_conf))
    conf["num_partitions"] = 3
    topic = Topic.from_dict(conf)
    diff = TopicDiff().set_diff("num_partitions", 50, 3)
    assert get_diff(topic) == diff, "Should have a diff on num_partitions"

    conf = json.loads(json.dumps(topic_conf))
    conf["replication_factor"] = 3
    topic = Topic.from_dict(conf)
    diff = TopicDiff().set_diff("replication_factor", 1, 3)
    assert get_diff(topic) == diff, "Should have a diff on replication_factor"
def test_alter_topic_config_works(topic_controller: TopicController,
                                  topic_id: str):
    initial_topic = Topic(topic_id, config={"cleanup.policy": "delete"})

    topic_controller.create_topics([initial_topic])
    topic_controller.update_from_cluster(initial_topic)
    config = initial_topic.config
    assert config.get("cleanup.policy") == "delete"
    change_topic = Topic(topic_id, config={"cleanup.policy": "compact"})
    topic_controller.alter_configs([change_topic])
    topic_controller.update_from_cluster(change_topic)
    after_changes_applied_topic = topic_controller.get_cluster_topic(topic_id)

    final_config = after_changes_applied_topic.config
    assert final_config.get("cleanup.policy") == "compact"
def test_topic_object_works(topic_controller: TopicController, topic: str):
    topic = topic_controller.get_cluster_topic(topic)
    assert isinstance(topic, Topic)
    assert len(topic.offsets) != 0
def test_topic_listing_works(topic_controller: TopicController, topic: str):
    topics = topic_controller.list_topics()
    assert topic in [t.name for t in topics]
def test_apply(topic_controller: TopicController, topic_id: str):
    runner = CliRunner()
    topic_name = f"apply_{topic_id}"
    topic_1 = {
        "name": topic_name + "_1",
        "replication_factor": 1,
        "num_partitions": 50,
        "config": {
            "cleanup.policy": "compact"
        },
    }
    topic_2 = {
        "name": topic_name + "_2",
        "replication_factor": 1,
        "num_partitions": 5,
        "config": {
            "cleanup.policy": "delete",
            "delete.retention.ms": 50000
        },
    }
    apply_conf = {"topics": [topic_1]}

    # 1: topic creation
    path = save_yaml(topic_id, apply_conf)
    result = runner.invoke(apply, ["-f", path], input="Y\n")
    assert (result.exit_code == 0 and "Successfully applied changes"
            in result.output), f"Calling apply failed, error: {result.output}"

    # 2: change cleanup policy to delete
    topic_1["config"]["cleanup.policy"] = "delete"
    path = save_yaml(topic_id, apply_conf)
    result = runner.invoke(apply, ["-f", path], input="Y\n")
    assert (result.exit_code == 0 and "Successfully applied changes"
            in result.output), f"Calling apply failed, error: {result.output}"

    # 3: add another topic and change the first one again
    apply_conf["topics"].append(topic_2)
    topic_1["config"]["cleanup.policy"] = "compact"
    path = save_yaml(topic_id, apply_conf)
    result = runner.invoke(apply, ["-f", path], input="Y\n")
    assert (result.exit_code == 0 and "Successfully applied changes"
            in result.output), f"Calling apply failed, error: {result.output}"

    # 4: no changes
    result = runner.invoke(apply, ["-f", path])
    assert (result.exit_code == 0 and "No changes detected, aborting"
            in result.output), f"Calling apply failed, error: {result.output}"

    # 5: change partitions - this attempt should be cancelled
    topic_1["num_partitions"] = 3
    topic_1["config"]["cleanup.policy"] = "delete"
    path = save_yaml(topic_id, apply_conf)
    result = runner.invoke(apply, ["-f", path], input="Y\n")
    assert (result.exit_code == 0
            and "to `replication_factor` and `num_partitions`"
            in result.output), f"Calling apply failed, error: {result.output}"
    # reset config to the old settings again
    topic_1["num_partitions"] = 50
    topic_1["config"]["cleanup.policy"] = "compact"

    # final: check results in the cluster to make sure they match
    for topic_conf in apply_conf["topics"]:
        topic_from_conf = Topic.from_dict(topic_conf)
        assert not topic_controller.diff_with_cluster(
            topic_from_conf
        ).has_changes, f"Topic configs don't match, diff is {topic_controller.diff_with_cluster(topic_from_conf)}"
Exemple #9
0
def test_offsets(filled_topic: Topic, topic_controller: TopicController):
    topic_controller.update_from_cluster(filled_topic)
    assert filled_topic.offsets == {0: Watermark(10, 0)}
Exemple #10
0
 def topic_controller(self) -> TopicController:
     if self.__topic_controller is None:
         self.__topic_controller = TopicController(self, self._config)
     return self.__topic_controller