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

lordgamez pushed a commit to branch MINIFICPP-2684
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git

commit 31b7dccc508d4baae591354af7c83749a981d4f9
Author: Gabor Gyimesi <[email protected]>
AuthorDate: Thu Nov 27 11:35:25 2025 +0100

    MINIFICPP-2684 Move MiNiFi controller tests to modular docker tests
---
 .../containers/minifi_container.py                 |  90 +++++++++++++++-
 .../resources/minifi-controller/config.yml         |   0
 docker/test/integration/cluster/ContainerStore.py  |   3 -
 .../test/integration/cluster/DockerTestCluster.py  |  84 +--------------
 .../cluster/MinifiControllerExecutor.py            |  78 --------------
 .../cluster/containers/MinifiContainer.py          |   7 --
 .../features/MiNiFi_integration_test_driver.py     |  36 -------
 docker/test/integration/features/steps/steps.py    | 116 ---------------------
 .../tests}/features/minifi_controller.feature      |   5 +-
 .../features/steps/minifi_controller_steps.py      |  91 ++++++++++++++++
 .../tests/features/steps/steps.py                  |   8 +-
 11 files changed, 186 insertions(+), 332 deletions(-)

diff --git 
a/behave_framework/src/minifi_test_framework/containers/minifi_container.py 
b/behave_framework/src/minifi_test_framework/containers/minifi_container.py
index 8db562e04..6787ccaa5 100644
--- a/behave_framework/src/minifi_test_framework/containers/minifi_container.py
+++ b/behave_framework/src/minifi_test_framework/containers/minifi_container.py
@@ -16,12 +16,16 @@
 #
 
 import logging
+import os
+from pathlib import Path
 from OpenSSL import crypto
 
 from minifi_test_framework.core.minifi_test_context import MinifiTestContext
 from minifi_test_framework.containers.file import File
+from minifi_test_framework.containers.host_file import HostFile
 from minifi_test_framework.minifi.minifi_flow_definition import 
MinifiFlowDefinition
 from minifi_test_framework.core.ssl_utils import 
make_cert_without_extended_usage, make_client_cert, make_server_cert
+from minifi_test_framework.core.helpers import wait_for_condition, retry_check
 from .container import Container
 
 
@@ -48,6 +52,10 @@ class MinifiContainer(Container):
                                
crypto.dump_certificate(type=crypto.FILETYPE_PEM, cert=minifi_server_cert) + 
crypto.dump_privatekey(type=crypto.FILETYPE_PEM, pkey=minifi_server_key)))
 
         self.is_fhs = 'MINIFI_INSTALLATION_TYPE=FHS' in 
str(self.client.images.get(test_context.minifi_container_image).history())
+        if self.is_fhs:
+            self.minifi_controller_path = '/usr/bin/minifi-controller'
+        else:
+            self.minifi_controller_path = 
'/opt/minifi/minifi-current/bin/minifi-controller'
 
         self._fill_default_properties()
         self._fill_default_log_properties()
@@ -67,7 +75,16 @@ class MinifiContainer(Container):
             
self.files.append(File("/opt/minifi/minifi-current/conf/minifi-log.properties",
                                    self._get_log_properties_file_content()))
 
-        return super().deploy()
+        resource_dir = Path(__file__).resolve().parent / "resources" / 
"minifi-controller"
+        
self.host_files.append(HostFile("/tmp/resources/minifi-controller/config.yml", 
os.path.join(resource_dir, "config.yml")))
+
+        super().deploy()
+        finished_str = "MiNiFi started"
+        return wait_for_condition(
+            condition=lambda: finished_str in self.get_logs(),
+            timeout_seconds=15,
+            bail_condition=lambda: self.exited,
+            context=None)
 
     def set_property(self, key: str, value: str):
         self.properties[key] = value
@@ -112,3 +129,74 @@ class MinifiContainer(Container):
         memory_usage_in_bytes = int(output.strip()) * 1024
         logging.info(f"MiNiFi memory usage: {memory_usage_in_bytes} bytes")
         return memory_usage_in_bytes
+
+    def set_controller_socket_properties(self):
+        self.properties["controller.socket.enable"] = "true"
+        self.properties["controller.socket.host"] = "localhost"
+        self.properties["controller.socket.port"] = "9998"
+        self.properties["controller.socket.local.any.interface"] = "false"
+
+    def update_flow_config_through_controller(self):
+        self.exec_run([self.minifi_controller_path, "--updateflow", 
"/tmp/resources/minifi-controller/config.yml"])
+
+    def updated_config_is_persisted(self) -> bool:
+        exit_code, output = self.exec_run(["cat", 
"/opt/minifi/minifi-current/conf/config.yml" if not self.is_fhs else 
"/etc/nifi-minifi-cpp/config.yml"])
+        if exit_code != 0:
+            logging.error("Failed to read MiNiFi config file to check if 
updated config is persisted")
+            return False
+        return "2f2a3b47-f5ba-49f6-82b5-bc1c86b96f38" in output
+
+    def stop_component_through_controller(self, component: str):
+        self.exec_run([self.minifi_controller_path, "--stop", component])
+
+    def start_component_through_controller(self, component: str):
+        self.exec_run([self.minifi_controller_path, "--start", component])
+
+    @retry_check(10, 1)
+    def is_component_running(self, component: str) -> bool:
+        (code, output) = self.exec_run([self.minifi_controller_path, "--list", 
"components"])
+        return code == 0 and component + ", running: true" in output
+
+    def get_connections(self):
+        (_, output) = self.exec_run([self.minifi_controller_path, "--list", 
"connections"])
+        connections = []
+        for line in output.split('\n'):
+            if not line.startswith('[') and not line.startswith('Connection 
Names'):
+                connections.append(line)
+        return connections
+
+    @retry_check(10, 1)
+    def connection_found_through_controller(self, connection: str) -> bool:
+        return connection in self.get_connections()
+
+    def get_full_connection_count(self) -> int:
+        (_, output) = self.exec_run([self.minifi_controller_path, "--getfull"])
+        for line in output.split('\n'):
+            if "are full" in line:
+                return int(line.split(' ')[0])
+        return -1
+
+    def get_connection_size(self, connection: str):
+        (_, output) = self.exec_run([self.minifi_controller_path, "--getsize", 
connection])
+        for line in output.split('\n'):
+            if "Size/Max of " + connection in line:
+                size_and_max = line.split(connection)[1].split('/')
+                return (int(size_and_max[0].strip()), 
int(size_and_max[1].strip()))
+        return (-1, -1)
+
+    def get_manifest(self) -> str:
+        (_, output) = self.exec_run([self.minifi_controller_path, 
"--manifest"])
+        manifest = ""
+        for line in output.split('\n'):
+            if not line.startswith('['):
+                manifest += line
+        return manifest
+
+    def create_debug_bundle(self) -> bool:
+        (code, _) = self.exec_run([self.minifi_controller_path, "--debug", 
"/tmp"])
+        if code != 0:
+            logging.error("Minifi controller debug command failed with code: 
%d", code)
+            return False
+
+        (code, _) = self.exec_run(["test", "-f", "/tmp/debug.tar.gz"])
+        return code == 0
diff --git a/docker/test/integration/resources/minifi-controller/config.yml 
b/behave_framework/src/minifi_test_framework/containers/resources/minifi-controller/config.yml
similarity index 100%
rename from docker/test/integration/resources/minifi-controller/config.yml
rename to 
behave_framework/src/minifi_test_framework/containers/resources/minifi-controller/config.yml
diff --git a/docker/test/integration/cluster/ContainerStore.py 
b/docker/test/integration/cluster/ContainerStore.py
index 6d87739bb..084bbc45d 100644
--- a/docker/test/integration/cluster/ContainerStore.py
+++ b/docker/test/integration/cluster/ContainerStore.py
@@ -273,9 +273,6 @@ class ContainerStore:
     def set_json_in_minifi(self):
         self.minifi_options.config_format = "json"
 
-    def set_controller_socket_properties_in_minifi(self):
-        self.minifi_options.enable_controller_socket = True
-
     def enable_log_metrics_publisher_in_minifi(self):
         self.minifi_options.enable_log_metrics_publisher = True
 
diff --git a/docker/test/integration/cluster/DockerTestCluster.py 
b/docker/test/integration/cluster/DockerTestCluster.py
index 93801e83e..458e0bd88 100644
--- a/docker/test/integration/cluster/DockerTestCluster.py
+++ b/docker/test/integration/cluster/DockerTestCluster.py
@@ -15,22 +15,16 @@
 import logging
 import time
 import re
-import tarfile
-import tempfile
-import os
-import gzip
-import shutil
 
 from .LogSource import LogSource
 from .ContainerStore import ContainerStore
 from .DockerCommunicator import DockerCommunicator
-from .MinifiControllerExecutor import MinifiControllerExecutor
 from .checkers.AzureChecker import AzureChecker
 from .checkers.PostgresChecker import PostgresChecker
 from .checkers.PrometheusChecker import PrometheusChecker
 from .checkers.ModbusChecker import ModbusChecker
 from .checkers.MqttHelper import MqttHelper
-from utils import get_peak_memory_usage, get_minifi_pid, get_memory_usage, 
retry_check
+from utils import get_peak_memory_usage, get_minifi_pid, get_memory_usage
 
 
 class DockerTestCluster:
@@ -42,7 +36,6 @@ class DockerTestCluster:
         self.azure_checker = AzureChecker(self.container_communicator)
         self.postgres_checker = PostgresChecker(self.container_communicator)
         self.prometheus_checker = PrometheusChecker()
-        self.minifi_controller_executor = 
MinifiControllerExecutor(self.container_communicator)
         self.modbus_checker = ModbusChecker(self.container_communicator)
         self.mqtt_helper = MqttHelper()
 
@@ -124,9 +117,6 @@ class DockerTestCluster:
     def set_json_in_minifi(self):
         self.container_store.set_json_in_minifi()
 
-    def set_controller_socket_properties_in_minifi(self):
-        self.container_store.set_controller_socket_properties_in_minifi()
-
     def enable_log_metrics_publisher_in_minifi(self):
         self.container_store.enable_log_metrics_publisher_in_minifi()
 
@@ -283,78 +273,6 @@ class DockerTestCluster:
         logging.warning(f"Memory usage ({current_memory_usage}) is more than 
the maximum asserted memory usage ({max_memory_usage})")
         return False
 
-    def update_flow_config_through_controller(self, container_name: str):
-        self.minifi_controller_executor.update_flow(container_name)
-
-    @retry_check(10, 1)
-    def check_minifi_controller_updated_config_is_persisted(self, 
container_name: str) -> bool:
-        return 
self.minifi_controller_executor.updated_config_is_persisted(container_name)
-
-    def stop_component_through_controller(self, component: str, 
container_name: str):
-        self.minifi_controller_executor.stop_component(component, 
container_name)
-
-    def start_component_through_controller(self, component: str, 
container_name: str):
-        self.minifi_controller_executor.start_component(component, 
container_name)
-
-    @retry_check(10, 1)
-    def check_component_not_running_through_controller(self, component: str, 
container_name: str) -> bool:
-        return not 
self.minifi_controller_executor.is_component_running(component, container_name)
-
-    @retry_check(10, 1)
-    def check_component_running_through_controller(self, component: str, 
container_name: str) -> bool:
-        return self.minifi_controller_executor.is_component_running(component, 
container_name)
-
-    @retry_check(10, 1)
-    def connection_found_through_controller(self, connection: str, 
container_name: str) -> bool:
-        return connection in 
self.minifi_controller_executor.get_connections(container_name)
-
-    @retry_check(10, 1)
-    def check_connections_full_through_controller(self, connection_count: int, 
container_name: str) -> bool:
-        return 
self.minifi_controller_executor.get_full_connection_count(container_name) == 
connection_count
-
-    @retry_check(10, 1)
-    def check_connection_size_through_controller(self, connection: str, size: 
int, max_size: int, container_name: str) -> bool:
-        return self.minifi_controller_executor.get_connection_size(connection, 
container_name) == (size, max_size)
-
-    @retry_check(10, 1)
-    def manifest_can_be_retrieved_through_minifi_controller(self, 
container_name: str) -> bool:
-        manifest = self.minifi_controller_executor.get_manifest(container_name)
-        return '"agentManifest": {' in manifest and '"componentManifest": {' 
in manifest and '"agentType": "cpp"' in manifest
-
-    @retry_check(10, 1)
-    def debug_bundle_can_be_retrieved_through_minifi_controller(self, 
container_name: str) -> bool:
-        with tempfile.TemporaryDirectory() as td:
-            result = 
self.minifi_controller_executor.get_debug_bundle(container_name, td)
-            if not result:
-                logging.error("Failed to get debug bundle")
-                return False
-
-            with tarfile.open(os.path.join(td, "debug.tar.gz")) as file:
-                file.extractall(td)
-
-            if not os.path.exists(os.path.join(td, "config.yml")):
-                logging.error("config.yml file was not found in debug bundle")
-                return False
-
-            if not os.path.exists(os.path.join(td, "minifi.properties")):
-                logging.error("minifi.properties file was not found in debug 
bundle")
-                return False
-
-            if not os.path.exists(os.path.join(td, "minifi.log.gz")):
-                logging.error("minifi.log.gz file was not found in debug 
bundle")
-                return False
-
-            with gzip.open(os.path.join(td, "minifi.log.gz"), 'rb') as f_in:
-                with open(os.path.join(td, "minifi.log"), 'wb') as f_out:
-                    shutil.copyfileobj(f_in, f_out)
-
-            with open(os.path.join(td, "minifi.log")) as f:
-                if 'MiNiFi started' not in f.read():
-                    logging.error("'MiNiFi started' log entry was not found in 
minifi.log file")
-                    return False
-
-            return True
-
     def set_value_on_plc_with_modbus(self, container_name, modbus_cmd):
         return 
self.modbus_checker.set_value_on_plc_with_modbus(container_name, modbus_cmd)
 
diff --git a/docker/test/integration/cluster/MinifiControllerExecutor.py 
b/docker/test/integration/cluster/MinifiControllerExecutor.py
deleted file mode 100644
index 880e43e74..000000000
--- a/docker/test/integration/cluster/MinifiControllerExecutor.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# 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.
-import logging
-from .DockerCommunicator import DockerCommunicator
-from .containers.MinifiContainer import MinifiContainer
-
-
-class MinifiControllerExecutor:
-    def __init__(self, container_communicator: DockerCommunicator):
-        self.container_communicator = container_communicator
-
-    def update_flow(self, container_name: str):
-        self.container_communicator.execute_command(container_name, 
[MinifiContainer.MINIFI_LOCATIONS.minifi_controller_path, "--updateflow", 
"/tmp/resources/minifi-controller/config.yml"])
-
-    def updated_config_is_persisted(self, container_name: str) -> bool:
-        (code, output) = 
self.container_communicator.execute_command(container_name, ["cat", 
MinifiContainer.MINIFI_LOCATIONS.config_path])
-        return code == 0 and "2f2a3b47-f5ba-49f6-82b5-bc1c86b96f38" in output
-
-    def stop_component(self, component: str, container_name: str):
-        self.container_communicator.execute_command(container_name, 
[MinifiContainer.MINIFI_LOCATIONS.minifi_controller_path, "--stop", component])
-
-    def start_component(self, component: str, container_name: str):
-        self.container_communicator.execute_command(container_name, 
[MinifiContainer.MINIFI_LOCATIONS.minifi_controller_path, "--start", component])
-
-    def is_component_running(self, component: str, container_name: str) -> 
bool:
-        (code, output) = 
self.container_communicator.execute_command(container_name, 
[MinifiContainer.MINIFI_LOCATIONS.minifi_controller_path, "--list", 
"components"])
-        return code == 0 and component + ", running: true" in output
-
-    def get_connections(self, container_name: str):
-        (_, output) = 
self.container_communicator.execute_command(container_name, 
[MinifiContainer.MINIFI_LOCATIONS.minifi_controller_path, "--list", 
"connections"])
-        connections = []
-        for line in output.split('\n'):
-            if not line.startswith('[') and not line.startswith('Connection 
Names'):
-                connections.append(line)
-        return connections
-
-    def get_full_connection_count(self, container_name: str) -> int:
-        (_, output) = 
self.container_communicator.execute_command(container_name, 
[MinifiContainer.MINIFI_LOCATIONS.minifi_controller_path, "--getfull"])
-        for line in output.split('\n'):
-            if "are full" in line:
-                return int(line.split(' ')[0])
-        return -1
-
-    def get_connection_size(self, connection: str, container_name: str):
-        (_, output) = 
self.container_communicator.execute_command(container_name, 
[MinifiContainer.MINIFI_LOCATIONS.minifi_controller_path, "--getsize", 
connection])
-        for line in output.split('\n'):
-            if "Size/Max of " + connection in line:
-                size_and_max = line.split(connection)[1].split('/')
-                return (int(size_and_max[0].strip()), 
int(size_and_max[1].strip()))
-        return (-1, -1)
-
-    def get_manifest(self, container_name: str) -> str:
-        (_, output) = 
self.container_communicator.execute_command(container_name, 
[MinifiContainer.MINIFI_LOCATIONS.minifi_controller_path, "--manifest"])
-        manifest = ""
-        for line in output.split('\n'):
-            if not line.startswith('['):
-                manifest += line
-        return manifest
-
-    def get_debug_bundle(self, container_name: str, dest: str) -> bool:
-        (code, _) = 
self.container_communicator.execute_command(container_name, 
[MinifiContainer.MINIFI_LOCATIONS.minifi_controller_path, "--debug", "/tmp"])
-        if code != 0:
-            logging.error("Minifi controller debug command failed with code: 
%d", code)
-            return False
-
-        return 
self.container_communicator.copy_file_from_container(container_name, 
"/tmp/debug.tar.gz", dest)
diff --git a/docker/test/integration/cluster/containers/MinifiContainer.py 
b/docker/test/integration/cluster/containers/MinifiContainer.py
index 387a3bd0d..f5185d1be 100644
--- a/docker/test/integration/cluster/containers/MinifiContainer.py
+++ b/docker/test/integration/cluster/containers/MinifiContainer.py
@@ -41,7 +41,6 @@ class MinifiOptions:
         self.config_format = "json"
         self.use_flow_config_from_url = False
         self.set_ssl_context_properties = False
-        self.enable_controller_socket = False
         self.enable_log_metrics_publisher = False
         self.enable_example_minifi_python_processors = False
         if "true" in os.environ['MINIFI_FIPS']:
@@ -186,12 +185,6 @@ class MinifiContainer(FlowContainer):
             if self.options.use_flow_config_from_url:
                 
f.write(f"nifi.c2.flow.url=http://minifi-c2-server-{self.feature_context.id}:10090/c2/config?class=minifi-test-class\n";)
 
-            if self.options.enable_controller_socket:
-                f.write("controller.socket.enable=true\n")
-                f.write("controller.socket.host=localhost\n")
-                f.write("controller.socket.port=9998\n")
-                f.write("controller.socket.local.any.interface=false\n")
-
             if self.options.use_nifi_python_processors_with_virtualenv or 
self.options.remove_python_requirements_txt or 
self.options.use_nifi_python_processors_without_dependencies:
                 
f.write("nifi.python.virtualenv.directory={minifi_python_venv_parent}/venv\n".format(minifi_python_venv_parent=MinifiContainer.MINIFI_LOCATIONS.minifi_python_venv_parent))
             elif 
self.options.use_nifi_python_processors_with_virtualenv_packages_installed:
diff --git a/docker/test/integration/features/MiNiFi_integration_test_driver.py 
b/docker/test/integration/features/MiNiFi_integration_test_driver.py
index d3dd8dd5c..73941ecda 100644
--- a/docker/test/integration/features/MiNiFi_integration_test_driver.py
+++ b/docker/test/integration/features/MiNiFi_integration_test_driver.py
@@ -374,42 +374,9 @@ class MiNiFi_integration_test:
     def set_json_in_minifi(self):
         self.cluster.set_json_in_minifi()
 
-    def set_controller_socket_properties_in_minifi(self):
-        self.cluster.set_controller_socket_properties_in_minifi()
-
     def llama_model_is_downloaded_in_minifi(self):
         self.cluster.llama_model_is_downloaded_in_minifi()
 
-    def update_flow_config_through_controller(self, container_name: str):
-        self.cluster.update_flow_config_through_controller(container_name)
-
-    def check_minifi_controller_updated_config_is_persisted(self, 
container_name: str):
-        assert 
self.cluster.check_minifi_controller_updated_config_is_persisted(container_name)
 or self.cluster.log_app_output()
-
-    def stop_component_through_controller(self, component: str, 
container_name: str):
-        self.cluster.stop_component_through_controller(component, 
container_name)
-
-    def start_component_through_controller(self, component: str, 
container_name: str):
-        self.cluster.start_component_through_controller(component, 
container_name)
-
-    def check_component_not_running_through_controller(self, component: str, 
container_name: str):
-        assert 
self.cluster.check_component_not_running_through_controller(component, 
container_name) or self.cluster.log_app_output()
-
-    def check_component_running_through_controller(self, component: str, 
container_name: str):
-        assert 
self.cluster.check_component_running_through_controller(component, 
container_name) or self.cluster.log_app_output()
-
-    def connection_found_through_controller(self, connection: str, 
container_name: str):
-        assert self.cluster.connection_found_through_controller(connection, 
container_name) or self.cluster.log_app_output()
-
-    def check_connections_full_through_controller(self, connection_count: int, 
container_name: str):
-        assert 
self.cluster.check_connections_full_through_controller(connection_count, 
container_name) or self.cluster.log_app_output()
-
-    def check_connection_size_through_controller(self, connection: str, size: 
int, max_size: int, container_name: str):
-        assert 
self.cluster.check_connection_size_through_controller(connection, size, 
max_size, container_name) or self.cluster.log_app_output()
-
-    def manifest_can_be_retrieved_through_minifi_controller(self, 
container_name: str):
-        assert 
self.cluster.manifest_can_be_retrieved_through_minifi_controller(container_name)
 or self.cluster.log_app_output()
-
     def enable_log_metrics_publisher_in_minifi(self):
         self.cluster.enable_log_metrics_publisher_in_minifi()
 
@@ -422,9 +389,6 @@ class MiNiFi_integration_test:
     def disable_openssl_fips_mode_in_minifi(self):
         self.cluster.disable_openssl_fips_mode_in_minifi()
 
-    def debug_bundle_can_be_retrieved_through_minifi_controller(self, 
container_name: str):
-        assert 
self.cluster.debug_bundle_can_be_retrieved_through_minifi_controller(container_name)
 or self.cluster.log_app_output()
-
     def set_value_on_plc_with_modbus(self, container_name, modbus_cmd):
         assert self.cluster.set_value_on_plc_with_modbus(container_name, 
modbus_cmd)
 
diff --git a/docker/test/integration/features/steps/steps.py 
b/docker/test/integration/features/steps/steps.py
index 9757441dd..606d5d76d 100644
--- a/docker/test/integration/features/steps/steps.py
+++ b/docker/test/integration/features/steps/steps.py
@@ -896,122 +896,6 @@ def step_impl(context):
     context.test.set_json_in_minifi()
 
 
-# MiNiFi controller
-@given(u'controller socket properties are set up')
-def step_impl(context):
-    context.test.set_controller_socket_properties_in_minifi()
-
-
-@when(u'MiNiFi config is updated through MiNiFi controller in the 
\"{minifi_container_name}\" flow')
-def step_impl(context, minifi_container_name: str):
-    context.test.update_flow_config_through_controller(minifi_container_name)
-
-
-@when(u'MiNiFi config is updated through MiNiFi controller')
-def step_impl(context):
-    context.execute_steps(f"when MiNiFi config is updated through MiNiFi 
controller in the \"minifi-cpp-flow-{context.feature_id}\" flow")
-
-
-@then(u'the updated config is persisted in the \"{minifi_container_name}\" 
flow')
-def step_impl(context, minifi_container_name: str):
-    
context.test.check_minifi_controller_updated_config_is_persisted(minifi_container_name)
-
-
-@then(u'the updated config is persisted')
-def step_impl(context):
-    context.execute_steps(f"then the updated config is persisted in the 
\"minifi-cpp-flow-{context.feature_id}\" flow")
-
-
-@when(u'the {component} component is stopped through MiNiFi controller in the 
\"{minifi_container_name}\" flow')
-def step_impl(context, minifi_container_name: str, component: str):
-    context.test.stop_component_through_controller(component, 
minifi_container_name)
-
-
-@when(u'the {component} component is stopped through MiNiFi controller')
-def step_impl(context, component: str):
-    context.execute_steps(f"when the {component} component is stopped through 
MiNiFi controller in the \"minifi-cpp-flow-{context.feature_id}\" flow")
-
-
-@when(u'the {component} component is started through MiNiFi controller in the 
\"{minifi_container_name}\" flow')
-def step_impl(context, minifi_container_name: str, component: str):
-    context.test.start_component_through_controller(component, 
minifi_container_name)
-
-
-@when(u'the {component} component is started through MiNiFi controller')
-def step_impl(context, component: str):
-    context.execute_steps(f"when the {component} component is started through 
MiNiFi controller in the \"minifi-cpp-flow-{context.feature_id}\" flow")
-
-
-@then(u'the {component} component is not running in the 
\"{minifi_container_name}\" flow')
-def step_impl(context, component: str, minifi_container_name: str):
-    context.test.check_component_not_running_through_controller(component, 
minifi_container_name)
-
-
-@then(u'the {component} component is not running')
-def step_impl(context, component: str):
-    context.execute_steps(f"then the {component} component is not running in 
the \"minifi-cpp-flow-{context.feature_id}\" flow")
-
-
-@then(u'the {component} component is running in the 
\"{minifi_container_name}\" flow')
-def step_impl(context, component: str, minifi_container_name: str):
-    context.test.check_component_running_through_controller(component, 
minifi_container_name)
-
-
-@then(u'the {component} component is running')
-def step_impl(context, component: str):
-    context.execute_steps(f"then the {component} component is running in the 
\"minifi-cpp-flow-{context.feature_id}\" flow")
-
-
-@then(u'connection \"{connection}\" can be seen through MiNiFi controller in 
the \"{minifi_container_name}\" flow')
-def step_impl(context, connection: str, minifi_container_name: str):
-    context.test.connection_found_through_controller(connection, 
minifi_container_name)
-
-
-@then(u'connection \"{connection}\" can be seen through MiNiFi controller')
-def step_impl(context, connection: str):
-    context.execute_steps(f"then connection \"{connection}\" can be seen 
through MiNiFi controller in the \"minifi-cpp-flow-{context.feature_id}\" flow")
-
-
-@then(u'{connection_count:d} connections can be seen full through MiNiFi 
controller in the \"{minifi_container_name}\" flow')
-def step_impl(context, connection_count: int, minifi_container_name: str):
-    context.test.check_connections_full_through_controller(connection_count, 
minifi_container_name)
-
-
-@then(u'{connection_count:d} connections can be seen full through MiNiFi 
controller')
-def step_impl(context, connection_count: int):
-    context.execute_steps(f"then {connection_count:d} connections can be seen 
full through MiNiFi controller in the \"minifi-cpp-flow-{context.feature_id}\" 
flow")
-
-
-@then(u'connection \"{connection}\" has {size:d} size and {max_size:d} max 
size through MiNiFi controller in the \"{minifi_container_name}\" flow')
-def step_impl(context, connection: str, size: int, max_size: int, 
minifi_container_name: str):
-    context.test.check_connection_size_through_controller(connection, size, 
max_size, minifi_container_name)
-
-
-@then(u'connection \"{connection}\" has {size:d} size and {max_size:d} max 
size through MiNiFi controller')
-def step_impl(context, connection: str, size: int, max_size: int):
-    context.execute_steps(f"then connection \"{connection}\" has {size:d} size 
and {max_size:d} max size through MiNiFi controller in the 
\"minifi-cpp-flow-{context.feature_id}\" flow")
-
-
-@then(u'manifest can be retrieved through MiNiFi controller in the 
\"{minifi_container_name}\" flow')
-def step_impl(context, minifi_container_name: str):
-    
context.test.manifest_can_be_retrieved_through_minifi_controller(minifi_container_name)
-
-
-@then(u'manifest can be retrieved through MiNiFi controller')
-def step_impl(context):
-    context.execute_steps(f"then manifest can be retrieved through MiNiFi 
controller in the \"minifi-cpp-flow-{context.feature_id}\" flow")
-
-
-@then(u'debug bundle can be retrieved through MiNiFi controller in the 
\"{minifi_container_name}\" flow')
-def step_impl(context, minifi_container_name: str):
-    
context.test.debug_bundle_can_be_retrieved_through_minifi_controller(minifi_container_name)
-
-
-@then(u'debug bundle can be retrieved through MiNiFi controller')
-def step_impl(context):
-    context.execute_steps(f"then debug bundle can be retrieved through MiNiFi 
controller in the \"minifi-cpp-flow-{context.feature_id}\" flow")
-
-
 @given(u'a SSL context service is set up for the following processor: 
\"{processor_name}\"')
 def step_impl(context, processor_name: str):
     setUpSslContextServiceForProcessor(context, processor_name)
diff --git a/docker/test/integration/features/minifi_controller.feature 
b/extensions/standard-processors/tests/features/minifi_controller.feature
similarity index 95%
rename from docker/test/integration/features/minifi_controller.feature
rename to 
extensions/standard-processors/tests/features/minifi_controller.feature
index c78f91ca4..0995c8f95 100644
--- a/docker/test/integration/features/minifi_controller.feature
+++ b/extensions/standard-processors/tests/features/minifi_controller.feature
@@ -17,16 +17,13 @@
 Feature: MiNiFi Controller functionalities
   Test MiNiFi Controller functionalities
 
-  Background:
-    Given the content of "/tmp/output" is monitored
-
   Scenario: Flow config can be updated through MiNiFi controller
     Given a GenerateFlowFile processor
     And a file with the content "test" is present in "/tmp/input"
     And controller socket properties are set up
     When all instances start up
     And MiNiFi config is updated through MiNiFi controller
-    Then a flowfile with the content "test" is placed in the monitored 
directory in less than 60 seconds
+    Then there is a single file with "test" content in the "/tmp/output" 
directory in less than 60 seconds
     And the updated config is persisted
 
   Scenario: A component can be stopped
diff --git 
a/extensions/standard-processors/tests/features/steps/minifi_controller_steps.py
 
b/extensions/standard-processors/tests/features/steps/minifi_controller_steps.py
new file mode 100644
index 000000000..8cefd0762
--- /dev/null
+++ 
b/extensions/standard-processors/tests/features/steps/minifi_controller_steps.py
@@ -0,0 +1,91 @@
+#
+#  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.
+#
+
+from behave import given, when, then
+from minifi_test_framework.core.helpers import retry_check
+from minifi_test_framework.core.minifi_test_context import MinifiTestContext
+
+
+@given(u'controller socket properties are set up')
+def step_impl(context: MinifiTestContext):
+    
context.get_or_create_default_minifi_container().set_controller_socket_properties()
+
+
+@when(u'MiNiFi config is updated through MiNiFi controller')
+def step_impl(context: MinifiTestContext):
+    
context.get_or_create_default_minifi_container().update_flow_config_through_controller()
+
+
+@then(u'the updated config is persisted')
+def step_impl(context: MinifiTestContext):
+    assert 
context.get_or_create_default_minifi_container().updated_config_is_persisted()
+
+
+@when(u'the {component} component is stopped through MiNiFi controller')
+def step_impl(context: MinifiTestContext, component: str):
+    
context.get_or_create_default_minifi_container().stop_component_through_controller(component)
+
+
+@when(u'the {component} component is started through MiNiFi controller')
+def step_impl(context: MinifiTestContext, component: str):
+    
context.get_or_create_default_minifi_container().start_component_through_controller(component)
+
+
+@then(u'the {component} component is not running')
+def step_impl(context: MinifiTestContext, component: str):
+    assert not 
context.get_or_create_default_minifi_container().is_component_running(component)
+
+
+@then(u'the {component} component is running')
+def step_impl(context: MinifiTestContext, component: str):
+    assert 
context.get_or_create_default_minifi_container().is_component_running(component)
+
+
+@then(u'connection \"{connection}\" can be seen through MiNiFi controller')
+def step_impl(context: MinifiTestContext, connection: str):
+    assert 
context.get_or_create_default_minifi_container().connection_found_through_controller(connection)
+
+
+@then(u'{connection_count:d} connections can be seen full through MiNiFi 
controller')
+def step_impl(context: MinifiTestContext, connection_count: int):
+    assert 
context.get_or_create_default_minifi_container().get_full_connection_count() == 
connection_count
+
+
+@retry_check(10, 1)
+def check_connection_size_through_controller(context: MinifiTestContext, 
connection: str, size: int, max_size: int) -> bool:
+    return 
context.get_or_create_default_minifi_container().get_connection_size(connection)
 == (size, max_size)
+
+
+@then(u'connection \"{connection}\" has {size:d} size and {max_size:d} max 
size through MiNiFi controller')
+def step_impl(context: MinifiTestContext, connection: str, size: int, 
max_size: int):
+    assert check_connection_size_through_controller(context, connection, size, 
max_size)
+
+
+@retry_check(10, 1)
+def manifest_can_be_retrieved_through_minifi_controller(context: 
MinifiTestContext) -> bool:
+    manifest = context.get_or_create_default_minifi_container().get_manifest()
+    return '"agentManifest": {' in manifest and '"componentManifest": {' in 
manifest and '"agentType": "cpp"' in manifest
+
+
+@then(u'manifest can be retrieved through MiNiFi controller')
+def step_impl(context: MinifiTestContext):
+    assert manifest_can_be_retrieved_through_minifi_controller(context)
+
+
+@then(u'debug bundle can be retrieved through MiNiFi controller')
+def step_impl(context: MinifiTestContext):
+    assert 
context.get_or_create_default_minifi_container().create_debug_bundle()
diff --git a/extensions/standard-processors/tests/features/steps/steps.py 
b/extensions/standard-processors/tests/features/steps/steps.py
index 779c8b075..f35234ffa 100644
--- a/extensions/standard-processors/tests/features/steps/steps.py
+++ b/extensions/standard-processors/tests/features/steps/steps.py
@@ -33,21 +33,21 @@ def step_impl(context: MinifiTestContext):
 
 
 @step("a Syslog client with UDP protocol is setup to send logs to minifi")
-def step_impl(context):
+def step_impl(context: MinifiTestContext):
     context.containers["syslog-udp"] = SyslogContainer("udp", context)
 
 
 @step(u'there is an accessible PLC with modbus enabled')
-def step_impl(context):
+def step_impl(context: MinifiTestContext):
     modbus_container = context.containers["diag-slave-tcp"] = 
DiagSlave(context)
     assert modbus_container.deploy()
 
 
 @step(u'PLC register has been set with {modbus_cmd} command')
-def step_impl(context, modbus_cmd):
+def step_impl(context: MinifiTestContext, modbus_cmd: str):
     assert 
context.containers["diag-slave-tcp"].set_value_on_plc_with_modbus(modbus_cmd) 
or context.containers["diag-slave-tcp"].log_app_output()
 
 
 @step('a TCP client is set up to send a test TCP message to minifi')
-def step_impl(context):
+def step_impl(context: MinifiTestContext):
     context.containers["tcp-client"] = TcpClientContainer(context)


Reply via email to