From e59f82500ffddd17af02c473df845612dcd970e9 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Sat, 17 Oct 2026 14:28:38 -0600 Subject: [PATCH 1/2] router: apply input routes with a single input and output With one input and one output, the router connected them directly and returned before applying the routes of the configuration. Route conditions were never evaluated, so records matching no route still reached the output. Take the shortcut only when no input has routes. Signed-off-by: Eduardo Silva --- src/flb_router.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/flb_router.c b/src/flb_router.c index 170b7e94105..7e7eac00d99 100644 --- a/src/flb_router.c +++ b/src/flb_router.c @@ -198,8 +198,12 @@ int flb_router_io_set(struct flb_config *config) in_count = mk_list_size(&config->inputs); out_count = mk_list_size(&config->outputs); - /* Mostly used for command line tests */ - if (in_count == 1 && out_count == 1) { + /* + * Mostly used for command line tests. Inputs with routes are connected by + * the router configuration below. + */ + if (in_count == 1 && out_count == 1 && + cfl_list_is_empty(&config->input_routes)) { i_ins = mk_list_entry_first(&config->inputs, struct flb_input_instance, _head); o_ins = mk_list_entry_first(&config->outputs, struct flb_output_instance, _head); From ea76030e5e7f0f4cb5e60208bf4828ad0d53e304 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Sat, 17 Oct 2026 14:28:38 -0600 Subject: [PATCH 2/2] tests: integration: out_stdout: cover routes with a single input and output Signed-off-by: Eduardo Silva --- ..._stdout_single_pair_conditional_match.yaml | 30 +++++++++++++++++++ ...t_stdout_single_pair_conditional_miss.yaml | 30 +++++++++++++++++++ .../out_stdout/tests/test_out_stdout_001.py | 26 ++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 tests/integration/scenarios/out_stdout/config/out_stdout_single_pair_conditional_match.yaml create mode 100644 tests/integration/scenarios/out_stdout/config/out_stdout_single_pair_conditional_miss.yaml diff --git a/tests/integration/scenarios/out_stdout/config/out_stdout_single_pair_conditional_match.yaml b/tests/integration/scenarios/out_stdout/config/out_stdout_single_pair_conditional_match.yaml new file mode 100644 index 00000000000..5471269dd53 --- /dev/null +++ b/tests/integration/scenarios/out_stdout/config/out_stdout_single_pair_conditional_match.yaml @@ -0,0 +1,30 @@ +service: + flush: 1 + grace: 1 + log_level: debug + http_server: on + http_port: ${FLUENT_BIT_HTTP_MONITORING_PORT} + +pipeline: + inputs: + - name: dummy + alias: single_pair_dummy + tag: single.pair + dummy: '{"message":"single pair record","topic":"topic1"}' + samples: 1 + routes: + logs: + - name: single_pair_topic1 + condition: + op: and + rules: + - field: $topic + op: eq + value: topic1 + to: + outputs: + - single_pair_stdout + + outputs: + - name: stdout + alias: single_pair_stdout diff --git a/tests/integration/scenarios/out_stdout/config/out_stdout_single_pair_conditional_miss.yaml b/tests/integration/scenarios/out_stdout/config/out_stdout_single_pair_conditional_miss.yaml new file mode 100644 index 00000000000..830c2587215 --- /dev/null +++ b/tests/integration/scenarios/out_stdout/config/out_stdout_single_pair_conditional_miss.yaml @@ -0,0 +1,30 @@ +service: + flush: 1 + grace: 1 + log_level: debug + http_server: on + http_port: ${FLUENT_BIT_HTTP_MONITORING_PORT} + +pipeline: + inputs: + - name: dummy + alias: single_pair_dummy + tag: single.pair + dummy: '{"message":"single pair record","topic":"topic2"}' + samples: 1 + routes: + logs: + - name: single_pair_topic1 + condition: + op: and + rules: + - field: $topic + op: eq + value: topic1 + to: + outputs: + - single_pair_stdout + + outputs: + - name: stdout + alias: single_pair_stdout diff --git a/tests/integration/scenarios/out_stdout/tests/test_out_stdout_001.py b/tests/integration/scenarios/out_stdout/tests/test_out_stdout_001.py index 928b574dfbe..33d847019a7 100644 --- a/tests/integration/scenarios/out_stdout/tests/test_out_stdout_001.py +++ b/tests/integration/scenarios/out_stdout/tests/test_out_stdout_001.py @@ -1,5 +1,6 @@ import json import os +import time from pathlib import Path import pytest @@ -347,3 +348,28 @@ def test_out_stdout_conditional_routing_corner_cases(mode, label, config_file): ) assert _stdout_lines_for_tag(log_text, f"{mode}_default_topic1") == [] assert _stdout_lines_for_tag(log_text, f"{mode}_miss_topic1") == [] + + +def test_out_stdout_single_pair_conditional_route_matches(): + """With one input and one output, a matching route still delivers.""" + service = Service("out_stdout_single_pair_conditional_match.yaml") + service.start() + log_text = service.wait_for_log_contains("[0] single_pair_topic1:", timeout=10) + service.stop() + + assert "connected input 'single_pair_dummy' route 'single_pair_topic1'" in log_text + assert "\"message\"=>\"single pair record\"" in log_text + + +def test_out_stdout_single_pair_conditional_route_drops_unmatched(): + """With one input and one output, records matching no route are not delivered.""" + service = Service("out_stdout_single_pair_conditional_miss.yaml") + service.start() + service.wait_for_log_contains( + "connected input 'single_pair_dummy' route 'single_pair_topic1'", timeout=10) + # several flushes for the sample to reach the output if it were routed + time.sleep(4) + log_text = service.read_log() + service.stop() + + assert "single pair record" not in log_text