This is an automated email from the ASF dual-hosted git repository.

pradeepagrawal8184 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new 469708a8d RANGER-5844: Add Docker system tests to verify Kafka publish 
authorization via Ranger (#1317)
469708a8d is described below

commit 469708a8d95d17f84ef42360dd92139f97e7fef6
Author: Chinmay Hegde <[email protected]>
AuthorDate: Fri Oct 16 17:59:44 2026 +0530

    RANGER-5844: Add Docker system tests to verify Kafka publish authorization 
via Ranger (#1317)
---
 functional-tests/kafka/test_kafka_01.py           | 139 ++++++++++++
 functional-tests/pytest.ini                       |   1 +
 functional-tests/ranger_test_utils/kafka_utils.py | 260 ++++++++++++++++++++++
 functional-tests/readme.md                        |  55 ++---
 functional-tests/run-tests.sh                     |   2 +-
 5 files changed, 420 insertions(+), 37 deletions(-)

diff --git a/functional-tests/kafka/test_kafka_01.py 
b/functional-tests/kafka/test_kafka_01.py
new file mode 100644
index 000000000..33e8f24e5
--- /dev/null
+++ b/functional-tests/kafka/test_kafka_01.py
@@ -0,0 +1,139 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Authorization is asserted via Kafka console producer output only. Access-audit 
asserts are
+deferred until Kafka plugin audits are reliably indexed in Docker — use
+ranger_test_utils.access_audit_utils when ready.
+
+AUDIT_FILTERS (future):
+  test_01_01 positive: accessType=publish, accessResult=1, 
aclEnforcer=ranger-acl,
+                       resourceName=<topic>, repoName=dev_kafka, 
requestUser=hrt_21
+  test_01_01 negative: accessType=publish, accessResult=0, 
aclEnforcer=ranger-acl,
+                       resourceName=<topic>, repoName=dev_kafka, 
requestUser=hrt_22
+"""
+
+import pytest
+
+from ranger_test_utils.hive_utils import delete_policies_by_id
+from ranger_test_utils.kafka_utils import (
+    KAFKA_ALLOWED_GROUP,
+    KAFKA_ALLOWED_USER,
+    KAFKA_AUTHZ_DENIED_SUBSTR,
+    KAFKA_DENIED_USER,
+    create_topic_allow_policy,
+    ensure_kerberos_user,
+    ensure_os_group_membership,
+    preflight_kafka_stack,
+    restore_missing_policies,
+    run_kafka_producer,
+    snapshot_policies,
+    wait_for_kafka_policy_propagation,
+)
+from ranger_test_utils.utils import (
+    configure_test_logging,
+    create_ranger_admin_session,
+    ensure_group_exists,
+    get_test_logger,
+    log_testcase_begin_for_pytest,
+    unique_suffix,
+)
+
+pytestmark = pytest.mark.kafka
+
+logger = get_test_logger(__name__)
+
+MESSAGE = "Hello Ranger Kafka"
+
+_admin_session = None
+_policy_id = None
+_original_policies = []
+_topic = None
+
+
+def _restore_dev_kafka_policies():
+    try:
+        if _policy_id is not None:
+            delete_policies_by_id(_admin_session, [_policy_id])
+    finally:
+        restore_missing_policies(_admin_session, _original_policies)
+
+
+def setup_module():
+    configure_test_logging(module_name=__name__)
+    logger.info("=== setup_module: start ===")
+    preflight_kafka_stack()
+
+    global _admin_session, _policy_id, _original_policies, _topic
+    _admin_session = create_ranger_admin_session()
+    _topic = "kafkaranger_test" + unique_suffix(6)
+    logger.info("Test topic: %s", _topic)
+
+    ensure_group_exists(_admin_session, KAFKA_ALLOWED_GROUP)
+    ensure_os_group_membership(KAFKA_ALLOWED_USER, KAFKA_ALLOWED_GROUP)
+    ensure_kerberos_user(KAFKA_ALLOWED_USER)
+    ensure_kerberos_user(KAFKA_DENIED_USER)
+
+    _original_policies = snapshot_policies(_admin_session)
+    try:
+        delete_policies_by_id(_admin_session, [policy["id"] for policy in 
_original_policies])
+        _policy_id = create_topic_allow_policy(_admin_session, _topic, 
KAFKA_ALLOWED_GROUP)
+        logger.info("Created topic allow policy id=%s for group %s", 
_policy_id, KAFKA_ALLOWED_GROUP)
+        wait_for_kafka_policy_propagation()
+    except BaseException:
+        # pytest does not run teardown_module when setup_module raises, so 
restore here.
+        _restore_dev_kafka_policies()
+        raise
+    logger.info("=== setup_module: done ===")
+
+
+def teardown_module():
+    if _admin_session is None:
+        return
+
+    logger.info("=== teardown_module: start ===")
+    _restore_dev_kafka_policies()
+    logger.info("=== teardown_module: done ===")
+
+
+def test_01_01_kafka_publish_topic_test_positive(request):
+    """hrt_21 is in the finance group, which the topic allow policy lets 
publish (creating the topic)."""
+    log_testcase_begin_for_pytest(logger, request.node.name, suite="KAFKA")
+    exit_code, output = run_kafka_producer(KAFKA_ALLOWED_USER, _topic, MESSAGE)
+    assert "TOPIC_AUTHORIZATION_FAILED" not in output and 
KAFKA_AUTHZ_DENIED_SUBSTR not in output, (
+        "Unexpected authorization failure publishing to "
+        + _topic
+        + "; exit_code="
+        + str(exit_code)
+        + " output="
+        + output
+    )
+    assert exit_code == 0, (
+        "Kafka producer failed; exit_code=" + str(exit_code) + " output=" + 
output
+    )
+
+
+def test_01_01_kafka_publish_topic_test_negative(request):
+    """hrt_22 has no policy on the topic, so publishing is denied."""
+    log_testcase_begin_for_pytest(logger, request.node.name, suite="KAFKA")
+    exit_code, output = run_kafka_producer(KAFKA_DENIED_USER, _topic, MESSAGE)
+    assert KAFKA_AUTHZ_DENIED_SUBSTR in output, (
+        "Expected "
+        + KAFKA_AUTHZ_DENIED_SUBSTR
+        + " in Kafka producer output; exit_code="
+        + str(exit_code)
+        + " output="
+        + output
+    )
diff --git a/functional-tests/pytest.ini b/functional-tests/pytest.ini
index 1cc7adb7e..d17dbeb90 100644
--- a/functional-tests/pytest.ini
+++ b/functional-tests/pytest.ini
@@ -31,6 +31,7 @@ markers =
     hive: Hive plugin enforcement (Docker HS2)
     hbase: HBase plugin enforcement (Docker HBase shell)
     hdfs_policy: HDFS Ranger plugin path policy enforcement (Docker dfs)
+    kafka: Kafka plugin enforcement (Docker Kafka console producer)
 pythonpath = .
 # No console logging during pytest; logger.info -> logs/<test_module_name>.log 
(see conftest.py).
 log_cli = false
diff --git a/functional-tests/ranger_test_utils/kafka_utils.py 
b/functional-tests/ranger_test_utils/kafka_utils.py
new file mode 100644
index 000000000..064511fe6
--- /dev/null
+++ b/functional-tests/ranger_test_utils/kafka_utils.py
@@ -0,0 +1,260 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Kafka Docker helpers for Ranger functional-tests (console producer + plugin 
enforcement)."""
+
+import json
+import shlex
+import time
+
+import pytest
+
+from ranger_test_utils.hive_utils import (
+    ADMIN_CONTAINER,
+    KDC_CONTAINER,
+    KERBEROS_REALM,
+    get_docker_client,
+    list_policies_for_service,
+)
+from ranger_test_utils.utils import (
+    LOGS_DIR,
+    POLICY_URL,
+    assert_http_ok,
+    ensure_logs_directory,
+    get_test_logger,
+    unique_suffix,
+)
+
+logger = get_test_logger(__name__)
+
+KAFKA_SERVICE_NAME = "dev_kafka"
+KAFKA_CONTAINER = "ranger-kafka"
+KAFKA_BOOTSTRAP_SERVER = "ranger-kafka.rangernw:9092"
+
+KAFKA_ALLOWED_USER = "hrt_21"
+KAFKA_DENIED_USER = "hrt_22"
+KAFKA_ALLOWED_GROUP = "finance"
+
+KAFKA_AUTHZ_DENIED_SUBSTR = "TopicAuthorizationException"
+
+# publish to a not-yet-existing topic: broker auto-creates it, which needs 
create + describe
+KAFKA_TOPIC_POLICY_ACCESS_TYPES = ["publish", "create", "describe"]
+
+# Kafka plugin polls Ranger for policy changes every 30s by default.
+KAFKA_POLICY_PROPAGATION_SLEEP_SEC = 40
+
+
+def _container_running(name):
+    try:
+        container = get_docker_client().containers.get(name)
+    except Exception:
+        return False
+    container.reload()
+    return container.status == "running"
+
+
+def preflight_kafka_stack():
+    """Skip tests when required Docker services are unavailable."""
+    required = [ADMIN_CONTAINER, KDC_CONTAINER, KAFKA_CONTAINER]
+    missing = [name for name in required if not _container_running(name)]
+    if missing:
+        pytest.skip(
+            "Kafka functional-tests need running containers: "
+            + ", ".join(missing)
+            + ". Run ./run-tests.sh postgres kafka from functional-tests/."
+        )
+
+
+def _user_principal(username):
+    return username + "@" + KERBEROS_REALM
+
+
+def _user_keytab_in_kafka_container(username):
+    return "/etc/keytabs/" + username + ".keytab"
+
+
+def ensure_kerberos_user(username):
+    """Create a user Kerberos principal and keytab on KDC, visible in 
ranger-kafka."""
+    kdc = get_docker_client().containers.get(KDC_CONTAINER)
+    principal = _user_principal(username)
+    keytab_in_kdc = "/etc/keytabs/ranger-kafka/" + username + ".keytab"
+
+    logger.info("Kerberos setup on %s: principal=%s keytab=%s", KDC_CONTAINER, 
principal, keytab_in_kdc)
+    kdc.exec_run('kadmin.local -q "addprinc -randkey ' + principal + '"', 
user="root")
+    kdc.exec_run("rm -f " + keytab_in_kdc, user="root")
+    # -norandkey keeps the key version, so keytabs this shared user already 
has in the
+    # hive/hbase containers stay valid.
+    exit_code, output = kdc.exec_run(
+        'kadmin.local -q "ktadd -norandkey -k ' + keytab_in_kdc + " " + 
principal + '"',
+        user="root",
+        demux=True,
+    )
+    if exit_code != 0:
+        raise RuntimeError(
+            "ktadd failed for " + principal + ": " + ((output[0] or b"") + 
(output[1] or b"")).decode()
+        )
+    kdc.exec_run("chmod 444 " + keytab_in_kdc, user="root")
+
+
+def ensure_os_group_membership(username, group):
+    """
+    Make username a member of group on the ranger-kafka OS.
+
+    The Kafka plugin resolves a user's groups from the broker's OS (Hadoop 
group
+    mapping), not from Ranger, so group-based policies need the membership 
here.
+    """
+    kafka = get_docker_client().containers.get(KAFKA_CONTAINER)
+    shell = (
+        "getent group " + group + " > /dev/null || groupadd " + group + "; "
+        "id " + username + " > /dev/null 2>&1 || useradd -M -s /sbin/nologin " 
+ username + "; "
+        "usermod -aG " + group + " " + username
+    )
+    exit_code, output = kafka.exec_run(["bash", "-c", shell], user="root", 
demux=True)
+    if exit_code != 0:
+        raise RuntimeError(
+            "Failed to add "
+            + username
+            + " to OS group "
+            + group
+            + " in "
+            + KAFKA_CONTAINER
+            + ": "
+            + ((output[0] or b"") + (output[1] or b"")).decode()
+        )
+    logger.info("OS group membership in %s: %s -> %s", KAFKA_CONTAINER, 
username, group)
+
+
+def run_kafka_producer(username, topic, message):
+    """
+    Publish one message to topic with kafka-console-producer.sh inside 
ranger-kafka,
+    authenticating as username from its keytab.
+
+    Returns (exit_code, combined_output).
+    """
+    kafka = get_docker_client().containers.get(KAFKA_CONTAINER)
+    props_path = "/tmp/kafka-producer-" + username + "-" + unique_suffix(6) + 
".properties"
+    properties = "\n".join(
+        [
+            "security.protocol=SASL_PLAINTEXT",
+            "sasl.mechanism=GSSAPI",
+            "sasl.kerberos.service.name=kafka",
+            "sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule 
required"
+            " useKeyTab=true storeKey=true doNotPrompt=true"
+            ' keyTab="' + _user_keytab_in_kafka_container(username) + '"'
+            ' principal="' + _user_principal(username) + '";',
+            # Ranger's Kafka authorizer denies the idempotent producer's 
cluster-level
+            # idempotent_write check, so publish with a plain producer.
+            "enable.idempotence=false",
+        ]
+    )
+    producer_cmd = (
+        "/opt/kafka/bin/kafka-console-producer.sh --bootstrap-server "
+        + KAFKA_BOOTSTRAP_SERVER
+        + " --topic "
+        + shlex.quote(topic)
+        + " --producer.config "
+        + props_path
+    )
+    shell = (
+        "printf '%s\\n' "
+        + shlex.quote(properties)
+        + " > "
+        + props_path
+        + "; printf '%s\\n' "
+        + shlex.quote(message)
+        + " | "
+        + producer_cmd
+        + '; rc=$?; rm -f '
+        + props_path
+        + '; exit "$rc"'
+    )
+    logger.info("Kafka producer: container=%s ranger_user=%s", 
KAFKA_CONTAINER, username)
+    logger.info("RUNNING: %s", producer_cmd)
+
+    exit_code, output = kafka.exec_run(["bash", "-c", shell], user="kafka", 
demux=True)
+    combined = (output[0] or b"").decode() + (output[1] or b"").decode()
+    logger.info("Kafka producer exit_code=%s output:\n%s", exit_code, combined)
+    return exit_code, combined
+
+
+def create_topic_allow_policy(session, topic, group, 
service_name=KAFKA_SERVICE_NAME):
+    """Create a policy allowing group to publish to topic. Returns the policy 
id."""
+    payload = {
+        "service": service_name,
+        "name": "allow publish on kafka topic " + topic + " - " + 
unique_suffix(),
+        "description": "Kafka topic allow policy for functional-tests",
+        "isEnabled": True,
+        "isAuditEnabled": True,
+        "resources": {
+            "topic": {"values": [topic], "isExcludes": False, "isRecursive": 
False},
+        },
+        "policyItems": [
+            {
+                "users": [],
+                "groups": [group],
+                "accesses": [
+                    {"type": perm, "isAllowed": True}
+                    for perm in KAFKA_TOPIC_POLICY_ACCESS_TYPES
+                ],
+                "delegateAdmin": False,
+            }
+        ],
+    }
+    response = session.post(POLICY_URL, json=payload)
+    assert_http_ok(response, (200, 201), "Create kafka topic allow policy", 
POLICY_URL)
+    policy_id = response.json().get("id")
+    assert policy_id is not None, "Create policy response missing id: " + 
response.text
+    return policy_id
+
+
+def snapshot_policies(session, service_name=KAFKA_SERVICE_NAME):
+    """Return every policy in the service and save them to logs/ before 
anything changes."""
+    policies = list_policies_for_service(session, service_name)
+    ensure_logs_directory()
+    path = LOGS_DIR / ("kafka_policies_snapshot_" + unique_suffix() + ".json")
+    path.write_text(json.dumps(policies, indent=2))
+    logger.info("Saved %s policies from %s to %s", len(policies), 
service_name, path)
+    return policies
+
+
+def restore_missing_policies(session, original_policies, 
service_name=KAFKA_SERVICE_NAME):
+    """
+    Re-create each original policy whose name is not currently in the service.
+
+    Safe to call after a partial setup or teardown: policies still present are 
skipped,
+    and a failed restore does not stop the others. Raises at the end if any 
failed.
+    """
+    current_names = {policy["name"] for policy in 
list_policies_for_service(session, service_name)}
+    restored = 0
+    failures = []
+    for policy in original_policies:
+        if policy["name"] in current_names:
+            continue
+        body = {key: value for key, value in policy.items() if key not in 
("id", "guid", "version")}
+        response = session.post(POLICY_URL, json=body)
+        if response.status_code in (200, 201):
+            restored += 1
+        else:
+            failures.append(policy["name"] + ": HTTP " + 
str(response.status_code) + " " + response.text)
+    logger.info("Restored %s policies in %s", restored, service_name)
+    if failures:
+        raise AssertionError(
+            "Failed to restore policies in " + service_name + ":\n" + 
"\n".join(failures)
+        )
+
+
+def 
wait_for_kafka_policy_propagation(seconds=KAFKA_POLICY_PROPAGATION_SLEEP_SEC):
+    logger.info("Waiting %ss for Kafka plugin policy propagation", seconds)
+    time.sleep(seconds)
diff --git a/functional-tests/readme.md b/functional-tests/readme.md
index c46bee8ec..c9f9e25af 100644
--- a/functional-tests/readme.md
+++ b/functional-tests/readme.md
@@ -31,35 +31,26 @@ A Docker-based test execution framework that validates 
Apache Ranger service int
 | **servicerest** | Test cases for Ranger Admin Service REST APIs |
 | **tagrest** | Test cases for Ranger Admin Tag REST APIs |
 | **api** | Public API v2 service and policy CRUD (admin Docker only) |
+| **api_tests** | Public API v2 user REST calls by role: admin, keyadmin, 
auditor, user role, and negative cases (admin Docker only) |
 | **hive** | Hive Ranger plugin enforcement via HS2/beeline (requires 
`ranger-hadoop` + `ranger-hive`) |
 | **hbase** | HBase Ranger plugin enforcement via HBase shell (requires 
`ranger-hadoop` + `ranger-hbase`) |
+| **kafka** | Kafka Ranger plugin enforcement via console producer (requires 
`ranger-kafka`) |
 
 ### Directory Structure
 
 ```text
 functional-tests/
-├── multiple modules containing test cases
-├── ...
-├── ranger_test_utils/utils.py   # Shared logging, HTTP asserts, Public API v2 
helpers
-├── hdfs/                        # Tests on HDFS encryption cycle
-├── kms/                         # Tests on KMS REST API
-├── xuserrest/                   # Tests on Ranger User/Group/Role REST APIs
-├── rolerest/                    # Tests on Ranger Role REST APIs
-├── servicerest/                 # Tests on Ranger Service REST APIs
-├── tagrest/                     # Tests on Ranger Tag REST APIs
-├── api/                         # Public API v2 (service / policy) tests
-├── hive/                        # Hive plugin enforcement tests
-├── hbase/                       # HBase plugin enforcement tests
-├── ranger_test_utils/hive_utils.py
-├── ranger_test_utils/hbase_utils.py
-├── ranger_test_utils/hdfs_utils.py
-├── ranger_test_utils/access_audit_utils.py  # For future access-audit asserts
-│
-├── ranger_test_utils/utils.py   # Shared logging, HTTP asserts, Public API v2 
helpers
+├── <component> test modules     # i.e hive,hdfs,kms etc
+├── REST API modules             # xuserrest,servicerest,api,tagrest etc
+|
 ├── pytest.ini                   # Registers custom pytest markers
 ├── run-tests.sh                 # Script to automate setup and test execution
 ├── requirements.txt             # Python dependencies
 └── readme.md                    # This documentation
+├── ranger_test_utils/utils.py   # Shared logging, HTTP asserts, Public API v2 
helpers
+├── ranger_test_utils/<service>_utils.py
+├── ranger_test_utils/access_audit_utils.py  # For future access-audit asserts
+
 ```
 
 > **Note:** A Python virtual environment folder named `myenv` is created 
 > automatically
@@ -102,7 +93,7 @@ Enter DB type (press Enter to default to postgres): postgres
 Available audit stores: opensearch, solr, none
 Enter audit store (press Enter to default to opensearch): opensearch
 
-Available test suites: rolerest xuserrest servicerest tagrest hdfs kms api hive
+Available test suites: rolerest xuserrest servicerest tagrest hdfs kms api 
hive ...
 Enter test suites space-separated (press Enter to run ALL): hdfs kms
 
 Available containers : hadoop hive hbase knox trino ozone kafka
@@ -222,32 +213,24 @@ Brought up based on what you enter at the containers 
prompt (or `SELECTED_CONTAI
 
 ---
 
-### Hive suite notes
-
-- Service repo name in Docker is `dev_hive` (not QE `cm_hive`).
-- Tests currently assert **beeline authorization output only**. Hive access 
audits helpers live in `ranger_test_utils/access_audit_utils.py` for a 
follow-up once auditing works.
-- Example: `./run-tests.sh postgres hive`
-
-### HBase suite notes
+### Note on hive, hbase, kafka suites
+- Each suite uses its own Docker service repo: `dev_hive`, `dev_hbase`, 
`dev_kafka`.
+- Tests assert on client output only (beeline, HBase shell, Kafka console 
producer). Access-audit checks are deferred; helpers are in 
`ranger_test_utils/access_audit_utils.py`.
+- `hive` and `hbase` start `ranger-hadoop` automatically. `kafka` starts 
`ranger-kafka`.
+- Example: `SELECTED_CONTAINERS="hive hbase kafka" ./run-tests.sh postgres 
hive hbase kafka`
 
-- Service repo name in Docker is `dev_hbase` (not QE `hbasedev`).
-- Tests currently assert **HBase shell authorization output only**. 
Access-audit helpers live in `ranger_test_utils/access_audit_utils.py` for a 
follow-up once auditing works.
-- Example: `./run-tests.sh postgres hbase`
 
-### HDFS suite notes (encryption + `hdfs_policy`)
+### HDFS suite notes
+- Service repo is `dev_hdfs`.
+- `./run-tests.sh postgres hdfs` does not start `ranger-hadoop`. Export 
`SELECTED_CONTAINERS=hadoop` (or `all`) first.
+- The whole `hdfs/` folder runs. For plugin tests only: `pytest 
hdfs/test_hdfs_group_policy_03.py -m hdfs_policy` (still needs 
`ranger-hadoop`and admin running).
 
-- Service repo for plugin tests is `dev_hdfs` (seeded by ranger-docker).
-- **`./run-tests.sh postgres hdfs` does not start `ranger-hadoop` by itself.** 
Export `SELECTED_CONTAINERS=hadoop` or `SELECTED_CONTAINERS=all` before running 
(or choose `hadoop` / `all` at the containers prompt).
-- `./run-tests.sh` runs the whole `hdfs/` folder (no marker filter). Use `-m 
hdfs_policy` only for selective local runs.
 - Example:
   ```text
   export AUDIT_INDEX_STORE=none
   export SELECTED_CONTAINERS=hadoop
   ./run-tests.sh postgres hdfs
   ```
-- Plugin tests only (skips encryption/KMS session setup in `hdfs/conftest.py`):
-  `pytest hdfs/test_hdfs_group_policy_03.py -m hdfs_policy`
-  Still requires `ranger-hadoop` (and Ranger Admin) running.
 
 ## Test Reports
 
diff --git a/functional-tests/run-tests.sh b/functional-tests/run-tests.sh
index e2d797a6f..5048f410e 100755
--- a/functional-tests/run-tests.sh
+++ b/functional-tests/run-tests.sh
@@ -17,7 +17,7 @@
 
 # All available test suites (pytest folders)
 
-ALL_TEST_SUITES=(rolerest xuserrest servicerest tagrest hdfs kms api api_tests 
hive hbase)
+ALL_TEST_SUITES=(rolerest xuserrest servicerest tagrest hdfs kms api api_tests 
hive hbase kafka)
 
 # Test-only suites (no docker-compose file needed)
 TEST_ONLY_SUITES=(rolerest xuserrest servicerest tagrest api api_tests)

Reply via email to