Skip to content

Commit 667d6bd

Browse files
committed
MINIFICPP-2668 Move standard processor tests to modular docker tests
1 parent 985912c commit 667d6bd

27 files changed

+297
-319
lines changed

behave_framework/src/minifi_test_framework/containers/container.py

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,16 @@ def not_empty_dir_exists(self, directory_path: str) -> bool:
137137
"sh -c {}".format(shlex.quote(f'[ "$(ls -A {directory_path})" ]')))
138138
return dir_not_empty_ec == 0
139139

140+
def directory_contains_empty_file(self, directory_path: str) -> bool:
141+
if not self.container or not self.not_empty_dir_exists(directory_path):
142+
return False
143+
144+
command = "sh -c {}".format(shlex.quote(f"find {directory_path} -maxdepth 1 -type f -empty"))
145+
146+
exit_code, _ = self.exec_run(command)
147+
148+
return exit_code == 0
149+
140150
def directory_contains_file_with_content(self, directory_path: str, expected_content: str) -> bool:
141151
if not self.container or not self.not_empty_dir_exists(directory_path):
142152
return False
@@ -250,25 +260,18 @@ def get_number_of_files(self, directory_path: str) -> int:
250260
logging.error(f"Error parsing output '{output}' from command '{count_command}'")
251261
return -1
252262

253-
def _verify_file_contents_in_running_container(self, directory_path: str, expected_contents: list[str]) -> bool:
254-
if not self.not_empty_dir_exists(directory_path):
255-
return False
256-
263+
def _get_contents_of_all_files_in_directory(self, directory_path: str) -> list[str] | None:
257264
safe_dir_path = shlex.quote(directory_path)
258265
list_files_command = f"find {safe_dir_path} -mindepth 1 -maxdepth 1 -type f -print0"
259266

260267
exit_code, output = self.exec_run(f"sh -c \"{list_files_command}\"")
261268

262269
if exit_code != 0:
263270
logging.error(f"Error running command '{list_files_command}': {output}")
264-
return False
271+
return None
265272

266273
actual_filepaths = [path for path in output.split('\0') if path]
267274

268-
if len(actual_filepaths) != len(expected_contents):
269-
logging.debug(f"Expected {len(expected_contents)} files, but found {len(actual_filepaths)}")
270-
return False
271-
272275
actual_file_contents = []
273276
for path in actual_filepaths:
274277
safe_path = shlex.quote(path)
@@ -279,10 +282,24 @@ def _verify_file_contents_in_running_container(self, directory_path: str, expect
279282
if exit_code != 0:
280283
error_message = f"Command to read file '{path}' failed with exit code {exit_code}"
281284
logging.error(error_message)
282-
return False
285+
return None
283286

284287
actual_file_contents.append(content)
285288

289+
return actual_file_contents
290+
291+
def _verify_file_contents_in_running_container(self, directory_path: str, expected_contents: list[str]) -> bool:
292+
if not self.not_empty_dir_exists(directory_path):
293+
return False
294+
295+
actual_file_contents = self._get_contents_of_all_files_in_directory(directory_path)
296+
if actual_file_contents is None:
297+
return False
298+
299+
if len(actual_file_contents) != len(expected_contents):
300+
logging.debug(f"Expected {len(expected_contents)} files, but found {len(actual_file_contents)}")
301+
return False
302+
286303
return sorted(actual_file_contents) == sorted(expected_contents)
287304

288305
def _verify_file_contents_in_stopped_container(self, directory_path: str, expected_contents: list[str]) -> bool:
@@ -347,6 +364,7 @@ def log_app_output(self) -> bool:
347364

348365
def verify_path_with_json_content(self, directory_path: str, expected_str: str) -> bool:
349366
if not self.container or not self.not_empty_dir_exists(directory_path):
367+
logging.warning(f"Container not running or directory does not exist: {directory_path}")
350368
return False
351369

352370
count_command = f"sh -c 'find {directory_path} -maxdepth 1 -type f | wc -l'"
@@ -378,3 +396,25 @@ def verify_path_with_json_content(self, directory_path: str, expected_str: str)
378396
expected_json = json.loads(expected_str)
379397

380398
return actual_json == expected_json
399+
400+
def directory_contains_file_with_json_content(self, directory_path: str, expected_content: str) -> bool:
401+
if not self.container or not self.not_empty_dir_exists(directory_path):
402+
logging.warning(f"Container not running or directory does not exist: {directory_path}")
403+
return False
404+
405+
actual_file_contents = self._get_contents_of_all_files_in_directory(directory_path)
406+
if actual_file_contents is None:
407+
return False
408+
409+
for file_content in actual_file_contents:
410+
try:
411+
actual_json = json.loads(file_content)
412+
expected_json = json.loads(expected_content)
413+
if actual_json == expected_json:
414+
return True
415+
logging.warning(f"File content does not match expected JSON: {file_content}")
416+
except json.JSONDecodeError:
417+
logging.error("Error decoding JSON content from file.")
418+
continue
419+
420+
return False

behave_framework/src/minifi_test_framework/containers/minifi_container.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ def set_property(self, key: str, value: str):
6666
def set_log_property(self, key: str, value: str):
6767
self.log_properties[key] = value
6868

69+
def enable_openssl_fips_mode(self):
70+
self.properties["nifi.openssl.fips.support.enable"] = "true"
71+
6972
def _fill_default_properties(self):
7073
if self.is_fhs:
7174
self.properties["nifi.flow.configuration.file"] = "/etc/nifi-minifi-cpp/config.yml"

behave_framework/src/minifi_test_framework/steps/checking_steps.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ def step_impl(context: MinifiTestContext, directory: str, timeout: str, contents
154154
context=context)
155155

156156

157-
@then("a flowfile with the JSON content \"{content}\" is placed in {directory} in less than {duration}")
158-
@then("a flowfile with the JSON content '{content}' is placed in {directory} in less than {duration}")
157+
@then("a file with the JSON content \"{content}\" is placed in the \"{directory}\" directory in less than {duration}")
158+
@then("a file with the JSON content '{content}' is placed in the '{directory}' directory in less than {duration}")
159159
def step_impl(context: MinifiTestContext, content: str, directory: str, duration: str):
160160
timeout_in_seconds = humanfriendly.parse_timespan(duration)
161161
assert wait_for_condition(
@@ -173,6 +173,15 @@ def step_impl(context: MinifiTestContext, max_increase: str, duration: str):
173173
assert final_memory_usage - initial_memory_usage <= max_increase_in_bytes
174174

175175

176+
@then("at least one file with the JSON content \"{content}\" is placed in the \"{directory}\" directory in less than {duration}")
177+
@then("at least one file with the JSON content '{content}' is placed in the '{directory}' directory in less than {duration}")
178+
def step_impl(context: MinifiTestContext, content: str, directory: str, duration: str):
179+
timeout_in_seconds = humanfriendly.parse_timespan(duration)
180+
assert wait_for_condition(
181+
condition=lambda: context.get_default_minifi_container().directory_contains_file_with_json_content(directory, content),
182+
timeout_seconds=timeout_in_seconds, bail_condition=lambda: context.get_default_minifi_container().exited, context=context)
183+
184+
176185
@then('after a wait of {duration}, at least {lower_bound:d} and at most {upper_bound:d} flowfiles are produced and placed in the "{directory}" directory')
177186
def step_impl(context, lower_bound, upper_bound, duration, directory):
178187
duration_seconds = humanfriendly.parse_timespan(duration)
@@ -196,3 +205,11 @@ def step_impl(context, directory, duration, contents):
196205
@then('exactly these files are in the "{directory}" directory in less than {duration}: ""')
197206
def step_impl(context, directory, duration):
198207
context.execute_steps(f'then no files are placed in the "{directory}" directory in {duration} of running time')
208+
209+
210+
@then("at least one empty file is placed in the \"{directory}\" directory in less than {duration}")
211+
def step_impl(context, directory, duration):
212+
timeout_in_seconds = humanfriendly.parse_timespan(duration)
213+
assert wait_for_condition(
214+
condition=lambda: context.get_default_minifi_container().directory_contains_empty_file(directory),
215+
timeout_seconds=timeout_in_seconds, bail_condition=lambda: context.get_default_minifi_container().exited, context=context)

behave_framework/src/minifi_test_framework/steps/core_steps.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import string
2121
import os
2222
import time
23+
import uuid
2324

2425
import humanfriendly
2526
from behave import when, step, given
@@ -58,6 +59,17 @@ def step_impl(context: MinifiTestContext, file_name: str, content: str, path: st
5859
context.get_or_create_default_minifi_container().files.append(File(os.path.join(path, file_name), new_content))
5960

6061

62+
@step('a file with the content "{content}" is present in "{path}"')
63+
def step_impl(context: MinifiTestContext, content: str, path: str):
64+
new_content = content.replace("\\n", "\n")
65+
context.get_or_create_default_minifi_container().files.append(File(os.path.join(path, str(uuid.uuid4())), new_content))
66+
67+
68+
@given("an empty file is present in \"{path}\"")
69+
def step_impl(context, path):
70+
context.get_or_create_default_minifi_container().files.append(File(os.path.join(path, str(uuid.uuid4())), ""))
71+
72+
6173
@given('a host resource file "{filename}" is bound to the "{container_path}" path in the MiNiFi container "{container_name}"')
6274
def step_impl(context: MinifiTestContext, filename: str, container_path: str, container_name: str):
6375
path = os.path.join(context.resource_dir, filename)
@@ -83,3 +95,8 @@ def step_impl(context: MinifiTestContext):
8395
@when("MiNiFi is restarted")
8496
def step_impl(context: MinifiTestContext):
8597
context.get_or_create_default_minifi_container().restart()
98+
99+
100+
@given("OpenSSL FIPS mode is enabled in MiNiFi")
101+
def step_impl(context):
102+
context.get_or_create_default_minifi_container().enable_openssl_fips_mode()

docker/test/integration/cluster/ContainerStore.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,11 @@
3131
from .containers.SyslogUdpClientContainer import SyslogUdpClientContainer
3232
from .containers.SyslogTcpClientContainer import SyslogTcpClientContainer
3333
from .containers.MinifiAsPodInKubernetesCluster import MinifiAsPodInKubernetesCluster
34-
from .containers.TcpClientContainer import TcpClientContainer
3534
from .containers.PrometheusContainer import PrometheusContainer
3635
from .containers.MinifiC2ServerContainer import MinifiC2ServerContainer
3736
from .containers.GrafanaLokiContainer import GrafanaLokiContainer
3837
from .containers.GrafanaLokiContainer import GrafanaLokiOptions
3938
from .containers.ReverseProxyContainer import ReverseProxyContainer
40-
from .containers.DiagSlave import DiagSlave
4139
from .containers.CouchbaseServerContainer import CouchbaseServerContainer
4240
from .FeatureContext import FeatureContext
4341

@@ -216,14 +214,6 @@ def acquire_container(self, context, container_name: str, engine='minifi-cpp', c
216214
network=self.network,
217215
image_store=self.image_store,
218216
command=command))
219-
elif engine == "tcp-client":
220-
return self.containers.setdefault(container_name,
221-
TcpClientContainer(feature_context=feature_context,
222-
name=container_name,
223-
vols=self.vols,
224-
network=self.network,
225-
image_store=self.image_store,
226-
command=command))
227217
elif engine == "prometheus":
228218
return self.containers.setdefault(container_name,
229219
PrometheusContainer(feature_context=feature_context,
@@ -276,14 +266,6 @@ def acquire_container(self, context, container_name: str, engine='minifi-cpp', c
276266
network=self.network,
277267
image_store=self.image_store,
278268
command=command))
279-
elif engine == "diag-slave-tcp":
280-
return self.containers.setdefault(container_name,
281-
DiagSlave(feature_context=feature_context,
282-
name=container_name,
283-
vols=self.vols,
284-
network=self.network,
285-
image_store=self.image_store,
286-
command=command))
287269
elif engine == "couchbase-server":
288270
return self.containers.setdefault(container_name,
289271
CouchbaseServerContainer(feature_context=feature_context,

docker/test/integration/cluster/ImageStore.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ def get_image(self, container_engine):
7171
image = self.__build_kinesis_image()
7272
elif container_engine == "reverse-proxy":
7373
image = self.__build_reverse_proxy_image()
74-
elif container_engine == "diag-slave-tcp":
75-
image = self.__build_diagslave_image()
7674
else:
7775
raise Exception("There is no associated image for " + container_engine)
7876

@@ -303,9 +301,6 @@ def __build_splunk_image(self):
303301
def __build_reverse_proxy_image(self):
304302
return self.__build_image_by_path(self.test_dir + "/resources/reverse-proxy", 'reverse-proxy')
305303

306-
def __build_diagslave_image(self):
307-
return self.__build_image_by_path(self.test_dir + "/resources/diagslave", 'diag-slave-tcp')
308-
309304
def __build_image(self, dockerfile, context_files=[]):
310305
conf_dockerfile_buffer = BytesIO()
311306
docker_context_buffer = BytesIO()

docker/test/integration/cluster/containers/DiagSlave.py

Lines changed: 0 additions & 36 deletions
This file was deleted.

docker/test/integration/cluster/containers/TcpClientContainer.py

Lines changed: 0 additions & 39 deletions
This file was deleted.

docker/test/integration/features/steps/steps.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,18 +1297,6 @@ def step_impl(context, parameter_context_name):
12971297
container.set_parameter_context_name(parameter_context_name)
12981298

12991299

1300-
# Modbus
1301-
@given(u'there is an accessible PLC with modbus enabled')
1302-
def step_impl(context):
1303-
context.test.acquire_container(context=context, name="diag-slave-tcp", engine="diag-slave-tcp")
1304-
context.test.start('diag-slave-tcp')
1305-
1306-
1307-
@given(u'PLC register has been set with {modbus_cmd} command')
1308-
def step_impl(context, modbus_cmd):
1309-
context.test.set_value_on_plc_with_modbus(context.test.get_container_name_with_postfix('diag-slave-tcp'), modbus_cmd)
1310-
1311-
13121300
# Couchbase
13131301
@when(u'a Couchbase server is started')
13141302
def step_impl(context):

docker/test/integration/minifi/processors/DefragmentText.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)