From b485aab7e71c1625cfc27e0f92c9509f42378458 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 5 May 2024 13:19:16 +0200 Subject: Adding upstream version 1.45.3+dfsg. Signed-off-by: Daniel Baumann --- src/fluent-bit/tests/include/aws_client_mock.c | 256 + src/fluent-bit/tests/include/aws_client_mock.h | 223 + .../tests/include/aws_client_mock_client_resp.def | 34 + .../tests/include/flb_tests_initialize_tls.h | 44 + src/fluent-bit/tests/internal/CMakeLists.txt | 216 + src/fluent-bit/tests/internal/README.md | 3 + src/fluent-bit/tests/internal/avro.c | 382 ++ src/fluent-bit/tests/internal/aws/CMakeLists.txt | 7 + src/fluent-bit/tests/internal/aws/placeholder.c | 11 + src/fluent-bit/tests/internal/aws_compress.c | 489 ++ src/fluent-bit/tests/internal/aws_credentials.c | 382 ++ .../tests/internal/aws_credentials_ec2.c | 1037 ++++ .../tests/internal/aws_credentials_http.c | 382 ++ .../tests/internal/aws_credentials_process.c | 496 ++ .../tests/internal/aws_credentials_profile.c | 405 ++ .../tests/internal/aws_credentials_sts.c | 939 +++ .../tests/internal/aws_credentials_test_internal.h | 42 + src/fluent-bit/tests/internal/aws_util.c | 395 ++ src/fluent-bit/tests/internal/base64.c | 50 + src/fluent-bit/tests/internal/bucket_queue.c | 248 + src/fluent-bit/tests/internal/config_format.c | 86 + .../tests/internal/config_format_fluentbit.c | 353 ++ src/fluent-bit/tests/internal/config_format_yaml.c | 324 + src/fluent-bit/tests/internal/config_map.c | 386 ++ src/fluent-bit/tests/internal/crypto.c | 202 + src/fluent-bit/tests/internal/csv.c | 167 + .../internal/data/avro/json_single_map_001.json | 5 + .../tests/internal/data/avro/live-sample.json | 25 + .../tests/internal/data/avro/multiline.json | 27 + .../credential_process/aws-credential-process | 14 + .../data/aws_credentials/shared_config.ini | 9 + .../aws_credentials/shared_credentials_file.ini | 28 + .../shared_credentials_file_nodefault.ini | 12 + .../aws_credentials/web_identity_token_file.txt | 1 + .../data/config_format/classic/fluent-bit.conf | 35 + .../config_format/classic/indent_level_error.conf | 6 + .../data/config_format/classic/issue6281.conf | 2 + .../config_format/classic/issue6281_input.conf | 2 + .../config_format/classic/issue6281_output.conf | 2 + .../data/config_format/classic/issue_5880.conf | 14 + .../data/config_format/classic/nolimitline.conf | 11 + .../data/config_format/classic/recursion.conf | 1 + .../data/config_format/classic/service.conf | 4 + .../data/config_format/yaml/fluent-bit.yaml | 29 + .../data/config_format/yaml/issue_7559.yaml | 14 + .../config_format/yaml/parsers/parsers-conf.yaml | 3 + .../data/config_format/yaml/parsers/parsers.conf | 6 + .../config_format/yaml/pipelines/slist/even.yaml | 7 + .../config_format/yaml/pipelines/slist/odd.yaml | 8 + .../internal/data/config_format/yaml/service.yaml | 5 + .../internal/data/config_format/yaml/test.yaml | 31 + .../config_format/yaml/test/dummy_pipeline.yaml | 13 + .../data/config_format/yaml/test/nested.yaml | 7 + .../tests/internal/data/file/empty_file.txt | 0 .../tests/internal/data/file/text_file.txt | 5 + .../input_chunk/log/a_thousand_plus_one_bytes.log | 2 + .../data/input_chunk/log/test_buffer_drop_chunks.h | 27 + .../data/input_chunk/log/test_buffer_valid.log | 3 + .../input_chunk/out/a_thousand_plus_one_bytes.out | 0 .../data/input_chunk/out/test_buffer_valid.out | 3 + .../tests/internal/data/input_chunk/parser.conf | 10 + .../tests/internal/data/mp/apache_10k.mp | Bin 0 -> 993663 bytes src/fluent-bit/tests/internal/data/pack/README.md | 3 + .../tests/internal/data/pack/bug342.json | 240 + .../tests/internal/data/pack/dup_keys_in.json | 1 + .../tests/internal/data/pack/dup_keys_out.json | 1 + .../internal/data/pack/json_single_map_001.json | 5 + .../internal/data/pack/json_single_map_002.json | 4 + src/fluent-bit/tests/internal/data/pack/mixed.py | 31 + .../tests/internal/data/pack/mixed_001.json | 1 + .../tests/internal/data/pack/mixed_001.mp | 1 + .../tests/internal/data/pack/mixed_001.txt | 1 + .../tests/internal/data/pack/mixed_002.json | 1 + .../tests/internal/data/pack/mixed_002.mp | Bin 0 -> 37 bytes .../tests/internal/data/pack/mixed_002.txt | 7 + .../tests/internal/data/pack/mixed_003.json | 1 + .../tests/internal/data/pack/mixed_003.mp | 1 + .../tests/internal/data/pack/mixed_003.txt | 1 + .../tests/internal/data/pack/utf8_bell.json | 1 + .../tests/internal/data/pack/utf8_bell.mp | 1 + .../tests/internal/data/pack/utf8_bell.txt | 1 + .../tests/internal/data/pack/utf8_copyright.json | 1 + .../tests/internal/data/pack/utf8_copyright.mp | 1 + .../tests/internal/data/pack/utf8_copyright.txt | 1 + .../tests/internal/data/pack/utf8_gen.py | 32 + .../tests/internal/data/pack/utf8_hokke.json | 1 + .../tests/internal/data/pack/utf8_hokke.mp | 1 + .../tests/internal/data/pack/utf8_hokke.txt | 1 + .../tests/internal/data/pack/utf8_relaxed.json | 1 + .../tests/internal/data/pack/utf8_relaxed.mp | 1 + .../tests/internal/data/pack/utf8_relaxed.txt | 1 + .../tests/internal/data/parser/json.conf | 200 + .../tests/internal/data/parser/regex.conf | 234 + .../tests/internal/data/reload/fluent-bit.conf | 15 + .../tests/internal/data/reload/yaml/processor.yaml | 41 + .../tests/internal/data/s3_local_buffer/.gitkeep | 1 + .../data/signv4/aws-sig-v4-test-suite/LICENSE | 202 + .../data/signv4/aws-sig-v4-test-suite/NOTICE | 2 + .../get-header-key-duplicate.authz | 1 + .../get-header-key-duplicate.creq | 9 + .../get-header-key-duplicate.req | 6 + .../get-header-key-duplicate.sreq | 7 + .../get-header-key-duplicate.sts | 4 + .../get-header-value-multiline.authz | 1 + .../get-header-value-multiline.creq | 9 + .../get-header-value-multiline.req | 6 + .../get-header-value-multiline.sreq | 7 + .../get-header-value-multiline.sts | 4 + .../get-header-value-order.authz | 1 + .../get-header-value-order.creq | 9 + .../get-header-value-order.req | 7 + .../get-header-value-order.sreq | 8 + .../get-header-value-order.sts | 4 + .../get-header-value-trim.authz | 1 + .../get-header-value-trim.creq | 10 + .../get-header-value-trim.req | 5 + .../get-header-value-trim.sreq | 6 + .../get-header-value-trim.sts | 4 + .../get-unreserved/get-unreserved.authz | 1 + .../get-unreserved/get-unreserved.creq | 8 + .../get-unreserved/get-unreserved.req | 3 + .../get-unreserved/get-unreserved.sreq | 4 + .../get-unreserved/get-unreserved.sts | 4 + .../aws-sig-v4-test-suite/get-utf8/get-utf8.authz | 1 + .../aws-sig-v4-test-suite/get-utf8/get-utf8.creq | 8 + .../aws-sig-v4-test-suite/get-utf8/get-utf8.req | 3 + .../aws-sig-v4-test-suite/get-utf8/get-utf8.sreq | 4 + .../aws-sig-v4-test-suite/get-utf8/get-utf8.sts | 4 + .../get-vanilla-empty-query-key.authz | 1 + .../get-vanilla-empty-query-key.creq | 8 + .../get-vanilla-empty-query-key.req | 3 + .../get-vanilla-empty-query-key.sreq | 4 + .../get-vanilla-empty-query-key.sts | 4 + .../get-vanilla-query-order-key-case.authz | 1 + .../get-vanilla-query-order-key-case.creq | 8 + .../get-vanilla-query-order-key-case.req | 3 + .../get-vanilla-query-order-key-case.sreq | 4 + .../get-vanilla-query-order-key-case.sts | 4 + .../get-vanilla-query-order-key.authz | 1 + .../get-vanilla-query-order-key.creq | 8 + .../get-vanilla-query-order-key.req | 3 + .../get-vanilla-query-order-key.sreq | 4 + .../get-vanilla-query-order-key.sts | 4 + .../get-vanilla-query-order-value.authz | 1 + .../get-vanilla-query-order-value.creq | 8 + .../get-vanilla-query-order-value.req | 3 + .../get-vanilla-query-order-value.sreq | 4 + .../get-vanilla-query-order-value.sts | 4 + .../get-vanilla-query-unreserved.authz | 1 + .../get-vanilla-query-unreserved.creq | 8 + .../get-vanilla-query-unreserved.req | 3 + .../get-vanilla-query-unreserved.sreq | 4 + .../get-vanilla-query-unreserved.sts | 4 + .../get-vanilla-query/get-vanilla-query.authz | 1 + .../get-vanilla-query/get-vanilla-query.creq | 8 + .../get-vanilla-query/get-vanilla-query.req | 3 + .../get-vanilla-query/get-vanilla-query.sreq | 4 + .../get-vanilla-query/get-vanilla-query.sts | 4 + .../get-vanilla-utf8-query.authz | 1 + .../get-vanilla-utf8-query.creq | 8 + .../get-vanilla-utf8-query.req | 3 + .../get-vanilla-utf8-query.sreq | 4 + .../get-vanilla-utf8-query.sts | 4 + .../get-vanilla/get-vanilla.authz | 1 + .../get-vanilla/get-vanilla.creq | 8 + .../get-vanilla/get-vanilla.req | 3 + .../get-vanilla/get-vanilla.sreq | 4 + .../get-vanilla/get-vanilla.sts | 4 + .../get-relative-relative.authz | 1 + .../get-relative-relative.creq | 8 + .../get-relative-relative.req | 3 + .../get-relative-relative.sreq | 4 + .../get-relative-relative.sts | 4 + .../normalize-path/get-relative/get-relative.authz | 1 + .../normalize-path/get-relative/get-relative.creq | 8 + .../normalize-path/get-relative/get-relative.req | 3 + .../normalize-path/get-relative/get-relative.sreq | 4 + .../normalize-path/get-relative/get-relative.sts | 4 + .../get-slash-dot-slash/get-slash-dot-slash.authz | 1 + .../get-slash-dot-slash/get-slash-dot-slash.creq | 8 + .../get-slash-dot-slash/get-slash-dot-slash.req | 3 + .../get-slash-dot-slash/get-slash-dot-slash.sreq | 4 + .../get-slash-dot-slash/get-slash-dot-slash.sts | 4 + .../get-slash-pointless-dot.authz | 1 + .../get-slash-pointless-dot.creq | 8 + .../get-slash-pointless-dot.req | 3 + .../get-slash-pointless-dot.sreq | 4 + .../get-slash-pointless-dot.sts | 4 + .../normalize-path/get-slash/get-slash.authz | 1 + .../normalize-path/get-slash/get-slash.creq | 8 + .../normalize-path/get-slash/get-slash.req | 3 + .../normalize-path/get-slash/get-slash.sreq | 4 + .../normalize-path/get-slash/get-slash.sts | 4 + .../normalize-path/get-slashes/get-slashes.authz | 1 + .../normalize-path/get-slashes/get-slashes.creq | 8 + .../normalize-path/get-slashes/get-slashes.req | 3 + .../normalize-path/get-slashes/get-slashes.sreq | 4 + .../normalize-path/get-slashes/get-slashes.sts | 4 + .../normalize-path/get-space/get-space.authz | 1 + .../normalize-path/get-space/get-space.creq | 8 + .../normalize-path/get-space/get-space.req | 3 + .../normalize-path/get-space/get-space.sreq | 4 + .../normalize-path/get-space/get-space.sts | 4 + .../normalize-path/normalize-path.txt | 3 + .../post-header-key-case.authz | 1 + .../post-header-key-case/post-header-key-case.creq | 8 + .../post-header-key-case/post-header-key-case.req | 3 + .../post-header-key-case/post-header-key-case.sreq | 4 + .../post-header-key-case/post-header-key-case.sts | 4 + .../post-header-key-sort.authz | 1 + .../post-header-key-sort/post-header-key-sort.creq | 9 + .../post-header-key-sort/post-header-key-sort.req | 4 + .../post-header-key-sort/post-header-key-sort.sreq | 5 + .../post-header-key-sort/post-header-key-sort.sts | 4 + .../post-header-value-case.authz | 1 + .../post-header-value-case.creq | 9 + .../post-header-value-case.req | 4 + .../post-header-value-case.sreq | 5 + .../post-header-value-case.sts | 4 + .../post-sts-header-after.authz | 1 + .../post-sts-header-after.creq | 8 + .../post-sts-header-after.req | 3 + .../post-sts-header-after.sreq | 5 + .../post-sts-header-after.sts | 4 + .../post-sts-header-before.authz | 1 + .../post-sts-header-before.creq | 9 + .../post-sts-header-before.req | 4 + .../post-sts-header-before.sreq | 5 + .../post-sts-header-before.sts | 4 + .../post-sts-token/readme.txt | 15 + .../post-vanilla-empty-query-value.authz | 1 + .../post-vanilla-empty-query-value.creq | 8 + .../post-vanilla-empty-query-value.req | 3 + .../post-vanilla-empty-query-value.sreq | 4 + .../post-vanilla-empty-query-value.sts | 4 + .../post-vanilla-query/post-vanilla-query.authz | 1 + .../post-vanilla-query/post-vanilla-query.creq | 8 + .../post-vanilla-query/post-vanilla-query.req | 3 + .../post-vanilla-query/post-vanilla-query.sreq | 4 + .../post-vanilla-query/post-vanilla-query.sts | 4 + .../post-vanilla/post-vanilla.authz | 1 + .../post-vanilla/post-vanilla.creq | 8 + .../post-vanilla/post-vanilla.req | 3 + .../post-vanilla/post-vanilla.sreq | 4 + .../post-vanilla/post-vanilla.sts | 4 + .../post-x-www-form-urlencoded-parameters.authz | 1 + .../post-x-www-form-urlencoded-parameters.creq | 9 + .../post-x-www-form-urlencoded-parameters.req | 6 + .../post-x-www-form-urlencoded-parameters.sreq | 7 + .../post-x-www-form-urlencoded-parameters.sts | 4 + .../post-x-www-form-urlencoded.authz | 1 + .../post-x-www-form-urlencoded.creq | 9 + .../post-x-www-form-urlencoded.req | 4 + .../post-x-www-form-urlencoded.sreq | 4 + .../post-x-www-form-urlencoded.sts | 4 + .../internal/data/stream_processor/gen_msgpack.sh | 40 + .../data/stream_processor/samples-hw/1.json | 4 + .../internal/data/stream_processor/samples-hw/1.mp | Bin 0 -> 257 bytes .../data/stream_processor/samples-hw/2.json | 4 + .../internal/data/stream_processor/samples-hw/2.mp | Bin 0 -> 268 bytes .../data/stream_processor/samples-hw/3.json | 3 + .../internal/data/stream_processor/samples-hw/3.mp | Bin 0 -> 201 bytes .../data/stream_processor/samples-hw/4.json | 4 + .../internal/data/stream_processor/samples-hw/4.mp | Bin 0 -> 260 bytes .../data/stream_processor/samples-hw/5.json | 4 + .../internal/data/stream_processor/samples-hw/5.mp | Bin 0 -> 272 bytes .../data/stream_processor/samples-hw/6.json | 3 + .../internal/data/stream_processor/samples-hw/6.mp | Bin 0 -> 204 bytes .../data/stream_processor/samples-hw/7.json | 4 + .../internal/data/stream_processor/samples-hw/7.mp | Bin 0 -> 262 bytes .../data/stream_processor/samples-subkeys.json | 9 + .../data/stream_processor/samples-subkeys.mp | Bin 0 -> 479 bytes .../internal/data/stream_processor/samples.json | 11 + .../internal/data/stream_processor/samples.mp | Bin 0 -> 726 bytes .../tests/internal/data/tls/certificate.pem | 22 + .../tests/internal/data/tls/private_key.pem | 28 + src/fluent-bit/tests/internal/env.c | 91 + src/fluent-bit/tests/internal/error_reporter.c | 82 + src/fluent-bit/tests/internal/file.c | 48 + src/fluent-bit/tests/internal/flb_event_loop.c | 592 ++ .../tests/internal/flb_tests_internal.h.in | 43 + src/fluent-bit/tests/internal/flb_time.c | 335 ++ src/fluent-bit/tests/internal/fstore.c | 84 + .../tests/internal/fuzzers/CMakeLists.txt | 60 + .../internal/fuzzers/aws_credentials_fuzzer.c | 132 + .../tests/internal/fuzzers/aws_util_fuzzer.c | 107 + .../tests/internal/fuzzers/base64_fuzzer.c | 20 + .../tests/internal/fuzzers/cmetrics_decode_fuzz.c | 69 + .../tests/internal/fuzzers/config_fuzzer.c | 417 ++ .../tests/internal/fuzzers/config_map_fuzzer.c | 212 + .../tests/internal/fuzzers/config_random_fuzzer.c | 57 + .../tests/internal/fuzzers/config_yaml_fuzzer.c | 65 + .../tests/internal/fuzzers/ctrace_fuzzer.c | 24 + .../tests/internal/fuzzers/engine_fuzzer.c | 171 + .../tests/internal/fuzzers/filter_stdout_fuzzer.c | 62 + .../tests/internal/fuzzers/flb_fuzz_header.h | 42 + .../tests/internal/fuzzers/flb_json_fuzzer.c | 82 + .../tests/internal/fuzzers/flb_mp_fuzzer.c | 55 + .../tests/internal/fuzzers/fstore_fuzzer.c | 86 + .../tests/internal/fuzzers/http_fuzzer.c | 116 + .../tests/internal/fuzzers/input_fuzzer.c | 164 + src/fluent-bit/tests/internal/fuzzers/local_test.c | 85 + .../tests/internal/fuzzers/msgpack_parse_fuzzer.c | 30 + .../internal/fuzzers/msgpack_to_gelf_fuzzer.c | 25 + .../tests/internal/fuzzers/multiline_fuzzer.c | 180 + .../internal/fuzzers/pack_json_state_fuzzer.c | 25 + .../tests/internal/fuzzers/parse_json_fuzzer.c | 69 + .../tests/internal/fuzzers/parse_logfmt_fuzzer.c | 50 + .../tests/internal/fuzzers/parse_ltsv_fuzzer.c | 35 + .../tests/internal/fuzzers/parser_fuzzer.c | 203 + .../tests/internal/fuzzers/record_ac_fuzzer.c | 101 + .../tests/internal/fuzzers/signv4_fuzzer.c | 111 + .../tests/internal/fuzzers/strp_fuzzer.c | 35 + .../tests/internal/fuzzers/utils_fuzzer.c | 242 + src/fluent-bit/tests/internal/gelf.c | 101 + src/fluent-bit/tests/internal/gzip.c | 46 + src/fluent-bit/tests/internal/hash.c | 165 + src/fluent-bit/tests/internal/hashtable.c | 413 ++ src/fluent-bit/tests/internal/hmac.c | 136 + src/fluent-bit/tests/internal/http_client.c | 478 ++ .../tests/internal/include/sp_cb_functions.h | 655 ++ src/fluent-bit/tests/internal/include/sp_helpers.h | 158 + .../tests/internal/include/sp_invalid_queries.h | 20 + .../tests/internal/include/sp_select_keys.h | 131 + .../tests/internal/include/sp_select_subkeys.h | 84 + .../tests/internal/include/sp_snapshot.h | 38 + src/fluent-bit/tests/internal/include/sp_window.h | 53 + src/fluent-bit/tests/internal/input_chunk.c | 516 ++ src/fluent-bit/tests/internal/log.c | 154 + src/fluent-bit/tests/internal/log_event_decoder.c | 281 + src/fluent-bit/tests/internal/lua.c | 325 + src/fluent-bit/tests/internal/metrics.c | 83 + src/fluent-bit/tests/internal/mp.c | 353 ++ src/fluent-bit/tests/internal/multiline.c | 1478 +++++ src/fluent-bit/tests/internal/network.c | 164 + src/fluent-bit/tests/internal/pack.c | 914 +++ src/fluent-bit/tests/internal/parser.c | 528 ++ src/fluent-bit/tests/internal/parser_json.c | 547 ++ src/fluent-bit/tests/internal/parser_logfmt.c | 398 ++ src/fluent-bit/tests/internal/parser_ltsv.c | 486 ++ src/fluent-bit/tests/internal/parser_regex.c | 491 ++ src/fluent-bit/tests/internal/pipe.c | 89 + src/fluent-bit/tests/internal/processor.c | 125 + src/fluent-bit/tests/internal/random.c | 33 + src/fluent-bit/tests/internal/record_accessor.c | 1731 ++++++ src/fluent-bit/tests/internal/regex.c | 330 ++ src/fluent-bit/tests/internal/reload.c | 249 + src/fluent-bit/tests/internal/ring_buffer.c | 168 + src/fluent-bit/tests/internal/router.c | 55 + src/fluent-bit/tests/internal/sds.c | 88 + src/fluent-bit/tests/internal/sds_list.c | 238 + src/fluent-bit/tests/internal/signv4.c | 666 +++ src/fluent-bit/tests/internal/slist.c | 205 + src/fluent-bit/tests/internal/stream_processor.c | 934 +++ src/fluent-bit/tests/internal/typecast.c | 359 ++ src/fluent-bit/tests/internal/unit_sizes.c | 59 + src/fluent-bit/tests/internal/uri.c | 87 + src/fluent-bit/tests/internal/utils.c | 622 ++ src/fluent-bit/tests/lib/acutest/README.md | 4 + src/fluent-bit/tests/lib/acutest/acutest.h | 1839 ++++++ src/fluent-bit/tests/lib/shunit2/.gitignore | 3 + src/fluent-bit/tests/lib/shunit2/.travis.yml | 29 + .../tests/lib/shunit2/CODE_OF_CONDUCT.md | 46 + src/fluent-bit/tests/lib/shunit2/LICENSE | 201 + src/fluent-bit/tests/lib/shunit2/README.md | 636 ++ .../tests/lib/shunit2/doc/CHANGES-2.1.md | 261 + .../tests/lib/shunit2/doc/RELEASE_NOTES-2.1.0.txt | 104 + .../tests/lib/shunit2/doc/RELEASE_NOTES-2.1.1.txt | 88 + .../tests/lib/shunit2/doc/RELEASE_NOTES-2.1.2.txt | 83 + .../tests/lib/shunit2/doc/RELEASE_NOTES-2.1.3.txt | 84 + .../tests/lib/shunit2/doc/RELEASE_NOTES-2.1.4.txt | 100 + .../tests/lib/shunit2/doc/RELEASE_NOTES-2.1.5.txt | 128 + .../tests/lib/shunit2/doc/RELEASE_NOTES-2.1.6.txt | 112 + .../tests/lib/shunit2/doc/RELEASE_NOTES-2.1.7.md | 66 + .../tests/lib/shunit2/doc/RELEASE_NOTES-2.1.8.md | 56 + src/fluent-bit/tests/lib/shunit2/doc/TODO.txt | 13 + .../tests/lib/shunit2/doc/contributors.md | 15 + .../tests/lib/shunit2/doc/design_doc.txt | 34 + .../tests/lib/shunit2/examples/equality_test.sh | 9 + .../tests/lib/shunit2/examples/lineno_test.sh | 15 + src/fluent-bit/tests/lib/shunit2/examples/math.inc | 17 + .../tests/lib/shunit2/examples/math_test.sh | 25 + .../tests/lib/shunit2/examples/mkdir_test.sh | 79 + .../tests/lib/shunit2/examples/mock_file.sh | 80 + .../tests/lib/shunit2/examples/mock_file_test.sh | 33 + .../tests/lib/shunit2/examples/party_test.sh | 16 + .../tests/lib/shunit2/examples/suite_test.sh | 32 + src/fluent-bit/tests/lib/shunit2/lib/shflags | 1222 ++++ src/fluent-bit/tests/lib/shunit2/lib/versions | 273 + src/fluent-bit/tests/lib/shunit2/shunit2 | 1343 +++++ .../tests/lib/shunit2/shunit2_args_test.sh | 59 + .../tests/lib/shunit2/shunit2_asserts_test.sh | 258 + .../tests/lib/shunit2/shunit2_failures_test.sh | 85 + .../tests/lib/shunit2/shunit2_macros_test.sh | 265 + .../tests/lib/shunit2/shunit2_misc_test.sh | 315 + .../tests/lib/shunit2/shunit2_standalone_test.sh | 38 + .../tests/lib/shunit2/shunit2_test_helpers | 234 + src/fluent-bit/tests/lib/shunit2/test_runner | 171 + src/fluent-bit/tests/runtime/CMakeLists.txt | 173 + src/fluent-bit/tests/runtime/config_map_opts.c | 35 + src/fluent-bit/tests/runtime/core-timeout.c | 94 + src/fluent-bit/tests/runtime/core_chunk_trace.c | 153 + src/fluent-bit/tests/runtime/core_engine.c | 167 + src/fluent-bit/tests/runtime/core_log.c | 308 + .../tests/runtime/custom_calyptia_test.c | 59 + .../tests/runtime/data/common/json_invalid.h | 6 + .../tests/runtime/data/common/json_long.h | 1006 ++++ .../tests/runtime/data/common/json_small.h | 256 + .../tests/runtime/data/common/parsers.conf | 1 + src/fluent-bit/tests/runtime/data/datadog/json.h | 12 + src/fluent-bit/tests/runtime/data/es/json_es.h | 17 + .../runtime/data/in_elasticsearch/json_bulk.h | 25 + .../annotations-exclude_default_text.log | 2 + .../annotations-exclude_invalid_text.log | 2 + .../annotations-exclude_multiple-1_container-1.log | 2 + .../annotations-exclude_multiple-1_container-2.log | 2 + .../annotations-exclude_multiple-1_container-3.log | 2 + .../annotations-exclude_multiple-1_container-4.log | 2 + .../annotations-exclude_multiple-2_container-1.log | 2 + .../annotations-exclude_multiple-2_container-2.log | 2 + .../annotations-exclude_multiple-2_container-3.log | 2 + .../annotations-exclude_multiple-2_container-4.log | 2 + .../annotations-exclude_multiple-3_container-1.log | 2 + .../annotations-exclude_multiple-3_container-2.log | 2 + .../annotations-exclude_multiple-3_container-3.log | 2 + .../annotations-exclude_multiple-3_container-4.log | 2 + .../annotations-exclude_multiple-4_container-1.log | 2 + .../annotations-exclude_multiple-4_container-2.log | 2 + .../annotations-exclude_multiple-4_container-3.log | 2 + .../annotations-exclude_multiple-4_container-4.log | 2 + .../annotations-exclude_stderr_text.log | 2 + .../annotations-exclude_stdout_text.log | 2 + .../annotations-parser_invalid_text.log | 2 + ...ations-parser_json-with-time_invalid-json-1.log | 1 + .../annotations-parser_json-with-time_json.log | 1 + .../annotations-parser_multiple-1_container-1.log | 2 + .../annotations-parser_multiple-1_container-2.log | 2 + .../annotations-parser_multiple-1_container-3.log | 2 + .../annotations-parser_multiple-1_container-4.log | 2 + .../annotations-parser_multiple-1_container-5.log | 2 + .../annotations-parser_multiple-2_container-1.log | 2 + .../annotations-parser_multiple-2_container-2.log | 2 + .../annotations-parser_multiple-2_container-3.log | 2 + .../annotations-parser_multiple-2_container-4.log | 2 + .../annotations-parser_multiple-2_container-5.log | 2 + ...tions-parser_regex-with-time_invalid-text-1.log | 1 + .../annotations-parser_regex-with-time_text.log | 1 + .../annotations-parser_stderr_text.log | 2 + .../annotations-parser_stdout_text.log | 2 + .../log/annotations/annotations_invalid_text.log | 1 + .../kubernetes/log/core/core_base_fluent-bit.log | 1 + .../data/kubernetes/log/core/core_no-meta_text.log | 1 + .../kubernetes/log/core/core_unescaping_json.log | 1 + .../kubernetes/log/core/core_unescaping_text.log | 1 + .../options_k8s-logging-exclude-disabled_text.log | 2 + .../options_k8s-logging-parser-disabled_text.log | 2 + .../log/options/options_keep-log-disabled_json.log | 1 + .../log/options/options_keep-log-enabled_json.log | 1 + .../options/options_merge-log-disabled_json.log | 1 + .../options_merge-log-enabled_invalid-json.log | 1 + .../log/options/options_merge-log-enabled_json.log | 1 + .../log/options/options_merge-log-enabled_text.log | 1 + .../log/options/options_merge-log-key_json.log | 1 + .../options_merge-log-trim-disabled_json.log | 1 + .../options_merge-log-trim-enabled_json.log | 1 + .../options_use-kubelet-disabled_fluent-bit.log | 1 + .../options_use-kubelet-enabled_fluent-bit.log | 1 + .../meta/annotations-exclude_default.meta | 7 + .../meta/annotations-exclude_invalid.meta | 7 + .../meta/annotations-exclude_multiple-1.meta | 9 + .../meta/annotations-exclude_multiple-2.meta | 10 + .../meta/annotations-exclude_multiple-3.meta | 11 + .../meta/annotations-exclude_multiple-4.meta | 11 + .../meta/annotations-exclude_stderr.meta | 7 + .../meta/annotations-exclude_stdout.meta | 7 + .../meta/annotations-parser_invalid.meta | 7 + .../meta/annotations-parser_json-with-time.meta | 7 + .../meta/annotations-parser_json-without-time.meta | 7 + .../meta/annotations-parser_multiple-1.meta | 12 + .../meta/annotations-parser_multiple-2.meta | 13 + .../meta/annotations-parser_regex-with-time.meta | 7 + .../annotations-parser_regex-without-time.meta | 7 + .../kubernetes/meta/annotations-parser_stderr.meta | 7 + .../kubernetes/meta/annotations-parser_stdout.meta | 7 + .../data/kubernetes/meta/annotations_invalid.meta | 12 + .../runtime/data/kubernetes/meta/core_base.meta | 116 + .../runtime/data/kubernetes/meta/core_no-meta.meta | 1 + .../data/kubernetes/meta/core_unescaping.meta | 4 + .../meta/default_kairosdb-914055854-b63vq.meta | 155 + .../meta/options_k8s-logging-exclude-disabled.meta | 7 + .../meta/options_k8s-logging-parser-disabled.meta | 7 + .../kubernetes/meta/options_keep-log-disabled.meta | 4 + .../kubernetes/meta/options_keep-log-enabled.meta | 4 + .../meta/options_merge-log-disabled.meta | 4 + .../kubernetes/meta/options_merge-log-enabled.meta | 4 + .../kubernetes/meta/options_merge-log-key.meta | 4 + .../meta/options_merge-log-trim-disabled.meta | 4 + .../meta/options_merge-log-trim-enabled.meta | 4 + .../meta/options_use-kubelet-disabled.meta | 116 + .../meta/options_use-kubelet-enabled.meta | 109 + .../annotations-exclude_invalid_text_stderr.out | 1 + .../annotations-exclude_invalid_text_stdout.out | 1 + ...tions-exclude_multiple-1_container-2_stderr.out | 1 + ...tions-exclude_multiple-1_container-3_stdout.out | 1 + ...tions-exclude_multiple-1_container-4_stderr.out | 1 + ...tions-exclude_multiple-1_container-4_stdout.out | 1 + ...tions-exclude_multiple-2_container-2_stderr.out | 1 + ...tions-exclude_multiple-2_container-3_stdout.out | 1 + ...tions-exclude_multiple-2_container-4_stderr.out | 1 + ...tions-exclude_multiple-2_container-4_stdout.out | 1 + ...tions-exclude_multiple-3_container-2_stderr.out | 1 + ...tions-exclude_multiple-3_container-3_stdout.out | 1 + ...tions-exclude_multiple-3_container-4_stderr.out | 1 + ...tions-exclude_multiple-3_container-4_stdout.out | 1 + ...tions-exclude_multiple-4_container-2_stderr.out | 1 + ...tions-exclude_multiple-4_container-3_stdout.out | 1 + ...tions-exclude_multiple-4_container-4_stderr.out | 1 + ...tions-exclude_multiple-4_container-4_stdout.out | 1 + .../annotations-exclude_stderr_text_stdout.out | 1 + .../annotations-exclude_stdout_text_stderr.out | 1 + .../annotations-parser_invalid_text_stderr.out | 1 + .../annotations-parser_invalid_text_stdout.out | 1 + ...ations-parser_json-with-time_invalid-json-1.out | 1 + .../annotations-parser_json-with-time_json.out | 1 + ...ations-parser_multiple-1_container-1_stderr.out | 1 + ...ations-parser_multiple-1_container-1_stdout.out | 1 + ...ations-parser_multiple-1_container-2_stderr.out | 1 + ...ations-parser_multiple-1_container-2_stdout.out | 1 + ...ations-parser_multiple-1_container-3_stderr.out | 1 + ...ations-parser_multiple-1_container-3_stdout.out | 1 + ...ations-parser_multiple-1_container-4_stderr.out | 1 + ...ations-parser_multiple-1_container-4_stdout.out | 1 + ...ations-parser_multiple-1_container-5_stderr.out | 1 + ...ations-parser_multiple-1_container-5_stdout.out | 1 + ...ations-parser_multiple-2_container-1_stderr.out | 1 + ...ations-parser_multiple-2_container-1_stdout.out | 1 + ...ations-parser_multiple-2_container-2_stderr.out | 1 + ...ations-parser_multiple-2_container-2_stdout.out | 1 + ...ations-parser_multiple-2_container-3_stderr.out | 1 + ...ations-parser_multiple-2_container-3_stdout.out | 1 + ...ations-parser_multiple-2_container-4_stderr.out | 1 + ...ations-parser_multiple-2_container-4_stdout.out | 1 + ...ations-parser_multiple-2_container-5_stderr.out | 1 + ...ations-parser_multiple-2_container-5_stdout.out | 1 + ...tions-parser_regex-with-time_invalid-text-1.out | 1 + .../annotations-parser_regex-with-time_text.out | 1 + .../annotations-parser_stderr_text_stderr.out | 1 + .../annotations-parser_stderr_text_stdout.out | 1 + .../annotations-parser_stdout_text_stderr.out | 1 + .../annotations-parser_stdout_text_stdout.out | 1 + .../out/annotations/annotations_invalid_text.out | 1 + .../kubernetes/out/core/core_base_fluent-bit.out | 1 + .../data/kubernetes/out/core/core_no-meta_text.out | 1 + .../kubernetes/out/core/core_unescaping_json.out | 1 + .../kubernetes/out/core/core_unescaping_text.out | 1 + .../kubernetes/out/kairosdb-914055854-b63vq.out | 1 + ...ns_k8s-logging-exclude-disabled_text_stderr.out | 1 + ...ns_k8s-logging-exclude-disabled_text_stdout.out | 1 + ...ons_k8s-logging-parser-disabled_text_stderr.out | 1 + ...ons_k8s-logging-parser-disabled_text_stdout.out | 1 + .../out/options/options_keep-log-disabled_json.out | 1 + .../out/options/options_keep-log-enabled_json.out | 1 + .../options/options_merge-log-disabled_json.out | 1 + .../options_merge-log-enabled_invalid-json.out | 1 + .../out/options/options_merge-log-enabled_json.out | 1 + .../out/options/options_merge-log-enabled_text.out | 1 + .../out/options/options_merge-log-key_json.out | 1 + .../options_merge-log-trim-disabled_json.out | 1 + .../options_merge-log-trim-enabled_json.out | 1 + .../options_use-kubelet-disabled_fluent-bit.out | 1 + .../options_use-kubelet-enabled_fluent-bit.out | 1 + .../tests/runtime/data/kubernetes/parsers.conf | 88 + .../tests/runtime/data/loki/labelmap.json | 10 + .../tests/runtime/data/podman/cgroupv2/42/net/dev | 6 + .../data/podman/cgroupv2/cgroup.controllers | 0 .../tests/runtime/data/podman/cgroupv2/config.json | 1 + .../containers/cgroup.procs | 1 + .../memory.current | 1 + .../tests/runtime/data/podman/garbage/42/net/dev | 1 + .../tests/runtime/data/podman/garbage/config.json | 1 + .../memory.current | 1 + .../memory.usage_in_bytes | 1 + .../runtime/data/podman/garbage_config/config.json | 1 + .../memory.current | 1 + .../memory.usage_in_bytes | 1 + .../memory.usage_in_bytes | 1 + .../tests/runtime/data/podman/no_proc/config.json | 1 + .../memory.current | 1 + .../memory.usage_in_bytes | 1 + .../tests/runtime/data/podman/no_sysfs/42/net/dev | 6 + .../tests/runtime/data/podman/no_sysfs/config.json | 1 + .../tests/runtime/data/podman/regular/42/net/dev | 6 + .../tests/runtime/data/podman/regular/config.json | 1 + .../memory.current | 1 + .../memory.usage_in_bytes | 1 + .../cgroup.procs | 3 + .../tests/runtime/data/podman/reversed/42/net/dev | 6 + .../tests/runtime/data/podman/reversed/config.json | 1 + .../memory.current | 1 + .../memory.usage_in_bytes | 1 + .../cgroup.procs | 3 + .../tests/runtime/data/stackdriver/json.h | 12 + .../data/stackdriver/stackdriver-credentials.json | 12 + .../stackdriver_multi_entries_severity.log | 4 + .../stackdriver/stackdriver_test_http_request.h | 134 + .../data/stackdriver/stackdriver_test_insert_id.h | 26 + .../stackdriver/stackdriver_test_k8s_resource.h | 89 + .../data/stackdriver/stackdriver_test_labels.h | 44 + .../data/stackdriver/stackdriver_test_log_name.h | 10 + .../stackdriver_test_monitored_resource.h | 46 + .../data/stackdriver/stackdriver_test_operation.h | 62 + .../stackdriver/stackdriver_test_resource_labels.h | 37 + .../stackdriver/stackdriver_test_source_location.h | 70 + .../data/stackdriver/stackdriver_test_span_id.h | 6 + .../data/stackdriver/stackdriver_test_timestamp.h | 62 + .../data/stackdriver/stackdriver_test_trace.h | 6 + .../stackdriver/stackdriver_test_trace_sampled.h | 11 + .../tests/runtime/data/tail/log/3943.log | 2 + .../tests/runtime/data/tail/log/dockermode.log | 3 + .../tail/log/dockermode_firstline_detection.log | 9 + .../data/tail/log/dockermode_multiple_lines.log | 6 + .../data/tail/log/dockermode_splitted_line.log | 6 + .../log/dockermode_splitted_multiple_lines.log | 8 + .../tests/runtime/data/tail/log/multiline_001.log | 6 + .../tests/runtime/data/tail/out/3943.out | 2 + .../tests/runtime/data/tail/out/dockermode.out | 3 + .../tail/out/dockermode_firstline_detection.out | 5 + .../data/tail/out/dockermode_multiple_lines.out | 2 + .../data/tail/out/dockermode_splitted_line.out | 2 + .../out/dockermode_splitted_multiple_lines.out | 2 + .../tests/runtime/data/tail/out/multiline_001.out | 1 + .../runtime/data/tail/out/skip_long_lines.out | 2 + .../tests/runtime/data/tail/parsers.conf | 10 + .../runtime/data/tail/parsers_multiline_json.conf | 24 + src/fluent-bit/tests/runtime/data/td/json_td.h | 506 ++ .../tests/runtime/data/tls/certificate.pem | 22 + .../tests/runtime/data/tls/private_key.pem | 28 + .../tests/runtime/data/wasm/append_tag.wasm | Bin 0 -> 512323 bytes .../tests/runtime/data/wasm/drop_record.wasm | Bin 0 -> 36610 bytes .../tests/runtime/data/wasm/modify_record.wasm | Bin 0 -> 512134 bytes .../tests/runtime/data/wasm/numeric_records.wasm | Bin 0 -> 517441 bytes .../tests/runtime/data/wasm/say_hello.wasm | Bin 0 -> 390348 bytes src/fluent-bit/tests/runtime/filter_aws.c | 846 +++ src/fluent-bit/tests/runtime/filter_checklist.c | 405 ++ src/fluent-bit/tests/runtime/filter_ecs.c | 445 ++ src/fluent-bit/tests/runtime/filter_expect.c | 555 ++ src/fluent-bit/tests/runtime/filter_grep.c | 840 +++ src/fluent-bit/tests/runtime/filter_kubernetes.c | 1086 ++++ src/fluent-bit/tests/runtime/filter_kubernetes.md | 69 + .../tests/runtime/filter_log_to_metrics.c | 698 +++ src/fluent-bit/tests/runtime/filter_lua.c | 984 +++ src/fluent-bit/tests/runtime/filter_modify.c | 1674 ++++++ src/fluent-bit/tests/runtime/filter_multiline.c | 699 +++ src/fluent-bit/tests/runtime/filter_nest.c | 302 + src/fluent-bit/tests/runtime/filter_parser.c | 833 +++ .../tests/runtime/filter_record_modifier.c | 595 ++ src/fluent-bit/tests/runtime/filter_rewrite_tag.c | 564 ++ src/fluent-bit/tests/runtime/filter_stdout.c | 84 + src/fluent-bit/tests/runtime/filter_throttle.c | 105 + .../tests/runtime/filter_throttle_size.c | 608 ++ .../tests/runtime/filter_type_converter.c | 389 ++ src/fluent-bit/tests/runtime/filter_wasm.c | 468 ++ .../tests/runtime/flb_tests_runtime.h.in | 52 + src/fluent-bit/tests/runtime/gen_data.py | 63 + src/fluent-bit/tests/runtime/http_callbacks.c | 58 + src/fluent-bit/tests/runtime/in_cpu.c | 1 + src/fluent-bit/tests/runtime/in_disk.c | 1 + src/fluent-bit/tests/runtime/in_dummy.c | 1 + src/fluent-bit/tests/runtime/in_elasticsearch.c | 899 +++ src/fluent-bit/tests/runtime/in_event_test.c | 35 + .../tests/runtime/in_fluentbit_metrics.c | 226 + src/fluent-bit/tests/runtime/in_forward.c | 579 ++ src/fluent-bit/tests/runtime/in_head.c | 1 + src/fluent-bit/tests/runtime/in_http.c | 444 ++ src/fluent-bit/tests/runtime/in_mem.c | 1 + src/fluent-bit/tests/runtime/in_mqtt.c | 396 ++ src/fluent-bit/tests/runtime/in_netif.c | 350 ++ src/fluent-bit/tests/runtime/in_opentelemetry.c | 376 ++ src/fluent-bit/tests/runtime/in_podman_metrics.c | 222 + src/fluent-bit/tests/runtime/in_proc.c | 1 + src/fluent-bit/tests/runtime/in_random.c | 1 + src/fluent-bit/tests/runtime/in_simple_systems.c | 576 ++ src/fluent-bit/tests/runtime/in_splunk.c | 824 +++ src/fluent-bit/tests/runtime/in_statsd.c | 324 + src/fluent-bit/tests/runtime/in_syslog.c | 1023 ++++ src/fluent-bit/tests/runtime/in_tail.c | 1583 +++++ src/fluent-bit/tests/runtime/in_tcp.c | 561 ++ src/fluent-bit/tests/runtime/in_udp.c | 440 ++ src/fluent-bit/tests/runtime/out_cloudwatch.c | 362 ++ src/fluent-bit/tests/runtime/out_counter.c | 126 + src/fluent-bit/tests/runtime/out_datadog.c | 173 + src/fluent-bit/tests/runtime/out_elasticsearch.c | 818 +++ src/fluent-bit/tests/runtime/out_exit.c | 210 + src/fluent-bit/tests/runtime/out_file.c | 824 +++ src/fluent-bit/tests/runtime/out_firehose.c | 200 + src/fluent-bit/tests/runtime/out_flowcounter.c | 317 + src/fluent-bit/tests/runtime/out_forward.c | 364 ++ src/fluent-bit/tests/runtime/out_http.c | 1060 ++++ src/fluent-bit/tests/runtime/out_kinesis.c | 200 + src/fluent-bit/tests/runtime/out_lib.c | 587 ++ src/fluent-bit/tests/runtime/out_loki.c | 623 ++ src/fluent-bit/tests/runtime/out_null.c | 127 + src/fluent-bit/tests/runtime/out_opensearch.c | 1077 ++++ src/fluent-bit/tests/runtime/out_plot.c | 157 + src/fluent-bit/tests/runtime/out_retry.c | 88 + src/fluent-bit/tests/runtime/out_s3.c | 241 + src/fluent-bit/tests/runtime/out_skywalking.c | 55 + src/fluent-bit/tests/runtime/out_splunk.c | 150 + src/fluent-bit/tests/runtime/out_stackdriver.c | 6252 ++++++++++++++++++++ src/fluent-bit/tests/runtime/out_stdout.c | 138 + src/fluent-bit/tests/runtime/out_syslog.c | 1644 +++++ src/fluent-bit/tests/runtime/out_tcp.c | 1004 ++++ src/fluent-bit/tests/runtime/out_td.c | 45 + src/fluent-bit/tests/runtime/wasm/go/Makefile | 24 + src/fluent-bit/tests/runtime/wasm/go/append_tag.go | 39 + .../tests/runtime/wasm/go/drop_record.go | 8 + src/fluent-bit/tests/runtime/wasm/go/go.mod | 9 + src/fluent-bit/tests/runtime/wasm/go/go.sum | 10 + .../tests/runtime/wasm/go/modify_record.go | 39 + .../tests/runtime/wasm/go/numeric_records.go | 44 + src/fluent-bit/tests/runtime/wasm/go/say_hello.go | 14 + src/fluent-bit/tests/runtime_shell/.gitignore | 2 + src/fluent-bit/tests/runtime_shell/CMakeLists.txt | 29 + src/fluent-bit/tests/runtime_shell/common.sh | 26 + .../tests/runtime_shell/conf/in_dummy_expect.conf | 25 + .../tests/runtime_shell/conf/in_expect_base.conf | 28 + .../runtime_shell/conf/in_http_tls_expect.conf | 13 + .../conf/in_syslog_tcp_plaintext_expect.conf | 8 + .../conf/in_syslog_tcp_tls_expect.conf | 14 + .../conf/in_syslog_udp_plaintext_expect.conf | 8 + .../conf/in_syslog_uds_dgram_plaintext_expect.conf | 7 + .../in_syslog_uds_stream_plaintext_expect.conf | 7 + .../tests/runtime_shell/conf/in_tail_expect.conf | 38 + .../tests/runtime_shell/in_dummy_expect.sh | 8 + .../tests/runtime_shell/in_http_tls_expect.sh | 29 + .../in_syslog_tcp_plaintext_expect.sh | 26 + .../runtime_shell/in_syslog_tcp_tls_expect.sh | 27 + .../in_syslog_udp_plaintext_expect.sh | 26 + .../in_syslog_uds_dgram_plaintext_expect.sh | 29 + .../in_syslog_uds_stream_plaintext_expect.sh | 24 + .../tests/runtime_shell/in_tail/README.md | 126 + .../in_tail/conf/multiline_rotation.conf | 60 + .../in_tail/conf/normal_rotation.conf | 55 + .../runtime_shell/in_tail/conf/rotate_link.conf | 20 + .../in_tail/conf/single_static_rotation.conf | 19 + .../runtime_shell/in_tail/conf/truncate_link.conf | 19 + .../in_tail/conf/truncate_rotation.conf | 19 + .../tests/runtime_shell/in_tail/logger_file.py | 72 + .../tests/runtime_shell/in_tail/run_tests.sh | 530 ++ .../tests/runtime_shell/in_tail/test_rotation.sh | 542 ++ .../tests/runtime_shell/in_tail_expect.sh | 16 + .../tests/runtime_shell/runtime_shell.env.in | 5 + .../tests/runtime_shell/tls/certificate.pem | 22 + .../tests/runtime_shell/tls/private_key.pem | 28 + 754 files changed, 82725 insertions(+) create mode 100644 src/fluent-bit/tests/include/aws_client_mock.c create mode 100644 src/fluent-bit/tests/include/aws_client_mock.h create mode 100644 src/fluent-bit/tests/include/aws_client_mock_client_resp.def create mode 100644 src/fluent-bit/tests/include/flb_tests_initialize_tls.h create mode 100644 src/fluent-bit/tests/internal/CMakeLists.txt create mode 100644 src/fluent-bit/tests/internal/README.md create mode 100644 src/fluent-bit/tests/internal/avro.c create mode 100644 src/fluent-bit/tests/internal/aws/CMakeLists.txt create mode 100644 src/fluent-bit/tests/internal/aws/placeholder.c create mode 100644 src/fluent-bit/tests/internal/aws_compress.c create mode 100644 src/fluent-bit/tests/internal/aws_credentials.c create mode 100644 src/fluent-bit/tests/internal/aws_credentials_ec2.c create mode 100644 src/fluent-bit/tests/internal/aws_credentials_http.c create mode 100644 src/fluent-bit/tests/internal/aws_credentials_process.c create mode 100644 src/fluent-bit/tests/internal/aws_credentials_profile.c create mode 100644 src/fluent-bit/tests/internal/aws_credentials_sts.c create mode 100644 src/fluent-bit/tests/internal/aws_credentials_test_internal.h create mode 100644 src/fluent-bit/tests/internal/aws_util.c create mode 100644 src/fluent-bit/tests/internal/base64.c create mode 100644 src/fluent-bit/tests/internal/bucket_queue.c create mode 100644 src/fluent-bit/tests/internal/config_format.c create mode 100644 src/fluent-bit/tests/internal/config_format_fluentbit.c create mode 100644 src/fluent-bit/tests/internal/config_format_yaml.c create mode 100644 src/fluent-bit/tests/internal/config_map.c create mode 100644 src/fluent-bit/tests/internal/crypto.c create mode 100644 src/fluent-bit/tests/internal/csv.c create mode 100644 src/fluent-bit/tests/internal/data/avro/json_single_map_001.json create mode 100644 src/fluent-bit/tests/internal/data/avro/live-sample.json create mode 100644 src/fluent-bit/tests/internal/data/avro/multiline.json create mode 100755 src/fluent-bit/tests/internal/data/aws_credentials/credential_process/aws-credential-process create mode 100644 src/fluent-bit/tests/internal/data/aws_credentials/shared_config.ini create mode 100644 src/fluent-bit/tests/internal/data/aws_credentials/shared_credentials_file.ini create mode 100644 src/fluent-bit/tests/internal/data/aws_credentials/shared_credentials_file_nodefault.ini create mode 100644 src/fluent-bit/tests/internal/data/aws_credentials/web_identity_token_file.txt create mode 100644 src/fluent-bit/tests/internal/data/config_format/classic/fluent-bit.conf create mode 100644 src/fluent-bit/tests/internal/data/config_format/classic/indent_level_error.conf create mode 100644 src/fluent-bit/tests/internal/data/config_format/classic/issue6281.conf create mode 100644 src/fluent-bit/tests/internal/data/config_format/classic/issue6281_input.conf create mode 100644 src/fluent-bit/tests/internal/data/config_format/classic/issue6281_output.conf create mode 100644 src/fluent-bit/tests/internal/data/config_format/classic/issue_5880.conf create mode 100644 src/fluent-bit/tests/internal/data/config_format/classic/nolimitline.conf create mode 100644 src/fluent-bit/tests/internal/data/config_format/classic/recursion.conf create mode 100644 src/fluent-bit/tests/internal/data/config_format/classic/service.conf create mode 100644 src/fluent-bit/tests/internal/data/config_format/yaml/fluent-bit.yaml create mode 100644 src/fluent-bit/tests/internal/data/config_format/yaml/issue_7559.yaml create mode 100644 src/fluent-bit/tests/internal/data/config_format/yaml/parsers/parsers-conf.yaml create mode 100644 src/fluent-bit/tests/internal/data/config_format/yaml/parsers/parsers.conf create mode 100644 src/fluent-bit/tests/internal/data/config_format/yaml/pipelines/slist/even.yaml create mode 100644 src/fluent-bit/tests/internal/data/config_format/yaml/pipelines/slist/odd.yaml create mode 100644 src/fluent-bit/tests/internal/data/config_format/yaml/service.yaml create mode 100644 src/fluent-bit/tests/internal/data/config_format/yaml/test.yaml create mode 100644 src/fluent-bit/tests/internal/data/config_format/yaml/test/dummy_pipeline.yaml create mode 100644 src/fluent-bit/tests/internal/data/config_format/yaml/test/nested.yaml create mode 100644 src/fluent-bit/tests/internal/data/file/empty_file.txt create mode 100644 src/fluent-bit/tests/internal/data/file/text_file.txt create mode 100644 src/fluent-bit/tests/internal/data/input_chunk/log/a_thousand_plus_one_bytes.log create mode 100644 src/fluent-bit/tests/internal/data/input_chunk/log/test_buffer_drop_chunks.h create mode 100644 src/fluent-bit/tests/internal/data/input_chunk/log/test_buffer_valid.log create mode 100644 src/fluent-bit/tests/internal/data/input_chunk/out/a_thousand_plus_one_bytes.out create mode 100644 src/fluent-bit/tests/internal/data/input_chunk/out/test_buffer_valid.out create mode 100644 src/fluent-bit/tests/internal/data/input_chunk/parser.conf create mode 100644 src/fluent-bit/tests/internal/data/mp/apache_10k.mp create mode 100644 src/fluent-bit/tests/internal/data/pack/README.md create mode 100644 src/fluent-bit/tests/internal/data/pack/bug342.json create mode 100644 src/fluent-bit/tests/internal/data/pack/dup_keys_in.json create mode 100644 src/fluent-bit/tests/internal/data/pack/dup_keys_out.json create mode 100644 src/fluent-bit/tests/internal/data/pack/json_single_map_001.json create mode 100644 src/fluent-bit/tests/internal/data/pack/json_single_map_002.json create mode 100644 src/fluent-bit/tests/internal/data/pack/mixed.py create mode 100644 src/fluent-bit/tests/internal/data/pack/mixed_001.json create mode 100644 src/fluent-bit/tests/internal/data/pack/mixed_001.mp create mode 100644 src/fluent-bit/tests/internal/data/pack/mixed_001.txt create mode 100644 src/fluent-bit/tests/internal/data/pack/mixed_002.json create mode 100644 src/fluent-bit/tests/internal/data/pack/mixed_002.mp create mode 100644 src/fluent-bit/tests/internal/data/pack/mixed_002.txt create mode 100644 src/fluent-bit/tests/internal/data/pack/mixed_003.json create mode 100644 src/fluent-bit/tests/internal/data/pack/mixed_003.mp create mode 100644 src/fluent-bit/tests/internal/data/pack/mixed_003.txt create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_bell.json create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_bell.mp create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_bell.txt create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_copyright.json create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_copyright.mp create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_copyright.txt create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_gen.py create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_hokke.json create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_hokke.mp create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_hokke.txt create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_relaxed.json create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_relaxed.mp create mode 100644 src/fluent-bit/tests/internal/data/pack/utf8_relaxed.txt create mode 100644 src/fluent-bit/tests/internal/data/parser/json.conf create mode 100644 src/fluent-bit/tests/internal/data/parser/regex.conf create mode 100644 src/fluent-bit/tests/internal/data/reload/fluent-bit.conf create mode 100644 src/fluent-bit/tests/internal/data/reload/yaml/processor.yaml create mode 100644 src/fluent-bit/tests/internal/data/s3_local_buffer/.gitkeep create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/LICENSE create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/NOTICE create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-key-duplicate/get-header-key-duplicate.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-key-duplicate/get-header-key-duplicate.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-key-duplicate/get-header-key-duplicate.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-key-duplicate/get-header-key-duplicate.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-key-duplicate/get-header-key-duplicate.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-multiline/get-header-value-multiline.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-multiline/get-header-value-multiline.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-multiline/get-header-value-multiline.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-multiline/get-header-value-multiline.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-multiline/get-header-value-multiline.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-order/get-header-value-order.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-order/get-header-value-order.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-order/get-header-value-order.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-order/get-header-value-order.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-order/get-header-value-order.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-trim/get-header-value-trim.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-trim/get-header-value-trim.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-trim/get-header-value-trim.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-trim/get-header-value-trim.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-header-value-trim/get-header-value-trim.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-unreserved/get-unreserved.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-unreserved/get-unreserved.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-unreserved/get-unreserved.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-unreserved/get-unreserved.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-unreserved/get-unreserved.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-utf8/get-utf8.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-utf8/get-utf8.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-utf8/get-utf8.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-utf8/get-utf8.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-utf8/get-utf8.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-empty-query-key/get-vanilla-empty-query-key.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-empty-query-key/get-vanilla-empty-query-key.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-empty-query-key/get-vanilla-empty-query-key.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-empty-query-key/get-vanilla-empty-query-key.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-empty-query-key/get-vanilla-empty-query-key.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-key-case/get-vanilla-query-order-key-case.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-key-case/get-vanilla-query-order-key-case.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-key-case/get-vanilla-query-order-key-case.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-key-case/get-vanilla-query-order-key-case.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-key-case/get-vanilla-query-order-key-case.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-key/get-vanilla-query-order-key.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-key/get-vanilla-query-order-key.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-key/get-vanilla-query-order-key.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-key/get-vanilla-query-order-key.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-key/get-vanilla-query-order-key.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-value/get-vanilla-query-order-value.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-value/get-vanilla-query-order-value.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-value/get-vanilla-query-order-value.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-value/get-vanilla-query-order-value.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-order-value/get-vanilla-query-order-value.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-unreserved/get-vanilla-query-unreserved.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-unreserved/get-vanilla-query-unreserved.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-unreserved/get-vanilla-query-unreserved.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-unreserved/get-vanilla-query-unreserved.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query-unreserved/get-vanilla-query-unreserved.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query/get-vanilla-query.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query/get-vanilla-query.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query/get-vanilla-query.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query/get-vanilla-query.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-query/get-vanilla-query.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-utf8-query/get-vanilla-utf8-query.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-utf8-query/get-vanilla-utf8-query.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-utf8-query/get-vanilla-utf8-query.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-utf8-query/get-vanilla-utf8-query.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla-utf8-query/get-vanilla-utf8-query.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla/get-vanilla.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla/get-vanilla.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla/get-vanilla.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla/get-vanilla.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/get-vanilla/get-vanilla.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-relative-relative/get-relative-relative.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-relative-relative/get-relative-relative.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-relative-relative/get-relative-relative.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-relative-relative/get-relative-relative.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-relative-relative/get-relative-relative.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-relative/get-relative.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-relative/get-relative.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-relative/get-relative.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-relative/get-relative.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-relative/get-relative.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash-dot-slash/get-slash-dot-slash.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash-dot-slash/get-slash-dot-slash.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash-dot-slash/get-slash-dot-slash.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash-dot-slash/get-slash-dot-slash.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash-dot-slash/get-slash-dot-slash.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash-pointless-dot/get-slash-pointless-dot.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash-pointless-dot/get-slash-pointless-dot.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash-pointless-dot/get-slash-pointless-dot.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash-pointless-dot/get-slash-pointless-dot.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash-pointless-dot/get-slash-pointless-dot.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash/get-slash.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash/get-slash.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash/get-slash.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash/get-slash.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slash/get-slash.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slashes/get-slashes.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slashes/get-slashes.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slashes/get-slashes.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slashes/get-slashes.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-slashes/get-slashes.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-space/get-space.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-space/get-space.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-space/get-space.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-space/get-space.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/get-space/get-space.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/normalize-path/normalize-path.txt create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-key-case/post-header-key-case.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-key-case/post-header-key-case.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-key-case/post-header-key-case.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-key-case/post-header-key-case.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-key-case/post-header-key-case.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-key-sort/post-header-key-sort.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-key-sort/post-header-key-sort.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-key-sort/post-header-key-sort.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-key-sort/post-header-key-sort.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-key-sort/post-header-key-sort.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-value-case/post-header-value-case.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-value-case/post-header-value-case.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-value-case/post-header-value-case.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-value-case/post-header-value-case.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-header-value-case/post-header-value-case.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-sts-token/post-sts-header-after/post-sts-header-after.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-sts-token/post-sts-header-after/post-sts-header-after.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-sts-token/post-sts-header-after/post-sts-header-after.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-sts-token/post-sts-header-after/post-sts-header-after.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-sts-token/post-sts-header-after/post-sts-header-after.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-sts-token/post-sts-header-before/post-sts-header-before.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-sts-token/post-sts-header-before/post-sts-header-before.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-sts-token/post-sts-header-before/post-sts-header-before.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-sts-token/post-sts-header-before/post-sts-header-before.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-sts-token/post-sts-header-before/post-sts-header-before.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-sts-token/readme.txt create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla-empty-query-value/post-vanilla-empty-query-value.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla-empty-query-value/post-vanilla-empty-query-value.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla-empty-query-value/post-vanilla-empty-query-value.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla-empty-query-value/post-vanilla-empty-query-value.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla-empty-query-value/post-vanilla-empty-query-value.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla-query/post-vanilla-query.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla-query/post-vanilla-query.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla-query/post-vanilla-query.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla-query/post-vanilla-query.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla-query/post-vanilla-query.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla/post-vanilla.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla/post-vanilla.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla/post-vanilla.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla/post-vanilla.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-vanilla/post-vanilla.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-x-www-form-urlencoded-parameters/post-x-www-form-urlencoded-parameters.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-x-www-form-urlencoded-parameters/post-x-www-form-urlencoded-parameters.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-x-www-form-urlencoded-parameters/post-x-www-form-urlencoded-parameters.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-x-www-form-urlencoded-parameters/post-x-www-form-urlencoded-parameters.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-x-www-form-urlencoded-parameters/post-x-www-form-urlencoded-parameters.sts create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-x-www-form-urlencoded/post-x-www-form-urlencoded.authz create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-x-www-form-urlencoded/post-x-www-form-urlencoded.creq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-x-www-form-urlencoded/post-x-www-form-urlencoded.req create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-x-www-form-urlencoded/post-x-www-form-urlencoded.sreq create mode 100644 src/fluent-bit/tests/internal/data/signv4/aws-sig-v4-test-suite/post-x-www-form-urlencoded/post-x-www-form-urlencoded.sts create mode 100755 src/fluent-bit/tests/internal/data/stream_processor/gen_msgpack.sh create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/1.json create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/1.mp create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/2.json create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/2.mp create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/3.json create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/3.mp create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/4.json create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/4.mp create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/5.json create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/5.mp create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/6.json create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/6.mp create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/7.json create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-hw/7.mp create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-subkeys.json create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples-subkeys.mp create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples.json create mode 100644 src/fluent-bit/tests/internal/data/stream_processor/samples.mp create mode 100644 src/fluent-bit/tests/internal/data/tls/certificate.pem create mode 100644 src/fluent-bit/tests/internal/data/tls/private_key.pem create mode 100644 src/fluent-bit/tests/internal/env.c create mode 100644 src/fluent-bit/tests/internal/error_reporter.c create mode 100644 src/fluent-bit/tests/internal/file.c create mode 100644 src/fluent-bit/tests/internal/flb_event_loop.c create mode 100644 src/fluent-bit/tests/internal/flb_tests_internal.h.in create mode 100644 src/fluent-bit/tests/internal/flb_time.c create mode 100644 src/fluent-bit/tests/internal/fstore.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/CMakeLists.txt create mode 100644 src/fluent-bit/tests/internal/fuzzers/aws_credentials_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/aws_util_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/base64_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/cmetrics_decode_fuzz.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/config_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/config_map_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/config_random_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/config_yaml_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/ctrace_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/engine_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/filter_stdout_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/flb_fuzz_header.h create mode 100644 src/fluent-bit/tests/internal/fuzzers/flb_json_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/flb_mp_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/fstore_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/http_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/input_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/local_test.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/msgpack_parse_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/msgpack_to_gelf_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/multiline_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/pack_json_state_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/parse_json_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/parse_logfmt_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/parse_ltsv_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/parser_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/record_ac_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/signv4_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/strp_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/fuzzers/utils_fuzzer.c create mode 100644 src/fluent-bit/tests/internal/gelf.c create mode 100644 src/fluent-bit/tests/internal/gzip.c create mode 100644 src/fluent-bit/tests/internal/hash.c create mode 100644 src/fluent-bit/tests/internal/hashtable.c create mode 100644 src/fluent-bit/tests/internal/hmac.c create mode 100644 src/fluent-bit/tests/internal/http_client.c create mode 100644 src/fluent-bit/tests/internal/include/sp_cb_functions.h create mode 100644 src/fluent-bit/tests/internal/include/sp_helpers.h create mode 100644 src/fluent-bit/tests/internal/include/sp_invalid_queries.h create mode 100644 src/fluent-bit/tests/internal/include/sp_select_keys.h create mode 100644 src/fluent-bit/tests/internal/include/sp_select_subkeys.h create mode 100644 src/fluent-bit/tests/internal/include/sp_snapshot.h create mode 100644 src/fluent-bit/tests/internal/include/sp_window.h create mode 100644 src/fluent-bit/tests/internal/input_chunk.c create mode 100644 src/fluent-bit/tests/internal/log.c create mode 100644 src/fluent-bit/tests/internal/log_event_decoder.c create mode 100644 src/fluent-bit/tests/internal/lua.c create mode 100644 src/fluent-bit/tests/internal/metrics.c create mode 100644 src/fluent-bit/tests/internal/mp.c create mode 100644 src/fluent-bit/tests/internal/multiline.c create mode 100644 src/fluent-bit/tests/internal/network.c create mode 100644 src/fluent-bit/tests/internal/pack.c create mode 100644 src/fluent-bit/tests/internal/parser.c create mode 100644 src/fluent-bit/tests/internal/parser_json.c create mode 100644 src/fluent-bit/tests/internal/parser_logfmt.c create mode 100644 src/fluent-bit/tests/internal/parser_ltsv.c create mode 100644 src/fluent-bit/tests/internal/parser_regex.c create mode 100644 src/fluent-bit/tests/internal/pipe.c create mode 100644 src/fluent-bit/tests/internal/processor.c create mode 100644 src/fluent-bit/tests/internal/random.c create mode 100644 src/fluent-bit/tests/internal/record_accessor.c create mode 100644 src/fluent-bit/tests/internal/regex.c create mode 100644 src/fluent-bit/tests/internal/reload.c create mode 100644 src/fluent-bit/tests/internal/ring_buffer.c create mode 100644 src/fluent-bit/tests/internal/router.c create mode 100644 src/fluent-bit/tests/internal/sds.c create mode 100644 src/fluent-bit/tests/internal/sds_list.c create mode 100644 src/fluent-bit/tests/internal/signv4.c create mode 100644 src/fluent-bit/tests/internal/slist.c create mode 100644 src/fluent-bit/tests/internal/stream_processor.c create mode 100644 src/fluent-bit/tests/internal/typecast.c create mode 100644 src/fluent-bit/tests/internal/unit_sizes.c create mode 100644 src/fluent-bit/tests/internal/uri.c create mode 100644 src/fluent-bit/tests/internal/utils.c create mode 100644 src/fluent-bit/tests/lib/acutest/README.md create mode 100644 src/fluent-bit/tests/lib/acutest/acutest.h create mode 100644 src/fluent-bit/tests/lib/shunit2/.gitignore create mode 100644 src/fluent-bit/tests/lib/shunit2/.travis.yml create mode 100644 src/fluent-bit/tests/lib/shunit2/CODE_OF_CONDUCT.md create mode 100644 src/fluent-bit/tests/lib/shunit2/LICENSE create mode 100644 src/fluent-bit/tests/lib/shunit2/README.md create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/CHANGES-2.1.md create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/RELEASE_NOTES-2.1.0.txt create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/RELEASE_NOTES-2.1.1.txt create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/RELEASE_NOTES-2.1.2.txt create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/RELEASE_NOTES-2.1.3.txt create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/RELEASE_NOTES-2.1.4.txt create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/RELEASE_NOTES-2.1.5.txt create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/RELEASE_NOTES-2.1.6.txt create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/RELEASE_NOTES-2.1.7.md create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/RELEASE_NOTES-2.1.8.md create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/TODO.txt create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/contributors.md create mode 100644 src/fluent-bit/tests/lib/shunit2/doc/design_doc.txt create mode 100755 src/fluent-bit/tests/lib/shunit2/examples/equality_test.sh create mode 100755 src/fluent-bit/tests/lib/shunit2/examples/lineno_test.sh create mode 100644 src/fluent-bit/tests/lib/shunit2/examples/math.inc create mode 100755 src/fluent-bit/tests/lib/shunit2/examples/math_test.sh create mode 100755 src/fluent-bit/tests/lib/shunit2/examples/mkdir_test.sh create mode 100755 src/fluent-bit/tests/lib/shunit2/examples/mock_file.sh create mode 100755 src/fluent-bit/tests/lib/shunit2/examples/mock_file_test.sh create mode 100755 src/fluent-bit/tests/lib/shunit2/examples/party_test.sh create mode 100755 src/fluent-bit/tests/lib/shunit2/examples/suite_test.sh create mode 100644 src/fluent-bit/tests/lib/shunit2/lib/shflags create mode 100755 src/fluent-bit/tests/lib/shunit2/lib/versions create mode 100755 src/fluent-bit/tests/lib/shunit2/shunit2 create mode 100755 src/fluent-bit/tests/lib/shunit2/shunit2_args_test.sh create mode 100755 src/fluent-bit/tests/lib/shunit2/shunit2_asserts_test.sh create mode 100755 src/fluent-bit/tests/lib/shunit2/shunit2_failures_test.sh create mode 100755 src/fluent-bit/tests/lib/shunit2/shunit2_macros_test.sh create mode 100755 src/fluent-bit/tests/lib/shunit2/shunit2_misc_test.sh create mode 100755 src/fluent-bit/tests/lib/shunit2/shunit2_standalone_test.sh create mode 100644 src/fluent-bit/tests/lib/shunit2/shunit2_test_helpers create mode 100755 src/fluent-bit/tests/lib/shunit2/test_runner create mode 100644 src/fluent-bit/tests/runtime/CMakeLists.txt create mode 100644 src/fluent-bit/tests/runtime/config_map_opts.c create mode 100644 src/fluent-bit/tests/runtime/core-timeout.c create mode 100644 src/fluent-bit/tests/runtime/core_chunk_trace.c create mode 100644 src/fluent-bit/tests/runtime/core_engine.c create mode 100644 src/fluent-bit/tests/runtime/core_log.c create mode 100644 src/fluent-bit/tests/runtime/custom_calyptia_test.c create mode 100755 src/fluent-bit/tests/runtime/data/common/json_invalid.h create mode 100755 src/fluent-bit/tests/runtime/data/common/json_long.h create mode 100755 src/fluent-bit/tests/runtime/data/common/json_small.h create mode 120000 src/fluent-bit/tests/runtime/data/common/parsers.conf create mode 100644 src/fluent-bit/tests/runtime/data/datadog/json.h create mode 100755 src/fluent-bit/tests/runtime/data/es/json_es.h create mode 100644 src/fluent-bit/tests/runtime/data/in_elasticsearch/json_bulk.h create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_default_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_invalid_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-1_container-1.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-1_container-2.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-1_container-3.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-1_container-4.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-2_container-1.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-2_container-2.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-2_container-3.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-2_container-4.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-3_container-1.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-3_container-2.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-3_container-3.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-3_container-4.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-4_container-1.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-4_container-2.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-4_container-3.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_multiple-4_container-4.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_stderr_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-exclude/annotations-exclude_stdout_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_invalid_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_json-with-time_invalid-json-1.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_json-with-time_json.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_multiple-1_container-1.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_multiple-1_container-2.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_multiple-1_container-3.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_multiple-1_container-4.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_multiple-1_container-5.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_multiple-2_container-1.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_multiple-2_container-2.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_multiple-2_container-3.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_multiple-2_container-4.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_multiple-2_container-5.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_regex-with-time_invalid-text-1.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_regex-with-time_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_stderr_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations-parser/annotations-parser_stdout_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/annotations/annotations_invalid_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/core/core_base_fluent-bit.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/core/core_no-meta_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/core/core_unescaping_json.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/core/core_unescaping_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_k8s-logging-exclude-disabled_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_k8s-logging-parser-disabled_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_keep-log-disabled_json.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_keep-log-enabled_json.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_merge-log-disabled_json.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_merge-log-enabled_invalid-json.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_merge-log-enabled_json.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_merge-log-enabled_text.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_merge-log-key_json.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_merge-log-trim-disabled_json.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_merge-log-trim-enabled_json.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_use-kubelet-disabled_fluent-bit.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/log/options/options_use-kubelet-enabled_fluent-bit.log create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-exclude_default.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-exclude_invalid.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-exclude_multiple-1.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-exclude_multiple-2.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-exclude_multiple-3.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-exclude_multiple-4.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-exclude_stderr.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-exclude_stdout.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-parser_invalid.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-parser_json-with-time.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-parser_json-without-time.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-parser_multiple-1.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-parser_multiple-2.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-parser_regex-with-time.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-parser_regex-without-time.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-parser_stderr.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations-parser_stdout.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/annotations_invalid.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/core_base.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/core_no-meta.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/core_unescaping.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/default_kairosdb-914055854-b63vq.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/options_k8s-logging-exclude-disabled.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/options_k8s-logging-parser-disabled.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/options_keep-log-disabled.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/options_keep-log-enabled.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/options_merge-log-disabled.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/options_merge-log-enabled.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/options_merge-log-key.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/options_merge-log-trim-disabled.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/options_merge-log-trim-enabled.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/options_use-kubelet-disabled.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/meta/options_use-kubelet-enabled.meta create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_invalid_text_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_invalid_text_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-1_container-2_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-1_container-3_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-1_container-4_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-1_container-4_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-2_container-2_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-2_container-3_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-2_container-4_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-2_container-4_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-3_container-2_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-3_container-3_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-3_container-4_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-3_container-4_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-4_container-2_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-4_container-3_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-4_container-4_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_multiple-4_container-4_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_stderr_text_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-exclude/annotations-exclude_stdout_text_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_invalid_text_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_invalid_text_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_json-with-time_invalid-json-1.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_json-with-time_json.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-1_container-1_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-1_container-1_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-1_container-2_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-1_container-2_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-1_container-3_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-1_container-3_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-1_container-4_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-1_container-4_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-1_container-5_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-1_container-5_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-2_container-1_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-2_container-1_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-2_container-2_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-2_container-2_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-2_container-3_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-2_container-3_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-2_container-4_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-2_container-4_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-2_container-5_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_multiple-2_container-5_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_regex-with-time_invalid-text-1.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_regex-with-time_text.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_stderr_text_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_stderr_text_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_stdout_text_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations-parser/annotations-parser_stdout_text_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/annotations/annotations_invalid_text.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/core/core_base_fluent-bit.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/core/core_no-meta_text.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/core/core_unescaping_json.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/core/core_unescaping_text.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/kairosdb-914055854-b63vq.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_k8s-logging-exclude-disabled_text_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_k8s-logging-exclude-disabled_text_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_k8s-logging-parser-disabled_text_stderr.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_k8s-logging-parser-disabled_text_stdout.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_keep-log-disabled_json.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_keep-log-enabled_json.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_merge-log-disabled_json.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_merge-log-enabled_invalid-json.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_merge-log-enabled_json.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_merge-log-enabled_text.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_merge-log-key_json.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_merge-log-trim-disabled_json.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_merge-log-trim-enabled_json.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_use-kubelet-disabled_fluent-bit.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/out/options/options_use-kubelet-enabled_fluent-bit.out create mode 100644 src/fluent-bit/tests/runtime/data/kubernetes/parsers.conf create mode 100644 src/fluent-bit/tests/runtime/data/loki/labelmap.json create mode 100644 src/fluent-bit/tests/runtime/data/podman/cgroupv2/42/net/dev create mode 100644 src/fluent-bit/tests/runtime/data/podman/cgroupv2/cgroup.controllers create mode 100644 src/fluent-bit/tests/runtime/data/podman/cgroupv2/config.json create mode 100644 src/fluent-bit/tests/runtime/data/podman/cgroupv2/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/containers/cgroup.procs create mode 100644 src/fluent-bit/tests/runtime/data/podman/cgroupv2/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/memory.current create mode 100644 src/fluent-bit/tests/runtime/data/podman/garbage/42/net/dev create mode 100644 src/fluent-bit/tests/runtime/data/podman/garbage/config.json create mode 100644 src/fluent-bit/tests/runtime/data/podman/garbage/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/memory.current create mode 100644 src/fluent-bit/tests/runtime/data/podman/garbage/memory/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/memory.usage_in_bytes create mode 100644 src/fluent-bit/tests/runtime/data/podman/garbage_config/config.json create mode 100644 src/fluent-bit/tests/runtime/data/podman/no_config/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/memory.current create mode 100644 src/fluent-bit/tests/runtime/data/podman/no_config/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/memory.usage_in_bytes create mode 100644 src/fluent-bit/tests/runtime/data/podman/no_config/memory/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/memory.usage_in_bytes create mode 100644 src/fluent-bit/tests/runtime/data/podman/no_proc/config.json create mode 100644 src/fluent-bit/tests/runtime/data/podman/no_proc/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/memory.current create mode 100644 src/fluent-bit/tests/runtime/data/podman/no_proc/memory/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/memory.usage_in_bytes create mode 100644 src/fluent-bit/tests/runtime/data/podman/no_sysfs/42/net/dev create mode 100644 src/fluent-bit/tests/runtime/data/podman/no_sysfs/config.json create mode 100644 src/fluent-bit/tests/runtime/data/podman/regular/42/net/dev create mode 100644 src/fluent-bit/tests/runtime/data/podman/regular/config.json create mode 100644 src/fluent-bit/tests/runtime/data/podman/regular/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/memory.current create mode 100644 src/fluent-bit/tests/runtime/data/podman/regular/memory/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/memory.usage_in_bytes create mode 100644 src/fluent-bit/tests/runtime/data/podman/regular/systemd/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/cgroup.procs create mode 100644 src/fluent-bit/tests/runtime/data/podman/reversed/42/net/dev create mode 100644 src/fluent-bit/tests/runtime/data/podman/reversed/config.json create mode 100644 src/fluent-bit/tests/runtime/data/podman/reversed/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/memory.current create mode 100644 src/fluent-bit/tests/runtime/data/podman/reversed/memory/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/memory.usage_in_bytes create mode 100644 src/fluent-bit/tests/runtime/data/podman/reversed/systemd/libpod-8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9/cgroup.procs create mode 100755 src/fluent-bit/tests/runtime/data/stackdriver/json.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver-credentials.json create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_multi_entries_severity.log create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_http_request.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_insert_id.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_k8s_resource.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_labels.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_log_name.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_monitored_resource.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_operation.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_resource_labels.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_source_location.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_span_id.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_timestamp.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_trace.h create mode 100644 src/fluent-bit/tests/runtime/data/stackdriver/stackdriver_test_trace_sampled.h create mode 100644 src/fluent-bit/tests/runtime/data/tail/log/3943.log create mode 100644 src/fluent-bit/tests/runtime/data/tail/log/dockermode.log create mode 100644 src/fluent-bit/tests/runtime/data/tail/log/dockermode_firstline_detection.log create mode 100644 src/fluent-bit/tests/runtime/data/tail/log/dockermode_multiple_lines.log create mode 100644 src/fluent-bit/tests/runtime/data/tail/log/dockermode_splitted_line.log create mode 100644 src/fluent-bit/tests/runtime/data/tail/log/dockermode_splitted_multiple_lines.log create mode 100644 src/fluent-bit/tests/runtime/data/tail/log/multiline_001.log create mode 100644 src/fluent-bit/tests/runtime/data/tail/out/3943.out create mode 100644 src/fluent-bit/tests/runtime/data/tail/out/dockermode.out create mode 100644 src/fluent-bit/tests/runtime/data/tail/out/dockermode_firstline_detection.out create mode 100644 src/fluent-bit/tests/runtime/data/tail/out/dockermode_multiple_lines.out create mode 100644 src/fluent-bit/tests/runtime/data/tail/out/dockermode_splitted_line.out create mode 100644 src/fluent-bit/tests/runtime/data/tail/out/dockermode_splitted_multiple_lines.out create mode 100644 src/fluent-bit/tests/runtime/data/tail/out/multiline_001.out create mode 100644 src/fluent-bit/tests/runtime/data/tail/out/skip_long_lines.out create mode 100644 src/fluent-bit/tests/runtime/data/tail/parsers.conf create mode 100644 src/fluent-bit/tests/runtime/data/tail/parsers_multiline_json.conf create mode 100755 src/fluent-bit/tests/runtime/data/td/json_td.h create mode 100644 src/fluent-bit/tests/runtime/data/tls/certificate.pem create mode 100644 src/fluent-bit/tests/runtime/data/tls/private_key.pem create mode 100755 src/fluent-bit/tests/runtime/data/wasm/append_tag.wasm create mode 100755 src/fluent-bit/tests/runtime/data/wasm/drop_record.wasm create mode 100755 src/fluent-bit/tests/runtime/data/wasm/modify_record.wasm create mode 100755 src/fluent-bit/tests/runtime/data/wasm/numeric_records.wasm create mode 100755 src/fluent-bit/tests/runtime/data/wasm/say_hello.wasm create mode 100644 src/fluent-bit/tests/runtime/filter_aws.c create mode 100644 src/fluent-bit/tests/runtime/filter_checklist.c create mode 100644 src/fluent-bit/tests/runtime/filter_ecs.c create mode 100644 src/fluent-bit/tests/runtime/filter_expect.c create mode 100644 src/fluent-bit/tests/runtime/filter_grep.c create mode 100644 src/fluent-bit/tests/runtime/filter_kubernetes.c create mode 100644 src/fluent-bit/tests/runtime/filter_kubernetes.md create mode 100644 src/fluent-bit/tests/runtime/filter_log_to_metrics.c create mode 100644 src/fluent-bit/tests/runtime/filter_lua.c create mode 100644 src/fluent-bit/tests/runtime/filter_modify.c create mode 100644 src/fluent-bit/tests/runtime/filter_multiline.c create mode 100644 src/fluent-bit/tests/runtime/filter_nest.c create mode 100644 src/fluent-bit/tests/runtime/filter_parser.c create mode 100644 src/fluent-bit/tests/runtime/filter_record_modifier.c create mode 100644 src/fluent-bit/tests/runtime/filter_rewrite_tag.c create mode 100644 src/fluent-bit/tests/runtime/filter_stdout.c create mode 100644 src/fluent-bit/tests/runtime/filter_throttle.c create mode 100644 src/fluent-bit/tests/runtime/filter_throttle_size.c create mode 100644 src/fluent-bit/tests/runtime/filter_type_converter.c create mode 100644 src/fluent-bit/tests/runtime/filter_wasm.c create mode 100644 src/fluent-bit/tests/runtime/flb_tests_runtime.h.in create mode 100755 src/fluent-bit/tests/runtime/gen_data.py create mode 100644 src/fluent-bit/tests/runtime/http_callbacks.c create mode 120000 src/fluent-bit/tests/runtime/in_cpu.c create mode 120000 src/fluent-bit/tests/runtime/in_disk.c create mode 120000 src/fluent-bit/tests/runtime/in_dummy.c create mode 100644 src/fluent-bit/tests/runtime/in_elasticsearch.c create mode 100644 src/fluent-bit/tests/runtime/in_event_test.c create mode 100644 src/fluent-bit/tests/runtime/in_fluentbit_metrics.c create mode 100644 src/fluent-bit/tests/runtime/in_forward.c create mode 120000 src/fluent-bit/tests/runtime/in_head.c create mode 100644 src/fluent-bit/tests/runtime/in_http.c create mode 120000 src/fluent-bit/tests/runtime/in_mem.c create mode 100644 src/fluent-bit/tests/runtime/in_mqtt.c create mode 100644 src/fluent-bit/tests/runtime/in_netif.c create mode 100644 src/fluent-bit/tests/runtime/in_opentelemetry.c create mode 100644 src/fluent-bit/tests/runtime/in_podman_metrics.c create mode 120000 src/fluent-bit/tests/runtime/in_proc.c create mode 120000 src/fluent-bit/tests/runtime/in_random.c create mode 100644 src/fluent-bit/tests/runtime/in_simple_systems.c create mode 100644 src/fluent-bit/tests/runtime/in_splunk.c create mode 100644 src/fluent-bit/tests/runtime/in_statsd.c create mode 100644 src/fluent-bit/tests/runtime/in_syslog.c create mode 100644 src/fluent-bit/tests/runtime/in_tail.c create mode 100644 src/fluent-bit/tests/runtime/in_tcp.c create mode 100644 src/fluent-bit/tests/runtime/in_udp.c create mode 100644 src/fluent-bit/tests/runtime/out_cloudwatch.c create mode 100644 src/fluent-bit/tests/runtime/out_counter.c create mode 100644 src/fluent-bit/tests/runtime/out_datadog.c create mode 100644 src/fluent-bit/tests/runtime/out_elasticsearch.c create mode 100644 src/fluent-bit/tests/runtime/out_exit.c create mode 100644 src/fluent-bit/tests/runtime/out_file.c create mode 100644 src/fluent-bit/tests/runtime/out_firehose.c create mode 100644 src/fluent-bit/tests/runtime/out_flowcounter.c create mode 100644 src/fluent-bit/tests/runtime/out_forward.c create mode 100644 src/fluent-bit/tests/runtime/out_http.c create mode 100644 src/fluent-bit/tests/runtime/out_kinesis.c create mode 100644 src/fluent-bit/tests/runtime/out_lib.c create mode 100644 src/fluent-bit/tests/runtime/out_loki.c create mode 100644 src/fluent-bit/tests/runtime/out_null.c create mode 100644 src/fluent-bit/tests/runtime/out_opensearch.c create mode 100644 src/fluent-bit/tests/runtime/out_plot.c create mode 100644 src/fluent-bit/tests/runtime/out_retry.c create mode 100644 src/fluent-bit/tests/runtime/out_s3.c create mode 100644 src/fluent-bit/tests/runtime/out_skywalking.c create mode 100644 src/fluent-bit/tests/runtime/out_splunk.c create mode 100644 src/fluent-bit/tests/runtime/out_stackdriver.c create mode 100644 src/fluent-bit/tests/runtime/out_stdout.c create mode 100644 src/fluent-bit/tests/runtime/out_syslog.c create mode 100644 src/fluent-bit/tests/runtime/out_tcp.c create mode 100644 src/fluent-bit/tests/runtime/out_td.c create mode 100644 src/fluent-bit/tests/runtime/wasm/go/Makefile create mode 100644 src/fluent-bit/tests/runtime/wasm/go/append_tag.go create mode 100644 src/fluent-bit/tests/runtime/wasm/go/drop_record.go create mode 100644 src/fluent-bit/tests/runtime/wasm/go/go.mod create mode 100644 src/fluent-bit/tests/runtime/wasm/go/go.sum create mode 100644 src/fluent-bit/tests/runtime/wasm/go/modify_record.go create mode 100644 src/fluent-bit/tests/runtime/wasm/go/numeric_records.go create mode 100644 src/fluent-bit/tests/runtime/wasm/go/say_hello.go create mode 100644 src/fluent-bit/tests/runtime_shell/.gitignore create mode 100644 src/fluent-bit/tests/runtime_shell/CMakeLists.txt create mode 100644 src/fluent-bit/tests/runtime_shell/common.sh create mode 100644 src/fluent-bit/tests/runtime_shell/conf/in_dummy_expect.conf create mode 100644 src/fluent-bit/tests/runtime_shell/conf/in_expect_base.conf create mode 100644 src/fluent-bit/tests/runtime_shell/conf/in_http_tls_expect.conf create mode 100644 src/fluent-bit/tests/runtime_shell/conf/in_syslog_tcp_plaintext_expect.conf create mode 100644 src/fluent-bit/tests/runtime_shell/conf/in_syslog_tcp_tls_expect.conf create mode 100644 src/fluent-bit/tests/runtime_shell/conf/in_syslog_udp_plaintext_expect.conf create mode 100644 src/fluent-bit/tests/runtime_shell/conf/in_syslog_uds_dgram_plaintext_expect.conf create mode 100644 src/fluent-bit/tests/runtime_shell/conf/in_syslog_uds_stream_plaintext_expect.conf create mode 100644 src/fluent-bit/tests/runtime_shell/conf/in_tail_expect.conf create mode 100755 src/fluent-bit/tests/runtime_shell/in_dummy_expect.sh create mode 100755 src/fluent-bit/tests/runtime_shell/in_http_tls_expect.sh create mode 100755 src/fluent-bit/tests/runtime_shell/in_syslog_tcp_plaintext_expect.sh create mode 100755 src/fluent-bit/tests/runtime_shell/in_syslog_tcp_tls_expect.sh create mode 100755 src/fluent-bit/tests/runtime_shell/in_syslog_udp_plaintext_expect.sh create mode 100755 src/fluent-bit/tests/runtime_shell/in_syslog_uds_dgram_plaintext_expect.sh create mode 100755 src/fluent-bit/tests/runtime_shell/in_syslog_uds_stream_plaintext_expect.sh create mode 100644 src/fluent-bit/tests/runtime_shell/in_tail/README.md create mode 100644 src/fluent-bit/tests/runtime_shell/in_tail/conf/multiline_rotation.conf create mode 100644 src/fluent-bit/tests/runtime_shell/in_tail/conf/normal_rotation.conf create mode 100644 src/fluent-bit/tests/runtime_shell/in_tail/conf/rotate_link.conf create mode 100644 src/fluent-bit/tests/runtime_shell/in_tail/conf/single_static_rotation.conf create mode 100644 src/fluent-bit/tests/runtime_shell/in_tail/conf/truncate_link.conf create mode 100644 src/fluent-bit/tests/runtime_shell/in_tail/conf/truncate_rotation.conf create mode 100755 src/fluent-bit/tests/runtime_shell/in_tail/logger_file.py create mode 100755 src/fluent-bit/tests/runtime_shell/in_tail/run_tests.sh create mode 100644 src/fluent-bit/tests/runtime_shell/in_tail/test_rotation.sh create mode 100755 src/fluent-bit/tests/runtime_shell/in_tail_expect.sh create mode 100644 src/fluent-bit/tests/runtime_shell/runtime_shell.env.in create mode 100644 src/fluent-bit/tests/runtime_shell/tls/certificate.pem create mode 100644 src/fluent-bit/tests/runtime_shell/tls/private_key.pem (limited to 'src/fluent-bit/tests') diff --git a/src/fluent-bit/tests/include/aws_client_mock.c b/src/fluent-bit/tests/include/aws_client_mock.c new file mode 100644 index 000000000..84ee6a1eb --- /dev/null +++ b/src/fluent-bit/tests/include/aws_client_mock.c @@ -0,0 +1,256 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#include "aws_client_mock.h" + +#include +#include + +/* Vtable mocked methods */ +static struct flb_http_client *flb_aws_client_mock_vtable_request( + struct flb_aws_client *aws_client, int method, const char *uri, const char *body, + size_t body_len, struct flb_aws_header *dynamic_headers, size_t dynamic_headers_len); + +/* Protected structs */ + +/* flb_aws_client_mock pointer returned by mock_generator */ +static struct flb_aws_client_mock *flb_aws_client_mock_instance = NULL; + +/* Generator that returns clients with the test vtable */ +static struct flb_aws_client_generator mock_generator = { + .create = flb_aws_client_create_mock, +}; + +/* Test/mock flb_aws_client vtable */ +static struct flb_aws_client_vtable mock_client_vtable = { + .request = flb_aws_client_mock_vtable_request, +}; + +/* + * Configure generator + * Note: Automatically creates mock and wires to generator + * Destroys any existing mock in generator + */ +void flb_aws_client_mock_configure_generator( + struct flb_aws_client_mock_request_chain *request_chain) +{ + flb_aws_client_mock_destroy_generator(); + flb_aws_client_mock_instance = flb_aws_client_mock_create(request_chain); +} + +/* + * Clean up generator's memory + * Cleanup should be called on exiting generator + */ +void flb_aws_client_mock_destroy_generator() +{ + if (flb_aws_client_mock_instance != NULL) { + flb_aws_client_mock_destroy(flb_aws_client_mock_instance); + } +} + +/* Create Mock of flb_aws_client */ +struct flb_aws_client_mock *flb_aws_client_mock_create( + struct flb_aws_client_mock_request_chain *request_chain) +{ + struct flb_aws_client_mock *mock = flb_calloc(1, sizeof(struct flb_aws_client_mock)); + + /* Create a surrogate aws_client and copy to mock client */ + struct flb_aws_client *surrogate_aws_client = flb_aws_client_generator()->create(); + mock->super = *surrogate_aws_client; + mock->surrogate = surrogate_aws_client; + memset(mock->surrogate, 0, sizeof(struct flb_aws_client)); + + /* Switch vtable to mock vtable */ + mock->super.client_vtable = &mock_client_vtable; + mock->request_chain = request_chain; + mock->next_request_index = 0; + return mock; +} + +/* Destroy flb_aws_client_mock */ +void flb_aws_client_mock_destroy(struct flb_aws_client_mock *mock) +{ + /* Remove from generator registry if stored */ + if (flb_aws_client_mock_instance == mock) { + flb_aws_client_mock_instance = NULL; + } + + /* Resurrect surrogate, and destroy flb_aws_client */ + *mock->surrogate = mock->super; + flb_aws_client_destroy(mock->surrogate); + + /* Destroy mock flb_aws_client */ + flb_free(mock); +} + +/* Return a Mocked flb_aws_client, ready for injection */ +struct flb_aws_client *flb_aws_client_mock_context(struct flb_aws_client_mock *mock) +{ + return (struct flb_aws_client *)mock; +} + +/* Get the number of unused requests */ +int flb_aws_client_mock_count_unused_requests(struct flb_aws_client_mock *mock) +{ + return mock->request_chain->length - mock->next_request_index; +} + +/* Set flb_aws_client_mock_instance used in mock generator */ +void flb_aws_client_mock_set_generator_instance(struct flb_aws_client_mock *mock) +{ + flb_aws_client_mock_instance = mock; +} + +/* Set flb_aws_client_mock_instance used in mock generator */ +struct flb_aws_client_mock *flb_aws_client_mock_get_generator_instance( + struct flb_aws_client_mock *mock) +{ + return flb_aws_client_mock_instance = mock; +} + +/* Get generator used in mock */ +struct flb_aws_client_generator *flb_aws_client_get_mock_generator() +{ + return &mock_generator; +} + +/* Get the number of unused requests */ +int flb_aws_client_mock_generator_count_unused_requests() +{ + TEST_ASSERT(flb_aws_client_mock_instance != 0); + return flb_aws_client_mock_count_unused_requests(flb_aws_client_mock_instance); +} + +/* Return the mock instance */ +struct flb_aws_client *flb_aws_client_create_mock() +{ + TEST_CHECK(flb_aws_client_mock_instance != NULL); + TEST_MSG( + "[aws_mock_client] Must initialize flb_aws_client_mock_instance before calling " + "flb_aws_client_create_mock()"); + TEST_MSG( + "[aws_mock_client] This ouccurs when the generator is called, before tests are " + "initialized."); + + return flb_aws_client_mock_context(flb_aws_client_mock_instance); +} + +/* Mock request used by flb_aws_client mock */ +static struct flb_http_client *flb_aws_client_mock_vtable_request( + struct flb_aws_client *aws_client, int method, const char *uri, const char *body, + size_t body_len, struct flb_aws_header *dynamic_headers, size_t dynamic_headers_len) +{ + int h; + int i; + int ret; + + /* Get access to mock */ + struct flb_aws_client_mock *mock = (struct flb_aws_client_mock *)aws_client; + + /* Check that a response is left in the chain */ + ret = TEST_CHECK(mock->next_request_index < mock->request_chain->length); + if (!ret) { + TEST_MSG( + "[flb_aws_client_mock] %d mock responses provided. Attempting to call %d " + "times. Aborting.", + (int)mock->request_chain->length, (int)mock->next_request_index + 1); + return NULL; + } + struct flb_aws_client_mock_response *response = + &(mock->request_chain->responses[mock->next_request_index]); + struct flb_http_client *c = NULL; + + /* create an http client so that we can set the response */ + c = flb_calloc(1, sizeof(struct flb_http_client)); + if (!c) { + flb_errno(); + return NULL; + } + mk_list_init(&c->headers); + + /* Response configuration */ + for (i = 0; i < response->length; ++i) { + struct flb_aws_client_mock_response_config *response_config = + &(response->config_parameters[i]); + void *val1 = response_config->config_value; + void *val2 = response_config->config_value_2; + + /* Expectations */ + if (response_config->config_parameter == FLB_AWS_CLIENT_MOCK_EXPECT_HEADER) { + int header_found = FLB_FALSE; + /* Search for header in request */ + for (h = 0; h < dynamic_headers_len; ++h) { + ret = strncmp(dynamic_headers[h].key, (char *)val1, + dynamic_headers[h].key_len); + if (ret == 0) { + /* Check header value */ + ret = strncmp(dynamic_headers[h].val, (char *)val2, + dynamic_headers[h].val_len + 1); + TEST_CHECK(ret == 0); + TEST_MSG("[aws_mock_client] Expected Header: (%s: %s)", (char *)val1, + (char *)val2); + TEST_MSG("[aws_mock_client] Received Header: (%s: %s)", (char *)val1, + dynamic_headers[h].val); + + header_found = FLB_TRUE; + } + } + TEST_CHECK(header_found); + TEST_MSG("[aws_mock_client] Expected Header: (%s: %s)", (char *)val1, + (char *)val2); + TEST_MSG("[aws_mock_client] Header not received"); + } + else if (response_config->config_parameter == FLB_AWS_CLIENT_MOCK_EXPECT_METHOD) { + char *flb_http_methods[] = { + "FLB_HTTP_GET", "FLB_HTTP_POST", "FLB_HTTP_PUT", + "FLB_HTTP_HEAD", "FLB_HTTP_CONNECT", "FLB_HTTP_PATCH", + }; + + /* + * Check method is what is expected + * Typecast config value from void * -> int + */ + TEST_CHECK(method == (int)(uintptr_t)val1); + TEST_MSG("[aws_mock_client] Expected HTTP Method: %s", + flb_http_methods[(int)(uintptr_t)val1]); + TEST_MSG("[aws_mock_client] Received HTTP Method: %s", + flb_http_methods[method]); + } + else if (response_config->config_parameter == + FLB_AWS_CLIENT_MOCK_EXPECT_HEADER_COUNT) { + TEST_CHECK(dynamic_headers_len == (int)(uintptr_t)val1); + TEST_MSG("[aws_mock_client] Expected %d Headers", (int)(uintptr_t)val1); + TEST_MSG("[aws_mock_client] Received %d Headers", + (int)(uintptr_t)dynamic_headers_len); + } + else if (response_config->config_parameter == FLB_AWS_CLIENT_MOCK_EXPECT_URI) { + ret = strncmp(uri, (char *)val1, strlen((char *)val1) + 1); + TEST_CHECK(ret == 0); + TEST_MSG("[aws_mock_client] Expected URI: %s", (char *)val1); + TEST_MSG("[aws_mock_client] Received URI: %s", uri); + } + + /* Replace response client */ + else if (response_config->config_parameter == + FLB_AWS_CLIENT_MOCK_CONFIG_REPLACE) { + flb_http_client_destroy(c); + c = (struct flb_http_client *)val1; + } + + /* + * Response setters + * Set client fields using XMacro definitions + */ +#define EXPAND_CLIENT_RESPONSE_PARAMETER(lower, UPPER, type) \ + else if (response_config->config_parameter == FLB_AWS_CLIENT_MOCK_SET_##UPPER) \ + { \ + c->resp.lower = CONVERT_##type((char *)val1); \ + } +#include "aws_client_mock_client_resp.def" +#undef EXPAND_CLIENT_RESPONSE_PARAMETER + } + + /* Increment request */ + ++mock->next_request_index; + + return c; +}; diff --git a/src/fluent-bit/tests/include/aws_client_mock.h b/src/fluent-bit/tests/include/aws_client_mock.h new file mode 100644 index 000000000..7cdfc8106 --- /dev/null +++ b/src/fluent-bit/tests/include/aws_client_mock.h @@ -0,0 +1,223 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + * AWS Client Mock + * + * Note: AWS Client Mock is not intended to be used with asynchronously + * running tests. A mock instance is stored and retrieved by + * the mock generator + */ + +/* + * FLB_AWS_CLIENT_MOCK() definition + * The following macro FLB_AWS_CLIENT_MOCK() translates a request definition + * into a c compound literal, which constructs a mock request chain + * at the block scope. + + * The following translation might ouccur: + + FLB_AWS_CLIENT_MOCK( + response( + expect("token", "aws_token") + expect("time", "123456") + set(STATUS, 200), + ), + response( + set(STATUS, 200), + ) + ) + + * ^^^^^^^^^^^^^^^^^^^^^^^^^ + * *~~~> Translates to ~~~>* + * *vvvvvvvvvvvvvvvvvvvvvvv* + + &(struct flb_aws_client_mock_request_chain){ + 2, + ((struct flb_aws_client_mock_response[]) { // Mock request chain + { + 3, + (struct flb_aws_client_mock_response_config[]){ + ((struct flb_aws_client_mock_response_config) { // Response + configuration FLB_AWS_CLIENT_MOCK_EXPECT_HEADER, (void *) "token", (void *) "aws_token" + }), + ((struct flb_aws_client_mock_response_config) + { FLB_AWS_CLIENT_MOCK_EXPECT_HEADER, + (void *) "time", + (void *) "123456" + } + ) + ((struct flb_aws_client_mock_response_config) { // Response + configuration FLB_AWS_CLIENT_MOCK_SET_STATUS, (void *) 200, (void *) 0 + }), + } + }, + { + 1, + &(struct flb_aws_client_mock_response_config) { + FLB_AWS_CLIENT_MOCK_SET_STATUS, + (void *) 200, + (void *) 0 + } + } + }) + } +*/ + +#ifndef AWS_CLIENT_MOCK_H +#define AWS_CLIENT_MOCK_H + +/* Variadic Argument Counter, Counts up to 64 variadic args */ +#define FLB_AWS_CLIENT_MOCK_COUNT64(...) \ + _FLB_AWS_CLIENT_MOCK_COUNT64(dummy, ##__VA_ARGS__, 63, 62, 61, 60, 59, 58, 57, 56, \ + 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, \ + 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, \ + 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, \ + 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define _FLB_AWS_CLIENT_MOCK_COUNT64( \ + x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, \ + x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, \ + x36, x37, x38, x39, x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x50, x51, x52, \ + x53, x54, x55, x56, x57, x58, x59, x60, x61, x62, x63, count, ...) \ + count + +#define FLB_AWS_CLIENT_MOCK_EVAL(...) __VA_ARGS__ +#define FLB_AWS_CLIENT_MOCK_EMPTY() +#define FLB_AWS_CLIENT_MOCK_DIFER(...) \ + FLB_AWS_CLIENT_MOCK_EVAL FLB_AWS_CLIENT_MOCK_EMPTY()(__VA_ARGS__) + +/* Make block-scope addressable compound-literal request chain */ +#define FLB_AWS_CLIENT_MOCK(...) \ + FLB_AWS_CLIENT_MOCK_EVAL(&(struct flb_aws_client_mock_request_chain){ \ + FLB_AWS_CLIENT_MOCK_COUNT64(__VA_ARGS__), \ + (struct flb_aws_client_mock_response[]){__VA_ARGS__}}) + +#define FLB_AWS_CLIENT_MOCK_RESPONSE(...) \ + { \ + FLB_AWS_CLIENT_MOCK_COUNT64(__VA_ARGS__), \ + (struct flb_aws_client_mock_response_config[]) \ + { \ + __VA_ARGS__ \ + } \ + } + +#define FLB_AWS_CLIENT_MOCK_VFUNC___(name, n) name##n +#define FLB_AWS_CLIENT_MOCK_VFUNC(name, n) FLB_AWS_CLIENT_MOCK_VFUNC___(name, n) + +#define FLB_AWS_CLIENT_MOCK_STAGE_CONFIG(mode, parameter, value, ...) \ + ((struct flb_aws_client_mock_response_config){ \ + FLB_AWS_CLIENT_MOCK_##mode##parameter, (void *)value, \ + FLB_AWS_CLIENT_MOCK_VFUNC( \ + FLB_AWS_CLIENT_MOCK_STAGE_CONFIG_OPTIONAL_VALUES_, \ + FLB_AWS_CLIENT_MOCK_COUNT64(__VA_ARGS__))(__VA_ARGS__)}) + +#define FLB_AWS_CLIENT_MOCK_STAGE_CONFIG_OPTIONAL_VALUES_1(value) (void *)value +#define FLB_AWS_CLIENT_MOCK_STAGE_CONFIG_OPTIONAL_VALUES_0() (void *)0 + +// DIFER() allows for correct arg count +#define response(...) FLB_AWS_CLIENT_MOCK_DIFER(FLB_AWS_CLIENT_MOCK_RESPONSE(__VA_ARGS__)) +#define expect(...) \ + FLB_AWS_CLIENT_MOCK_DIFER(FLB_AWS_CLIENT_MOCK_STAGE_CONFIG(EXPECT_, __VA_ARGS__)) +#define config(...) \ + FLB_AWS_CLIENT_MOCK_DIFER(FLB_AWS_CLIENT_MOCK_STAGE_CONFIG(CONFIG_, __VA_ARGS__)) +#define set(...) \ + FLB_AWS_CLIENT_MOCK_DIFER(FLB_AWS_CLIENT_MOCK_STAGE_CONFIG(SET_, __VA_ARGS__)) + +/* Includes */ +#include + +#include "../lib/acutest/acutest.h" + +/* Enum */ +enum flb_aws_client_mock_response_config_parameter { + FLB_AWS_CLIENT_MOCK_EXPECT_METHOD, // int: FLB_HTTP_ where method = { "GET", + // "POST", "PUT", "HEAD", "CONNECT", "PATCH" } + FLB_AWS_CLIENT_MOCK_EXPECT_HEADER, // (string, string): (header key, header value) + FLB_AWS_CLIENT_MOCK_EXPECT_HEADER_COUNT, // int: header count + FLB_AWS_CLIENT_MOCK_EXPECT_URI, // string: uri + FLB_AWS_CLIENT_MOCK_CONFIG_REPLACE, // flb_http_client ptr. Client can be null if + // needed +// Define all client fields using XMacro definitions +#define EXPAND_CLIENT_RESPONSE_PARAMETER(x, UPPER, y) FLB_AWS_CLIENT_MOCK_SET_##UPPER, +#include "aws_client_mock_client_resp.def" +#undef EXPAND_CLIENT_RESPONSE_PARAMETER +}; + +/* Structs */ +struct flb_aws_client_mock_response_config { + enum flb_aws_client_mock_response_config_parameter config_parameter; + void *config_value; // Most configuration must be passed in string format. + void *config_value_2; +}; + +struct flb_aws_client_mock_response { + size_t length; + struct flb_aws_client_mock_response_config *config_parameters; +}; + +struct flb_aws_client_mock_request_chain { + size_t length; + struct flb_aws_client_mock_response *responses; +}; + +struct flb_aws_client_mock { + /* This member must come first in the struct's memory layout + * so that this struct can mock flb_aws_client context */ + struct flb_aws_client super; + struct flb_aws_client *surrogate; + + /* Additional data members added to mock */ + struct flb_aws_client_mock_request_chain *request_chain; + size_t next_request_index; +}; + +/* Declarations */ + +/* + * Configure mock generator to be returned by flb_aws_client_get_mock_generator() + * Generator is injected into credential providers and returns a mocked + * flb_aws_client instance. + * + * Note: Automatically creates mock and wires to generator + * Destroys any existing mock in generator + */ +void flb_aws_client_mock_configure_generator( + struct flb_aws_client_mock_request_chain *request_chain); + +/* + * Clean up generator memory + * Note: Cleanup should be called at the end of each test + */ +void flb_aws_client_mock_destroy_generator(); + +/* Create Mock of flb_aws_client */ +struct flb_aws_client_mock *flb_aws_client_mock_create( + struct flb_aws_client_mock_request_chain *request_chain); + +/* + * Destroy flb_aws_client_mock + * Note: flb_aws_client_destroy must not be used prior to flb_aws_client_mock_destroy. + */ +void flb_aws_client_mock_destroy(struct flb_aws_client_mock *mock); + +/* Get the number of unused requests */ +int flb_aws_client_mock_count_unused_requests(struct flb_aws_client_mock *mock); + +/* Return a Mocked flb_aws_client, ready for injection */ +struct flb_aws_client *flb_aws_client_mock_context(struct flb_aws_client_mock *mock); + +/* Generator Methods */ +/* Get/set flb_aws_client_mock_instance used by mock generator */ +void flb_aws_client_mock_set_generator_instance(struct flb_aws_client_mock *mock); +struct flb_aws_client_mock *flb_aws_client_mock_get_generator_instance( + struct flb_aws_client_mock *mock); + +int flb_aws_client_mock_generator_count_unused_requests(); + +/* Substitute Methods */ +/* Get generator used in mock */ +struct flb_aws_client_generator *flb_aws_client_get_mock_generator(); + +/* Return the mock instance */ +struct flb_aws_client *flb_aws_client_create_mock(); + +#endif /* AWS_CLIENT_MOCK_H */ diff --git a/src/fluent-bit/tests/include/aws_client_mock_client_resp.def b/src/fluent-bit/tests/include/aws_client_mock_client_resp.def new file mode 100644 index 000000000..225cc2ea1 --- /dev/null +++ b/src/fluent-bit/tests/include/aws_client_mock_client_resp.def @@ -0,0 +1,34 @@ +/* XMacro Definition for Mock AWS Client http_client Response */ + +/* Converters: CONVERT_ */ +#define EVAL1(...) __VA_ARGS__ +#define CONVERT_T_INT(str) (int) (uintptr_t) str +#define CONVERT_T_SIZE_T(str) (size_t) str +#define CONVERT_T_LONG(str) (long) str +#define CONVERT_T_CHAR_STAR(str) str + +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(status, STATUS, T_INT)) /* HTTP response status */ +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(content_length, CONTENT_LENGTH, T_INT)) /* Content length set by headers */ +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(chunked_encoding, CHUNKED_ENCODEING, T_INT)) /* Chunked transfer encoding ? */ +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(connection_close, CONNECTION_CLOSE, T_INT)) /* connection: close ? */ +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(chunked_cur_size, CHUNKED_CUR_SIZE, T_LONG)) +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(chunked_exp_size, CHUNKED_EXP_SIZE, T_LONG)) /* expected chunked size */ +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(chunk_processed_end, CHUNK_PROCESSED_END, T_CHAR_STAR)) /* Position to mark last chunk */ +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(headers_end, HEADERS_END, T_CHAR_STAR)) /* Headers end (\r\n\r\n) */ + +/* Payload: body response: reference to 'data' */ +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(payload, PAYLOAD, T_CHAR_STAR)) +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(payload_size, PAYLOAD_SIZE, T_SIZE_T)) + +/* Buffer to store server response */ +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(data, DATA, T_CHAR_STAR)) +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(data_len, DATA_LEN, T_SIZE_T)) +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(data_size, DATA_SIZE, T_SIZE_T)) +EVAL1(EXPAND_CLIENT_RESPONSE_PARAMETER(data_size_max, DATA_SIZE_MAX, T_SIZE_T)) + +#undef CONVERT_T_INT +#undef CONVERT_T_SIZE +#undef CONVERT_T_LONG +#undef CONVERT_T_CHAR_STAR + +#undef EVAL1 diff --git a/src/fluent-bit/tests/include/flb_tests_initialize_tls.h b/src/fluent-bit/tests/include/flb_tests_initialize_tls.h new file mode 100644 index 000000000..bfe16f229 --- /dev/null +++ b/src/fluent-bit/tests/include/flb_tests_initialize_tls.h @@ -0,0 +1,44 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2019-2020 The Fluent Bit Authors + * Copyright (C) 2015-2018 Treasure Data Inc. + * + * Licensed 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. + */ + +#ifndef FLB_TESTS_INITALIZE_TLS_H +#define FLB_TESTS_INITALIZE_TLS_H + +#include +#include + +struct flb_config *test_env_config = NULL; + +static inline void flb_test_env_config_init(void) +{ + test_env_config = flb_config_init(); + + if (test_env_config == NULL) { + return; + } +} + +static inline void flb_test_env_config_destroy(void) { + if (test_env_config != NULL) { + flb_config_exit(test_env_config); + } +} + +#endif diff --git a/src/fluent-bit/tests/internal/CMakeLists.txt b/src/fluent-bit/tests/internal/CMakeLists.txt new file mode 100644 index 000000000..5288004db --- /dev/null +++ b/src/fluent-bit/tests/internal/CMakeLists.txt @@ -0,0 +1,216 @@ +find_package(Threads REQUIRED) + +include_directories(cutest/) + +set(UNIT_TESTS_FILES + pack.c + pipe.c + sds.c + sds_list.c + hmac.c + crypto.c + hash.c + slist.c + router.c + network.c + unit_sizes.c + hashtable.c + http_client.c + utils.c + gzip.c + random.c + config_map.c + mp.c + input_chunk.c + flb_time.c + file.c + csv.c + multiline.c + typecast.c + base64.c + bucket_queue.c + flb_event_loop.c + ring_buffer.c + regex.c + parser_json.c + parser_ltsv.c + parser_regex.c + parser_logfmt.c + env.c + log.c + log_event_decoder.c + processor.c + uri.c + ) + +# Config format +set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + config_format.c + config_format_fluentbit.c +) + +if(FLB_HAVE_LIBYAML) + set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + config_format_yaml.c + ) +endif() + +if (NOT WIN32) + set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + gelf.c + fstore.c + reload.c + ) +endif() + +if(FLB_PARSER) + set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + parser.c + ) +endif() + +if(FLB_STREAM_PROCESSOR) + set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + stream_processor.c + ) +endif() + +if(FLB_RECORD_ACCESSOR) + set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + record_accessor.c + ) +endif() + +if(FLB_METRICS) + set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + metrics.c + ) +endif() + +if(FLB_SIGNV4) + set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + signv4.c + ) +endif() + +if(FLB_AVRO_ENCODER) + set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + avro.c + ) +endif() + +if(FLB_AWS) + set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + aws_util.c + aws_compress.c + aws_credentials.c + aws_credentials_ec2.c + aws_credentials_sts.c + aws_credentials_http.c + aws_credentials_profile.c + ) + if(FLB_HAVE_AWS_CREDENTIAL_PROCESS) + set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + aws_credentials_process.c + ) + endif() +endif() + +if(FLB_AWS_ERROR_REPORTER) + set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + error_reporter.c + ) +endif() + +if(FLB_LUAJIT) + set(UNIT_TESTS_FILES + ${UNIT_TESTS_FILES} + lua.c + ) +endif() + +set(UNIT_TESTS_DATA + data/tls/certificate.pem + data/tls/private_key.pem + data/pack/json_single_map_001.json + data/pack/json_single_map_002.json + data/parser/json.conf + data/parser/regex.conf + data/input_chunk/log/a_thousand_plus_one_bytes.log + data/input_chunk/log/test_buffer_valid.log + ) + +set(FLB_TESTS_DATA_PATH ${CMAKE_CURRENT_SOURCE_DIR}/) +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/flb_tests_internal.h.in" + "${CMAKE_CURRENT_SOURCE_DIR}/flb_tests_internal.h" + ) + +# Move data files to the path the test binaries can find them +macro(FLB_TEST_COPY_DATA path) + configure_file(${path} ${CMAKE_CURRENT_BINARY_DIR}/${path} COPYONLY) +endmacro() + +foreach(test_data ${UNIT_TESTS_DATA}) + FLB_TEST_COPY_DATA(${test_data}) +endforeach() + +# Prepare list of unit tests function +function(prepare_unit_tests TEST_PREFIX SOURCEFILES) + foreach(source_file ${SOURCEFILES}) + get_filename_component(source_file_we ${source_file} NAME_WE) + set(source_file_we ${TEST_PREFIX}${source_file_we}) + if(FLB_WITHOUT_${source_file_we}) + message("Skipping test ${source_file_we}") + else() + add_executable( + ${source_file_we} + ${source_file} + ) + add_sanitizers(${source_file_we}) + + if(FLB_JEMALLOC) + target_link_libraries(${source_file_we} libjemalloc ${CMAKE_THREAD_LIBS_INIT}) + else() + target_link_libraries(${source_file_we} ${CMAKE_THREAD_LIBS_INIT}) + endif() + + if(FLB_AWS) + target_link_libraries(${source_file_we} flb-aws) + endif() + + if(FLB_STREAM_PROCESSOR) + target_link_libraries(${source_file_we} flb-sp) + endif() + + target_link_libraries(${source_file_we} fluent-bit-static cfl-static) + + if(FLB_AVRO_ENCODER) + target_link_libraries(${source_file_we} avro-static jansson) + endif() + + add_test(NAME ${source_file_we} + COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${source_file_we} + WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}/build) + set_tests_properties(${source_file_we} PROPERTIES LABELS "internal") + endif() + endforeach() +endfunction(prepare_unit_tests) + +prepare_unit_tests(flb-it- "${UNIT_TESTS_FILES}") + +if(FLB_TESTS_INTERNAL_FUZZ) + add_subdirectory(fuzzers) +endif() diff --git a/src/fluent-bit/tests/internal/README.md b/src/fluent-bit/tests/internal/README.md new file mode 100644 index 000000000..4ea04b20d --- /dev/null +++ b/src/fluent-bit/tests/internal/README.md @@ -0,0 +1,3 @@ +# Fluent Bit Internal Tests + +The following directory contains unit tests to validate specific functions of Fluent Bit core (not plugins). diff --git a/src/fluent-bit/tests/internal/avro.c b/src/fluent-bit/tests/internal/avro.c new file mode 100644 index 000000000..45f073439 --- /dev/null +++ b/src/fluent-bit/tests/internal/avro.c @@ -0,0 +1,382 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#include +#include +#include +#include +#include +#include +#include + +#include "flb_tests_internal.h" + +/* AVRO iteration tests */ +#define AVRO_SINGLE_MAP1 FLB_TESTS_DATA_PATH "/data/avro/json_single_map_001.json" +#define AVRO_MULTILINE_JSON FLB_TESTS_DATA_PATH "/data/avro/live-sample.json" + +const char JSON_SINGLE_MAP_001_SCHEMA[] = +"{\"type\":\"record\",\ + \"name\":\"Map001\",\ + \"fields\":[\ + {\"name\": \"key001\", \"type\": \"int\"},\ + {\"name\": \"key002\", \"type\": \"float\"},\ + {\"name\": \"key003\", \"type\": \"string\"},\ + {\"name\": \"key004\", \"type\":\ + {\"type\": \"array\", \"items\":\ + {\"type\": \"map\",\"values\": \"int\"}}}]}"; + +msgpack_unpacked test_init(avro_value_t *aobject, avro_schema_t *aschema, const char *json_schema, const char *json_data) { + char *out_buf; + size_t out_size; + int root_type; + + avro_value_iface_t *aclass = flb_avro_init(aobject, (char *)json_schema, strlen(json_schema), aschema); + TEST_CHECK(aclass != NULL); + + char *data = mk_file_to_buffer(json_data); + TEST_CHECK(data != NULL); + + size_t len = strlen(data); + + TEST_CHECK(flb_pack_json(data, len, &out_buf, &out_size, &root_type, NULL) == 0); + + msgpack_unpacked msg; + msgpack_unpacked_init(&msg); + TEST_CHECK(msgpack_unpack_next(&msg, out_buf, out_size, NULL) == MSGPACK_UNPACK_SUCCESS); + + avro_value_iface_decref(aclass); + flb_free(data); + flb_free(out_buf); + + return msg; +} +/* Unpack msgpack per avro schema */ +void test_unpack_to_avro() +{ + avro_value_t aobject; + avro_schema_t aschema; + + msgpack_unpacked mp = test_init(&aobject, &aschema, JSON_SINGLE_MAP_001_SCHEMA, AVRO_SINGLE_MAP1); + + msgpack_object_print(stderr, mp.data); + flb_msgpack_to_avro(&aobject, &mp.data); + + avro_value_t test_value; + TEST_CHECK(avro_value_get_by_name(&aobject, "key001", &test_value, NULL) == 0); + + int val001 = 0; + avro_value_get_int(&test_value, &val001); + TEST_CHECK(val001 == 123456789); + + TEST_CHECK(avro_value_get_by_name(&aobject, "key002", &test_value, NULL) == 0); + + float val002 = 0.0f; + // for some reason its rounding to this value + float val002_actual = 0.999888f; + avro_value_get_float(&test_value, &val002); + char str1[80]; + char str2[80]; + sprintf(str1, "%f", val002); + sprintf(str2, "%f", val002_actual); + flb_info("val002:%s:\n", str1); + flb_info("val002_actual:%s:\n", str2); + TEST_CHECK((strcmp(str1, str2) == 0)); + + TEST_CHECK(avro_value_get_by_name(&aobject, "key003", &test_value, NULL) == 0); + const char *val003 = NULL; + size_t val003_size = 0; + avro_value_get_string(&test_value, &val003, &val003_size); + flb_info("val003_size:%zu:\n", val003_size); + TEST_CHECK(val003[val003_size] == '\0'); + + TEST_CHECK((strcmp(val003, "abcdefghijk") == 0)); + // avro_value_get_by_name returns ths string length plus the NUL + TEST_CHECK(val003_size == 12); + + TEST_CHECK(avro_value_get_by_name(&aobject, "key004", &test_value, NULL) == 0); + + size_t asize = 0; + avro_value_get_size(&test_value, &asize); + flb_info("asize:%zu:\n", asize); + + TEST_CHECK(asize == 2); + + // check the first map + avro_value_t k8sRecord; + TEST_CHECK(avro_value_get_by_index(&test_value, 0, &k8sRecord, NULL) == 0); + + size_t msize = 0; + avro_value_get_size(&k8sRecord, &msize); + flb_info("msize:%zu:\n", msize); + + TEST_CHECK(msize == 2); + + avro_value_t obj_test; + const char *actual_key = NULL; + int actual = 0; + + // check the first item in the map + TEST_CHECK(avro_value_get_by_index(&k8sRecord, 0, &obj_test, &actual_key) == 0); + flb_info("actual_key:%s:\n", actual_key); + + TEST_CHECK(strcmp(actual_key, "a") == 0); + TEST_CHECK(avro_value_get_int(&obj_test, &actual) == 0); + TEST_CHECK(actual == 1); + + // check the second item in the map + TEST_CHECK(avro_value_get_by_index(&k8sRecord, 1, &obj_test, &actual_key) == 0); + flb_info("actual_key:%s:\n", actual_key); + + TEST_CHECK(strcmp(actual_key, "b") == 0); + TEST_CHECK(avro_value_get_int(&obj_test, &actual) == 0); + TEST_CHECK(actual == 2); + + // check the second map + TEST_CHECK(avro_value_get_by_index(&test_value, 1, &k8sRecord, NULL) == 0); + + avro_value_get_size(&k8sRecord, &msize); + flb_info("msize:%zu:\n", msize); + + TEST_CHECK(msize == 2); + + avro_value_decref(&aobject); + avro_schema_decref(aschema); + msgpack_unpacked_destroy(&mp); +} + +void test_parse_reordered_schema() +{ + // test same schema but different order of fields + const char *ts1 = "{\"name\":\"qavrov2_record\",\"type\":\"record\",\"fields\":[{\"name\":\"log\",\"type\":\"string\"},{\"name\":\"capture\",\"type\":\"string\"},{\"name\":\"kubernetes\",\"type\":{\"name\":\"krec\",\"type\":\"record\",\"fields\":[{\"name\":\"pod_name\",\"type\":\"string\"},{\"name\":\"namespace_name\",\"type\":\"string\"},{\"name\":\"pod_id\",\"type\":\"string\"},{\"name\":\"labels\",\"type\":{\"type\":\"map\",\"values\":\"string\"}},{\"name\":\"annotations\",\"type\":{\"type\":\"map\",\"values\":\"string\"}},{\"name\":\"host\",\"type\":\"string\"},{\"name\":\"container_name\",\"type\":\"string\"},{\"name\":\"docker_id\",\"type\":\"string\"},{\"name\":\"container_hash\",\"type\":\"string\"},{\"name\":\"container_image\",\"type\":\"string\"}]}}]}"; + const char *ts2 = "{\"name\":\"qavrov2_record\",\"type\":\"record\",\"fields\":[{\"name\":\"capture\",\"type\":\"string\"},{\"name\":\"log\",\"type\":\"string\"},{\"name\":\"kubernetes\",\"type\":{\"name\":\"krec\",\"type\":\"record\",\"fields\":[{\"name\":\"namespace_name\",\"type\":\"string\"},{\"name\":\"pod_name\",\"type\":\"string\"},{\"name\":\"pod_id\",\"type\":\"string\"},{\"name\":\"annotations\",\"type\":{\"type\":\"map\",\"values\":\"string\"}},{\"name\":\"labels\",\"type\":{\"type\":\"map\",\"values\":\"string\"}},{\"name\":\"host\",\"type\":\"string\"},{\"name\":\"container_name\",\"type\":\"string\"},{\"name\":\"docker_id\",\"type\":\"string\"},{\"name\":\"container_hash\",\"type\":\"string\"},{\"name\":\"container_image\",\"type\":\"string\"}]}}]}"; + const char *ts3 = "{\"name\":\"qavrov2_record\",\"type\":\"record\",\"fields\":[{\"name\":\"newnovalue\",\"type\":\"string\"},{\"name\":\"capture\",\"type\":\"string\"},{\"name\":\"log\",\"type\":\"string\"},{\"name\":\"kubernetes\",\"type\":{\"name\":\"krec\",\"type\":\"record\",\"fields\":[{\"name\":\"namespace_name\",\"type\":\"string\"},{\"name\":\"pod_name\",\"type\":\"string\"},{\"name\":\"pod_id\",\"type\":\"string\"},{\"name\":\"annotations\",\"type\":{\"type\":\"map\",\"values\":\"string\"}},{\"name\":\"labels\",\"type\":{\"type\":\"map\",\"values\":\"string\"}},{\"name\":\"host\",\"type\":\"string\"},{\"name\":\"container_name\",\"type\":\"string\"},{\"name\":\"docker_id\",\"type\":\"string\"},{\"name\":\"container_hash\",\"type\":\"string\"},{\"name\":\"container_image\",\"type\":\"string\"}]}}]}"; + + const char *schemas[] = {ts1, ts2, ts3, ts2, ts1, NULL}; + + int i=0; + for (i=0; schemas[i] != NULL ; i++) { + + avro_value_t aobject = {0}; + avro_schema_t aschema = {0}; + + msgpack_unpacked msg = test_init(&aobject, &aschema, schemas[i], AVRO_MULTILINE_JSON); + + msgpack_object_print(stderr, msg.data); + + flb_msgpack_to_avro(&aobject, &msg.data); + + avro_value_t log0; + TEST_CHECK(avro_value_get_by_name(&aobject, "log", &log0, NULL) == 0); + + size_t size1 = 0; + const char *log_line = NULL; + TEST_CHECK(avro_value_get_string(&log0, &log_line, &size1) == 0); + char *pre = "2020-08-21T15:49:48.154291375Z"; + TEST_CHECK((strncmp(pre, log_line, strlen(pre)) == 0)); + flb_info("log_line len:%zu:\n", strlen(log_line)); + + avro_value_t kubernetes0; + TEST_CHECK(avro_value_get_by_name(&aobject, "kubernetes", &kubernetes0, NULL) == 0); + + avro_value_get_size(&kubernetes0, &size1); + flb_info("asize:%zu:\n", size1); + TEST_CHECK(size1 == 10); + + avro_value_t pn; + TEST_CHECK(avro_value_get_by_name(&kubernetes0, "pod_name", &pn, NULL) == 0); + + const char *pod_name = NULL; + size_t pod_name_size = 0; + TEST_CHECK(avro_value_get_string(&pn, &pod_name, &pod_name_size) == 0); + TEST_CHECK(strcmp(pod_name, "rrrr-bert-completion-tb1-6786c9c8-wj25m") == 0); + TEST_CHECK(pod_name[pod_name_size] == '\0'); + TEST_CHECK(strlen(pod_name) == (pod_name_size-1)); + + avro_value_t nn; + TEST_CHECK(avro_value_get_by_name(&kubernetes0, "namespace_name", &nn, NULL) == 0); + + const char *namespace_name = NULL; + size_t namespace_name_size = 0; + TEST_CHECK(avro_value_get_string(&nn, &namespace_name, &namespace_name_size) == 0); + TEST_CHECK(strcmp(namespace_name, "k8s-fgg") == 0); + + avro_value_t mapX; + TEST_CHECK(avro_value_get_by_name(&kubernetes0, "annotations", &mapX, NULL) == 0); + + avro_value_get_size(&mapX, &size1); + flb_info("asize:%zu:\n", size1); + + TEST_CHECK(size1 == 5); + + // check the first item in the map + avro_value_t doas; + TEST_CHECK(avro_value_get_by_name(&mapX, "doAs", &doas, NULL) == 0); + const char *doaser = NULL; + size_t doaser_size; + TEST_CHECK(avro_value_get_string(&doas, &doaser, &doaser_size) == 0); + TEST_CHECK((strcmp(doaser, "weeb") == 0)); + + // check the second item in the map + avro_value_t iddecorator; + TEST_CHECK(avro_value_get_by_name(&mapX, "iddecorator.dkdk.username", &iddecorator, NULL) == 0); + const char *idder = NULL; + size_t idder_size; + TEST_CHECK(avro_value_get_string(&iddecorator, &idder, &idder_size) == 0); + TEST_CHECK((strcmp(idder, "rrrr") == 0)); + + avro_schema_decref(aschema); + msgpack_unpacked_destroy(&msg); + avro_value_decref(&aobject); + } + +} + +// int msgpack2avro(avro_value_t *val, msgpack_object *o) +// get a schema for a type like this: +// http://avro.apache.org/docs/current/api/c/index.html#_examples +// ../lib/msgpack-3.2.0/include/msgpack/pack.h +// static int msgpack_pack_nil(msgpack_packer* pk); +void test_msgpack2avro() +{ + avro_value_t aobject; + avro_schema_t schema = avro_schema_null(); + avro_value_iface_t *aclass = avro_generic_class_from_schema(schema); + avro_generic_value_new(aclass, &aobject); + + msgpack_sbuffer sbuf; + msgpack_packer pk; + msgpack_zone mempool; + msgpack_object deserialized; + + /* msgpack::sbuffer is a simple buffer implementation. */ + msgpack_sbuffer_init(&sbuf); + + /* serialize values into the buffer using msgpack_sbuffer_write callback function. */ + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + + msgpack_pack_nil(&pk); + + /* deserialize the buffer into msgpack_object instance. */ + /* deserialized object is valid during the msgpack_zone instance alive. */ + msgpack_zone_init(&mempool, 2048); + msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized); + + TEST_CHECK((msgpack2avro(&aobject, &deserialized) == FLB_TRUE)); + + msgpack_zone_destroy(&mempool); + msgpack_sbuffer_destroy(&sbuf); +} +const char JSON_SINGLE_MAP_001_SCHEMA_WITH_UNION[] = +"{\"type\":\"record\",\ + \"name\":\"Map001\",\ + \"fields\":[\ + {\"name\": \"key001\", \"type\": \"int\"},\ + {\"name\": \"key002\", \"type\": \"float\"},\ + {\"name\": \"key003\", \"type\": \"string\"},\ + { \ + \"name\": \"status\", \ + \"default\": null, \ + \"type\": [\"null\", \"string\"] \ + }, \ + {\"name\": \"key004\", \"type\":\ + {\"type\": \"array\", \"items\":\ + {\"type\": \"map\",\"values\": \"int\"}}}]}"; +void test_union_type_sanity() +{ + avro_value_t aobject; + avro_schema_t aschema; + + msgpack_unpacked msg = test_init(&aobject, &aschema, JSON_SINGLE_MAP_001_SCHEMA_WITH_UNION, AVRO_SINGLE_MAP1); + + msgpack_object_print(stderr, msg.data); + flb_msgpack_to_avro(&aobject, &msg.data); + + size_t totalSize = 0; + avro_value_get_size(&aobject, &totalSize); + flb_info("totalSize:%zu:\n", totalSize); + // this is key001,2,3,4 and the status field which is the union type + TEST_CHECK(totalSize == 5); + + avro_value_t test_value; + TEST_CHECK(avro_value_get_by_name(&aobject, "key001", &test_value, NULL) == 0); + + int val001 = 0; + avro_value_get_int(&test_value, &val001); + TEST_CHECK(val001 == 123456789); + + TEST_CHECK(avro_value_get_by_name(&aobject, "key002", &test_value, NULL) == 0); + + float val002 = 0.0f; + // for some reason its rounding to this value + float val002_actual = 0.999888f; + avro_value_get_float(&test_value, &val002); + char str1[80]; + char str2[80]; + sprintf(str1, "%f", val002); + sprintf(str2, "%f", val002_actual); + flb_info("val002:%s:\n", str1); + flb_info("val002_actual:%s:\n", str2); + TEST_CHECK((strcmp(str1, str2) == 0)); + + TEST_CHECK(avro_value_get_by_name(&aobject, "key003", &test_value, NULL) == 0); + const char *val003 = NULL; + size_t val003_size = 0; + TEST_CHECK(avro_value_get_string(&test_value, &val003, &val003_size) == 0); + flb_info("val003_size:%zu:\n", val003_size); + TEST_CHECK(val003[val003_size] == '\0'); + + TEST_CHECK((strcmp(val003, "abcdefghijk") == 0)); + // avro_value_get_by_name returns ths string length plus the NUL + TEST_CHECK(val003_size == 12); + + TEST_CHECK(avro_value_get_by_name(&aobject, "key004", &test_value, NULL) == 0); + + size_t asize = 0; + avro_value_get_size(&test_value, &asize); + flb_info("asize:%zu:\n", asize); + + TEST_CHECK(asize == 2); + + TEST_CHECK(avro_value_get_by_name(&aobject, "status", &test_value, NULL) == 0); + + avro_value_decref(&aobject); + avro_schema_decref(aschema); + msgpack_unpacked_destroy(&msg); +} + +void test_union_type_branches() +{ + avro_value_t aobject; + avro_schema_t aschema; + + msgpack_unpacked mp = test_init(&aobject, &aschema, JSON_SINGLE_MAP_001_SCHEMA_WITH_UNION, AVRO_SINGLE_MAP1); + + flb_msgpack_to_avro(&aobject, &mp.data); + + avro_value_t test_value; + TEST_CHECK(avro_value_get_by_name(&aobject, "status", &test_value, NULL) == 0); + TEST_CHECK(avro_value_get_type(&test_value) == AVRO_UNION); + + int discriminant = 0; + TEST_CHECK(avro_value_get_discriminant(&test_value, &discriminant) == 0); + TEST_CHECK(discriminant == -1); + + avro_value_t branch; + TEST_CHECK(avro_value_get_current_branch(&test_value, &branch) != 0); + + TEST_CHECK(avro_value_set_branch(&test_value, 0, &branch) == 0); + TEST_CHECK(avro_value_set_null(&branch) == 0); + + TEST_CHECK(avro_value_get_null(&branch) == 0); + + avro_value_decref(&aobject); + avro_schema_decref(aschema); + msgpack_unpacked_destroy(&mp); +} +TEST_LIST = { + /* Avro */ + { "msgpack_to_avro_basic", test_unpack_to_avro}, + { "test_parse_reordered_schema", test_parse_reordered_schema}, + { "test_union_type_sanity", test_union_type_sanity}, + { "test_union_type_branches", test_union_type_branches}, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/aws/CMakeLists.txt b/src/fluent-bit/tests/internal/aws/CMakeLists.txt new file mode 100644 index 000000000..1685c0e24 --- /dev/null +++ b/src/fluent-bit/tests/internal/aws/CMakeLists.txt @@ -0,0 +1,7 @@ +# AWS unit tests +set(UNIT_TESTS_FILES + placeholder.c + ) + +# Prepare list of unit tests +prepare_unit_tests(flb-it-aws_ "${UNIT_TESTS_FILES}") diff --git a/src/fluent-bit/tests/internal/aws/placeholder.c b/src/fluent-bit/tests/internal/aws/placeholder.c new file mode 100644 index 000000000..133c9a32d --- /dev/null +++ b/src/fluent-bit/tests/internal/aws/placeholder.c @@ -0,0 +1,11 @@ +#include "../flb_tests_internal.h" + +static void test_placeholder() +{ + return; +} + +TEST_LIST = { + { "placeholder" , test_placeholder }, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/aws_compress.c b/src/fluent-bit/tests/internal/aws_compress.c new file mode 100644 index 000000000..180a0985b --- /dev/null +++ b/src/fluent-bit/tests/internal/aws_compress.c @@ -0,0 +1,489 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include + +#include +#include "flb_tests_internal.h" + +#define FLB_AWS_COMPRESS_TEST_TYPE_COMPRESS 1 +#define FLB_AWS_COMPRESS_TEST_TYPE_B64_TRUNCATE 2 + +/* test case definition struct */ +struct flb_aws_test_case { + char* compression_keyword; + char* in_data; + char* expect_out_data_b64; + int expect_ret; +}; + +/* test loop function declarations */ +static unsigned char * base64_encode(const unsigned char *src, size_t len, + size_t *out_len); +static unsigned char * base64_decode(const unsigned char *src, size_t len, + size_t *out_len); +static void flb_aws_compress_general_test_cases(int test_type, + struct flb_aws_test_case *cases, + size_t max_out_len, + int(*decompress)(void *in_data, + size_t in_len, + void **out_data, + size_t *out_len)); +static void flb_aws_compress_test_cases(struct flb_aws_test_case *cases); +static void flb_aws_compress_truncate_b64_test_cases__gzip_decode( + struct flb_aws_test_case *cases, + size_t max_out_len); + +/** ------ Test Cases ------ **/ +void test_compression_gzip() +{ + struct flb_aws_test_case cases[] = + { + { + "gzip", + "hello hello hello hello hello hello", + "H4sIAAAAAAAA/8tIzcnJV8jARwIAVzdihSMAAAA=", + 0 + }, + { 0 } + }; + + flb_aws_compress_test_cases(cases); +} + +void test_b64_truncated_gzip() +{ +struct flb_aws_test_case cases[] = + { + { + "gzip", + "hello hello hello hello hello hello", + "hello hello hello hello hello hello", /* Auto decoded via gzip */ + 0 /* Expected ret */ + }, + { 0 } + }; + + flb_aws_compress_truncate_b64_test_cases__gzip_decode(cases, + 41); +} + +void test_b64_truncated_gzip_truncation() +{ +struct flb_aws_test_case cases[] = + { + { + "gzip", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp" + "or incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, qui" + "s nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequ" + "at. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum do" + "lore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proiden" + "t, sunt in culpa qui officia deserunt mollit anim id est laborum. xyz", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp" + "or incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, qui" + "s nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequ" + "at. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum do" + "lore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proiden" + "t, su[Truncated...]" + /*"nt in culpa qui officia deserunt mollit anim id est laborum. xyz",*/ + "", + 0 /* Expected ret */ + }, + { + "gzip", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp" + "or incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, qui" + "s nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequ" + "at. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum do" + "lore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proiden" + "t, sunt in culpa qui officia deserunt mollit anim id est laborum.", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp" + "or incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, qui" + "s nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequ" + "at. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum do" + "lore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proiden" + "t, sunt in culpa qui officia deserunt mollit anim id est laborum.", + 0 /* Expected ret */ + }, + { 0 } + }; + + flb_aws_compress_truncate_b64_test_cases__gzip_decode(cases, + 381); +} + +void test_b64_truncated_gzip_truncation_buffer_too_small() +{ +struct flb_aws_test_case cases[] = + { + { + "gzip", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp" + "or incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, qui" + "s nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequ" + "at. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum do" + "lore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proiden" + "t, sunt in culpa qui officia deserunt mollit anim id est laborum.", + "", + -1 /* Expected ret */ + }, + { + "gzip", + "", + "", + -1 /* Expected ret: Buffer too small */ + }, + { 0 } + }; + + flb_aws_compress_truncate_b64_test_cases__gzip_decode(cases, + 14); +} + +void test_b64_truncated_gzip_truncation_edge() +{ +struct flb_aws_test_case cases[] = + { + /*{ + "gzip", + "", + "", + 0 + }, *//* This test case fails, because GZIP can zip empty strings but not unzip */ + { + "gzip", + "[Truncated...]", /* Endless loop? */ + "", + -1 /* Expected ret */ + }, + { 0 } + }; + + flb_aws_compress_truncate_b64_test_cases__gzip_decode(cases, + 51); +} + +void test_b64_truncated_gzip_truncation_multi_rounds() +{ +struct flb_aws_test_case cases[] = + { + { + "gzip", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp" + "or incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, qui" + "s nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequ" + "at. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum do" + "lore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proiden" + "t, sunt in culpa qui officia deserunt mollit anim id est laborum." + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "", /* First half of the compression is heavy, the second half is light. */ + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp" + "or incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, qui" + "s nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequ" + "at. Duis aute irure dolor in reprehenderit in voluptate velit es" + "[Truncated...]", /* Bad estimation of resizing, 3 truncation iterations + * needed */ + 0 /* Expected ret */ + }, + { 0 } + }; + + flb_aws_compress_truncate_b64_test_cases__gzip_decode(cases, + 300); +} + +TEST_LIST = { + { "test_compression_gzip", test_compression_gzip }, + { "test_b64_truncated_gzip", test_b64_truncated_gzip }, + { "test_b64_truncated_gzip_truncation", test_b64_truncated_gzip_truncation }, + { "test_b64_truncated_gzip_truncation_buffer_too_small", + test_b64_truncated_gzip_truncation_buffer_too_small }, + { "test_b64_truncated_gzip_truncation_edge", + test_b64_truncated_gzip_truncation_edge }, + { "test_b64_truncated_gzip_truncation_multi_rounds", + test_b64_truncated_gzip_truncation_multi_rounds }, + { 0 } +}; + +/** ------ Helper Methods ------ **/ + +/* test case loop for flb_aws_compress */ +static void flb_aws_compress_test_cases(struct flb_aws_test_case *cases) +{ + flb_aws_compress_general_test_cases(FLB_AWS_COMPRESS_TEST_TYPE_COMPRESS, + cases, 0, NULL); +} + +/* test case loop for flb_aws_compress */ +static void flb_aws_compress_truncate_b64_test_cases__gzip_decode( + struct flb_aws_test_case *cases, + size_t max_out_len) +{ + flb_aws_compress_general_test_cases(FLB_AWS_COMPRESS_TEST_TYPE_B64_TRUNCATE, + cases, max_out_len, &flb_gzip_uncompress); +} + +/* General test case loop flb_aws_compress */ +static void flb_aws_compress_general_test_cases(int test_type, + struct flb_aws_test_case *cases, + size_t max_out_len, + int(*decompress)(void *in_data, + size_t in_len, + void **out_data, + size_t *out_len)) +{ + int ret; + size_t len; + int compression_type = FLB_AWS_COMPRESS_NONE; + unsigned char* out_data; + size_t out_data_len; + unsigned char* out_data_b64; + size_t out_data_b64_len; + struct flb_config *config; + struct flb_aws_test_case *tcase = cases; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + flb_config_exit(config); + + while (tcase->compression_keyword != 0) { + + size_t in_data_len = strlen(tcase->in_data); + compression_type = flb_aws_compression_get_type(tcase->compression_keyword); + + TEST_CHECK(compression_type != -1); + TEST_MSG("| flb_aws_get_compression_type: failed to get compression type for " + "keyword " + "%s", tcase->compression_keyword); + + if (test_type == FLB_AWS_COMPRESS_TEST_TYPE_COMPRESS) { + ret = flb_aws_compression_compress(compression_type, (void *) tcase->in_data, + in_data_len, (void **) &out_data, + &out_data_len); + } + else { + ret = flb_aws_compression_b64_truncate_compress(compression_type, max_out_len, + (void *) tcase->in_data, + in_data_len, + (void **) &out_data, + &out_data_len); + } + + TEST_CHECK(ret == tcase->expect_ret); + TEST_MSG("| Expected return value: %i", tcase->expect_ret); + TEST_MSG("| Produced return value: %i", ret); + + if (ret != 0) { + TEST_MSG("*- For input data: %s", tcase->in_data); + ++tcase; + continue; + } + + if (test_type == FLB_AWS_COMPRESS_TEST_TYPE_COMPRESS) { + out_data_b64 = base64_encode(out_data, out_data_len, &out_data_b64_len); + /* remove newline character which is a part of this encode algo */ + --out_data_b64_len; + flb_free(out_data); + out_data = NULL; + } + else { + /* decode b64 so we can compare plain text */ + out_data_b64 = base64_decode(out_data, out_data_len, &out_data_b64_len); + flb_free(out_data); + out_data = out_data_b64; + out_data_len = out_data_b64_len; + ret = decompress(out_data, out_data_len, (void *)&out_data_b64, + &out_data_b64_len); + flb_free(out_data); + out_data = NULL; + if (!TEST_CHECK(ret == 0)) { + TEST_MSG("| Decompression failure"); + out_data_b64 = flb_malloc(1); /* placeholder malloc */ + } + } + + ret = memcmp(tcase->expect_out_data_b64, out_data_b64, out_data_b64_len); + TEST_CHECK(ret == 0); + TEST_MSG("| Expected output(%s): %s", + (test_type == FLB_AWS_COMPRESS_TEST_TYPE_COMPRESS) + ? "b64" : "decompressed", tcase->expect_out_data_b64); + TEST_MSG("| Produced output(%s): %s", + (test_type == FLB_AWS_COMPRESS_TEST_TYPE_COMPRESS) + ? "b64" : "decompressed", out_data_b64); + + len = strlen(tcase->expect_out_data_b64); + TEST_CHECK(len == out_data_b64_len); + TEST_MSG("| Expected length: %zu", len); + TEST_MSG("| Produced length: %zu", out_data_b64_len); + + TEST_MSG("*- For input data: %s", tcase->in_data); + + flb_free(out_data_b64); + ++tcase; + } +} + +/* B64 check script copied from Monkey Auth Plugin */ +/* Change log: + * Removed auto new line entry from every 72 characters to make consistant with + * the actual base64 conversion + */ +/* Copied from monkey/plugins/auth/base64.c */ + +#define __mem_alloc malloc +#define __mem_free free + +static const unsigned char base64_table[65] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/** + * base64_encode - Base64 encode + * @src: Data to be encoded + * @len: Length of the data to be encoded + * @out_len: Pointer to output length variable, or %NULL if not used + * Returns: Allocated buffer of out_len bytes of encoded data, + * or %NULL on failure + * + * Caller is responsible for freeing the returned buffer. Returned buffer is + * nul terminated to make it easier to use as a C string. The nul terminator is + * not included in out_len. + */ +static unsigned char * base64_encode(const unsigned char *src, size_t len, + size_t *out_len) +{ + unsigned char *out, *pos; + const unsigned char *end, *in; + size_t olen; + size_t line_len; + + olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */ + olen += olen / 72; /* line feeds */ + olen++; /* nul termination */ + if (olen < len) + return NULL; /* integer overflow */ + + out = __mem_alloc(olen); + + if (out == NULL) + return NULL; + + end = src + len; + in = src; + pos = out; + line_len = 0; + while (end - in >= 3) { + *pos++ = base64_table[in[0] >> 2]; + *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; + *pos++ = base64_table[in[2] & 0x3f]; + in += 3; + line_len += 4; + } + + if (end - in) { + *pos++ = base64_table[in[0] >> 2]; + if (end - in == 1) { + *pos++ = base64_table[(in[0] & 0x03) << 4]; + *pos++ = '='; + } else { + *pos++ = base64_table[((in[0] & 0x03) << 4) | + (in[1] >> 4)]; + *pos++ = base64_table[(in[1] & 0x0f) << 2]; + } + *pos++ = '='; + line_len += 4; + } + + if (line_len) + *pos++ = '\n'; + + *pos = '\0'; + if (out_len) + *out_len = pos - out; + return out; +} + +/** + * base64_decode - Base64 decode + * @src: Data to be decoded + * @len: Length of the data to be decoded + * @out_len: Pointer to output length variable + * Returns: Allocated buffer of out_len bytes of decoded data, + * or %NULL on failure + * + * Caller is responsible for freeing the returned buffer. + */ +static unsigned char * base64_decode(const unsigned char *src, size_t len, + size_t *out_len) +{ + unsigned char dtable[256], *out, *pos, block[4], tmp; + size_t i, count, olen; + int pad = 0; + + memset(dtable, 0x80, 256); + for (i = 0; i < sizeof(base64_table) - 1; i++) + dtable[base64_table[i]] = (unsigned char) i; + dtable['='] = 0; + + count = 0; + for (i = 0; i < len; i++) { + if (dtable[src[i]] != 0x80) + count++; + } + + if (count == 0 || count % 4) + return NULL; + + olen = (count / 4 * 3) + 1; + pos = out = __mem_alloc(olen); + if (out == NULL) + return NULL; + + count = 0; + for (i = 0; i < len; i++) { + tmp = dtable[src[i]]; + if (tmp == 0x80) + continue; + + if (src[i] == '=') + pad++; + block[count] = tmp; + count++; + if (count == 4) { + *pos++ = (block[0] << 2) | (block[1] >> 4); + *pos++ = (block[1] << 4) | (block[2] >> 2); + *pos++ = (block[2] << 6) | block[3]; + count = 0; + if (pad) { + if (pad == 1) + pos--; + else if (pad == 2) + pos -= 2; + else { + /* Invalid padding */ + __mem_free(out); + return NULL; + } + break; + } + } + } + *pos = '\0'; + + *out_len = pos - out; + return out; +} + +/* End of copied base64.c from monkey */ diff --git a/src/fluent-bit/tests/internal/aws_credentials.c b/src/fluent-bit/tests/internal/aws_credentials.c new file mode 100644 index 000000000..2f8a670e0 --- /dev/null +++ b/src/fluent-bit/tests/internal/aws_credentials.c @@ -0,0 +1,382 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include + +#include "flb_tests_internal.h" + +#define ACCESS_KEY "akid" +#define SECRET_KEY "skid" +#define TOKEN "token" + +/* Credentials Environment Variables */ +#define AWS_ACCESS_KEY_ID "AWS_ACCESS_KEY_ID" +#define AWS_SECRET_ACCESS_KEY "AWS_SECRET_ACCESS_KEY" +#define AWS_SESSION_TOKEN "AWS_SESSION_TOKEN" + + +static void unsetenv_credentials() +{ + int ret; + + ret = unsetenv(AWS_ACCESS_KEY_ID); + if (ret < 0) { + flb_errno(); + return; + } + ret = unsetenv(AWS_SECRET_ACCESS_KEY); + if (ret < 0) { + flb_errno(); + return; + } + ret = unsetenv(AWS_SESSION_TOKEN); + if (ret < 0) { + flb_errno(); + return; + } +} + +/* test for the env provider */ +static void test_environment_provider() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + struct flb_config *config; + int ret; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + /* set environment */ + ret = setenv(AWS_ACCESS_KEY_ID, ACCESS_KEY, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(AWS_SECRET_ACCESS_KEY, SECRET_KEY, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(AWS_SESSION_TOKEN, TOKEN, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_aws_env_provider_create(); + if (!provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(TOKEN, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(TOKEN, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + unsetenv_credentials(); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); +} + +/* token is not required */ +static void test_environment_provider_no_token() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + struct flb_config *config; + int ret; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + /* set environment */ + ret = setenv(AWS_ACCESS_KEY_ID, ACCESS_KEY, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(AWS_SECRET_ACCESS_KEY, SECRET_KEY, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_aws_env_provider_create(); + if (!provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(creds->session_token == NULL); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(creds->session_token == NULL); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + unsetenv_credentials(); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); +} + +/* access and secret key are required */ +static void test_environment_provider_only_access() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + struct flb_config *config; + int ret; + + unsetenv_credentials(); + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + /* set environment */ + ret = setenv(AWS_ACCESS_KEY_ID, ACCESS_KEY, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_aws_env_provider_create(); + if (!provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + flb_aws_credentials_destroy(creds); + + /* refresh should return -1 (failure) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret < 0); + + unsetenv_credentials(); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); +} + +/* test the env provider when no cred env vars are set */ +static void test_environment_provider_unset() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + struct flb_config *config; + int ret; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + unsetenv_credentials(); + + provider = flb_aws_env_provider_create(); + if (!provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* refresh should return -1 (failure) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret < 0); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); +} + +static void test_credential_expiration() +{ + struct tm tm = {0}; + /* one hour in the future */ + time_t exp_expected = time(NULL) + 3600; + char time_stamp[50]; + time_t exp_actual; + TEST_CHECK(gmtime_r(&exp_expected, &tm) != NULL); + + TEST_CHECK(strftime(time_stamp, 50, "%Y-%m-%dT%H:%M:%SZ", &tm) > 0); + + exp_actual = flb_aws_cred_expiration(time_stamp); + + TEST_CHECK(exp_actual == exp_expected); +} + +static void test_standard_chain_provider() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + struct flb_config *config; + int ret; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + /* set environment */ + ret = setenv(AWS_ACCESS_KEY_ID, ACCESS_KEY, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(AWS_SECRET_ACCESS_KEY, SECRET_KEY, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(AWS_SESSION_TOKEN, TOKEN, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_standard_chain_provider_create(config, NULL, "us-west-2", + "https://sts.us-west-2.amazonaws.com", + NULL, + flb_aws_client_generator(), + NULL); + if (!provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(TOKEN, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(TOKEN, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + unsetenv_credentials(); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); +} + +TEST_LIST = { + { "test_credential_expiration" , test_credential_expiration}, + { "environment_credential_provider" , test_environment_provider}, + { "environment_provider_no_token" , test_environment_provider_no_token}, + { "environment_provider_only_access_key" , + test_environment_provider_only_access}, + { "environment_credential_provider_unset" , + test_environment_provider_unset}, + { "test_standard_chain_provider" , test_standard_chain_provider}, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/aws_credentials_ec2.c b/src/fluent-bit/tests/internal/aws_credentials_ec2.c new file mode 100644 index 000000000..6370b1561 --- /dev/null +++ b/src/fluent-bit/tests/internal/aws_credentials_ec2.c @@ -0,0 +1,1037 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include "../include/aws_client_mock.h" +#include "../include/aws_client_mock.c" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "flb_tests_internal.h" + +/* Global variables for tests */ +struct flb_aws_provider *provider; +struct flb_aws_credentials *creds; +struct flb_config *config; +struct flb_config *config_fluent; +int ret; + +/* + * Hardcoding a copy of the ec2 credential provider struct from flb_aws_credentials_ec2.c + * Note: this will require a change if the other copy is changed. + * A provider that obtains credentials from EC2 IMDS. + */ +struct flb_aws_provider_ec2 { + struct flb_aws_credentials *creds; + time_t next_refresh; + + /* upstream connection to IMDS */ + struct flb_aws_client *client; + + /* IMDS interface */ + struct flb_aws_imds *imds_interface; +}; + +/* + * Setup test & Initialize test environment + * Required for fluent bit debug logs + * Note: Log level definitions do not work. + * Example: config_fluent->verbose = FLB_LOG_OFF + */ +void setup_test(struct flb_aws_client_mock_request_chain *request_chain) { + /* Initialize test environment */ + config_fluent = flb_config_init(); + + flb_aws_client_mock_configure_generator(request_chain); + + /* Init provider */ + config = flb_calloc(1, sizeof(struct flb_config)); + TEST_ASSERT(config != NULL); + mk_list_init(&config->upstreams); + provider = flb_ec2_provider_create(config, flb_aws_client_get_mock_generator()); + TEST_ASSERT(provider != NULL); +} + +/* Test clean up */ +void cleanup_test() { + flb_aws_client_mock_destroy_generator(); + if (provider != NULL) { + ((struct flb_aws_provider_ec2 *) (provider->implementation))->client = NULL; + flb_aws_provider_destroy(provider); + provider = NULL; + } + if (config != NULL) { + flb_free(config); + } + if (config_fluent != NULL) { + flb_config_exit(config_fluent); + config_fluent = NULL; + } +} + +/* + * IMDSv2 -- Test Summary + * First call to get_credentials(): + * -> 2 requests are made to obtain IMDSv2 token + * -> 2 requests are made to access credentials + * Second call to get_credentials() hits cache: + * -> 0 requests are made + * refresh(): + * -> 2 requests are made to access credentials + */ +static void test_ec2_provider_v2() +{ + setup_test(FLB_AWS_CLIENT_MOCK( + /* First call to get_credentials() */ + response( + expect(URI, "/"), + expect(HEADER, "X-aws-ec2-metadata-token", "INVALID"), + expect(METHOD, FLB_HTTP_GET), + set(STATUS, 401) + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + set(STATUS, 200), + set(PAYLOAD, "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(PAYLOAD_SIZE, 56) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "My_Instance_Name"), + set(PAYLOAD_SIZE, 16) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2021-09-16T18:29:09Z\",\n" + " \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"XACCESSEC2XXX\",\n \"SecretAccessKey\"" + " : \"XSECRETEC2XXXXXXXXXXXXXX\",\n \"Token\" : \"XTOKENEC2XXXXXXXXXXXXXXX==\",\n" + " \"Expiration\" : \"3021-09-17T00:41:00Z\"\n}"), /* Expires Year 3021 */ + set(PAYLOAD_SIZE, 257) + ), + + /* Second call to get_credentials() hits cache */ + + /* Refresh credentials (No token refesh) */ + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "My_Instance_Name_New"), + set(PAYLOAD_SIZE, 20) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name_New"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2021-09-16T18:29:09Z\",\n" + " \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"YACCESSEC2XXX\",\n \"SecretAccessKey\"" + " : \"YSECRETEC2XXXXXXXXXXXXXX\",\n \"Token\" : \"YTOKENEC2XXXXXXXXXXXXXXX==\",\n" + " \"Expiration\" : \"3021-09-17T00:41:00Z\"\n}"), // Expires Year 3021 + set(PAYLOAD_SIZE, 257) + ) + )); + + /* Repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Retrieve from cache */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + /* Retrieve refreshed credentials from cache */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("YACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("YSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("YTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Check we have exhausted our response list */ + TEST_CHECK(flb_aws_client_mock_generator_count_unused_requests() == 0); + + cleanup_test(); +} + +/* + * IMDSv1 -- Fallback Test Summary + * First call to get_credentials(): + * -> 1 requests is made to test for IMDSv2 + * -> 2 requests are made to access credentials + * Second call to get_credentials() hits cache + * -> 0 requests are made + * refresh(): + * -> 2 requests are made to access credentials + */ +static void test_ec2_provider_v1() +{ + setup_test(FLB_AWS_CLIENT_MOCK( + /* First call to get_credentials() */ + response( + expect(URI, "/"), + expect(HEADER, "X-aws-ec2-metadata-token", "INVALID"), + expect(HEADER_COUNT, 1), + expect(METHOD, FLB_HTTP_GET), + set(STATUS, 200) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER_COUNT, 0), + set(STATUS, 200), + set(PAYLOAD, "My_Instance_Name"), + set(PAYLOAD_SIZE, 16) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER_COUNT, 0), + set(STATUS, 200), + set(PAYLOAD, "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2021-09-16T18:29:09Z\",\n" + " \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"XACCESSEC2XXX\",\n \"SecretAccessKey\"" + " : \"XSECRETEC2XXXXXXXXXXXXXX\",\n \"Token\" : \"XTOKENEC2XXXXXXXXXXXXXXX==\",\n" + " \"Expiration\" : \"3021-09-17T00:41:00Z\"\n}"), /* Expires Year 3021 */ + set(PAYLOAD_SIZE, 257) + ), + + /* Second call to get_credentials() hits cache */ + + /* Refresh credentials (No token refesh) */ + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER_COUNT, 0), + set(STATUS, 200), + set(PAYLOAD, "My_Instance_Name_New"), + set(PAYLOAD_SIZE, 20) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name_New"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER_COUNT, 0), + set(STATUS, 200), + set(PAYLOAD, "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2021-09-16T18:29:09Z\",\n" + " \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"YACCESSEC2XXX\",\n \"SecretAccessKey\"" + " : \"YSECRETEC2XXXXXXXXXXXXXX\",\n \"Token\" : \"YTOKENEC2XXXXXXXXXXXXXXX==\",\n" + " \"Expiration\" : \"3021-09-17T00:41:00Z\"\n}"), // Expires Year 3021 + set(PAYLOAD_SIZE, 257) + ) + )); + + /* Repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Retrieve from cache */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + /* Retrieve refreshed credentials from cache */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("YACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("YSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("YTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Check we have exhausted our response list */ + TEST_CHECK(flb_aws_client_mock_generator_count_unused_requests() == 0); + + cleanup_test(); +} + +/* + * IMDSv1 -- IMDSv2 Timeout, Fallback Test Summary + * First call to get_credentials(): + * -> 1 requests is made to test for IMDSv2 (IMDSv2) + * -> 1 request made to get token (Timeout failure) + * -> 1 request made to check IMDSv1 fallback (Failure - IMDSv1 not allowed) + * + * Second call to get_credentials(): + * -> 1 requests is made to test for IMDSv2 (IMDSv2) + * -> 1 request made to get token (Timeout failure) + * -> 1 request made to check IMDSv1 fallback (Success) + * -> 2 requests are made to access credentials + * Second call to get_credentials() hits cache + * -> 0 requests are made + * refresh(): + * -> 2 requests are made to access credentials + */ +static void test_ec2_provider_v1_v2_timeout() +{ + setup_test(FLB_AWS_CLIENT_MOCK( + /* First call to get_credentials() */ + response( + expect(URI, "/"), + expect(HEADER, "X-aws-ec2-metadata-token", "INVALID"), + expect(HEADER_COUNT, 1), + expect(METHOD, FLB_HTTP_GET), + set(STATUS, 401) + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + config(REPLACE, (struct flb_http_client *) NULL) /* Replicate timeout failure */ + ), + response( + expect(URI, "/"), + expect(METHOD, FLB_HTTP_GET), + set(STATUS, 401) /* IMDSv1 not allowed */ + ), + + /* Second call to get_credentials() */ + response( + expect(URI, "/"), + expect(HEADER, "X-aws-ec2-metadata-token", "INVALID"), + expect(HEADER_COUNT, 1), + expect(METHOD, FLB_HTTP_GET), + set(STATUS, 401) + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + config(REPLACE, (struct flb_http_client *) NULL) /* Replicate timeout failure */ + ), + response( + expect(URI, "/"), + expect(METHOD, FLB_HTTP_GET), + set(STATUS, 200) /* IMDSv1 is allowed */ + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER_COUNT, 0), + set(STATUS, 200), + set(PAYLOAD, "My_Instance_Name"), + set(PAYLOAD_SIZE, 16) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER_COUNT, 0), + set(STATUS, 200), + set(PAYLOAD, "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2021-09-16T18:29:09Z\",\n" + " \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"XACCESSEC2XXX\",\n \"SecretAccessKey\"" + " : \"XSECRETEC2XXXXXXXXXXXXXX\",\n \"Token\" : \"XTOKENEC2XXXXXXXXXXXXXXX==\",\n" + " \"Expiration\" : \"3021-09-17T00:41:00Z\"\n}"), /* Expires Year 3021 */ + set(PAYLOAD_SIZE, 257) + ), + + /* Second call to get_credentials() hits cache */ + + /* Refresh credentials (No token refesh) */ + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER_COUNT, 0), + set(STATUS, 200), + set(PAYLOAD, "My_Instance_Name_New"), + set(PAYLOAD_SIZE, 20) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name_New"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER_COUNT, 0), + set(STATUS, 200), + set(PAYLOAD, "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2021-09-16T18:29:09Z\",\n" + " \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"YACCESSEC2XXX\",\n \"SecretAccessKey\"" + " : \"YSECRETEC2XXXXXXXXXXXXXX\",\n \"Token\" : \"YTOKENEC2XXXXXXXXXXXXXXX==\",\n" + " \"Expiration\" : \"3021-09-17T00:41:00Z\"\n}"), // Expires Year 3021 + set(PAYLOAD_SIZE, 257) + ) + )); + + /* First call: IMDSv1 and IMDSv2 not accessible */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds == NULL); + + /* + * Second call: IMDSv2 timeout, IMDSv1 accessible + * Repeated calls to get credentials should return the same set + */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Retrieve from cache */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + /* Retrieve refreshed credentials from cache */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("YACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("YSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("YTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Check we have exhausted our response list */ + TEST_CHECK(flb_aws_client_mock_generator_count_unused_requests() == 0); + + cleanup_test(); +} + + +/* + * IMDS Version Detection Error -- Test Summary + * First call to get_credentials(): + * -> 1 request made to test for IMDSv2 (Fails, 404) + * Second call to get_credentials(): + * -> 1 request made to test for IMDSv2 (Fails, null http_client) + * Third call to get_credentials(): + * -> 1 request made to test for IMDSv2 (Success) + * -> 1 request made to get token (Failure) + * Fourth call to get_credentials(): + * -> 2 requests made to obtain IMDSv2 token (Success) + * -> 2 requests made to access credentials (Success) + */ +static void test_ec2_provider_version_detection_error() +{ + setup_test(FLB_AWS_CLIENT_MOCK( + /* First call to get_credentials(): Version detection failure */ + response( + expect(URI, "/"), + expect(HEADER, "X-aws-ec2-metadata-token", "INVALID"), + expect(HEADER_COUNT, 1), + expect(METHOD, FLB_HTTP_GET), + set(STATUS, 404) // IMDS not found (not likely to happen) + ), + + /* Second call to get_credentials(): Version detection failure */ + response( + expect(URI, "/"), + expect(HEADER, "X-aws-ec2-metadata-token", "INVALID"), + expect(METHOD, FLB_HTTP_GET), + config(REPLACE, (struct flb_http_client *) NULL) + ), + + /* Third call to get_credentials(): Version detection success */ + response( + expect(URI, "/"), + expect(HEADER, "X-aws-ec2-metadata-token", "INVALID"), + expect(METHOD, FLB_HTTP_GET), + set(STATUS, 401) + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + set(STATUS, 200), + set(PAYLOAD, "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(PAYLOAD_SIZE, 56) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "My_Instance_Name"), + set(PAYLOAD_SIZE, 16) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2021-09-16T18:29:09Z\",\n" + " \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"XACCESSEC2XXX\",\n \"SecretAccessKey\"" + " : \"XSECRETEC2XXXXXXXXXXXXXX\",\n \"Token\" : \"XTOKENEC2XXXXXXXXXXXXXXX==\",\n" + " \"Expiration\" : \"3021-09-17T00:41:00Z\"\n}"), /* Expires Year 3021 */ + set(PAYLOAD_SIZE, 257) + ) + )); + + /* Version detection failure: Status 404 */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* Version detection failure: NULL response */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* Version detection success: IMDSv2 */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Retrieve from cache */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Check we have exhausted our response list */ + TEST_CHECK(flb_aws_client_mock_generator_count_unused_requests() == 0); + + cleanup_test(); +} + +/* + * IMDS Aquire Token Error -- Test Summary + * First call to get_credentials(): + * -> 1 request made to test for IMDSv2 (Success) + * -> 1 request made to obtain IMDSv2 token (Fails) <-* Aquire token error + * -> 1 request made to check IMDSv1 fallback (Unauthorized) + * Second call to get_credentials(): + * -> 1 request made to access instance name (Invalid token) + * -> 1 request made to obtain IMDSv2 token (Success) + * -> 1 request made to access instance name (Success) + * -> 1 request made to access credentials (Invalid token) + * -> 1 request made to obtain IMDSv2 token (Fails) <-* Aquire token error + * Third call to get_credentials(): + * -> 1 request made to access instance name (Invalid token) + * -> 1 request made to obtain IMDSv2 token (Success) + * -> 1 request made to access instance name (Success) + * -> 1 request made to access credentials (Invalid token) + * -> 1 request made to obtain IMDSv2 token (Success) + * -> 1 request made to access credentials (Success, but credentials are expired as of Year 2000) + * Fourth call to get_credentials(): - hits expired cache + * -> 1 request made to access credentials (Invalid token) + * -> 1 request made to obtain IMDSv2 token (http_client is null) <-* Aquire token error + * Fifth call to get_credentials(): - hits expired cache + * -> 1 request made to access credentials (Invalid token) + * -> 1 request made to obtain IMDSv2 token (Success) + * -> 2 requests are made to access credentials + */ +static void test_ec2_provider_acquire_token_error() +{ + setup_test(FLB_AWS_CLIENT_MOCK( + + /* + * First call to get_credentials(): + * -> 1 request made to test for IMDSv2 (Success) + * -> 1 request made to obtain IMDSv2 token (Fails) <-* Aquire token error + * -> 1 request made to check IMDSv1 fallback (Unauthorized) + */ + response( + expect(URI, "/"), + expect(HEADER, "X-aws-ec2-metadata-token", "INVALID"), /* Why is this not invalid_token? */ + expect(HEADER_COUNT, 1), + expect(METHOD, FLB_HTTP_GET), + set(STATUS, 401) /* IMDSv2 */ + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + config(REPLACE, NULL) /* HTTP Client is null */ + ), + response( + expect(URI, "/"), + expect(METHOD, FLB_HTTP_GET), + set(STATUS, 401) /* IMDSv1 not allowed */ + ), + + /* + * Second call to get_credentials(): + * -> 1 request made to test for IMDSv2 (Success) + * -> 1 request made to obtain IMDSv2 token (Success) <-* Bad token + * -> 1 request made to access instance name (Invalid token) + * -> 1 request made to obtain IMDSv2 token (Success) + * -> 1 request made to access instance name (Success) + * -> 1 request made to access credentials (Invalid token) + * -> 1 request made to obtain IMDSv2 token (Fails) <-* Aquire token error + */ + response( + expect(URI, "/"), + expect(HEADER, "X-aws-ec2-metadata-token", "INVALID"), /* Why is this not invalid_token? */ + expect(HEADER_COUNT, 1), + expect(METHOD, FLB_HTTP_GET), + set(STATUS, 401) /* IMDSv2 */ + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + set(STATUS, 200), + set(PAYLOAD, "BAD_ANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(PAYLOAD_SIZE, 56) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "BAD_ANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), /* Token failed to be set */ + set(STATUS, 401) /* Unauthorized, bad token */ + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + set(STATUS, 200), + set(PAYLOAD, "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(PAYLOAD_SIZE, 56) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "My_Instance_Name"), + set(PAYLOAD_SIZE, 16) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 401) /* Unauthorized, bad token */ + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + set(STATUS, 404), /* This should never actually happen */ + set(PAYLOAD, "Token not found"), + set(PAYLOAD_SIZE, 15) + ), + + /* + * Third call to get_credentials(): +  * -> 1 request made to access instance name (Invalid token) +  * -> 1 request made to obtain IMDSv2 token (Success) +  * -> 1 request made to access instance name (Success) +  * -> 1 request made to access credentials (Invalid token) +  * -> 1 request made to obtain IMDSv2 token (Success) +  * -> 1 request made to access credentials (Success, but credentials are expired as of Year 2000) + */ + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), /* Token failed to be set */ + set(STATUS, 401) /* Unauthorized, bad token */ + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + set(STATUS, 200), + set(PAYLOAD, "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(PAYLOAD_SIZE, 56) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "My_Instance_Name"), + set(PAYLOAD_SIZE, 16) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 401) /* Unauthorized, bad token */ + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + set(STATUS, 200), + set(PAYLOAD, "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(PAYLOAD_SIZE, 56) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2021-09-16T18:29:09Z\",\n" + " \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"XACCESSEC2XXX\",\n \"SecretAccessKey\"" + " : \"XSECRETEC2XXXXXXXXXXXXXX\",\n \"Token\" : \"XTOKENEC2XXXXXXXXXXXXXXX==\",\n" + " \"Expiration\" : \"2000-09-17T00:41:00Z\"\n}"), /* Expires Year 2000 */ + set(PAYLOAD_SIZE, 257) + ), + + /* + * Fourth call to get_credentials(): - hits expired cache + * -> 1 request made to access credentials (Invalid token) + * -> 1 request made to obtain IMDSv2 token (http_client is null) <-* Aquire token error + */ + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 401) /* Unauthorized, bad token */ + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + config(REPLACE, NULL) /* HTTP Client is null */ + ), + + /* + * Fifth call to get_credentials(): - hits expired cache + * -> 1 request made to access credentials (Invalid token) + * -> 1 request made to obtain IMDSv2 token (Success) + * -> 2 requests are made to access credentials + */ + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 401) /* Unauthorized, bad token */ + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + set(STATUS, 200), + set(PAYLOAD, "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(PAYLOAD_SIZE, 56) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "My_Instance_Name"), + set(PAYLOAD_SIZE, 16) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2021-09-16T18:29:09Z\",\n" + " \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"YACCESSEC2XXX\",\n \"SecretAccessKey\"" + " : \"YSECRETEC2XXXXXXXXXXXXXX\",\n \"Token\" : \"YTOKENEC2XXXXXXXXXXXXXXX==\",\n" + " \"Expiration\" : \"3021-09-17T00:41:00Z\"\n}"), /* Expires Year 3021 */ + set(PAYLOAD_SIZE, 257) + ) + )); + + /* 1. Aquire token error */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* 2. Aquire token error */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* 3. Aquire token success */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* 4. Aquire token error */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); /* Remains unchanged */ + + /* 5. Aquire token success */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("YACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("YSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("YTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Check we have exhausted our response list */ + TEST_CHECK(flb_aws_client_mock_generator_count_unused_requests() == 0); + + cleanup_test(); +} + +/* + * IMDS Metadata Request Failure -- Test Summary + * First call to get_credentials(): + * -> 2 requests are made to obtain IMDSv2 token + * -> 1 request is made to access instance name (fails, null client) + * Second call to get_credentials(): -- token cached + * -> 1 request is made to access instance name (success) + * -> 1 request is made to access credentials (fails, 404) + * Third call to get_credentials(): -- token cached + * -> 1 request is made to access instance name + * -> 1 request is made to access credentials (fails, garbage fuzz input) + * Fourth call to get_credentials(): -- token cached + * -> 1 request is made to access instance name + * -> 1 request is made to access credentials (success) + */ +static void test_ec2_provider_metadata_request_error() +{ + setup_test(FLB_AWS_CLIENT_MOCK( + /* First call to get_credentials() */ + response( + expect(URI, "/"), + expect(HEADER, "X-aws-ec2-metadata-token", "INVALID"), + expect(METHOD, FLB_HTTP_GET), + set(STATUS, 401) + ), + response( + expect(URI, "/latest/api/token"), + expect(HEADER, "X-aws-ec2-metadata-token-ttl-seconds", "21600"), /* 6 hours */ + expect(METHOD, FLB_HTTP_PUT), + set(STATUS, 200), + set(PAYLOAD, "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(PAYLOAD_SIZE, 56) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + config(REPLACE, NULL) + ), + + /* Second call to get_credentials() */ + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "My_Instance_Name"), + set(PAYLOAD_SIZE, 16) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 404), + set(PAYLOAD, "IMDS server not found"), /* This should never happen */ + set(PAYLOAD_SIZE, 21) + ), + + /* Third call to get_credentials() */ + response( + expect(URI, "/latest/meta-data/iam/security-credentials/"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, "My_Instance_Name"), + set(PAYLOAD_SIZE, 16) + ), + response( + expect(URI, "/latest/meta-data/iam/security-credentials/My_Instance_Name"), + expect(METHOD, FLB_HTTP_GET), + expect(HEADER, "X-aws-ec2-metadata-token", "AQAAANjUxxxxxxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_Q=="), + set(STATUS, 200), + set(PAYLOAD, ("{tsJ@&K+Xo9?'a,uxb)=/iZg\"M4B\\&,qb" + "Y\\%%niHubN^I[#arpu9|A':W!JZ@?frM|\"" + "?aVK~provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* Second call to get_credentials() */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* Third call to get_credentials() */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* Fourth call to get_credentials() */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Retrieve from cache */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + TEST_CHECK(strcmp("XACCESSEC2XXX", creds->access_key_id) == 0); + TEST_CHECK(strcmp("XSECRETEC2XXXXXXXXXXXXXX", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("XTOKENEC2XXXXXXXXXXXXXXX==", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* Check we have exhausted our response list */ + TEST_CHECK(flb_aws_client_mock_generator_count_unused_requests() == 0); + + cleanup_test(); +} + +/* IMDS specific testing */ + +/* + * IMDS Creation and Destruction -- Test Summary + * First call to flb_aws_imds_create (fail) + * -> upstream not set + * Second call to flb_aws_imds_create (fail) + * -> upstream set + * -> upstream tcp not equal to IMDS (random text) + * Third call to flb_aws_imds_create (fail) + * -> upstream set + * -> upstream tcp not equal to IMDS (one fewer character) + * Fourth call to flb_aws_imds_create (fail) + * -> upstream set + * -> upstream tcp not equal to IMDS (one extra character) + * Fifth call to flb_aws_imds_create (fail) + * -> upstream set + * -> upstream tcp equal to IMDS address + * -> upstream port not equal to IMDS port (number 0) + * Sixth call to flb_aws_imds_create (success) + * -> upstream set + * -> upstream tcp equal to IMDS address + * -> upstream port equal to IMDS port (80) + * First call to flb_aws_imds_destroy (success) + */ +static void test_ec2_imds_create_and_destroy() +{ + /* Full test setup not needed */ + /* Initialize test environment */ + config_fluent = flb_config_init(); + + struct flb_aws_imds_config i_config = flb_aws_imds_config_default; + struct flb_aws_client a_client = { 0 }; + struct flb_aws_imds* imds; + + struct flb_upstream u_stream = { 0 }; + + /* First call to flb_aws_imds_create */ + imds = flb_aws_imds_create(&i_config, &a_client); + TEST_CHECK(imds == NULL); + + /* Second call to flb_aws_imds_create */ + a_client.upstream = &u_stream; + u_stream.tcp_host = "Invalid host"; + imds = flb_aws_imds_create(&i_config, &a_client); + TEST_CHECK(imds == NULL); + + /* Third call to flb_aws_imds_create */ + u_stream.tcp_host = "169.254.169.254ExtraInvalid"; + imds = flb_aws_imds_create(&i_config, &a_client); + TEST_CHECK(imds == NULL); + + /* Fourth call to flb_aws_imds_create */ + u_stream.tcp_host = "169.254.169.254"; + u_stream.tcp_port = 0xBAD; + imds = flb_aws_imds_create(&i_config, &a_client); + TEST_CHECK(imds == NULL); + + /* Fifth call to flb_aws_imds_create */ + u_stream.tcp_host = "169.254.169.254"; + u_stream.tcp_port = 80; + imds = flb_aws_imds_create(&i_config, &a_client); + TEST_CHECK(imds != NULL); + + /* Destruction */ + flb_aws_imds_destroy(imds); + + flb_config_exit(config_fluent); +} + +TEST_LIST = { + { "test_ec2_provider_v2" , test_ec2_provider_v2}, + { "test_ec2_provider_v1" , test_ec2_provider_v1}, + { "test_ec2_provider_v1_v2_timeout" , test_ec2_provider_v1_v2_timeout}, + { "test_ec2_provider_version_detection_error" , test_ec2_provider_version_detection_error}, + { "test_ec2_provider_acquire_token_error" , test_ec2_provider_acquire_token_error}, + { "test_ec2_provider_metadata_request_error" , test_ec2_provider_metadata_request_error}, + { "test_ec2_imds_create_and_destroy" , test_ec2_imds_create_and_destroy}, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/aws_credentials_http.c b/src/fluent-bit/tests/internal/aws_credentials_http.c new file mode 100644 index 000000000..55912da3a --- /dev/null +++ b/src/fluent-bit/tests/internal/aws_credentials_http.c @@ -0,0 +1,382 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "flb_tests_internal.h" + +#define ACCESS_KEY_HTTP "http_akid" +#define SECRET_KEY_HTTP "http_skid" +#define TOKEN_HTTP "http_token" + +#define HTTP_CREDENTIALS_RESPONSE "{\n\ + \"AccessKeyId\": \"http_akid\",\n\ + \"Expiration\": \"2025-10-24T23:00:23Z\",\n\ + \"RoleArn\": \"TASK_ROLE_ARN\",\n\ + \"SecretAccessKey\": \"http_skid\",\n\ + \"Token\": \"http_token\"\n\ +}" + +/* + * Unexpected/invalid HTTP response. The goal of this is not to test anything + * that might happen in production, but rather to test the error handling + * code for the providers. This helps ensure all code paths are tested and + * the error handling code does not introduce memory leaks. + */ +#define HTTP_RESPONSE_MALFORMED "{\n\ + \"AccessKeyId\": \"http_akid\",\n\ + \"partially-correct\": \"json\",\n\ + \"RoleArn\": \"TASK_ROLE_ARN\",\n\ + \"but incomplete\": \"and not terminated with a closing brace\",\n\ + \"Token\": \"http_token\"" + + +/* + * Global Variable that allows us to check the number of calls + * made in each test + */ +int g_request_count; + +struct flb_http_client *request_happy_case(struct flb_aws_client *aws_client, + int method, const char *uri) +{ + struct flb_http_client *c = NULL; + + TEST_CHECK(method == FLB_HTTP_GET); + + TEST_CHECK(strstr(uri, "happy-case") != NULL); + + /* create an http client so that we can set the response */ + c = flb_calloc(1, sizeof(struct flb_http_client)); + if (!c) { + flb_errno(); + return NULL; + } + mk_list_init(&c->headers); + + c->resp.status = 200; + c->resp.payload = HTTP_CREDENTIALS_RESPONSE; + c->resp.payload_size = strlen(HTTP_CREDENTIALS_RESPONSE); + + return c; +} + +/* unexpected output test- see description for HTTP_RESPONSE_MALFORMED */ +struct flb_http_client *request_malformed(struct flb_aws_client *aws_client, + int method, const char *uri) +{ + struct flb_http_client *c = NULL; + + TEST_CHECK(method == FLB_HTTP_GET); + + TEST_CHECK(strstr(uri, "malformed") != NULL); + + /* create an http client so that we can set the response */ + c = flb_calloc(1, sizeof(struct flb_http_client)); + if (!c) { + flb_errno(); + return NULL; + } + mk_list_init(&c->headers); + + c->resp.status = 200; + c->resp.payload = HTTP_RESPONSE_MALFORMED; + c->resp.payload_size = strlen(HTTP_RESPONSE_MALFORMED); + + return c; +} + +struct flb_http_client *request_error_case(struct flb_aws_client *aws_client, + int method, const char *uri) +{ + struct flb_http_client *c = NULL; + + TEST_CHECK(method == FLB_HTTP_GET); + + TEST_CHECK(strstr(uri, "error-case") != NULL); + + /* create an http client so that we can set the response */ + c = flb_calloc(1, sizeof(struct flb_http_client)); + if (!c) { + flb_errno(); + return NULL; + } + mk_list_init(&c->headers); + + c->resp.status = 400; + c->resp.payload = NULL; + c->resp.payload_size = 0; + + return c; +} + +/* test/mock version of the flb_aws_client request function */ +struct flb_http_client *test_http_client_request(struct flb_aws_client *aws_client, + int method, const char *uri, + const char *body, size_t body_len, + struct flb_aws_header *dynamic_headers, + size_t dynamic_headers_len) +{ + g_request_count++; + /* + * route to the correct test case fn using the uri + */ + if (strstr(uri, "happy-case") != NULL) { + return request_happy_case(aws_client, method, uri); + } else if (strstr(uri, "error-case") != NULL) { + return request_error_case(aws_client, method, uri); + } else if (strstr(uri, "malformed") != NULL) { + return request_malformed(aws_client, method, uri); + } + + /* uri should match one of the above conditions */ + flb_errno(); + return NULL; + +} + +/* Test/mock flb_aws_client */ +static struct flb_aws_client_vtable test_vtable = { + .request = test_http_client_request, +}; + +struct flb_aws_client *test_http_client_create() +{ + struct flb_aws_client *client = flb_calloc(1, + sizeof(struct flb_aws_client)); + if (!client) { + flb_errno(); + return NULL; + } + client->client_vtable = &test_vtable; + return client; +} + +/* Generator that returns clients with the test vtable */ +static struct flb_aws_client_generator test_generator = { + .create = test_http_client_create, +}; + +struct flb_aws_client_generator *generator_in_test() +{ + return &test_generator; +} + +/* http and ecs providers */ +static void test_http_provider() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + int ret; + struct flb_config *config; + flb_sds_t host; + flb_sds_t path; + + g_request_count = 0; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + host = flb_sds_create("127.0.0.1"); + if (!host) { + flb_errno(); + flb_config_exit(config); + return; + } + path = flb_sds_create("/happy-case"); + if (!path) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_http_provider_create(config, host, path, + generator_in_test()); + + if (!provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(ACCESS_KEY_HTTP, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SECRET_KEY_HTTP, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(TOKEN_HTTP, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(ACCESS_KEY_HTTP, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SECRET_KEY_HTTP, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(TOKEN_HTTP, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + /* + * Request count should be 2: + * - One for the first call to get_credentials (2nd should hit cred cache) + * - One for the call to refresh + */ + TEST_CHECK(g_request_count == 2); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); +} + +static void test_http_provider_error_case() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + int ret; + struct flb_config *config; + flb_sds_t host; + flb_sds_t path; + + g_request_count = 0; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + host = flb_sds_create("127.0.0.1"); + if (!host) { + flb_errno(); + flb_config_exit(config); + return; + } + path = flb_sds_create("/error-case"); + if (!path) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_http_provider_create(config, host, path, + generator_in_test()); + + if (!provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + /* get_credentials will fail */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* refresh should return -1 (failure) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret < 0); + + /* + * Request count should be 3: + * - Each call to get_credentials and refresh invokes the client's + * request method and returns a request failure. + */ + TEST_CHECK(g_request_count == 3); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); +} + +static void test_http_provider_malformed_response() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + int ret; + struct flb_config *config; + flb_sds_t host; + flb_sds_t path; + + g_request_count = 0; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + mk_list_init(&config->upstreams); + + host = flb_sds_create("127.0.0.1"); + if (!host) { + flb_errno(); + flb_config_exit(config); + return; + } + path = flb_sds_create("/malformed"); + if (!path) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_http_provider_create(config, host, path, + generator_in_test()); + + if (!provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + /* get_credentials will fail */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* refresh should return -1 (failure) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret < 0); + + /* + * Request count should be 3: + * - Each call to get_credentials and refresh invokes the client's + * request method and returns a request failure. + */ + TEST_CHECK(g_request_count == 3); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); +} + +TEST_LIST = { + { "test_http_provider" , test_http_provider}, + { "test_http_provider_error_case" , test_http_provider_error_case}, + { "test_http_provider_malformed_response" , + test_http_provider_malformed_response}, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/aws_credentials_process.c b/src/fluent-bit/tests/internal/aws_credentials_process.c new file mode 100644 index 000000000..3add81fe4 --- /dev/null +++ b/src/fluent-bit/tests/internal/aws_credentials_process.c @@ -0,0 +1,496 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include + +#include "aws_credentials_test_internal.h" + +#define _TOSTRING(X) #X +#define TOSTRING(X) _TOSTRING(X) +#define TESTCASE_NAME() "aws_credentials_process.c:" TOSTRING(__LINE__) + +#define MUST_SETENV(name, value) TEST_ASSERT(setenv(name, value, 1) == 0) +#define MUST_UNSETENV(name) TEST_ASSERT(unsetenv(name) == 0) + +static int unset_process_env() +{ + int ret; + + ret = unset_profile_env(); + if (ret < 0) { + return -1; + } + + ret = unsetenv("_AWS_SECRET_ACCESS_KEY"); + if (ret < 0) { + flb_errno(); + return -1; + } + + ret = unsetenv("_AWS_SESSION_TOKEN"); + if (ret < 0) { + flb_errno(); + return -1; + } + + ret = unsetenv("_AWS_EXPIRATION"); + if (ret < 0) { + flb_errno(); + return -1; + } + + ret = unsetenv("_AWS_EXIT_CODE"); + if (ret < 0) { + flb_errno(); + return -1; + } + + return 0; +} + +static void test_credential_process_default(void) +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials* creds; + char* original_path = getenv("PATH"); + + /* Print a newline so the test output starts on its own line. */ + fprintf(stderr, "\n"); + + TEST_CHECK(unset_process_env() == 0); + + MUST_SETENV("AWS_CONFIG_FILE", AWS_TEST_DATA_PATH("shared_config.ini")); + MUST_SETENV("PATH", AWS_TEST_DATA_PATH("credential_process")); + + provider = flb_profile_provider_create(NULL); + TEST_ASSERT(provider != NULL); + + /* These environment variables are used by the test credential_process. */ + MUST_SETENV("_AWS_SECRET_ACCESS_KEY", "aws_secret_access_key"); + MUST_SETENV("_AWS_SESSION_TOKEN", "aws_session_token"); + MUST_SETENV("_AWS_EXPIRATION", "+15 minutes"); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp("default", creds->access_key_id) == 0); + TEST_CHECK(strcmp("aws_secret_access_key", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("aws_session_token", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + creds = NULL; + + /* Repeated calls to get_credentials should return the cached credentials. */ + + MUST_SETENV("_AWS_SECRET_ACCESS_KEY", "aws_secret_access_key_2"); + MUST_SETENV("_AWS_SESSION_TOKEN", "aws_session_token_2"); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp("default", creds->access_key_id) == 0); + TEST_CHECK(strcmp("aws_secret_access_key", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("aws_session_token", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + creds = NULL; + + /* Calling refresh should fetch the new credentials. */ + + MUST_SETENV("_AWS_SECRET_ACCESS_KEY", "aws_secret_access_key_3"); + MUST_SETENV("_AWS_SESSION_TOKEN", "aws_session_token_3"); + + TEST_ASSERT(provider->provider_vtable->refresh(provider) == 0); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp("default", creds->access_key_id) == 0); + TEST_CHECK(strcmp("aws_secret_access_key_3", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("aws_session_token_3", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + creds = NULL; + + flb_aws_provider_destroy(provider); + provider = NULL; + + if (original_path) { + MUST_SETENV("PATH", original_path); + } else { + MUST_UNSETENV("PATH"); + } +} + +static void test_credential_process_no_expiration(void) +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials* creds; + char* original_path = getenv("PATH"); + + /* Print a newline so the test output starts on its own line. */ + fprintf(stderr, "\n"); + + TEST_CHECK(unset_process_env() == 0); + + MUST_SETENV("AWS_CONFIG_FILE", AWS_TEST_DATA_PATH("shared_config.ini")); + MUST_SETENV("AWS_PROFILE", "nondefault"); + MUST_SETENV("PATH", AWS_TEST_DATA_PATH("credential_process")); + + provider = flb_profile_provider_create(NULL); + TEST_ASSERT(provider != NULL); + + /* These environment variables are used by the test credential_process. */ + MUST_SETENV("_AWS_SECRET_ACCESS_KEY", "aws_secret_access_key"); + MUST_SETENV("_AWS_SESSION_TOKEN", "aws_session_token"); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp("nondefault", creds->access_key_id) == 0); + TEST_CHECK(strcmp("aws_secret_access_key", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("aws_session_token", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + creds = NULL; + + /* Repeated calls to get_credentials should return the cached credentials. */ + + MUST_SETENV("_AWS_SECRET_ACCESS_KEY", "aws_secret_access_key_2"); + MUST_SETENV("_AWS_SESSION_TOKEN", "aws_session_token_2"); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp("nondefault", creds->access_key_id) == 0); + TEST_CHECK(strcmp("aws_secret_access_key", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("aws_session_token", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + creds = NULL; + + /* Calling refresh should fetch the new credentials. */ + + MUST_SETENV("_AWS_SECRET_ACCESS_KEY", "aws_secret_access_key_3"); + MUST_SETENV("_AWS_SESSION_TOKEN", "aws_session_token_3"); + + TEST_ASSERT(provider->provider_vtable->refresh(provider) == 0); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp("nondefault", creds->access_key_id) == 0); + TEST_CHECK(strcmp("aws_secret_access_key_3", creds->secret_access_key) == 0); + TEST_CHECK(strcmp("aws_session_token_3", creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + creds = NULL; + + flb_aws_provider_destroy(provider); + provider = NULL; + + if (original_path) { + MUST_SETENV("PATH", original_path); + } else { + MUST_UNSETENV("PATH"); + } +} + +struct credential_process_expired_testcase { + char* name; + char* expiration; +}; + +struct credential_process_expired_testcase credential_process_expired_testcases[] = { + /* Credentials that have already expired will be refreshed. */ + { + .name = "expired", + .expiration = "-5 minutes", + }, + + /* Credentials that expire within the next minute will be refreshed. */ + { + .name = "expiring soon", + .expiration = "+30 seconds", + }, +}; + +static void test_credential_process_expired_helper(char* expiration) +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials* creds; + char* original_path = getenv("PATH"); + + TEST_CHECK(unset_process_env() == 0); + + MUST_SETENV("AWS_CONFIG_FILE", AWS_TEST_DATA_PATH("shared_config.ini")); + MUST_SETENV("AWS_PROFILE", "nondefault"); + MUST_SETENV("PATH", AWS_TEST_DATA_PATH("credential_process")); + + provider = flb_profile_provider_create(NULL); + TEST_ASSERT(provider != NULL); + + /* These environment variable are used by the test credential_process. */ + MUST_SETENV("_AWS_SECRET_ACCESS_KEY", "aws_secret_access_key"); + if (expiration) { + MUST_SETENV("_AWS_EXPIRATION", expiration); + } + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp("nondefault", creds->access_key_id) == 0); + TEST_CHECK(strcmp("aws_secret_access_key", creds->secret_access_key) == 0); + TEST_CHECK(creds->session_token == NULL); + + flb_aws_credentials_destroy(creds); + creds = NULL; + + /* Repeated calls to get_credentials should fetch new credentials. */ + + MUST_SETENV("_AWS_SECRET_ACCESS_KEY", "aws_secret_access_key_2"); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp("nondefault", creds->access_key_id) == 0); + TEST_CHECK(strcmp("aws_secret_access_key_2", creds->secret_access_key) == 0); + TEST_CHECK(creds->session_token == NULL); + + flb_aws_credentials_destroy(creds); + creds = NULL; + + flb_aws_provider_destroy(provider); + provider = NULL; + + if (original_path) { + MUST_SETENV("PATH", original_path); + } else { + MUST_UNSETENV("PATH"); + } +} + +static void test_credential_process_expired(void) +{ + int i; + int num_testcases = sizeof(credential_process_expired_testcases) / + sizeof(credential_process_expired_testcases[0]); + struct credential_process_expired_testcase* current_testcase = NULL; + + /* Print a newline so the test output starts on its own line. */ + fprintf(stderr, "\n"); + + for (i = 0; i < num_testcases; i++) { + current_testcase = &credential_process_expired_testcases[i]; + TEST_CASE(current_testcase->name); + test_credential_process_expired_helper(current_testcase->expiration); + } +} + +static void test_credential_process_failure(void) +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials* creds; + char* original_path = getenv("PATH"); + + /* Print a newline so the test output starts on its own line. */ + fprintf(stderr, "\n"); + + TEST_CHECK(unset_process_env() == 0); + + MUST_SETENV("AWS_CONFIG_FILE", AWS_TEST_DATA_PATH("shared_config.ini")); + MUST_SETENV("PATH", AWS_TEST_DATA_PATH("credential_process")); + + provider = flb_profile_provider_create(NULL); + TEST_ASSERT(provider != NULL); + + /* These environment variables are used by the test credential_process. */ + MUST_SETENV("_AWS_SECRET_ACCESS_KEY", "aws_secret_access_key"); + MUST_SETENV("_AWS_EXIT_CODE", "1"); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds == NULL); + + flb_aws_credentials_destroy(creds); + creds = NULL; + + /* Repeated calls to get_credentials should try to fetch the credentials again. */ + + MUST_SETENV("_AWS_SECRET_ACCESS_KEY", "aws_secret_access_key_2"); + MUST_UNSETENV("_AWS_EXIT_CODE"); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp("default", creds->access_key_id) == 0); + TEST_CHECK(strcmp("aws_secret_access_key_2", creds->secret_access_key) == 0); + + flb_aws_credentials_destroy(creds); + creds = NULL; + + flb_aws_provider_destroy(provider); + provider = NULL; + + if (original_path) { + MUST_SETENV("PATH", original_path); + } else { + MUST_UNSETENV("PATH"); + } +} + +struct parse_credential_process_testcase { + char* name; + char* input; + + /* + * NULL-terminated array of tokens that should be returned. + * The choice of 10 here is completely arbitrary. + * Since a char*[] cannot be NULL, we need a separate flag for the failure cases. + */ + char* expected[10]; + int should_fail; +}; + +struct parse_credential_process_testcase parse_credential_process_testcases[] = { + { + .name = TESTCASE_NAME(), + .input = "my-process", + .expected = { "my-process", NULL }, + }, + { + .name = TESTCASE_NAME(), + .input = " my-process ", + .expected = { "my-process", NULL }, + }, + { + .name = TESTCASE_NAME(), + .input = "my-process arg1 arg2", + .expected = { "my-process", "arg1", "arg2", NULL }, + }, + { + .name = TESTCASE_NAME(), + .input = " my-process arg1 arg2 ", + .expected = { "my-process", "arg1", "arg2", NULL }, + }, + { + .name = TESTCASE_NAME(), + .input = "my-process \"arg1 \" arg2 \"\"", + .expected = { "my-process", "arg1 ", "arg2", "", NULL }, + }, + { + .name = TESTCASE_NAME(), + .input = "\"my process\"", + .expected = { "my process", NULL }, + }, + { + .name = TESTCASE_NAME(), + .input = " \"my process\" \" \" ", + .expected = { "my process", " ", NULL }, + }, + { + .name = TESTCASE_NAME(), + .input = "", + .expected = { NULL }, + }, + { + .name = TESTCASE_NAME(), + .input = "\"unterminated", + .should_fail = FLB_TRUE, + }, + { + .name = TESTCASE_NAME(), + .input = " \"unterminated ", + .should_fail = FLB_TRUE, + }, + { + .name = TESTCASE_NAME(), + .input = "abc\"def\"", + .should_fail = FLB_TRUE, + }, + { + .name = TESTCASE_NAME(), + .input = " abc\"def\" ", + .should_fail = FLB_TRUE, + }, + { + .name = TESTCASE_NAME(), + .input = "\"abc\"def", + .should_fail = FLB_TRUE, + }, + { + .name = TESTCASE_NAME(), + .input = " \"abc\"def ", + .should_fail = FLB_TRUE, + }, +}; + +static void test_parse_credential_process_helper(char* input, char** expected) +{ + char* cpy = NULL; + char** tokens = NULL; + int i = 0; + int input_len = strlen(input) + 1; + + /* + * String literals are immutable, but parse_credential_process modifies its input. + * To circumvent this, copy the literal into a mutable string. + * Note: Because the return value of parse_credential_process will contain pointers + * into this string, we cannot free the copy until we are done with the token array. + */ + cpy = flb_malloc(input_len + 1); + TEST_ASSERT(cpy != NULL); + memcpy(cpy, input, input_len); + + tokens = parse_credential_process(cpy); + + if (expected) { + TEST_ASSERT(tokens != NULL); + for (i = 0; expected[i]; i++) { + TEST_ASSERT_(tokens[i] != NULL, "expected='%s', got=(null)", expected[i]); + TEST_CHECK_(strcmp(expected[i], tokens[i]) == 0, "expected='%s', got='%s'", + expected[i], tokens[i]); + } + TEST_ASSERT_(tokens[i] == NULL, "expected=(null), got='%s'", tokens[i]); + } + else { + TEST_ASSERT(tokens == NULL); + } + + flb_free(tokens); + flb_free(cpy); +} + +static void test_parse_credential_process(void) +{ + int i; + int num_testcases = sizeof(parse_credential_process_testcases) / + sizeof(parse_credential_process_testcases[0]); + struct parse_credential_process_testcase* current_testcase = NULL; + char** expected = NULL; + + /* Print a newline so the test output starts on its own line. */ + fprintf(stderr, "\n"); + + for (i = 0; i < num_testcases; i++) { + current_testcase = &parse_credential_process_testcases[i]; + TEST_CASE(current_testcase->name); + if (current_testcase->should_fail) { + expected = NULL; + } + else { + expected = current_testcase->expected; + } + test_parse_credential_process_helper(current_testcase->input, expected); + } +} + +TEST_LIST = { + { "test_credential_process_default", test_credential_process_default }, + { "test_credential_process_no_expiration", test_credential_process_no_expiration }, + { "test_credential_process_expired", test_credential_process_expired }, + { "test_credential_process_failure", test_credential_process_failure }, + { "test_parse_credential_process", test_parse_credential_process }, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/aws_credentials_profile.c b/src/fluent-bit/tests/internal/aws_credentials_profile.c new file mode 100644 index 000000000..1335bd957 --- /dev/null +++ b/src/fluent-bit/tests/internal/aws_credentials_profile.c @@ -0,0 +1,405 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include + +#include "aws_credentials_test_internal.h" + +#define TEST_CREDENTIALS_FILE AWS_TEST_DATA_PATH("shared_credentials_file.ini") + +#define TEST_CREDENTIALS_NODEFAULT AWS_TEST_DATA_PATH("shared_credentials_file_nodefault.ini") + +/* these credentials look real but are not */ +#define AKID_DEFAULT_PROFILE "ASIASDMPIJWXJAXT3O3T" +#define SKID_DEFAULT_PROFILE "EAUBpd/APPT4Nfi4DWY3gnt5TU/4T49laqS5zh8W" +#define TOKEN_DEFAULT_PROFILE "IQoJb3JpZ2luX2VjEOD//////////wEaCNVzLWVh\ +c3QtMSJHMEUCIKCn7v/EDowMZvJnciSJbxA7rIV4p1K6pOUvcLHM+9EzNgIgeiYbfA47DGS\ +qoEZS3yrRWGN8Fr4Q/bK7ANRgv09Hth8q1gEIWRABGgwxNDQ3MTg3MTE0NzAiDGSqzyXiic\ +OZp63afiqzAUyWOljOn5HaIxRfpQ5pTf+o4roJ2KPlHn+XHEKJZKien4Ydm7zeVi7SbPLKo\ +cjmjYJd31PrlbJ43C6AyrhmY57qaD7Zz4N3N0V6mekzvlAeARXsa4deflsbemqkp1WVsBLk\ +O6qUuk+N04+MxIVXAxkW9RSPRTVjxeS2m5Yobygto58WLFE8gacRoNd4lCK4JUmEdiaxJEQ\ +QO7leZ3v1XxQr6QBS8P/GmcJYcQTxlA6AFQxIMJKGwfAFOuMB2cEc8cF2Htiqf3LVGMk/6b\ +YKkW7fHUtrnttp28jgWtbbLtFbX/zIdlqwm73Ryp7lI+xkM4XNIT+6ZKa4Xw0/Zw3xLzlk3\ +jic6QWPAcffwR6kOunoTOWJzPskK/RZ4Cd+GyGarxG27Cz6xolAzAsDpdGQwV7kCCUPi6/V\ +HjefwKEk9HjZfejC5WuCS173qFrU9kNb4IrYhnK+wmRzzJfgpWUwerdiJKBz95j1iW9rP1a\ +8p1xLR3EXUMN3LIW0+gP8sFjg5iiqDkaS/tUXWZndM2QdJLcrxwAutFchc0nqJHYTijw=" + +#define AKID_NONDEFAULT_PROFILE "akid" +#define SKID_NONDEFAULT_PROFILE "skid" + +#define AKID_NOSPACE_PROFILE "akidnospace" +#define SKID_NOSPACE_PROFILE "skidnospace" +#define TOKEN_NOSPACE_PROFILE "tokennospace" + +#define AKID_WEIRDWHITESPACE_PROFILE "akidweird" +#define SKID_WEIRDWHITESPACE_PROFILE "skidweird" +#define TOKEN_WEIRDWHITESPACE_PROFILE "tokenweird///token==" + +#define CUSTOM_PROFILE_ACCESS_KEY_ID "custom_access_key_id" +#define CUSTOM_PROFILE_SECRET_ACCESS_KEY "custom_secret_access_key" + +static void test_profile_default() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials*creds; + struct flb_config *config; + int ret; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + TEST_CHECK(unset_profile_env() == 0); + + ret = setenv("AWS_SHARED_CREDENTIALS_FILE", TEST_CREDENTIALS_FILE, 1); + TEST_ASSERT(ret == 0); + + provider = flb_profile_provider_create(NULL); + TEST_ASSERT(provider != NULL); + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp(AKID_DEFAULT_PROFILE, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SKID_DEFAULT_PROFILE, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(TOKEN_DEFAULT_PROFILE, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp(AKID_DEFAULT_PROFILE, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SKID_DEFAULT_PROFILE, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(TOKEN_DEFAULT_PROFILE, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); + + TEST_CHECK(unset_profile_env() == 0); +} + +static void test_profile_custom() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials*creds; + struct flb_config *config; + int ret; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + TEST_CHECK(unset_profile_env() == 0); + + ret = setenv("AWS_SHARED_CREDENTIALS_FILE", TEST_CREDENTIALS_FILE, 1); + TEST_ASSERT(ret == 0); + + provider = flb_profile_provider_create("custom"); + TEST_ASSERT(provider != NULL); + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp(CUSTOM_PROFILE_ACCESS_KEY_ID, creds->access_key_id) == 0); + TEST_CHECK(strcmp(CUSTOM_PROFILE_SECRET_ACCESS_KEY, creds->secret_access_key) == 0); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp(CUSTOM_PROFILE_ACCESS_KEY_ID, creds->access_key_id) == 0); + TEST_CHECK(strcmp(CUSTOM_PROFILE_SECRET_ACCESS_KEY, creds->secret_access_key) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); + + TEST_CHECK(unset_profile_env() == 0); +} + +static void test_profile_non_default() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials*creds; + struct flb_config *config; + int ret; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + TEST_CHECK(unset_profile_env() == 0); + + ret = setenv("AWS_SHARED_CREDENTIALS_FILE", TEST_CREDENTIALS_FILE, 1); + TEST_ASSERT(ret == 0); + + ret = setenv("AWS_PROFILE", "nondefault", 1); + TEST_ASSERT(ret == 0); + + provider = flb_profile_provider_create(NULL); + TEST_ASSERT(provider != NULL); + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp(AKID_NONDEFAULT_PROFILE, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SKID_NONDEFAULT_PROFILE, creds->secret_access_key) == 0); + TEST_CHECK(creds->session_token == NULL); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp(AKID_NONDEFAULT_PROFILE, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SKID_NONDEFAULT_PROFILE, creds->secret_access_key) == 0); + TEST_CHECK(creds->session_token == NULL); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); + + TEST_CHECK(unset_profile_env() == 0); +} + +static void test_profile_no_space() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials*creds; + struct flb_config *config; + int ret; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + TEST_CHECK(unset_profile_env() == 0); + + ret = setenv("AWS_SHARED_CREDENTIALS_FILE", TEST_CREDENTIALS_FILE, 1); + TEST_ASSERT(ret == 0); + + ret = setenv("AWS_DEFAULT_PROFILE", "nospace", 1); + TEST_ASSERT(ret == 0); + + provider = flb_profile_provider_create(NULL); + TEST_ASSERT(provider != NULL); + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp(AKID_NOSPACE_PROFILE, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SKID_NOSPACE_PROFILE, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(TOKEN_NOSPACE_PROFILE, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_ASSERT(creds != NULL); + + TEST_CHECK(strcmp(AKID_NOSPACE_PROFILE, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SKID_NOSPACE_PROFILE, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(TOKEN_NOSPACE_PROFILE, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); + + TEST_CHECK(unset_profile_env() == 0); +} + +static void test_profile_weird_whitespace() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials*creds; + struct flb_config *config; + int ret; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + TEST_CHECK(unset_profile_env() == 0); + + ret = setenv("AWS_SHARED_CREDENTIALS_FILE", TEST_CREDENTIALS_FILE, 1); + TEST_ASSERT(ret == 0); + + ret = setenv("AWS_DEFAULT_PROFILE", "weirdwhitespace", 1); + TEST_ASSERT(ret == 0); + + provider = flb_profile_provider_create(NULL); + TEST_ASSERT(provider != NULL); + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(AKID_WEIRDWHITESPACE_PROFILE, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SKID_WEIRDWHITESPACE_PROFILE, + creds->secret_access_key) == 0); + TEST_CHECK(strcmp(TOKEN_WEIRDWHITESPACE_PROFILE, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(AKID_WEIRDWHITESPACE_PROFILE, creds->access_key_id) == 0); + TEST_CHECK(strcmp(SKID_WEIRDWHITESPACE_PROFILE, + creds->secret_access_key) == 0); + TEST_CHECK(strcmp(TOKEN_WEIRDWHITESPACE_PROFILE, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); + + TEST_CHECK(unset_profile_env() == 0); +} + +static void test_profile_missing() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials*creds; + struct flb_config *config; + int ret; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + TEST_CHECK(unset_profile_env() == 0); + + ret = setenv("AWS_SHARED_CREDENTIALS_FILE", TEST_CREDENTIALS_FILE, 1); + TEST_ASSERT(ret == 0); + + ret = setenv("AWS_DEFAULT_PROFILE", "missing", 1); + TEST_ASSERT(ret == 0); + + provider = flb_profile_provider_create(NULL); + TEST_ASSERT(provider != NULL); + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + flb_aws_credentials_destroy(creds); + + /* refresh should return -1 (failure) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret < 0); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); + + TEST_CHECK(unset_profile_env() == 0); +} + +static void test_profile_nodefault() +{ + struct flb_aws_provider *provider; + struct flb_aws_credentials*creds; + struct flb_config *config; + int ret; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + TEST_CHECK(unset_profile_env() == 0); + + ret = setenv("AWS_SHARED_CREDENTIALS_FILE", TEST_CREDENTIALS_NODEFAULT, 1); + TEST_ASSERT(ret == 0); + + provider = flb_profile_provider_create(NULL); + TEST_ASSERT(provider != NULL); + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + flb_aws_credentials_destroy(creds); + + /* refresh should return -1 (failure) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret < 0); + + flb_aws_provider_destroy(provider); + flb_config_exit(config); + + TEST_CHECK(unset_profile_env() == 0); +} + + +TEST_LIST = { + { "test_profile_default", test_profile_default }, + { "test_profile_non_default", test_profile_non_default }, + { "test_profile_no_space", test_profile_no_space }, + { "test_profile_weird_whitespace", test_profile_weird_whitespace }, + { "test_profile_missing", test_profile_missing }, + { "test_profile_nodefault", test_profile_nodefault }, + { "test_profile_custom", test_profile_custom }, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/aws_credentials_sts.c b/src/fluent-bit/tests/internal/aws_credentials_sts.c new file mode 100644 index 000000000..146d937e7 --- /dev/null +++ b/src/fluent-bit/tests/internal/aws_credentials_sts.c @@ -0,0 +1,939 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "flb_tests_internal.h" + +#define EKS_ACCESS_KEY "eks_akid" +#define EKS_SECRET_KEY "eks_skid" +#define EKS_TOKEN "eks_token" + +#define STS_ACCESS_KEY "sts_akid" +#define STS_SECRET_KEY "sts_skid" +#define STS_TOKEN "sts_token" + +/* standard environment variables */ +#define AWS_ACCESS_KEY_ID "AWS_ACCESS_KEY_ID" +#define AWS_SECRET_ACCESS_KEY "AWS_SECRET_ACCESS_KEY" +#define AWS_SESSION_TOKEN "AWS_SESSION_TOKEN" + +#define TOKEN_FILE_ENV_VAR "AWS_WEB_IDENTITY_TOKEN_FILE" +#define ROLE_ARN_ENV_VAR "AWS_ROLE_ARN" +#define SESSION_NAME_ENV_VAR "AWS_ROLE_SESSION_NAME" + +#define WEB_TOKEN_FILE FLB_TESTS_DATA_PATH "/data/aws_credentials/\ +web_identity_token_file.txt" + +#define STS_RESPONSE_EKS "\n\ + \n\ + amzn1.account.AF6RHO7KZU5XRVQJGXK6HB56KR2A\n\ +\n\ + client.5498841531868486423.1548@apps.example.com\n\ + \n\ + arn:aws:sts::123456789012:assumed-role/WebIdentityRole/app1\n\ + AROACLKWSDQRAOEXAMPLE:app1\n\ + \n\ + \n\ + eks_token\n\ + eks_skid\n\ + 2025-10-24T23:00:23Z\n\ + eks_akid\n\ + \n\ + www.amazon.com\n\ + \n\ + \n\ + ad4156e9-bce1-11e2-82e6-6b6efEXAMPLE\n\ + \n\ +" + +#define STS_RESPONSE_ASSUME_ROLE "\n\ + \n\ + \n\ + arn:aws:sts::123456789012:assumed-role/demo/TestAR\n\ + ARO123EXAMPLE123:TestAR\n\ + \n\ + \n\ + sts_akid\n\ + sts_skid\n\ + sts_token\n\ + 2025-11-09T13:34:41Z\n\ + \n\ + 6\n\ + \n\ + \n\ + c6104cbe-af31-11e0-8154-cbc7ccf896c7\n\ + \n\ +" + +/* + * Unexpected/invalid STS response. The goal of this is not to test anything + * that might happen in production, but rather to test the error handling + * code for the providers. This helps ensure all code paths are tested and + * the error handling code does not introduce memory leaks. + */ + +#define STS_RESPONSE_MALFORMED "{\n\ + \"__type\": \"some unexpected response\",\n\ + \"this tests\": the error handling code\",\n\ +\"This looks like JSON but is not valid.\"\n\ +It also contains xml tags that a correct\n\ +response would have" + +/* + * Global Variable that allows us to check the number of calls + * made in each test + */ +int g_request_count; + +/* Each test case has its own request function */ + +/* unexpected output test- see description for STS_RESPONSE_MALFORMED */ +struct flb_http_client *request_unexpected_response(struct flb_aws_client + *aws_client, int method, + const char *uri) +{ + struct flb_http_client *c; + TEST_CHECK(method == FLB_HTTP_GET); + + /* create an http client so that we can set the response */ + c = flb_calloc(1, sizeof(struct flb_http_client)); + if (!c) { + flb_errno(); + return NULL; + } + mk_list_init(&c->headers); + + c->resp.status = 200; + c->resp.payload = STS_RESPONSE_MALFORMED; + c->resp.payload_size = strlen(STS_RESPONSE_MALFORMED); + + return c; +} +struct flb_http_client *request_eks_test1(struct flb_aws_client *aws_client, + int method, const char *uri) +{ + struct flb_http_client *c; + + TEST_CHECK(method == FLB_HTTP_GET); + TEST_CHECK(strstr(uri, "Action=AssumeRoleWithWebIdentity") != NULL); + TEST_CHECK(strstr(uri, "RoleArn=arn:aws:iam::123456789012:role/test") + != NULL); + TEST_CHECK(strstr(uri, "WebIdentityToken=this-is-a-fake-jwt") != NULL); + TEST_CHECK(strstr(uri, "RoleSessionName=session_name") != NULL); + + /* create an http client so that we can set the response */ + c = flb_calloc(1, sizeof(struct flb_http_client)); + if (!c) { + flb_errno(); + return NULL; + } + mk_list_init(&c->headers); + + c->resp.status = 200; + c->resp.payload = STS_RESPONSE_EKS; + c->resp.payload_size = strlen(STS_RESPONSE_EKS); + + return c; +} + +struct flb_http_client *request_eks_flb_sts_session_name(struct flb_aws_client + *aws_client, + int method, + const char *uri) +{ + struct flb_http_client *c; + + TEST_CHECK(method == FLB_HTTP_GET); + TEST_CHECK(strstr(uri, "Action=AssumeRoleWithWebIdentity") != NULL); + TEST_CHECK(strstr(uri, "RoleArn=arn:aws:iam::123456789012:role/" + "randomsession") != NULL); + TEST_CHECK(strstr(uri, "WebIdentityToken=this-is-a-fake-jwt") != NULL); + /* this test case has a random session name */ + TEST_CHECK(strstr(uri, "RoleSessionName=") != NULL); + /* session name should not be the same as test 1 */ + TEST_CHECK(strstr(uri, "RoleSessionName=session_name") == NULL); + + /* create an http client so that we can set the response */ + c = flb_calloc(1, sizeof(struct flb_http_client)); + if (!c) { + flb_errno(); + return NULL; + } + mk_list_init(&c->headers); + + c->resp.status = 200; + c->resp.payload = STS_RESPONSE_EKS; + c->resp.payload_size = strlen(STS_RESPONSE_EKS); + + return c; +} + +struct flb_http_client *request_eks_api_error(struct flb_aws_client *aws_client, + int method, const char *uri) +{ + struct flb_http_client *c; + + TEST_CHECK(method == FLB_HTTP_GET); + TEST_CHECK(strstr(uri, "Action=AssumeRoleWithWebIdentity") != NULL); + TEST_CHECK(strstr(uri, "RoleArn=arn:aws:iam::123456789012:role/apierror") + != NULL); + TEST_CHECK(strstr(uri, "WebIdentityToken=this-is-a-fake-jwt") != NULL); + /* this test case has a random session name */ + TEST_CHECK(strstr(uri, "RoleSessionName=") != NULL); + /* session name should not be the same as test 1 */ + TEST_CHECK(strstr(uri, "RoleSessionName=session_name") == NULL); + + /* create an http client so that we can set the response */ + c = flb_calloc(1, sizeof(struct flb_http_client)); + if (!c) { + flb_errno(); + return NULL; + } + mk_list_init(&c->headers); + + c->resp.status = 500; + c->resp.payload = NULL; + c->resp.payload_size = 0; + + return c; +} + +struct flb_http_client *request_sts_test1(struct flb_aws_client *aws_client, + int method, const char *uri) +{ + struct flb_http_client *c; + + TEST_CHECK(method == FLB_HTTP_GET); + TEST_CHECK(strstr(uri, "Action=AssumeRole") != NULL); + TEST_CHECK(strstr(uri, "RoleArn=arn:aws:iam::123456789012:role/test") + != NULL); + TEST_CHECK(strstr(uri, "ExternalId=external_id") != NULL); + TEST_CHECK(strstr(uri, "RoleSessionName=session_name") != NULL); + + /* create an http client so that we can set the response */ + c = flb_calloc(1, sizeof(struct flb_http_client)); + if (!c) { + flb_errno(); + return NULL; + } + mk_list_init(&c->headers); + + c->resp.status = 200; + c->resp.payload = STS_RESPONSE_ASSUME_ROLE; + c->resp.payload_size = strlen(STS_RESPONSE_ASSUME_ROLE); + + return c; +} + +struct flb_http_client *request_sts_api_error(struct flb_aws_client *aws_client, + int method, const char *uri) +{ + struct flb_http_client *c; + + TEST_CHECK(method == FLB_HTTP_GET); + TEST_CHECK(strstr(uri, "Action=AssumeRole") != NULL); + TEST_CHECK(strstr(uri, "RoleArn=arn:aws:iam::123456789012:role/apierror") + != NULL); + TEST_CHECK(strstr(uri, "ExternalId=external_id") != NULL); + TEST_CHECK(strstr(uri, "RoleSessionName=session_name") != NULL); + + /* create an http client so that we can set the response */ + c = flb_calloc(1, sizeof(struct flb_http_client)); + if (!c) { + flb_errno(); + return NULL; + } + mk_list_init(&c->headers); + + c->resp.status = 400; + c->resp.payload = NULL; + c->resp.payload_size = 0; + + return c; +} + +/* test/mock version of the flb_aws_client request function */ +struct flb_http_client *test_http_client_request(struct flb_aws_client *aws_client, + int method, const char *uri, + const char *body, size_t body_len, + struct flb_aws_header + *dynamic_headers, + size_t dynamic_headers_len) +{ + g_request_count++; + if (strcmp(aws_client->name, "sts_client_eks_provider") == 0) { + /* + * route to the correct test case fn using the uri - the role + * name is different in each test case. + */ + if (strstr(uri, "test1") != NULL) { + return request_eks_test1(aws_client, method, uri); + } else if (strstr(uri, "randomsession") != NULL) { + return request_eks_flb_sts_session_name(aws_client, method, uri); + } else if (strstr(uri, "apierror") != NULL) { + return request_eks_api_error(aws_client, method, uri); + } else if (strstr(uri, "unexpected_api_response") != NULL) { + return request_unexpected_response(aws_client, method, uri); + } + + /* uri should match one of the above conditions */ + flb_errno(); + return NULL; + } else if (strcmp(aws_client->name, "sts_client_assume_role_provider") == 0) + { + if (strstr(uri, "test1") != NULL) { + return request_sts_test1(aws_client, method, uri); + } else if (strstr(uri, "apierror") != NULL) { + return request_sts_api_error(aws_client, method, uri); + } else if (strstr(uri, "unexpected_api_response") != NULL) { + return request_unexpected_response(aws_client, method, uri); + } + /* uri should match one of the above conditions */ + flb_errno(); + return NULL; + } + + /* client name should match one of the above conditions */ + flb_errno(); + return NULL; + +} + +/* Test/mock flb_aws_client */ +static struct flb_aws_client_vtable test_vtable = { + .request = test_http_client_request, +}; + +struct flb_aws_client *test_http_client_create() +{ + struct flb_aws_client *client = flb_calloc(1, + sizeof(struct flb_aws_client)); + if (!client) { + flb_errno(); + return NULL; + } + client->client_vtable = &test_vtable; + return client; +} + +/* Generator that returns clients with the test vtable */ +static struct flb_aws_client_generator test_generator = { + .create = test_http_client_create, +}; + +struct flb_aws_client_generator *generator_in_test() +{ + return &test_generator; +} + +static void unsetenv_eks() +{ + int ret; + + ret = unsetenv(TOKEN_FILE_ENV_VAR); + if (ret < 0) { + flb_errno(); + return; + } + ret = unsetenv(ROLE_ARN_ENV_VAR); + if (ret < 0) { + flb_errno(); + return; + } + ret = unsetenv(SESSION_NAME_ENV_VAR); + if (ret < 0) { + flb_errno(); + return; + } +} + +static void test_flb_sts_session_name() +{ + char *session_name = flb_sts_session_name(); + + TEST_CHECK(strlen(session_name) == 32); + + flb_free(session_name); +} + +static void test_sts_uri() +{ + flb_sds_t uri; + + uri = flb_sts_uri("AssumeRole", "myrole", "mysession", + "myexternalid", NULL); + TEST_CHECK(strcmp(uri, "/?Version=2011-06-15&Action=AssumeRole" + "&RoleSessionName=mysession&RoleArn=myrole" + "&ExternalId=myexternalid") == 0); + flb_sds_destroy(uri); +} + +static void test_process_sts_response() +{ + struct flb_aws_credentials *creds; + struct flb_config *config; + time_t expiration; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + creds = flb_parse_sts_resp(STS_RESPONSE_EKS, &expiration); + + TEST_CHECK(strcmp(EKS_ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(EKS_SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(EKS_TOKEN, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + flb_config_exit(config); +} + +static void test_eks_provider() { + struct flb_config *config; + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + int ret; + + g_request_count = 0; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + /* set env vars */ + ret = setenv(ROLE_ARN_ENV_VAR, "arn:aws:iam::123456789012:role/test1", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(SESSION_NAME_ENV_VAR, "session_name", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(TOKEN_FILE_ENV_VAR, WEB_TOKEN_FILE, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_eks_provider_create(config, NULL, "us-west-2", + "https://sts.us-west-2.amazonaws.com", + NULL, generator_in_test()); + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(EKS_ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(EKS_SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(EKS_TOKEN, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(EKS_ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(EKS_SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(EKS_TOKEN, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + /* + * Request count should be 2: + * - One for the first call to get_credentials (2nd should hit cred cache) + * - One for the call to refresh + */ + TEST_CHECK(g_request_count == 2); + + flb_aws_provider_destroy(provider); + unsetenv_eks(); + flb_config_exit(config); +} + +static void test_eks_provider_random_session_name() { + struct flb_config *config; + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + int ret; + + g_request_count = 0; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + /* set env vars - session name is not set */ + unsetenv_eks(); + ret = setenv(ROLE_ARN_ENV_VAR, + "arn:aws:iam::123456789012:role/randomsession", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(TOKEN_FILE_ENV_VAR, WEB_TOKEN_FILE, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_eks_provider_create(config, NULL, "us-west-2", + "https://sts.us-west-2.amazonaws.com", + NULL, generator_in_test()); + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(EKS_ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(EKS_SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(EKS_TOKEN, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(EKS_ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(EKS_SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(EKS_TOKEN, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + /* + * Request count should be 2: + * - One for the first call to get_credentials (2nd should hit cred cache) + * - One for the call to refresh + */ + TEST_CHECK(g_request_count == 2); + + flb_aws_provider_destroy(provider); + unsetenv_eks(); + flb_config_exit(config); +} + +/* unexpected output test- see description for STS_RESPONSE_MALFORMED */ +static void test_eks_provider_unexpected_api_response() { + struct flb_config *config; + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + int ret; + + g_request_count = 0; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + unsetenv_eks(); + ret = setenv(ROLE_ARN_ENV_VAR, "arn:aws:iam::123456789012:role/" + "unexpected_api_response", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(TOKEN_FILE_ENV_VAR, WEB_TOKEN_FILE, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_eks_provider_create(config, NULL, "us-west-2", + "https://sts.us-west-2.amazonaws.com", + NULL, generator_in_test()); + + /* API will return an error - creds will be NULL */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* refresh should return -1 (failure) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret < 0); + + /* + * Request count should be 3: + * - Each call to get_credentials and refresh invokes the client's + * request method and returns a request failure. + */ + TEST_CHECK(g_request_count == 3); + + flb_aws_provider_destroy(provider); + unsetenv_eks(); + flb_config_exit(config); +} + +static void test_eks_provider_api_error() { + struct flb_config *config; + struct flb_aws_provider *provider; + struct flb_aws_credentials *creds; + int ret; + + g_request_count = 0; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + unsetenv_eks(); + ret = setenv(ROLE_ARN_ENV_VAR, "arn:aws:iam::123456789012:role/apierror", + 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(TOKEN_FILE_ENV_VAR, WEB_TOKEN_FILE, 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_eks_provider_create(config, NULL, "us-west-2", + "https://sts.us-west-2.amazonaws.com", + NULL, generator_in_test()); + + /* API will return an error - creds will be NULL */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* refresh should return -1 (failure) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret < 0); + + /* + * Request count should be 3: + * - Each call to get_credentials and refresh invokes the client's + * request method and returns a request failure. + */ + TEST_CHECK(g_request_count == 3); + + flb_aws_provider_destroy(provider); + unsetenv_eks(); + flb_config_exit(config); +} + +static void test_sts_provider() { + struct flb_config *config; + struct flb_aws_provider *provider; + struct flb_aws_provider *base_provider; + struct flb_aws_credentials *creds; + int ret; + + g_request_count = 0; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + /* use the env provider as the base provider */ + /* set environment */ + ret = setenv(AWS_ACCESS_KEY_ID, "base_akid", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(AWS_SECRET_ACCESS_KEY, "base_skid", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(AWS_SESSION_TOKEN, "base_token", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + + base_provider = flb_aws_env_provider_create(); + if (!base_provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_sts_provider_create(config, NULL, base_provider, "external_id", + "arn:aws:iam::123456789012:role/test1", + "session_name", "cn-north-1", + "https://sts.us-west-2.amazonaws.com", + NULL, generator_in_test()); + if (!provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(STS_ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(STS_SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(STS_TOKEN, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + creds = provider->provider_vtable->get_credentials(provider); + if (!creds) { + flb_errno(); + flb_config_exit(config); + return; + } + TEST_CHECK(strcmp(STS_ACCESS_KEY, creds->access_key_id) == 0); + TEST_CHECK(strcmp(STS_SECRET_KEY, creds->secret_access_key) == 0); + TEST_CHECK(strcmp(STS_TOKEN, creds->session_token) == 0); + + flb_aws_credentials_destroy(creds); + + /* refresh should return 0 (success) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret == 0); + + /* + * Request count should be 2: + * - One for the first call to get_credentials (2nd should hit cred cache) + * - One for the call to refresh + */ + TEST_CHECK(g_request_count == 2); + + flb_aws_provider_destroy(base_provider); + flb_aws_provider_destroy(provider); + flb_config_exit(config); +} + +static void test_sts_provider_api_error() { + struct flb_config *config; + struct flb_aws_provider *provider; + struct flb_aws_provider *base_provider; + struct flb_aws_credentials *creds; + int ret; + + g_request_count = 0; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + /* use the env provider as the base provider */ + /* set environment */ + ret = setenv(AWS_ACCESS_KEY_ID, "base_akid", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(AWS_SECRET_ACCESS_KEY, "base_skid", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(AWS_SESSION_TOKEN, "base_token", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + + base_provider = flb_aws_env_provider_create(); + if (!base_provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_sts_provider_create(config, NULL, base_provider, "external_id", + "arn:aws:iam::123456789012:role/apierror", + "session_name", "cn-north-1", + "https://sts.us-west-2.amazonaws.com", + NULL, + generator_in_test()); + if (!provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* refresh should return -1 (failure) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret < 0); + + /* + * Request count should be 3: + * - Each call to get_credentials and refresh invokes the client's + * request method and returns a request failure. + */ + TEST_CHECK(g_request_count == 3); + + flb_aws_provider_destroy(base_provider); + flb_aws_provider_destroy(provider); + flb_config_exit(config); +} + +/* unexpected output test- see description for STS_RESPONSE_MALFORMED */ +static void test_sts_provider_unexpected_api_response() { + struct flb_config *config; + struct flb_aws_provider *provider; + struct flb_aws_provider *base_provider; + struct flb_aws_credentials *creds; + int ret; + + g_request_count = 0; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + /* use the env provider as the base provider */ + /* set environment */ + ret = setenv(AWS_ACCESS_KEY_ID, "base_akid", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(AWS_SECRET_ACCESS_KEY, "base_skid", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + ret = setenv(AWS_SESSION_TOKEN, "base_token", 1); + if (ret < 0) { + flb_errno(); + flb_config_exit(config); + return; + } + + base_provider = flb_aws_env_provider_create(); + if (!base_provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + provider = flb_sts_provider_create(config, NULL, base_provider, "external_id", + "arn:aws:iam::123456789012:role/" + "unexpected_api_response", + "session_name", "cn-north-1", + "https://sts.us-west-2.amazonaws.com", + NULL, + generator_in_test()); + if (!provider) { + flb_errno(); + flb_config_exit(config); + return; + } + + /* repeated calls to get credentials should return the same set */ + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + creds = provider->provider_vtable->get_credentials(provider); + TEST_CHECK(creds == NULL); + + /* refresh should return -1 (failure) */ + ret = provider->provider_vtable->refresh(provider); + TEST_CHECK(ret < 0); + + /* + * Request count should be 3: + * - Each call to get_credentials and refresh invokes the client's + * request method and returns a request failure. + */ + TEST_CHECK(g_request_count == 3); + + flb_aws_provider_destroy(base_provider); + flb_aws_provider_destroy(provider); + flb_config_exit(config); +} + + +TEST_LIST = { + { "test_flb_sts_session_name" , test_flb_sts_session_name}, + { "test_sts_uri" , test_sts_uri}, + { "process_sts_response" , test_process_sts_response}, + { "eks_credential_provider" , test_eks_provider}, + { "eks_credential_provider_random_session_name" , + test_eks_provider_random_session_name}, + { "test_eks_provider_unexpected_api_response" , + test_eks_provider_unexpected_api_response}, + { "eks_credential_provider_api_error" , test_eks_provider_api_error}, + { "sts_credential_provider" , test_sts_provider}, + { "sts_credential_provider_api_error" , test_sts_provider_api_error}, + { "sts_credential_provider_unexpected_api_response" , + test_sts_provider_unexpected_api_response}, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/aws_credentials_test_internal.h b/src/fluent-bit/tests/internal/aws_credentials_test_internal.h new file mode 100644 index 000000000..bd3357822 --- /dev/null +++ b/src/fluent-bit/tests/internal/aws_credentials_test_internal.h @@ -0,0 +1,42 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#ifndef AWS_CREDENTIALS_TEST_INTERNAL_H + +#define AWS_CREDENTIALS_TEST_INTERNAL_H + +#include "flb_tests_internal.h" + +#define AWS_TEST_DATA_PATH(FILE_PATH) FLB_TESTS_DATA_PATH "data/aws_credentials/" FILE_PATH + +static int unset_profile_env() +{ + int ret; + ret = unsetenv("HOME"); + if (ret < 0) { + flb_errno(); + return -1; + } + ret = unsetenv("AWS_CONFIG_FILE"); + if (ret < 0) { + flb_errno(); + return -1; + } + ret = unsetenv("AWS_SHARED_CREDENTIALS_FILE"); + if (ret < 0) { + flb_errno(); + return -1; + } + ret = unsetenv("AWS_DEFAULT_PROFILE"); + if (ret < 0) { + flb_errno(); + return -1; + } + ret = unsetenv("AWS_PROFILE"); + if (ret < 0) { + flb_errno(); + return -1; + } + return 0; +} + +#endif /* AWS_CREDENTIALS_TEST_INTERNAL_H */ diff --git a/src/fluent-bit/tests/internal/aws_util.c b/src/fluent-bit/tests/internal/aws_util.c new file mode 100644 index 000000000..6f6fbdb1a --- /dev/null +++ b/src/fluent-bit/tests/internal/aws_util.c @@ -0,0 +1,395 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include + +#include "flb_tests_internal.h" + +#define S3_KEY_FORMAT_TAG_PART "logs/$TAG[2]/$TAG[0]/%Y/%m/%d" +#define S3_OBJECT_KEY_TAG_PART "logs/ccc/aa/2020/08/15" + +#define S3_KEY_FORMAT_FULL_TAG "logs/$TAG/%Y/%m/%d" +#define S3_OBJECT_KEY_FULL_TAG "logs/aa.bb.ccc/2020/08/15" + +#define S3_KEY_FORMAT_SPECIAL_CHARCATERS_TAG "logs/my.great_photos-2020:jan/$TAG/%Y/%m/%d" +#define S3_OBJECT_KEY_SPECIAL_CHARCATERS_TAG "logs/my.great_photos-2020:jan/aa.bb.ccc/2020/08/15" + +#define S3_OBJECT_KEY_INVALID_DELIMITER "logs/aa.bb-ccc[2]/aa.bb-ccc/2020/08/15" + +#define S3_KEY_FORMAT_INVALID_TAG "logs/$TAG[2]/$TAG[-1]/%Y/%m/%d" +#define S3_OBJECY_KEY_INVALID_TAG "logs/ccc/aa.bb.ccc[-1]/2020/08/15" + +#define S3_KEY_FORMAT_OUT_OF_BOUNDS_TAG "logs/$TAG[2]/$TAG[]/%Y/%m/%d" + +#define S3_KEY_FORMAT_STATIC_STRING "logs/fluent-bit" + +#define S3_KEY_FORMAT_UUID "logs/$UUID" +#define S3_OBJECT_KEY_UUID "logs/" + +#define S3_KEY_FORMAT_ALL_OPTIONS "logs/$TAG[2]/$TAG[1]/$TAG[0]/%Y/%m/%d/file-$INDEX-$UUID" +#define S3_OBJECT_KEY_ALL_OPTIONS "logs/ccc/bb/aa/2020/08/15/file-0-" + +#define S3_KEY_FORMAT_VALID_INDEX "logs/a-$INDEX-b-c" +#define S3_OBJECT_KEY_VALID_INDEX "logs/a-12-b-c" +#define S3_OBJECT_KEY_PRE_OVERFLOW_INDEX "logs/a-18446744073709551615-b-c" +#define S3_OBJECT_KEY_POST_OVERFLOW_INDEX "logs/a-0-b-c" + +#define S3_KEY_FORMAT_MIXED_TIMESTAMP "logs/%Y/m/%m/d/%d/%q" +#ifdef FLB_SYSTEM_MACOS +/* macOS's strftime throws away for % character for % and suqsequent invalid format character. */ +#define S3_OBJECT_KEY_MIXED_TIMESTAMP "logs/2020/m/08/d/15/q" +#else +#define S3_OBJECT_KEY_MIXED_TIMESTAMP "logs/2020/m/08/d/15/%q" +#endif + +#define NO_TAG "" +#define TAG "aa.bb.ccc" +#define MULTI_DELIMITER_TAG "aa.bb-ccc" +#define TAG_DELIMITER "." +#define TAG_DELIMITERS ".-" +#define INVALID_TAG_DELIMITERS ",/" +#define VALID_SEQ_INDEX 0 + +static void initialization_crutch() +{ + struct flb_config *config; + + config = flb_config_init(); + + if (config == NULL) { + return; + } + + flb_config_exit(config); +} + + +pthread_mutex_t env_mutex = PTHREAD_MUTEX_INITIALIZER; +static int mktime_utc(struct tm *day, time_t *tm) +{ + int ret; + char *tzvar = NULL; + char orig_tz[256] = {0}; + time_t t; + + if (!TEST_CHECK(day != NULL)) { + TEST_MSG("struct tm is null"); + return -1; + } + if (!TEST_CHECK(tm != NULL)) { + TEST_MSG("time_t is null"); + return -1; + } + + pthread_mutex_lock(&env_mutex); + + /* save current TZ var */ + tzvar = getenv("TZ"); + if (tzvar != NULL) { + if (!TEST_CHECK(strlen(tzvar) <= sizeof(orig_tz))) { + TEST_MSG("TZ is large. len=%ld TZ=%s", strlen(tzvar), tzvar); + pthread_mutex_unlock(&env_mutex); + return -1; + } + strncpy(&orig_tz[0], tzvar, sizeof(orig_tz)); + } + + /* setenv is not thread safe */ + ret = setenv("TZ", "UTC", 1); + if (!TEST_CHECK(ret == 0)) { + TEST_MSG("setenv failed"); + pthread_mutex_unlock(&env_mutex); + return -1; + } + + t = mktime(day); + *tm = t; + + /* restore TZ */ + if (tzvar != NULL) { + ret = setenv("TZ", &orig_tz[0], 1); + } + else { + ret = unsetenv("TZ"); + } + + pthread_mutex_unlock(&env_mutex); + + return ret; +} + +static void test_flb_aws_error() +{ + flb_sds_t error_type; + char *api_response = "{\"__type\":\"IncompleteSignatureException\"," + "\"message\": \"Credential must have exactly 5 " + "slash-delimited elements, e.g. keyid/date/region/" + "service/term, got ''\"}"; + char *garbage = "garbage"; /* something that can't be parsed */ + + initialization_crutch(); + + error_type = flb_aws_error(api_response, strlen(api_response)); + + TEST_CHECK(strcmp("IncompleteSignatureException", error_type) == 0); + + flb_sds_destroy(error_type); + + error_type = flb_aws_error(garbage, strlen(garbage)); + + TEST_CHECK(error_type == NULL); + + flb_sds_destroy(error_type); +} + +static void test_flb_aws_endpoint() +{ + char *endpoint; + + initialization_crutch(); + + endpoint = flb_aws_endpoint("cloudwatch", "ap-south-1"); + + TEST_CHECK(strcmp("cloudwatch.ap-south-1.amazonaws.com", + endpoint) == 0); + flb_free(endpoint); + + /* China regions have a different TLD */ + endpoint = flb_aws_endpoint("cloudwatch", "cn-north-1"); + + TEST_CHECK(strcmp("cloudwatch.cn-north-1.amazonaws.com.cn", + endpoint) == 0); + flb_free(endpoint); + +} + +static void test_flb_get_s3_key_multi_tag_exists() +{ + flb_sds_t s3_key_format = NULL; + struct tm day = { 0, 0, 0, 15, 7, 120}; + time_t t; + + initialization_crutch(); + + mktime_utc(&day, &t); + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_TAG_PART, t, TAG, TAG_DELIMITER, 0); + TEST_CHECK(strcmp(s3_key_format, S3_OBJECT_KEY_TAG_PART) == 0); + + flb_sds_destroy(s3_key_format); +} + +static void test_flb_get_s3_key_full_tag() +{ + flb_sds_t s3_key_format = NULL; + struct tm day = { 0, 0, 0, 15, 7, 120}; + time_t t; + + initialization_crutch(); + + mktime_utc(&day, &t); + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_FULL_TAG, t, TAG, TAG_DELIMITER, 0); + TEST_CHECK(strcmp(s3_key_format, S3_OBJECT_KEY_FULL_TAG) == 0); + + flb_sds_destroy(s3_key_format); +} + +static void test_flb_get_s3_key_tag_special_characters() +{ + flb_sds_t s3_key_format = NULL; + struct tm day = { 0, 0, 0, 15, 7, 120}; + time_t t; + + initialization_crutch(); + + mktime_utc(&day, &t); + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_SPECIAL_CHARCATERS_TAG, t, TAG, + TAG_DELIMITER, 0); + TEST_CHECK(strcmp(s3_key_format, S3_OBJECT_KEY_SPECIAL_CHARCATERS_TAG) == 0); + + flb_sds_destroy(s3_key_format); +} + +static void test_flb_get_s3_key_multi_tag_delimiter() +{ + flb_sds_t s3_key_format = NULL; + struct tm day = { 0, 0, 0, 15, 7, 120}; + time_t t; + + initialization_crutch(); + + mktime_utc(&day, &t); + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_TAG_PART, t, MULTI_DELIMITER_TAG, + TAG_DELIMITERS, 0); + TEST_CHECK(strcmp(s3_key_format, S3_OBJECT_KEY_TAG_PART) == 0); + + flb_sds_destroy(s3_key_format); +} + +static void test_flb_get_s3_key_invalid_tag_delimiter() +{ + flb_sds_t s3_key_format = NULL; + struct tm day = { 0, 0, 0, 15, 7, 120}; + time_t t; + + initialization_crutch(); + + mktime_utc(&day, &t); + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_TAG_PART, t, MULTI_DELIMITER_TAG, + INVALID_TAG_DELIMITERS, 0); + TEST_CHECK(strcmp(s3_key_format, S3_OBJECT_KEY_INVALID_DELIMITER) == 0); + + flb_sds_destroy(s3_key_format); +} + +static void test_flb_get_s3_key_invalid_tag_index() +{ + flb_sds_t s3_key_format = NULL; + struct tm day = { 0, 0, 0, 15, 7, 120}; + time_t t; + + initialization_crutch(); + + mktime_utc(&day, &t); + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_INVALID_TAG, t, TAG, TAG_DELIMITER, 0); + TEST_CHECK(strcmp(s3_key_format, S3_OBJECY_KEY_INVALID_TAG) == 0); + + flb_sds_destroy(s3_key_format); +} + +static void test_flb_get_s3_key_invalid_key_length() +{ + int i; + char buf[1100] = ""; + char tmp[1024] = ""; + flb_sds_t s3_key_format = NULL; + + initialization_crutch(); + + for (i = 0; i <= 975; i++){ + tmp[i] = 'a'; + } + snprintf(buf, sizeof(buf), "%s%s", S3_KEY_FORMAT_SPECIAL_CHARCATERS_TAG, tmp); + struct tm day = { 0, 0, 0, 15, 7, 120}; + time_t t; + + mktime_utc(&day, &t); + s3_key_format = flb_get_s3_key(buf, t, TAG, TAG_DELIMITER, 0); + TEST_CHECK(strlen(s3_key_format) <= 1024); + + flb_sds_destroy(s3_key_format); +} + +static void test_flb_get_s3_key_static_string() +{ + flb_sds_t s3_key_format = NULL; + struct tm day = { 0, 0, 0, 15, 7, 120}; + time_t t; + + initialization_crutch(); + + mktime_utc(&day, &t); + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_STATIC_STRING, t, NO_TAG, + TAG_DELIMITER, 0); + TEST_CHECK(strcmp(s3_key_format, S3_KEY_FORMAT_STATIC_STRING) == 0); + + flb_sds_destroy(s3_key_format); +} + +static void test_flb_get_s3_key_valid_index() +{ + flb_sds_t s3_key_format = NULL; + struct tm day = { 0, 0, 0, 15, 7, 120}; + time_t t; + + initialization_crutch(); + + mktime_utc(&day, &t); + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_VALID_INDEX, t, NO_TAG, + TAG_DELIMITER, 12); + TEST_CHECK(strcmp(s3_key_format, S3_OBJECT_KEY_VALID_INDEX) == 0); + + flb_sds_destroy(s3_key_format); +} + +static void test_flb_get_s3_key_increment_index() +{ + struct tm day = { 0, 0, 0, 15, 7, 120}; + time_t t; + flb_sds_t s3_key_format = NULL; + + initialization_crutch(); + + mktime_utc(&day, &t); + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_VALID_INDEX, t, NO_TAG, + TAG_DELIMITER, 5); + + TEST_CHECK(strcmp(s3_key_format, "logs/a-5-b-c") == 0); + + flb_sds_destroy(s3_key_format); + + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_VALID_INDEX, t, NO_TAG, + TAG_DELIMITER, 10); + + TEST_CHECK(strcmp(s3_key_format, "logs/a-10-b-c") == 0); + + flb_sds_destroy(s3_key_format); +} + +static void test_flb_get_s3_key_index_overflow() +{ + flb_sds_t s3_key_format = NULL; + struct tm day = { 0, 0, 0, 15, 7, 120}; + time_t t; + uint64_t index = 18446744073709551615U; + + initialization_crutch(); + + mktime_utc(&day, &t); + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_VALID_INDEX, t, NO_TAG, + TAG_DELIMITER, index); + TEST_CHECK(strcmp(s3_key_format, S3_OBJECT_KEY_PRE_OVERFLOW_INDEX) == 0); + flb_sds_destroy(s3_key_format); + + index++; + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_VALID_INDEX, t, NO_TAG, + TAG_DELIMITER, index); + TEST_CHECK(strcmp(s3_key_format, S3_OBJECT_KEY_POST_OVERFLOW_INDEX) == 0); + + flb_sds_destroy(s3_key_format); +} + +static void test_flb_get_s3_key_mixed_timestamp() +{ + flb_sds_t s3_key_format = NULL; + struct tm day = { 0, 0, 0, 15, 7, 120}; + time_t t; + + initialization_crutch(); + + mktime_utc(&day, &t); + s3_key_format = flb_get_s3_key(S3_KEY_FORMAT_MIXED_TIMESTAMP, t, NO_TAG, + TAG_DELIMITER, 12); + TEST_CHECK(strcmp(s3_key_format, S3_OBJECT_KEY_MIXED_TIMESTAMP) == 0); + + flb_sds_destroy(s3_key_format); +} + +TEST_LIST = { + { "parse_api_error" , test_flb_aws_error}, + { "flb_aws_endpoint" , test_flb_aws_endpoint}, + {"flb_get_s3_key_multi_tag_exists", test_flb_get_s3_key_multi_tag_exists}, + {"flb_get_s3_key_full_tag", test_flb_get_s3_key_full_tag}, + {"flb_get_s3_key_tag_special_characters", test_flb_get_s3_key_tag_special_characters}, + {"flb_get_s3_key_multi_tag_delimiter", test_flb_get_s3_key_multi_tag_delimiter}, + {"flb_get_s3_key_invalid_tag_delimiter", test_flb_get_s3_key_invalid_tag_delimiter}, + {"flb_get_s3_key_invalid_tag_index", test_flb_get_s3_key_invalid_tag_index}, + {"flb_get_s3_key_invalid_key_length", test_flb_get_s3_key_invalid_key_length}, + {"flb_get_s3_key_static_string", test_flb_get_s3_key_static_string}, + {"flb_get_s3_key_valid_index", test_flb_get_s3_key_valid_index}, + {"flb_get_s3_key_increment_index", test_flb_get_s3_key_increment_index}, + {"flb_get_s3_key_index_overflow", test_flb_get_s3_key_index_overflow}, + {"flb_get_s3_key_mixed_timestamp", test_flb_get_s3_key_mixed_timestamp}, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/base64.c b/src/fluent-bit/tests/internal/base64.c new file mode 100644 index 000000000..4375870fc --- /dev/null +++ b/src/fluent-bit/tests/internal/base64.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include + +#include "flb_tests_internal.h" + +static void b64_basic_test_encode() +{ + char* data = "Hello world"; + char out[100]; + char* expect = "SGVsbG8gd29ybGQ="; + size_t olen; + out[16] = 'X'; + + flb_base64_encode((unsigned char *) out, 100, &olen, (unsigned char *)data, 11); + + TEST_CHECK(strlen(out) == 16 && olen == 16); + TEST_MSG("Base64 encode failed to output result of expected length"); + + TEST_CHECK(strcmp(out, expect) == 0); + TEST_MSG("Base64 encode failed to output result of expected value"); + + TEST_CHECK(out[16] == 0); + TEST_MSG("Base64 not null terminated"); + return; +} + +static void b64_basic_test_decode() +{ + char* data = "SGVsbG8gd29ybGQ="; + char out[100] = { 0 }; + char* expect = "Hello world"; + size_t olen; + + flb_base64_decode((unsigned char *) out, 100, &olen, (unsigned char *)data, 16); + + TEST_CHECK(strlen(out) == 11 && olen == 11); + TEST_MSG("Base64 decode failed to output result of expected length"); + + TEST_CHECK(strcmp(out, expect) == 0); + TEST_MSG("Base64 decode failed to output result of expected value"); + return; +} + +TEST_LIST = { + { "b64_basic_test_encode" , b64_basic_test_encode }, + { "b64_basic_test_decode", b64_basic_test_decode }, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/bucket_queue.c b/src/fluent-bit/tests/internal/bucket_queue.c new file mode 100644 index 000000000..ddc93597e --- /dev/null +++ b/src/fluent-bit/tests/internal/bucket_queue.c @@ -0,0 +1,248 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include +#include +#include + +#include "flb_tests_internal.h" + +#include +#include + +#include +#include + +#define TST_PRIORITY_OP_ADD 1 +#define TST_PRIORITY_OP_DELETE 2 +#define TST_PRIORITY_OP_EXPECT 3 +#define TST_PRIORITY_OP_POP 3 + + +struct bucket_queue_entry { + char *tag; + size_t priority; + struct mk_list item; + size_t add_idx; +}; + +struct bucket_queue_op_add { + struct bucket_queue_entry *entries; +}; + +struct bucket_queue_op_expect { + char *tag; +}; + +struct bucket_queue_op_pop { + char *tag; +}; + +union bucket_queue_op_union { + struct bucket_queue_op_pop pop; + struct bucket_queue_op_add add; + struct bucket_queue_op_expect expect; +}; + +struct bucket_queue_op { + char op; + void *op_description; +}; + +void test_create_destroy() +{ + struct flb_bucket_queue *bucket_queue; + bucket_queue = flb_bucket_queue_create(100); + flb_bucket_queue_destroy(bucket_queue); +} + +void test_add_priorities() +{ + struct flb_bucket_queue *bucket_queue; + + struct bucket_queue_op operations[] = { + { + TST_PRIORITY_OP_ADD, + &(struct bucket_queue_op_add) { + (struct bucket_queue_entry[]) { + { + "a", + 2 /* priority */ + }, + { + "b", + 2 /* priority */ + }, + { + "c", + 0 /* priority */ + }, + { + "d", + 2 /* priority */ + }, + { + "e", + 3 /* priority */ + }, + { 0 } + } + } + }, + { + TST_PRIORITY_OP_POP, + &(struct bucket_queue_op_pop) { + "c" + } + }, + { + TST_PRIORITY_OP_POP, + &(struct bucket_queue_op_pop) { + "a" + } + }, + { + TST_PRIORITY_OP_POP, + &(struct bucket_queue_op_pop) { + "b" + } + }, + { + TST_PRIORITY_OP_POP, + &(struct bucket_queue_op_pop) { + "d" + } + }, + { + TST_PRIORITY_OP_POP, + &(struct bucket_queue_op_pop) { + "e" + } + }, + { + TST_PRIORITY_OP_POP, + &(struct bucket_queue_op_pop) { + "" + } + }, + { + TST_PRIORITY_OP_ADD, + &(struct bucket_queue_op_add) { + (struct bucket_queue_entry[]) { + { + "f", + 1 /* priority */ + }, + { + "g", + 1 /* priority */ + }, + { + "h", + 0 + }, + { 0 } + } + } + }, + { + TST_PRIORITY_OP_POP, + &(struct bucket_queue_op_pop) { + "h" + } + }, + { + TST_PRIORITY_OP_POP, + &(struct bucket_queue_op_pop) { + "f" + } + }, + { + TST_PRIORITY_OP_POP, + &(struct bucket_queue_op_pop) { + "g" + } + }, + { + TST_PRIORITY_OP_POP, + &(struct bucket_queue_op_pop) { + "" + } + }, + { + TST_PRIORITY_OP_POP, + &(struct bucket_queue_op_pop) { + "" + } + }, + { 0 } + }; + + bucket_queue = flb_bucket_queue_create(4); + struct bucket_queue_op *op; + struct bucket_queue_op_add *op_desc_add; + struct bucket_queue_op_pop *op_desc_pop; + struct bucket_queue_entry *bucket_queue_entry; + struct mk_list *list_entry; + size_t add_idx = 0; + int ret; + int retB; + + for (op = operations; op->op != 0; ++op) { + if (op->op == TST_PRIORITY_OP_ADD) { + op_desc_add = (struct bucket_queue_op_add *) op->op_description; + for (bucket_queue_entry = op_desc_add->entries; bucket_queue_entry->tag != 0; + ++bucket_queue_entry) { + bucket_queue_entry->add_idx = add_idx++; + ret = flb_bucket_queue_add(bucket_queue, &bucket_queue_entry->item, + bucket_queue_entry->priority); + TEST_CHECK(ret == 0); + TEST_MSG("[op %zu][entry %zu] Add failed. Returned %d", op - operations, + bucket_queue_entry - op_desc_add->entries, ret); + } + } + + else if (op->op == TST_PRIORITY_OP_POP) { + op_desc_pop = (struct bucket_queue_op_pop *) op->op_description; + list_entry = flb_bucket_queue_pop_min(bucket_queue); + ret = strcmp("", op_desc_pop->tag); + + if (ret == 0) { + TEST_CHECK(list_entry == NULL); + TEST_MSG("[op %zu] Pop failed.", op - operations); + TEST_MSG("Expect: null"); + TEST_MSG("Produced: list_entry %p", list_entry); + } + else { + TEST_CHECK(list_entry != NULL); + TEST_MSG("[op %zu] Pop failed.", op - operations); + TEST_MSG("Expect: non-null"); + TEST_MSG("Produced: null"); + + bucket_queue_entry = mk_list_entry(list_entry, struct bucket_queue_entry, item); + ret = strcmp(bucket_queue_entry->tag, op_desc_pop->tag); + TEST_CHECK(ret == 0); + TEST_MSG("[op %zu] Pop failed.", op - operations); + TEST_MSG("Expect tag: %s", op_desc_pop->tag); + TEST_MSG("Produced tag: %s", bucket_queue_entry->tag); + + ret = strlen(bucket_queue_entry->tag); + retB = strlen(op_desc_pop->tag); + TEST_CHECK(ret == retB); + TEST_MSG("[op %zu] Pop failed.", op - operations); + TEST_MSG("Expect tag len: %d", retB); + TEST_MSG("Produced tag len: %d", ret); + } + } + } + + flb_bucket_queue_destroy(bucket_queue); +} + +TEST_LIST = { + {"create_destroy" , test_create_destroy}, + {"add_priorities" , test_add_priorities}, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/config_format.c b/src/fluent-bit/tests/internal/config_format.c new file mode 100644 index 000000000..7f887a541 --- /dev/null +++ b/src/fluent-bit/tests/internal/config_format.c @@ -0,0 +1,86 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "flb_tests_internal.h" + +void test_api() +{ + struct flb_cf *cf; + struct flb_cf_section *s_tmp; + struct flb_cf_section *service; + struct flb_cf_group *g_tmp; + struct cfl_variant *ret; + struct flb_kv *meta; + + /* create context */ + cf = flb_cf_create(); + TEST_CHECK(cf != NULL); + + /* create service section */ + service = flb_cf_section_create(cf, "SERVICE", 7); + TEST_CHECK(service != NULL); + + /* add a property */ + ret = flb_cf_section_property_add(cf, service->properties, "key", 3, "val", 3); + TEST_CHECK(ret != NULL); + + /* add a property with empty spaces on left/right */ + ret = flb_cf_section_property_add(cf, service->properties, " key ", 5, " val ", 7); + TEST_CHECK(ret != NULL); + + /* add an invalid property */ + ret = flb_cf_section_property_add(cf, service->properties, " ", 3, "", 0); + TEST_CHECK(ret == NULL); + + /* try to add another 'SERVICE' section, it should return the same one */ + s_tmp = flb_cf_section_create(cf, "SERVICE", 7); + TEST_CHECK(s_tmp == service); + + /* add a valid section */ + s_tmp = flb_cf_section_create(cf, "INPUT", 5); + TEST_CHECK(s_tmp != NULL); + + TEST_CHECK(mk_list_size(&cf->inputs) == 1); + + /* add property to the section recently created */ + ret = flb_cf_section_property_add(cf, s_tmp->properties, "key", 3, "val", 3); + TEST_CHECK(ret != NULL); + + /* groups: add groups to the last section created */ + g_tmp = flb_cf_group_create(cf, s_tmp, "FLUENT GROUP", 12); + TEST_CHECK(g_tmp != NULL); + + /* add properties to the group */ + ret = flb_cf_section_property_add(cf, g_tmp->properties, "key", 3, "val", 3); + TEST_CHECK(ret != NULL); + + /* groups: invalid group */ + g_tmp = flb_cf_group_create(cf, s_tmp, "", 0); + TEST_CHECK(g_tmp == NULL); + + /* Meta commands */ + meta = flb_cf_meta_property_add(cf, "@SET a=1 ", 20); + TEST_CHECK(meta != NULL); + TEST_CHECK(flb_sds_len(meta->key) == 3 && strcmp(meta->key, "SET") == 0); + TEST_CHECK(flb_sds_len(meta->val) == 3 && strcmp(meta->val, "a=1") == 0); + + /* invalid meta */ + meta = flb_cf_meta_property_add(cf, "@a=1 ", 5); + TEST_CHECK(meta == NULL); + + /* destroy context */ + flb_cf_destroy(cf); +} + +TEST_LIST = { + { "api" , test_api}, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/config_format_fluentbit.c b/src/fluent-bit/tests/internal/config_format_fluentbit.c new file mode 100644 index 000000000..3f1585739 --- /dev/null +++ b/src/fluent-bit/tests/internal/config_format_fluentbit.c @@ -0,0 +1,353 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "flb_tests_internal.h" + +#define FLB_000 FLB_TESTS_DATA_PATH "/data/config_format/classic/fluent-bit.conf" +#define FLB_001 FLB_TESTS_DATA_PATH "/data/config_format/classic/issue_5880.conf" +#define FLB_002 FLB_TESTS_DATA_PATH "/data/config_format/classic/indent_level_error.conf" +#define FLB_003 FLB_TESTS_DATA_PATH "/data/config_format/classic/recursion.conf" +#define FLB_004 FLB_TESTS_DATA_PATH "/data/config_format/classic/issue6281.conf" +#define FLB_005 FLB_TESTS_DATA_PATH "/data/config_format/classic/nolimitline.conf" + +#define ERROR_LOG "fluentbit_conf_error.log" + +/* data/config_format/fluent-bit.conf */ +void test_basic() +{ + struct mk_list *head; + struct flb_cf *cf; + struct flb_cf_section *s; + struct flb_cf_group *g; + + cf = flb_cf_fluentbit_create(NULL, FLB_000, NULL, 0); + TEST_CHECK(cf != NULL); + + /* Total number of sections */ + TEST_CHECK(mk_list_size(&cf->sections) == 8); + + /* SERVICE check */ + TEST_CHECK(cf->service != NULL); + if (cf->service) { + TEST_CHECK(cfl_list_size(&cf->service->properties->list) == 3); + } + + /* Meta commands */ + TEST_CHECK(mk_list_size(&cf->metas) == 2); + + /* Check number sections per list */ + TEST_CHECK(mk_list_size(&cf->parsers) == 1); + TEST_CHECK(mk_list_size(&cf->multiline_parsers) == 1); + TEST_CHECK(mk_list_size(&cf->customs) == 1); + TEST_CHECK(mk_list_size(&cf->inputs) == 1); + TEST_CHECK(mk_list_size(&cf->filters) == 1); + TEST_CHECK(mk_list_size(&cf->outputs) == 1); + TEST_CHECK(mk_list_size(&cf->others) == 1); + + /* groups */ + s = flb_cf_section_get_by_name(cf, "input"); + TEST_CHECK(s != NULL); + TEST_CHECK(mk_list_size(&s->groups) == 2); + + mk_list_foreach(head, &s->groups) { + g = mk_list_entry(head, struct flb_cf_group, _head); + TEST_CHECK(cfl_list_size(&g->properties->list) == 2); + } + + printf("\n"); + flb_cf_dump(cf); + + flb_cf_destroy(cf); +} + +struct str_list { + size_t size; + char **lists; +}; + +static int check_str_list(struct str_list *list, FILE *fp) +{ + flb_sds_t error_str = NULL; + char *p = NULL; + size_t size; + int str_size = 4096; + int i; + int fd = fileno(fp); + struct stat st; + + if (!TEST_CHECK(list != NULL)) { + TEST_MSG("list is NULL"); + return -1; + } + if (!TEST_CHECK(fp != NULL)) { + TEST_MSG("fp is NULL"); + return -1; + } + + if (!TEST_CHECK(fstat(fd, &st) == 0)) { + TEST_MSG("fstat failed"); + return -1; + } + str_size = st.st_size; + error_str = flb_sds_create_size(str_size); + if (!TEST_CHECK(error_str != NULL)) { + TEST_MSG("flb_sds_create_size failed."); + return -1; + } + + size = fread(error_str, 1, str_size, fp); + if (size < str_size) { + if (!TEST_CHECK(ferror(fp) == 0)) { + TEST_MSG("fread failed."); + clearerr(fp); + flb_sds_destroy(error_str); + return -1; + } + clearerr(fp); + } + + for (i=0; isize; i++) { + p = strstr(error_str, list->lists[i]); + if (!TEST_CHECK(p != NULL)) { + TEST_MSG(" Got :%s\n expect:%s", error_str, list->lists[i]); + } + } + + flb_sds_destroy(error_str); + return 0; +} + + +/* https://github.com/fluent/fluent-bit/issues/5880 */ +void missing_value() +{ + struct flb_cf *cf; + FILE *fp = NULL; + char *expected_strs[] = {"undefined value", ":9:" /* lieno*/ }; + struct str_list expected = { + .size = sizeof(expected_strs)/sizeof(char*), + .lists = &expected_strs[0], + }; + + unlink(ERROR_LOG); + + fp = freopen(ERROR_LOG, "w+", stderr); + if (!TEST_CHECK(fp != NULL)) { + TEST_MSG("freopen failed. errno=%d path=%s", errno, ERROR_LOG); + exit(EXIT_FAILURE); + } + + cf = flb_cf_fluentbit_create(NULL, FLB_001, NULL, 0); + TEST_CHECK(cf == NULL); + fflush(fp); + fclose(fp); + + fp = fopen(ERROR_LOG, "r"); + if (!TEST_CHECK(fp != NULL)) { + TEST_MSG("fopen failed. errno=%d path=%s", errno, ERROR_LOG); + unlink(ERROR_LOG); + exit(EXIT_FAILURE); + } + + check_str_list(&expected, fp); + + fclose(fp); + unlink(ERROR_LOG); +} + +void indent_level_error() +{ + struct flb_cf *cf; + FILE *fp = NULL; + char *expected_strs[] = {"invalid", "indent", "level"}; + struct str_list expected = { + .size = sizeof(expected_strs)/sizeof(char*), + .lists = &expected_strs[0], + }; + + unlink(ERROR_LOG); + + fp = freopen(ERROR_LOG, "w+", stderr); + if (!TEST_CHECK(fp != NULL)) { + TEST_MSG("freopen failed. errno=%d path=%s", errno, ERROR_LOG); + exit(EXIT_FAILURE); + } + + cf = flb_cf_create(); + if (!TEST_CHECK(cf != NULL)) { + TEST_MSG("flb_cf_create failed"); + exit(EXIT_FAILURE); + } + + cf = flb_cf_fluentbit_create(cf, FLB_002, NULL, 0); + TEST_CHECK(cf == NULL); + fflush(fp); + fclose(fp); + + fp = fopen(ERROR_LOG, "r"); + if (!TEST_CHECK(fp != NULL)) { + TEST_MSG("fopen failed. errno=%d path=%s", errno, ERROR_LOG); + if (cf != NULL) { + flb_cf_destroy(cf); + } + unlink(ERROR_LOG); + exit(EXIT_FAILURE); + } + + check_str_list(&expected, fp); + if (cf != NULL) { + flb_cf_destroy(cf); + } + fclose(fp); + unlink(ERROR_LOG); +} + +void recursion() +{ + struct flb_cf *cf; + + cf = flb_cf_create(); + if (!TEST_CHECK(cf != NULL)) { + TEST_MSG("flb_cf_create failed"); + exit(EXIT_FAILURE); + } + + cf = flb_cf_fluentbit_create(cf, FLB_003, NULL, 0); + + /* No SIGSEGV means success */ +} + + +/* + * https://github.com/fluent/fluent-bit/issues/6281 + * + * Fluent-bit loads issue6281.conf that loads issue6281_input/output.conf. + * + * config dir -+-- issue6281.conf + * | + * +-- issue6281_input.conf + * | + * +-- issue6281_output.conf + */ +void not_current_dir_files() +{ + struct flb_cf *cf; + + cf = flb_cf_create(); + if (!TEST_CHECK(cf != NULL)) { + TEST_MSG("flb_cf_create failed"); + exit(EXIT_FAILURE); + } + + cf = flb_cf_fluentbit_create(cf, FLB_004, NULL, 0); + if (!TEST_CHECK(cf != NULL)) { + TEST_MSG("flb_cf_fluentbit_create failed"); + exit(EXIT_FAILURE); + } + + if (cf != NULL) { + flb_cf_destroy(cf); + } +} + +/* data/config_format/nolimitline.conf */ +void test_nolimit_line() +{ + struct flb_cf *cf; + struct flb_cf_section *s; + struct cfl_list *p_head; + struct cfl_kvpair *kv; + + cf = flb_cf_fluentbit_create(NULL, FLB_005, NULL, 0); + TEST_CHECK(cf != NULL); + + /* Total number of sections */ + TEST_CHECK(mk_list_size(&cf->sections) == 3); + + /* SERVICE check */ + TEST_CHECK(cf->service == NULL); + + /* Meta commands */ + TEST_CHECK(mk_list_size(&cf->metas) == 0); + + /* Check number sections per list */ + TEST_CHECK(mk_list_size(&cf->inputs) == 1); + TEST_CHECK(mk_list_size(&cf->filters) == 1); + TEST_CHECK(mk_list_size(&cf->outputs) == 1); + + /* Check the previous line buffer limit */ + s = flb_cf_section_get_by_name(cf, "filter"); + TEST_CHECK(s != NULL); + TEST_CHECK(mk_list_size(&s->groups) == 0); + + if (cfl_list_size(&s->properties->list) > 0) { + TEST_CHECK(cfl_list_size(&s->properties->list) == 4); + cfl_list_foreach(p_head, &s->properties->list) { + kv = cfl_list_entry(p_head, struct cfl_kvpair, _head); + if (strcmp(kv->key, "code") == 0) { + TEST_CHECK(cfl_sds_len(kv->val->data.as_string) > FLB_DEFAULT_CF_BUF_SIZE); + } + } + } + + printf("\n"); + flb_cf_dump(cf); + + flb_cf_destroy(cf); +} + +static inline int check_snake_case(char *input, char *output) +{ + int len; + int ret; + flb_sds_t out; + struct flb_cf *cf; + + + cf = flb_cf_create(); + flb_cf_set_origin_format(cf, FLB_CF_CLASSIC); + + len = strlen(input); + out = flb_cf_key_translate(cf, input, len); + + ret = strcmp(out, output); + + flb_sds_destroy(out); + + flb_cf_destroy(cf); + + if (ret == 0) { + return FLB_TRUE; + } + + return FLB_FALSE; +} + +static void test_snake_case_key() +{ + /* normal conversion */ + TEST_CHECK(check_snake_case("a", "a") == FLB_TRUE); + TEST_CHECK(check_snake_case("aB", "ab") == FLB_TRUE); + TEST_CHECK(check_snake_case("aBc", "abc") == FLB_TRUE); + TEST_CHECK(check_snake_case("interval_Sec", "interval_sec") == FLB_TRUE); +} + +TEST_LIST = { + { "basic" , test_basic}, + { "missing_value_issue5880" , missing_value}, + { "indent_level_error" , indent_level_error}, + { "recursion" , recursion}, + { "not_current_dir_files", not_current_dir_files}, + { "no_limit_line", test_nolimit_line}, + { "snake_case_key", test_snake_case_key}, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/config_format_yaml.c b/src/fluent-bit/tests/internal/config_format_yaml.c new file mode 100644 index 000000000..3135022ba --- /dev/null +++ b/src/fluent-bit/tests/internal/config_format_yaml.c @@ -0,0 +1,324 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "flb_tests_internal.h" + +#define FLB_TESTS_CONF_PATH FLB_TESTS_DATA_PATH "/data/config_format/yaml" +#define FLB_000 FLB_TESTS_CONF_PATH "/fluent-bit.yaml" +#define FLB_001 FLB_TESTS_CONF_PATH "/issue_7559.yaml" + +/* + * Configurations to test: + * * basic single input to single output + * * basic single input to single output with a filter + * * includes + * * slist + * * conf parsers + * * yaml parsers + * * customs + * * service + * * env + */ + +/* data/config_format/fluent-bit.yaml */ +static void test_basic() +{ + struct mk_list *head; + struct flb_cf *cf; + struct flb_cf_section *s; + struct flb_cf_group *g; + struct cfl_variant *v; + int idx = 0; + + cf = flb_cf_yaml_create(NULL, FLB_000, NULL, 0); + TEST_CHECK(cf != NULL); + if (!cf) { + exit(EXIT_FAILURE); + } + + /* Total number of sections */ + TEST_CHECK(mk_list_size(&cf->sections) == 9); + + /* SERVICE check */ + TEST_CHECK(cf->service != NULL); + if (cf->service) { + TEST_CHECK(cfl_list_size(&cf->service->properties->list) == 3); + } + + /* Check number sections per list */ + TEST_CHECK(mk_list_size(&cf->parsers) == 0); + TEST_CHECK(mk_list_size(&cf->multiline_parsers) == 0); + TEST_CHECK(mk_list_size(&cf->customs) == 1); + TEST_CHECK(mk_list_size(&cf->inputs) == 3); + TEST_CHECK(mk_list_size(&cf->filters) == 1); + TEST_CHECK(mk_list_size(&cf->outputs) == 2); + TEST_CHECK(mk_list_size(&cf->others) == 1); + + /* check inputs */ + idx = 0; + mk_list_foreach(head, &cf->inputs) { + s = mk_list_entry(head, struct flb_cf_section, _head_section); + switch (idx) { + case 0: + v = flb_cf_section_property_get(cf, s, "name"); + TEST_CHECK(v->type == CFL_VARIANT_STRING); + TEST_CHECK(strcmp(v->data.as_string, "dummy") == 0); + break; + case 1: + v = flb_cf_section_property_get(cf, s, "name"); + TEST_CHECK(v->type == CFL_VARIANT_STRING); + TEST_CHECK(strcmp(v->data.as_string, "tail") == 0); + v = flb_cf_section_property_get(cf, s, "path"); + TEST_CHECK(v->type == CFL_VARIANT_STRING); + TEST_CHECK(strcmp(v->data.as_string, "./test.log") == 0); + break; + case 2: + v = flb_cf_section_property_get(cf, s, "name"); + TEST_CHECK(v->type == CFL_VARIANT_STRING); + TEST_CHECK(strcmp(v->data.as_string, "tail") == 0); + v = flb_cf_section_property_get(cf, s, "path"); + TEST_CHECK(v->type == CFL_VARIANT_STRING); + TEST_CHECK(strcmp(v->data.as_string, "./test.log") == 0); + break; + } + idx++; + } + + /* check outputs */ + idx = 0; + mk_list_foreach(head, &cf->outputs) { + s = mk_list_entry(head, struct flb_cf_section, _head_section); + switch (idx) { + case 0: + v = flb_cf_section_property_get(cf, s, "name"); + TEST_CHECK(v->type == CFL_VARIANT_STRING); + TEST_CHECK(strcmp(v->data.as_string, "stdout") == 0); + break; + case 1: + v = flb_cf_section_property_get(cf, s, "name"); + TEST_CHECK(v->type == CFL_VARIANT_STRING); + TEST_CHECK(strcmp(v->data.as_string, "stdout") == 0); + break; + } + idx++; + } + + /* check filters */ + idx = 0; + mk_list_foreach(head, &cf->filters) { + s = mk_list_entry(head, struct flb_cf_section, _head_section); + switch (idx) { + case 0: + v = flb_cf_section_property_get(cf, s, "name"); + TEST_CHECK(v->type == CFL_VARIANT_STRING); + TEST_CHECK(strcmp(v->data.as_string, "record_modifier") == 0); + break; + } + idx++; + } + + /* groups */ + s = flb_cf_section_get_by_name(cf, "input"); + TEST_CHECK(s != NULL); + TEST_CHECK(mk_list_size(&s->groups) == 1); + + mk_list_foreach(head, &s->groups) { + g = mk_list_entry(head, struct flb_cf_group, _head); + TEST_CHECK(cfl_list_size(&g->properties->list) == 2); + } + + printf("\n"); + flb_cf_dump(cf); + flb_cf_destroy(cf); +} + +/* https://github.com/fluent/fluent-bit/issues/7559 */ +static void test_customs_section() +{ + struct flb_cf *cf; + struct flb_cf_section *s; + + cf = flb_cf_yaml_create(NULL, FLB_001, NULL, 0); + TEST_CHECK(cf != NULL); + if (!cf) { + exit(EXIT_FAILURE); + } + + /* Total number of sections */ + if(!TEST_CHECK(mk_list_size(&cf->sections) == 3)) { + TEST_MSG("Section number error. Got=%d expect=3", mk_list_size(&cf->sections)); + } + + s = flb_cf_section_get_by_name(cf, "customs"); + TEST_CHECK(s != NULL); + if (!TEST_CHECK(s->type == FLB_CF_CUSTOM)) { + TEST_MSG("Section type error. Got=%d expect=%d", s->type, FLB_CF_CUSTOM); + } + + flb_cf_dump(cf); + flb_cf_destroy(cf); +} + +static void test_slist_even() +{ + struct flb_cf *cf; + struct flb_cf_section *s; + struct cfl_variant *v; + struct mk_list *head; + + cf = flb_cf_yaml_create(NULL, FLB_TESTS_CONF_PATH "/pipelines/slist/even.yaml", NULL, 0); + TEST_CHECK(cf != NULL); + if (!cf) { + exit(EXIT_FAILURE); + } + + /* Total number of inputs */ + if(!TEST_CHECK(mk_list_size(&cf->inputs) == 1)) { + TEST_MSG("Section number error. Got=%d expect=1", mk_list_size(&cf->inputs)); + } + + mk_list_foreach(head, &cf->inputs) { + s = mk_list_entry(head, struct flb_cf_section, _head_section); + TEST_CHECK(s != NULL); + + v = flb_cf_section_property_get(cf, s, "success_header"); + TEST_CHECK(v->type == CFL_VARIANT_ARRAY); + if (!TEST_CHECK(v->data.as_array->entry_count == 2)) { + TEST_MSG("Section number error. Got=%lud expect=2", v->data.as_array->entry_count); + } + } + + flb_cf_dump(cf); + flb_cf_destroy(cf); +} + +static void test_slist_odd() +{ + struct flb_cf *cf; + struct flb_cf_section *s; + struct cfl_variant *v; + struct mk_list *head; + + cf = flb_cf_yaml_create(NULL, FLB_TESTS_CONF_PATH "/pipelines/slist/odd.yaml", NULL, 0); + TEST_CHECK(cf != NULL); + if (!cf) { + exit(EXIT_FAILURE); + } + + /* Total number of inputs */ + if(!TEST_CHECK(mk_list_size(&cf->inputs) == 1)) { + TEST_MSG("Section number error. Got=%d expect=1", mk_list_size(&cf->inputs)); + } + + mk_list_foreach(head, &cf->inputs) { + s = mk_list_entry(head, struct flb_cf_section, _head_section); + TEST_CHECK(s != NULL); + + v = flb_cf_section_property_get(cf, s, "success_header"); + TEST_CHECK(v->type == CFL_VARIANT_ARRAY); + if (!TEST_CHECK(v->data.as_array->entry_count == 3)) { + TEST_MSG("Section number error. Got=%lud expect=3", v->data.as_array->entry_count); + } + } + + flb_cf_dump(cf); + flb_cf_destroy(cf); +} + + +static void test_parser_conf() +{ + struct flb_cf *cf; + struct flb_config *config; + int ret; + int cnt; + + cf = flb_cf_yaml_create(NULL, FLB_TESTS_CONF_PATH "/parsers/parsers-conf.yaml", NULL, 0); + TEST_CHECK(cf != NULL); + if (!cf) { + exit(EXIT_FAILURE); + } + + config = flb_config_init(); + TEST_CHECK(config != NULL); + config->conf_path = flb_strdup(FLB_TESTS_CONF_PATH "/parsers/"); + + // count the parsers registered automatically by fluent-bit + cnt = mk_list_size(&config->parsers); + // load the parsers from the configuration + ret = flb_config_load_config_format(config, cf); + if (ret != 0) { + exit(EXIT_FAILURE);; + } + + /* Total number of inputs */ + if(!TEST_CHECK(mk_list_size(&config->parsers) == cnt+1)) { + TEST_MSG("Section number error. Got=%d expect=%d", + mk_list_size(&config->parsers), + cnt+1); + } + + flb_cf_dump(cf); + flb_cf_destroy(cf); + flb_config_exit(config); +} + +static inline int check_camel_to_snake(char *input, char *output) +{ + int len; + int ret = -1; + flb_sds_t out; + struct flb_cf *cf; + + cf = flb_cf_create(); + flb_cf_set_origin_format(cf, FLB_CF_YAML); + + len = strlen(input); + out = flb_cf_key_translate(cf, input, len); + + ret = strcmp(out, output); + flb_sds_destroy(out); + + flb_cf_destroy(cf); + + if (ret == 0) { + return FLB_TRUE; + } + + return FLB_FALSE; +} + + +static void test_camel_case_key() +{ + /* normal conversion */ + TEST_CHECK(check_camel_to_snake("a", "a") == FLB_TRUE); + TEST_CHECK(check_camel_to_snake("aB", "a_b") == FLB_TRUE); + TEST_CHECK(check_camel_to_snake("aBc", "a_bc") == FLB_TRUE); + TEST_CHECK(check_camel_to_snake("aBcA", "a_bc_a") == FLB_TRUE); + TEST_CHECK(check_camel_to_snake("aBCD", "a_b_c_d") == FLB_TRUE); + TEST_CHECK(check_camel_to_snake("intervalSec", "interval_sec") == FLB_TRUE); + + /* unsupported conversion, we force lowercase in Yaml */ + TEST_CHECK(check_camel_to_snake("AA", "AA") == FLB_TRUE); + TEST_CHECK(check_camel_to_snake("Interval_Sec", "Interval_Sec") == FLB_TRUE); + +} + +TEST_LIST = { + { "basic" , test_basic}, + { "customs section", test_customs_section}, + { "slist odd", test_slist_odd}, + { "slist even", test_slist_even}, + { "parsers file conf", test_parser_conf}, + { "camel_case_key", test_camel_case_key}, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/config_map.c b/src/fluent-bit/tests/internal/config_map.c new file mode 100644 index 000000000..b709d016d --- /dev/null +++ b/src/fluent-bit/tests/internal/config_map.c @@ -0,0 +1,386 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include +#include +#include + +#include "flb_tests_internal.h" + +struct context { + /* Single values */ + int num_int; + size_t size; + time_t time; + char boolean; + double num_double; + flb_sds_t string; + struct mk_list *list1; + struct mk_list *list2; + + /* Multiple entries */ + struct mk_list *mult_num_int; + struct mk_list *mult_boolean; + struct mk_list *mult_num_double; + struct mk_list *mult_string; + struct mk_list *mult_list1; + struct mk_list *mult_list2; +}; + +struct flb_config_map config_map[] = { + { + FLB_CONFIG_MAP_BOOL, + "boolean", + "true", + 0, FLB_TRUE, offsetof(struct context, boolean), + NULL + }, + { + FLB_CONFIG_MAP_INT, + "num_int", + "123", + 0, FLB_TRUE, offsetof(struct context, num_int), + NULL + }, + { + FLB_CONFIG_MAP_DOUBLE, + "num_double", "0.12345", + 0, FLB_TRUE, offsetof(struct context, num_double), + NULL + }, + { + FLB_CONFIG_MAP_STR, + "string", + "test", + 0, FLB_TRUE, offsetof(struct context, string), + NULL + }, + + /* SIZE */ + { + FLB_CONFIG_MAP_SIZE, + "test_size", + "2M", + 0, FLB_TRUE, offsetof(struct context, size), + NULL + }, + + /* TIME */ + { + FLB_CONFIG_MAP_TIME, + "test_time", + "2H", + 0, FLB_TRUE, offsetof(struct context, time), + NULL + }, + + /* CSLIST */ + { + FLB_CONFIG_MAP_CLIST, + "test_clist", + "a, b, c ,d,e , f, g,h,i,jk , lm , n o,pqr,, , ,stuv,xyz", + 0, FLB_TRUE, offsetof(struct context, list1), + NULL + }, + + /* SLIST */ + { + FLB_CONFIG_MAP_SLIST_4, + "test_slist", + "a b c de f ghi jk l m n o pqr stuv xyz", + 0, FLB_TRUE, offsetof(struct context, list2), + NULL + }, + + /* EOF */ + {0} +}; + +struct flb_config_map config_map_mult[] = { + { + FLB_CONFIG_MAP_BOOL, + "no_mult", + "true", + 0, FLB_TRUE, 1, + NULL + }, + { + FLB_CONFIG_MAP_BOOL, + "mult_boolean", + NULL, + FLB_CONFIG_MAP_MULT, FLB_TRUE, offsetof(struct context, mult_boolean), + NULL + }, + { + FLB_CONFIG_MAP_INT, + "mult_num_int", + "123", + FLB_CONFIG_MAP_MULT, FLB_TRUE, offsetof(struct context, mult_num_int), + NULL + }, + { + FLB_CONFIG_MAP_DOUBLE, + "mult_num_double", "0.12345", + FLB_CONFIG_MAP_MULT, FLB_TRUE, offsetof(struct context, mult_num_double), + NULL + }, + { + FLB_CONFIG_MAP_STR, + "mult_string", + "test", + FLB_CONFIG_MAP_MULT, FLB_TRUE, offsetof(struct context, mult_string), + NULL + }, + { + FLB_CONFIG_MAP_CLIST, + "mult_clist", + "a, b, c ,d,e , f, g,h,i,jk , lm , n o,pqr,, , ,stuv,xyz", + FLB_CONFIG_MAP_MULT, FLB_TRUE, offsetof(struct context, mult_list1), + NULL + }, + { + FLB_CONFIG_MAP_SLIST_4, + "mult_slist", + "a b c de f ghi jk l m n o pqr stuv xyz", + FLB_CONFIG_MAP_MULT, FLB_TRUE, offsetof(struct context, mult_list2), + NULL + }, + + /* EOF */ + {0} +}; + +void test_helper() +{ + int ret; + struct context ctx; + struct mk_list *map; + struct mk_list prop; + struct flb_config *config; + + config = flb_config_init(); + if (!config) { + exit(1); + } + + memset(&ctx, '\0', sizeof(struct context)); + + /* Create invalid property */ + flb_kv_init(&prop); + flb_kv_item_create(&prop, "bad", "property"); + + map = flb_config_map_create(config, config_map); + TEST_CHECK(map != NULL); + + ret = flb_config_map_properties_check("test", &prop, map); + TEST_CHECK(ret == -1); + + flb_config_map_destroy(map); + flb_kv_release(&prop); + + flb_config_exit(config); +} + +void test_create() +{ + int ret; + struct context ctx; + struct mk_list *map; + struct mk_list properties; + struct flb_slist_entry *e; + struct flb_config *config; + + config = flb_config_init(); + if (!config) { + exit(1); + } + + memset(&ctx, '\0', sizeof(struct context)); + mk_list_init(&properties); + + map = flb_config_map_create(config, config_map); + TEST_CHECK(map != NULL); + + /* Populate default values only */ + ret = flb_config_map_set(&properties, map, &ctx); + TEST_CHECK(ret == 0); + + TEST_CHECK(ctx.boolean == 1); + TEST_CHECK(ctx.num_int == 123); + TEST_CHECK(ctx.num_double == 0.12345); + TEST_CHECK(ctx.size == 2000000); + TEST_CHECK(ctx.time == 7200); + TEST_CHECK(strcmp(ctx.string, "test") == 0); + TEST_CHECK(flb_sds_len(ctx.string) == 4); + TEST_CHECK(mk_list_size(ctx.list1) == 15); + TEST_CHECK(mk_list_size(ctx.list2) == 5); + + e = mk_list_entry_last(ctx.list2, struct flb_slist_entry, _head); + TEST_CHECK(strcmp(e->str, "f ghi jk l m n o pqr stuv xyz") == 0); + flb_config_map_destroy(map); + + flb_config_exit(config); +} + +void test_override_defaults() +{ + int ret; + struct context ctx; + struct mk_list *map; + struct mk_list properties; + struct flb_slist_entry *e; + struct flb_config *config; + + config = flb_config_init(); + if (!config) { + exit(1); + } + + memset(&ctx, '\0', sizeof(struct context)); + mk_list_init(&properties); + + map = flb_config_map_create(config, config_map); + TEST_CHECK(map != NULL); + + /* Create a properties list that will override default values */ + flb_kv_item_create(&properties, "boolean", "false"); + flb_kv_item_create(&properties, "num_int", "321"); + flb_kv_item_create(&properties, "num_double", "0.54321"); + flb_kv_item_create(&properties, "string", "no test"); + flb_kv_item_create(&properties, "test_time", "1H"); + flb_kv_item_create(&properties, "test_size", "1M"); + flb_kv_item_create(&properties, "test_clist", "abc, def, ghi ,,,,jkl "); + flb_kv_item_create(&properties, "test_slist", "abc def ghi jkl m n o"); + + /* Populate default values only */ + ret = flb_config_map_set(&properties, map, &ctx); + TEST_CHECK(ret == 0); + + TEST_CHECK(ctx.boolean == 0); + TEST_CHECK(ctx.num_int == 321); + TEST_CHECK(ctx.num_double == 0.54321); + TEST_CHECK(ctx.size == 1000000); + TEST_CHECK(ctx.time == 3600); + TEST_CHECK(strcmp(ctx.string, "no test") == 0); + TEST_CHECK(flb_sds_len(ctx.string) == 7); + TEST_CHECK(mk_list_size(ctx.list1) == 4); + TEST_CHECK(mk_list_size(ctx.list2) == 5); + + e = mk_list_entry_last(ctx.list2, struct flb_slist_entry, _head); + TEST_CHECK(strcmp(e->str, "m n o") == 0); + + flb_kv_release(&properties); + flb_config_map_destroy(map); + + flb_config_exit(config); +} + +/* Check that single property raise an error if are set multiple times (dups) */ +void test_no_multiple() +{ + int ret; + struct context ctx; + struct mk_list *map; + struct mk_list prop; + struct flb_config *config; + + config = flb_config_init(); + if (!config) { + exit(1); + } + + memset(&ctx, '\0', sizeof(struct context)); + + /* Assign the property multiple times */ + flb_kv_init(&prop); + flb_kv_item_create(&prop, "no_mult", "true"); + flb_kv_item_create(&prop, "no_mult", "false"); + + map = flb_config_map_create(config, config_map_mult); + TEST_CHECK(map != NULL); + + ret = flb_config_map_properties_check("test", &prop, map); + TEST_CHECK(ret == -1); + + flb_config_map_destroy(map); + flb_kv_release(&prop); + + flb_config_exit(config); +} + +void test_multiple() +{ + int ret; + int i; + int total; + struct context ctx; + struct mk_list *map; + struct mk_list prop; + struct mk_list *head; + struct flb_config_map_val *mv; + struct flb_config *config; + + config = flb_config_init(); + if (!config) { + exit(1); + } + + memset(&ctx, '\0', sizeof(struct context)); + + /* Create invalid property */ + flb_kv_init(&prop); + flb_kv_item_create(&prop, "mult_boolean", "true"); + flb_kv_item_create(&prop, "mult_boolean", "false"); + + flb_kv_item_create(&prop, "mult_clist", "a, b, c"); + flb_kv_item_create(&prop, "mult_clist", "d, e, f"); + flb_kv_item_create(&prop, "mult_clist", "g, h, i"); + + flb_kv_item_create(&prop, "mult_slist", "d e f g"); + + map = flb_config_map_create(config, config_map_mult); + TEST_CHECK(map != NULL); + + ret = flb_config_map_properties_check("test", &prop, map); + TEST_CHECK(ret == 0); + + ret = flb_config_map_set(&prop, map, &ctx); + TEST_CHECK(ret == 0); + + i = 0; + flb_config_map_foreach(head, mv, ctx.mult_boolean) { + if (i == 0) { + TEST_CHECK(mv->val.boolean == FLB_TRUE); + } + else { + TEST_CHECK(mv->val.boolean == FLB_FALSE); + } + i++; + } + + total = 0; + flb_config_map_foreach(head, mv, ctx.mult_list1) { + total++; + } + TEST_CHECK(total == 4); + + total = 0; + flb_config_map_foreach(head, mv, ctx.mult_list2) { + total++; + } + + flb_config_map_destroy(map); + flb_kv_release(&prop); + flb_config_exit(config); +} + +TEST_LIST = { + { "helper" , test_helper}, + { "create" , test_create}, + { "override_defaults", test_override_defaults}, + { "no_multiple" , test_no_multiple}, + { "multiple" , test_multiple}, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/crypto.c b/src/fluent-bit/tests/internal/crypto.c new file mode 100644 index 000000000..e8c9bb43b --- /dev/null +++ b/src/fluent-bit/tests/internal/crypto.c @@ -0,0 +1,202 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include + +#include "flb_tests_internal.h" + +#define PRIVATE_KEY (unsigned char *) \ + "-----BEGIN RSA PRIVATE KEY-----\n" \ + "MIICXgIBAAKBgQDUkO22PyhYHJlXYQomNXEeX7ChfdqyY1ukUMsPQPbmjgsDZ/tG\n" \ + "rvNtJVtwuOjGi+DGTG+fSFdgoGDbypOXOC5sX2Luwen+Ixvqay1V3pm16cOVOHf8\n" \ + "XYAMLqTh1Aq3CykQeuTLKQPGG5rL6utFsgzQEgVpSZdLi2W3RfcJGS22EQIDAQAB\n" \ + "AoGAPMuWsWEu8MR9NviSJotyZvWHVyjfu9WfCEfzS9GQzDAkBj1fKMAw7y6YEI1S\n" \ + "RjcLequx4SSXmRNFoJc3zzBKVj77vf60vahoaq11My9pMLDSENK/JKW+VpueKYrT\n" \ + "5Z9C6y9dB7NKXd8YANDApYNc4+a4l01WFNxjBXJveDo6+IECQQD0iT1ne96LIPFO\n" \ + "j82SGlDkc1w7ZOZKl5kvRwM1VfXmDzdpFhEDndDnFa7Dth3t0QOQVVkbOUnNvQ+Z\n" \ + "XEVr6l2FAkEA3ogBoIns72p8sRqE2Uavum53M7SxRJTN/Fn5mBN6aNX2if4M2k6r\n" \ + "Uwhyld6k0PwAB1zVNUlTi0pyR7BcnrAGHQJBAO81NTD+1hLJVeQg/do3Dfx78LRV\n" \ + "HoXHSF0cHUJWZWX4ap7MrDYachkrd7sRcrOJq+/L3Y+o+c5dbF38ChjnuTUCQQCg\n" \ + "3ZDPjOVK7Z/WJ2WB7Cd8jf590lGTUj7V/fUAipQi1Qm0F4MTDWusSp8K2DgtGv6q\n" \ + "U+GM88UBHIAgcs2BqZ3BAkEAjKEOgXNjeYabdkVrQMvJMAJF52vBpSksrV1jqV1F\n" \ + "AH/sGR3C9faYNzFltPnQcE0USluDQRS/7UHNtn1VEBb34A==\n" \ + "-----END RSA PRIVATE KEY-----\n" + +#define PRIVATE_KEY_LENGTH (strlen((char *) PRIVATE_KEY)) + +#define PUBLIC_KEY (unsigned char *) \ + "-----BEGIN PUBLIC KEY-----\n" \ + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUkO22PyhYHJlXYQomNXEeX7Ch\n" \ + "fdqyY1ukUMsPQPbmjgsDZ/tGrvNtJVtwuOjGi+DGTG+fSFdgoGDbypOXOC5sX2Lu\n" \ + "wen+Ixvqay1V3pm16cOVOHf8XYAMLqTh1Aq3CykQeuTLKQPGG5rL6utFsgzQEgVp\n" \ + "SZdLi2W3RfcJGS22EQIDAQAB\n" \ + "-----END PUBLIC KEY-----\n" + +#define PUBLIC_KEY_LENGTH (strlen((char *) PUBLIC_KEY)) + +#define INPUT_DATA (unsigned char *) "This was encrypted by fluent-bits RSA wrapper!" + +#define INPUT_DATA_LENGTH (strlen((char *) INPUT_DATA)) + +#define SIGNATURE_INPUT INPUT_DATA +#define SIGNATURE_INPUT_LENGTH INPUT_DATA_LENGTH + +#define SIGNATURE_DIGEST_TYPE FLB_HASH_SHA256 +#define SIGNATURE_PADDING_TYPE FLB_CRYPTO_PADDING_PKCS1 +#define SIGNATURE_OUTPUT ((unsigned char []) { \ + 0x73, 0x03, 0x78, 0x0b, 0x61, 0x2a, 0x3b, 0x94, 0x5e, 0x26, 0x77, 0x65, \ + 0x96, 0x74, 0x96, 0xbb, 0x6b, 0x1b, 0xdf, 0x8b, 0xfa, 0xa2, 0x57, 0x77, \ + 0xc3, 0x39, 0xaf, 0x21, 0x56, 0x43, 0x87, 0xfe, 0xfb, 0x90, 0xa1, 0x19, \ + 0xf4, 0xc3, 0xe1, 0x74, 0xdb, 0x6b, 0x6a, 0x89, 0xeb, 0x01, 0x4e, 0xbc, \ + 0xf7, 0xe6, 0x0b, 0x7c, 0x1b, 0xa1, 0x6a, 0x7b, 0x55, 0x24, 0x1f, 0xbc, \ + 0x78, 0x20, 0x11, 0x76, 0xf5, 0x02, 0x16, 0x29, 0xb4, 0x17, 0xff, 0x29, \ + 0x43, 0x89, 0x4a, 0x7d, 0x23, 0x0d, 0x63, 0x59, 0x76, 0x75, 0xd2, 0x9d, \ + 0x2c, 0x9f, 0x56, 0x6d, 0x27, 0x53, 0xeb, 0xa3, 0xa7, 0x90, 0x56, 0x4d, \ + 0x88, 0xe5, 0x4e, 0x55, 0xca, 0x36, 0x58, 0x6f, 0x16, 0x1a, 0xb9, 0x1c, \ + 0x4a, 0x8b, 0x0c, 0x30, 0x41, 0x19, 0x93, 0x23, 0x47, 0xcc, 0x41, 0x6c, \ + 0x9a, 0x15, 0x9e, 0xec, 0x22, 0xac, 0x4a, 0xb9 \ + }) + +#define SIGNATURE_OUTPUT_LENGTH (sizeof(ENCRYPTED_DATA)) + +#define ENCRYPTION_PADDING_TYPE FLB_CRYPTO_PADDING_PKCS1 +#define ENCRYPTION_INPUT INPUT_DATA +#define ENCRYPTED_DATA ((unsigned char []) { \ + 0x0b, 0xd3, 0x91, 0x15, 0xb4, 0xed, 0xcd, 0x6c, 0xf1, 0x5c, 0x88, 0x15, \ + 0xde, 0x9d, 0x02, 0x7a, 0x0c, 0x13, 0x93, 0xdc, 0x98, 0x7c, 0x7c, 0xa0, \ + 0x70, 0x80, 0xff, 0x88, 0x68, 0xb6, 0x17, 0x10, 0xfd, 0x02, 0xaa, 0x96, \ + 0x54, 0x75, 0x83, 0x51, 0x9e, 0xe3, 0x72, 0x58, 0xd3, 0x01, 0x79, 0x61, \ + 0xfa, 0x17, 0x18, 0x48, 0xa8, 0xcb, 0xe9, 0x54, 0x5d, 0x87, 0x83, 0x86, \ + 0x5f, 0x1b, 0xf2, 0x01, 0x7f, 0x98, 0x93, 0xa1, 0x6e, 0x2d, 0x23, 0x2c, \ + 0x8b, 0xc9, 0x36, 0xad, 0xfc, 0xdb, 0x9d, 0xa0, 0xd2, 0x17, 0xa1, 0x9d, \ + 0x2e, 0x25, 0xee, 0x54, 0xf5, 0xe3, 0xa6, 0xdb, 0x98, 0x7a, 0x09, 0xef, \ + 0x43, 0xcc, 0x7e, 0x44, 0x53, 0x7e, 0x4a, 0x8b, 0x14, 0x9b, 0x42, 0x67, \ + 0xa2, 0x9a, 0x51, 0xdb, 0xf4, 0xfc, 0x93, 0xe7, 0xe1, 0xda, 0x28, 0xad, \ + 0x97, 0x7e, 0xd4, 0xc0, 0xe2, 0x4e, 0xfa, 0xeb \ + }) + +#define ENCRYPTED_DATA_LENGTH (sizeof(ENCRYPTED_DATA)) + + +/* This test encrypts and decrypts a buffer with a pre-generated 1024 bit RSA + * key and then ensures the results match. + */ + +static void test_rsa_simple_encrypt() +{ + unsigned char decrypted_data_buffer[1024 * 10]; + size_t decrypted_data_buffer_size; + unsigned char encrypted_data_buffer[1024 * 10]; + size_t encrypted_data_buffer_size; + int result; + + encrypted_data_buffer_size = sizeof(encrypted_data_buffer); + decrypted_data_buffer_size = sizeof(decrypted_data_buffer); + + result = flb_crypto_encrypt_simple(ENCRYPTION_PADDING_TYPE, + PUBLIC_KEY, PUBLIC_KEY_LENGTH, + INPUT_DATA, INPUT_DATA_LENGTH, + encrypted_data_buffer, + &encrypted_data_buffer_size); + + TEST_CHECK(result == FLB_CRYPTO_SUCCESS); + + if (result == FLB_CRYPTO_SUCCESS) { + result = flb_crypto_decrypt_simple(ENCRYPTION_PADDING_TYPE, + PRIVATE_KEY, + PRIVATE_KEY_LENGTH, + encrypted_data_buffer, + encrypted_data_buffer_size, + decrypted_data_buffer, + &decrypted_data_buffer_size); + + TEST_CHECK(result == FLB_CRYPTO_SUCCESS); + TEST_CHECK(decrypted_data_buffer_size == INPUT_DATA_LENGTH); + + if (result == FLB_CRYPTO_SUCCESS) { + TEST_CHECK(memcmp(decrypted_data_buffer, INPUT_DATA, INPUT_DATA_LENGTH) == 0); + } + } +} + +/* This test decrypts a buffer that was encrpyted using openssls rsa utility + * with a pre-generated 1024 bit RSA key and then ensures the results match. + */ + +static void test_rsa_simple_decrypt() +{ + unsigned char decrypted_data_buffer[1024 * 10]; + size_t decrypted_data_buffer_size; + int result; + + decrypted_data_buffer_size = sizeof(decrypted_data_buffer); + + result = flb_crypto_decrypt_simple(ENCRYPTION_PADDING_TYPE, + PRIVATE_KEY, + PRIVATE_KEY_LENGTH, + ENCRYPTED_DATA, + ENCRYPTED_DATA_LENGTH, + decrypted_data_buffer, + &decrypted_data_buffer_size); + + TEST_CHECK(result == FLB_CRYPTO_SUCCESS); + TEST_CHECK(decrypted_data_buffer_size == INPUT_DATA_LENGTH); + + if (result == FLB_CRYPTO_SUCCESS) { + TEST_CHECK(memcmp(decrypted_data_buffer, INPUT_DATA, INPUT_DATA_LENGTH) == 0); + } +} + + +/* This test signs a message using a pre-generated 1024 bit RSA key and + * compares the signature with one that has been pre-generated using + * openssls pkeyutil. + */ + +static void test_rsa_simple_sign() +{ + unsigned char signature_buffer[1024]; + size_t signature_buffer_size; + unsigned char digest_buffer[32]; + int result; + + result = flb_hash_simple(SIGNATURE_DIGEST_TYPE, + SIGNATURE_INPUT, + SIGNATURE_INPUT_LENGTH, + digest_buffer, + sizeof(digest_buffer)); + + TEST_CHECK(result == FLB_CRYPTO_SUCCESS); + + if (result == FLB_CRYPTO_SUCCESS) { + signature_buffer_size = sizeof(signature_buffer); + + result = flb_crypto_sign_simple(FLB_CRYPTO_PRIVATE_KEY, + SIGNATURE_PADDING_TYPE, + SIGNATURE_DIGEST_TYPE, + PRIVATE_KEY, + PRIVATE_KEY_LENGTH, + digest_buffer, + sizeof(digest_buffer), + signature_buffer, + &signature_buffer_size); + + TEST_CHECK(result == FLB_CRYPTO_SUCCESS); + TEST_CHECK(signature_buffer_size == SIGNATURE_OUTPUT_LENGTH); + + if (result == FLB_CRYPTO_SUCCESS) { + TEST_CHECK(memcmp(signature_buffer, + SIGNATURE_OUTPUT, + SIGNATURE_OUTPUT_LENGTH) == 0); + } + } +} + +TEST_LIST = { + { "test_rsa_simple_encrypt", test_rsa_simple_encrypt }, + { "test_rsa_simple_decrypt", test_rsa_simple_decrypt }, + { "test_rsa_simple_sign", test_rsa_simple_sign }, + + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/csv.c b/src/fluent-bit/tests/internal/csv.c new file mode 100644 index 000000000..ad4503eb7 --- /dev/null +++ b/src/fluent-bit/tests/internal/csv.c @@ -0,0 +1,167 @@ +#include +#include +#include + +#include "flb_tests_internal.h" + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +#define row_count 3 +#define col_count 4 + +char data[] = + "r0c1,,,\r" + ",r1c2,\"\",\"r1three\nlines\nfield\"\r\n" + "r2c1,r2c2,\"\"\"r2c\n3\n\",\"r2three\nlines\nfield\"\"\"\n"; + +char *parse_expected[row_count][col_count] = { + { "r0c1", "", "", "" }, + { "", "r1c2", "", "r1three\nlines\nfield" }, + { "r2c1", "r2c2", "\"r2c\n3\n", "r2three\nlines\nfield\"" }, +}; + +char *split_expected[row_count] = { + "r0c1,,,\r", + ",r1c2,\"\",\"r1three\nlines\nfield\"\r\n", + "r2c1,r2c2,\"\"\"r2c\n3\n\",\"r2three\nlines\nfield\"\"\"\n", +}; + +struct parse_state { + char **parsed; + size_t current_row; + size_t current_col; +}; + +static void field_parsed(void *data, const char *field, size_t field_len) +{ + struct parse_state *state = data; + size_t col = state->current_col; + size_t row = state->current_row; + char *fdup = strndup(field, field_len); + state->parsed[row * col_count + col] = fdup; + state->current_col++; +} + +static char **parse_data_step(int step) +{ + int i; + size_t len = sizeof(data); + struct parse_state state; + char *bufptr; + struct flb_csv_state csv_state; + size_t field_count; + state.parsed = malloc(sizeof *state.parsed * row_count * col_count); + state.current_row = 0; + state.current_col = 0; + flb_csv_init(&csv_state, field_parsed, &state); + bufptr = data; + for (i = 0; i < sizeof(data);) { + int ret; + size_t bl = MIN(len - i, step); + ret = flb_csv_parse_record(&csv_state, &bufptr, &bl, &field_count); + i = bufptr - data; + if (ret == FLB_CSV_SUCCESS) { + TEST_CHECK(field_count == 4); + state.current_row++; + state.current_col = 0; + } + else if (ret == FLB_CSV_EOF) { + continue; + } + else { + abort(); + }; + } + flb_csv_destroy(&csv_state); + return state.parsed; +} + +static void check_parse_result(char **result) +{ + int row, col; + + for (row = 0; row < row_count; row++) { + for (col = 0; col < col_count; col++) { + char *res = result[row * col_count + col]; + TEST_CHECK(strcmp(res, parse_expected[row][col]) == 0); + TEST_MSG("Mismatch on row %d, col %d", row, col); + TEST_MSG("Expected: %s", parse_expected[row][col]); + TEST_MSG("Result: %s", result[row * col_count + col]); + free(res); + } + } + + free(result); +} + +static void check_split_result(char **result) +{ + int row; + + for (row = 0; row < row_count; row++) { + char *res = result[row]; + TEST_CHECK(strcmp(res, split_expected[row]) == 0); + TEST_MSG("Mismatch on row %d", row); + TEST_MSG("Expected: %s", split_expected[row]); + TEST_MSG("Result: %s", result[row]); + free(res); + } + + free(result); +} + +static char **split_rows_step(int step) +{ + int i; + size_t len = sizeof(data); + char *bufptr; + char *row_start; + size_t current_row = 0; + char **result = malloc(sizeof *result * row_count); + struct flb_csv_state csv_state; + flb_csv_init(&csv_state, NULL, NULL); + bufptr = data; + row_start = data; + size_t field_count; + for (i = 0; i < len;) { + int ret; + size_t bl = MIN(len - i, step); + ret = flb_csv_parse_record(&csv_state, &bufptr, &bl, &field_count); + i = bufptr - data; + if (ret == FLB_CSV_SUCCESS) { + TEST_CHECK(field_count == 4); + result[current_row] = strndup(row_start, bufptr - row_start); + row_start = bufptr; + current_row++; + } + else if (ret == FLB_CSV_EOF) { + continue; + } else { + abort(); + }; + } + flb_csv_destroy(&csv_state); + return result; +} + +static void test_basic() +{ + int step; + for (step = 1; step <= sizeof(data); step++) { + check_parse_result(parse_data_step(step)); + } +} + +static void test_split_lines() +{ + int step; + for (step = 1; step <= sizeof(data); step++) { + check_split_result(split_rows_step(step)); + } +} + +TEST_LIST = { + { "basic" , test_basic}, + { "split_lines" , test_split_lines}, + { 0 } +}; diff --git a/src/fluent-bit/tests/internal/data/avro/json_single_map_001.json b/src/fluent-bit/tests/internal/data/avro/json_single_map_001.json new file mode 100644 index 000000000..6833b3929 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/avro/json_single_map_001.json @@ -0,0 +1,5 @@ +{"key001": 123456789, + "key002": 0.999887766, + "key003": "abcdefghijk", + "key004": [{"a": 1, "b": 2}, {"c": 3, "d": 4}] +} diff --git a/src/fluent-bit/tests/internal/data/avro/live-sample.json b/src/fluent-bit/tests/internal/data/avro/live-sample.json new file mode 100644 index 000000000..ba6eb8aca --- /dev/null +++ b/src/fluent-bit/tests/internal/data/avro/live-sample.json @@ -0,0 +1,25 @@ +{ + "log": "2020-08-21T15:49:48.154291375ZstderrFhdfsExists:invokeMethod((Lorg/apache/hadoop/fs/Path;)Z)error:2020-08-21T15:49:48.154296328ZstderrForg.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security..SecretManager$Invalid):(HDFS_DELEGATION_273964959forweeb)can'tbefoundincache2020-08-21T15:49:48.154300089ZstderrFatorg.apache.hadoop.ipc.Client.call(Client.java:1475)2020-08-21T15:49:48.154303281ZstderrFatorg.apache.hadoop.ipc.Client.call(Client.java:1412)2020-08-21T15:49:48.154307503ZstderrFatorg.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:229)2020-08-21T15:49:48.154311268ZstderrFatcom.sun.proxy.$Proxy9.getFileInfo(UnknownSource)2020-08-21T15:49:48.154314514ZstderrFatorg.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.getFileInfo(ClientNamenodeProtocolTranslatorPB.java:771)2020-08-21T15:49:48.154317916ZstderrFatsun.reflect.GeneratedMethodAccessor2.invoke(UnknownSource)2020-08-21T15:49:48.154328852ZstderrFatsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)2020-08-21T15:49:48.154332363ZstderrFatjava.lang.reflect.Method.invoke(Method.java:498)2020-08-21T15:49:48.154335464ZstderrFatorg.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:191)2020-08-21T15:49:48.154338276ZstderrFatorg.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:102)2020-08-21T15:49:48.15434115ZstderrFatcom.sun.proxy.$Proxy10.getFileInfo(UnknownSource)2020-08-21T15:49:48.154344323ZstderrFatorg.apache.hadoop.hdfs.DFSClient.getFileInfo(DFSClient.java:2108)2020-08-21T15:49:48.154347224ZstderrFatorg.apache.hadoop.hdfs.DistributedFileSystem$22.doCall(DistributedFileSystem.java:1305)2020-08-21T15:49:48.154350059ZstderrFatorg.apache.hadoop.hdfs.DistributedFileSystem$22.doCall(DistributedFileSystem.java:1301)2020-08-21T15:49:48.154352819ZstderrFatorg.apache.hadoop.fs.FileSystemLinkResolver.resolve(FileSystemLinkResolver.java:81)2020-08-21T15:49:48.154355939ZstderrFatorg.apache.hadoop.hdfs.DistributedFileSystem.getFileStatus(DistributedFileSystem.java:1301)2020-08-21T15:49:48.154358773ZstderrFatorg.apache.hadoop.fs.FileSystem.exists(FileSystem.java:1424)", + "capture": "2020-08-21T15:49:53.16823268ZstderrF20/08/2115:49:53WARNipc.Client:Exceptionencounteredwhileconnectingtotheserver:org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security..SecretManager$Invalid):(HDFS_DELEGATION_273964959forweeb)can'tbefoundincache", + "kubernetes": { + "pod_name": "rrrr-bert-completion-tb1-6786c9c8-wj25m", + "namespace_name": "k8s-fgg", + "pod_id": "50bfc67d-cd3c-410d-9369-8bda8f33b1c7", + "labels": { + "app": "customized-tb1", + "pod-template-hash": "6786c9c8" + }, + "annotations": { + "doAs": "weeb", + "iddecorator.dkdk.username": "rrrr", + "kubernetes.io/limit-ranger": "LimitRangerpluginset:cpu,memoryrequestforcontainertensorboard;cpu,memorylimitforcontainertensorboard;cpu,memoryrequestforinitcontainerfetcher;cpu,memorylimitforinitcontainerfetcher", + "kubernetes.io/psp": "katib-nfs-provisioner", + "podpreset.admission.kubernetes.io/podpreset-kube-master": "60792473" + }, + "host": "wedddd.dkdk.qqqq.com", + "container_name": "tb1", + "docker_id": "50bfc67d-cd3c-410d-9369-8bda8f33b1c7", + "container_hash": "qqqq.corp.qqqq.com/ai/centos/tf1.15.0-py3.7-horovod@sha256:68b6885f6d1d3fd87ce425a2b2aa687440b9578740d60996912a816ae67be85e", + "container_image": "qqqq.corp.qqqq.com/ai/centos/tf1.15.0-py3.7-horovod:1.2" + } + } diff --git a/src/fluent-bit/tests/internal/data/avro/multiline.json b/src/fluent-bit/tests/internal/data/avro/multiline.json new file mode 100644 index 000000000..8d0173e89 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/avro/multiline.json @@ -0,0 +1,27 @@ +[ + { + "date": 1597871185.922652, + "log": "2020-08-19T21:06:24.337499838Z stderr F hdfsExists: invokeMethod((Lorg/apache/hadoop/fs/Path;)Z) error:\n2020-08-19T21:06:24.33754077Z stderr F org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security..SecretManager$Invalid): (HDFS_DELEGATION_ 273964959 for weeb) can't be found in cache\n2020-08-19T21:06:24.337544598Z stderr F \tat org.apache.hadoop.ipc.Client.call(Client.java:1475)\n2020-08-19T21:06:24.337547418Z stderr F \tat org.apache.hadoop.ipc.Client.call(Client.java:1412)\n2020-08-19T21:06:24.337550469Z stderr F \tat org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:229)\n2020-08-19T21:06:24.337553603Z stderr F \tat com.sun.proxy.$Proxy9.getFileInfo(Unknown Source)\n2020-08-19T21:06:24.337556408Z stderr F \tat org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.getFileInfo(ClientNamenodeProtocolTranslatorPB.java:771)\n2020-08-19T21:06:24.337559359Z stderr F \tat sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)\n2020-08-19T21:06:24.337562715Z stderr F \tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n2020-08-19T21:06:24.337565488Z stderr F \tat java.lang.reflect.Method.invoke(Method.java:498)\n2020-08-19T21:06:24.337574315Z stderr F \tat org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:191)\n2020-08-19T21:06:24.337577049Z stderr F \tat org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:102)\n2020-08-19T21:06:24.33757971Z stderr F \tat com.sun.proxy.$Proxy10.getFileInfo(Unknown Source)\n2020-08-19T21:06:24.337582469Z stderr F \tat org.apache.hadoop.hdfs.DFSClient.getFileInfo(DFSClient.java:2108)\n2020-08-19T21:06:24.337585132Z stderr F \tat org.apache.hadoop.hdfs.DistributedFileSystem$22.doCall(DistributedFileSystem.java:1305)\n2020-08-19T21:06:24.337587799Z stderr F \tat org.apache.hadoop.hdfs.DistributedFileSystem$22.doCall(DistributedFileSystem.java:1301)\n2020-08-19T21:06:24.337590342Z stderr F \tat org.apache.hadoop.fs.FileSystemLinkResolver.resolve(FileSystemLinkResolver.java:81)\n2020-08-19T21:06:24.337592897Z stderr F \tat org.apache.hadoop.hdfs.DistributedFileSystem.getFileStatus(DistributedFileSystem.java:1301)\n2020-08-19T21:06:24.337595578Z stderr F \tat org.apache.hadoop.fs.FileSystem.exists(FileSystem.java:1424)", + "kubernetes": { + "pod_name": "rrrr-bert-completion-tb1-6786c9c8-wj25m", + "namespace_name": "k8s-fgg", + "pod_id": "50bfc67d-cd3c-410d-9369-8bda8f33b1c7", + "labels": { + "app": "customized-tb1", + "pod-template-hash": "6786c9c8" + }, + "annotations": { + "doAs": "weeb", + "iddecorator.dkdk.username": "rrrr", + "kubernetes.io/limit-ranger": "LimitRanger", + "kubernetes.io/psp": "katib-nfs-provisioner", + "podpreset.admission.kubernetes.io/podpreset-kube-master": "60792473" + }, + "host": "wedddd.dkdk.qqqq.com", + "container_name": "tb1", + "docker_id": "50bfc67d-cd3c-410d-9369-8bda8f33b1c7", + "container_hash": "qqqq.corp.qqqq.com/ai/centos/tf1.15.0-py3.7-horovod@sha256:68b6885f6d1d3fd87ce425a2b2aa687440b9578740d60996912a816ae67be85e", + "container_image": "qqqq.corp.qqqq.com/ai/centos/tf1.15.0-py3.7-horovod:1.2" + } + } +] diff --git a/src/fluent-bit/tests/internal/data/aws_credentials/credential_process/aws-credential-process b/src/fluent-bit/tests/internal/data/aws_credentials/credential_process/aws-credential-process new file mode 100755 index 000000000..45d906505 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/aws_credentials/credential_process/aws-credential-process @@ -0,0 +1,14 @@ +#!/bin/sh + +printf '{"Version":1,"AccessKeyId":"%s","SecretAccessKey":"%s"' "${1}" "${_AWS_SECRET_ACCESS_KEY}" +if [ -n "${_AWS_SESSION_TOKEN}" ]; then + printf ',"SessionToken":"%s"' "${_AWS_SESSION_TOKEN}" +fi +if [ -n "${_AWS_EXPIRATION}" ]; then + printf ',"Expiration":"%s"' "$(/bin/date -d "${_AWS_EXPIRATION}" --utc '+%Y-%m-%dT%H:%M:%SZ')" +fi +printf '}' + +if [ -n "${_AWS_EXIT_CODE}" ]; then + exit "${_AWS_EXIT_CODE}" +fi diff --git a/src/fluent-bit/tests/internal/data/aws_credentials/shared_config.ini b/src/fluent-bit/tests/internal/data/aws_credentials/shared_config.ini new file mode 100644 index 000000000..451b23ba8 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/aws_credentials/shared_config.ini @@ -0,0 +1,9 @@ +[default] +region = us-east-1 +credential_process = aws-credential-process default +output = json + +[profile nondefault] +region = us-east-1 +credential_process = aws-credential-process nondefault +output = json diff --git a/src/fluent-bit/tests/internal/data/aws_credentials/shared_credentials_file.ini b/src/fluent-bit/tests/internal/data/aws_credentials/shared_credentials_file.ini new file mode 100644 index 000000000..be9520a4d --- /dev/null +++ b/src/fluent-bit/tests/internal/data/aws_credentials/shared_credentials_file.ini @@ -0,0 +1,28 @@ +[default] +aws_access_key_id = ASIASDMPIJWXJAXT3O3T +aws_secret_access_key = EAUBpd/APPT4Nfi4DWY3gnt5TU/4T49laqS5zh8W +aws_session_token = IQoJb3JpZ2luX2VjEOD//////////wEaCNVzLWVhc3QtMSJHMEUCIKCn7v/EDowMZvJnciSJbxA7rIV4p1K6pOUvcLHM+9EzNgIgeiYbfA47DGSqoEZS3yrRWGN8Fr4Q/bK7ANRgv09Hth8q1gEIWRABGgwxNDQ3MTg3MTE0NzAiDGSqzyXiicOZp63afiqzAUyWOljOn5HaIxRfpQ5pTf+o4roJ2KPlHn+XHEKJZKien4Ydm7zeVi7SbPLKocjmjYJd31PrlbJ43C6AyrhmY57qaD7Zz4N3N0V6mekzvlAeARXsa4deflsbemqkp1WVsBLkO6qUuk+N04+MxIVXAxkW9RSPRTVjxeS2m5Yobygto58WLFE8gacRoNd4lCK4JUmEdiaxJEQQO7leZ3v1XxQr6QBS8P/GmcJYcQTxlA6AFQxIMJKGwfAFOuMB2cEc8cF2Htiqf3LVGMk/6bYKkW7fHUtrnttp28jgWtbbLtFbX/zIdlqwm73Ryp7lI+xkM4XNIT+6ZKa4Xw0/Zw3xLzlk3jic6QWPAcffwR6kOunoTOWJzPskK/RZ4Cd+GyGarxG27Cz6xolAzAsDpdGQwV7kCCUPi6/VHjefwKEk9HjZfejC5WuCS173qFrU9kNb4IrYhnK+wmRzzJfgpWUwerdiJKBz95j1iW9rP1a8p1xLR3EXUMN3LIW0+gP8sFjg5iiqDkaS/tUXWZndM2QdJLcrxwAutFchc0nqJHYTijw= + +[nondefault] +aws_access_key_id = akid +aws_secret_access_key = skid + +[custom] +aws_access_key_id=custom_access_key_id +aws_secret_access_key=custom_secret_access_key + +#some comment line +sadfjasdlkfajskldfjasd some garbage = not_actually_valid_but=parser_should_handle_it + +[headerwithnokeys] + +[nospace] +aws_access_key_id=akidnospace +aws_secret_access_key=skidnospace +aws_session_token=tokennospace + +[weirdwhitespace] +aws_access_key_id= akidweird +aws_secret_access_key= skidweird + +aws_session_token=tokenweird///token== diff --git a/src/fluent-bit/tests/internal/data/aws_credentials/shared_credentials_file_nodefault.ini b/src/fluent-bit/tests/internal/data/aws_credentials/shared_credentials_file_nodefault.ini new file mode 100644 index 000000000..532d17dd4 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/aws_credentials/shared_credentials_file_nodefault.ini @@ -0,0 +1,12 @@ +[nondefault] +aws_access_key_id = akid +aws_secret_access_key = skid + +[nospace] +aws_access_key_id=akidnospace +aws_secret_access_key=skidnospace +aws_session_token=tokennospace + +[weirdwhitespace] +aws_access_key_id= akidweird +aws_secret_access_key= skidweird diff --git a/src/fluent-bit/tests/internal/data/aws_credentials/web_identity_token_file.txt b/src/fluent-bit/tests/internal/data/aws_credentials/web_identity_token_file.txt new file mode 100644 index 000000000..cb43252b5 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/aws_credentials/web_identity_token_file.txt @@ -0,0 +1 @@ +this-is-a-fake-jwt \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/config_format/classic/fluent-bit.conf b/src/fluent-bit/tests/internal/data/config_format/classic/fluent-bit.conf new file mode 100644 index 000000000..9acaa6757 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/classic/fluent-bit.conf @@ -0,0 +1,35 @@ +@SET a=1 +@SET b=2 +@INCLUDE service.conf + +[PARSER] + name test_api + +[MULTILINE_PARSER] + name abc + +[CUSTOM] + name calyptia + +[INPUT] + name tail + path /var/log/containers/*.log + + [GROUP 1] + key1 aa + key2 bb + + [GROUP 2] + key3 cc + key4 dd + +[FILTER] + name stdout + match * + +[OUTPUT] + name null + match * + +[UNKNOWN] + name blah diff --git a/src/fluent-bit/tests/internal/data/config_format/classic/indent_level_error.conf b/src/fluent-bit/tests/internal/data/config_format/classic/indent_level_error.conf new file mode 100644 index 000000000..6aabb6c82 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/classic/indent_level_error.conf @@ -0,0 +1,6 @@ +[INPUT] + Name dummy + +[OUTPUT] + Name stdout + Match * diff --git a/src/fluent-bit/tests/internal/data/config_format/classic/issue6281.conf b/src/fluent-bit/tests/internal/data/config_format/classic/issue6281.conf new file mode 100644 index 000000000..372be20de --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/classic/issue6281.conf @@ -0,0 +1,2 @@ +@INCLUDE issue6281_input.conf +@INCLUDE issue6281_output.conf \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/config_format/classic/issue6281_input.conf b/src/fluent-bit/tests/internal/data/config_format/classic/issue6281_input.conf new file mode 100644 index 000000000..1125e31c7 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/classic/issue6281_input.conf @@ -0,0 +1,2 @@ +[INPUT] + Name dummy \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/config_format/classic/issue6281_output.conf b/src/fluent-bit/tests/internal/data/config_format/classic/issue6281_output.conf new file mode 100644 index 000000000..6ac53a12c --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/classic/issue6281_output.conf @@ -0,0 +1,2 @@ +[OUTPUT] + Name stdout \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/config_format/classic/issue_5880.conf b/src/fluent-bit/tests/internal/data/config_format/classic/issue_5880.conf new file mode 100644 index 000000000..57bfa81df --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/classic/issue_5880.conf @@ -0,0 +1,14 @@ +[INPUT] + Name dummy + Tag dummy + +[FILTER] + Name modify + Match * + ADD foo bar + ADD + +[OUTPUT] + Name stdout + Match * + Format diff --git a/src/fluent-bit/tests/internal/data/config_format/classic/nolimitline.conf b/src/fluent-bit/tests/internal/data/config_format/classic/nolimitline.conf new file mode 100644 index 000000000..e7fff8420 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/classic/nolimitline.conf @@ -0,0 +1,11 @@ +[INPUT] + name dummy + +[FILTER] + Name lua + Match * + code local str = 'abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd'; function cb_filter(tag, ts, record) record.str = str; return 1, ts, record end + call cb_filter + +[OUTPUT] + name stdout diff --git a/src/fluent-bit/tests/internal/data/config_format/classic/recursion.conf b/src/fluent-bit/tests/internal/data/config_format/classic/recursion.conf new file mode 100644 index 000000000..10fb25d89 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/classic/recursion.conf @@ -0,0 +1 @@ +@INCLUDE rec* \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/config_format/classic/service.conf b/src/fluent-bit/tests/internal/data/config_format/classic/service.conf new file mode 100644 index 000000000..15d1730cc --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/classic/service.conf @@ -0,0 +1,4 @@ +[SERVICE] + flush 1 + log_level info + http_server on diff --git a/src/fluent-bit/tests/internal/data/config_format/yaml/fluent-bit.yaml b/src/fluent-bit/tests/internal/data/config_format/yaml/fluent-bit.yaml new file mode 100644 index 000000000..49894552f --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/yaml/fluent-bit.yaml @@ -0,0 +1,29 @@ +env: + flush_interval: 1 + +includes: + - service.yaml + +customs: + - name: ${observability} + api_key: zyJUb2tlbklEItoiY2ZlMTcx + +pipeline: + inputs: + - name: tail + path: ./test.log + parser: json + read_from_head: true + - name: tail + path: ./test.log + parser: json + read_from_head: true + + filters: + - name: record_modifier + match: "*" + record: powered_by calyptia + + outputs: + - name: stdout + match: "*" diff --git a/src/fluent-bit/tests/internal/data/config_format/yaml/issue_7559.yaml b/src/fluent-bit/tests/internal/data/config_format/yaml/issue_7559.yaml new file mode 100644 index 000000000..00927cae3 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/yaml/issue_7559.yaml @@ -0,0 +1,14 @@ +customs: + - name: calyptia + +pipeline: + inputs: + - name: fluentbit_metrics + scrape_interval: 30 + scrape_on_start: true + tag: _calyptia_cloud +service: + HTTP_Listen: 0.0.0.0 + HTTP_PORT: 2020 + HTTP_Server: 'On' + Log_Level: debug diff --git a/src/fluent-bit/tests/internal/data/config_format/yaml/parsers/parsers-conf.yaml b/src/fluent-bit/tests/internal/data/config_format/yaml/parsers/parsers-conf.yaml new file mode 100644 index 000000000..6421a8a1f --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/yaml/parsers/parsers-conf.yaml @@ -0,0 +1,3 @@ +--- +service: + parsers_file: parsers.conf diff --git a/src/fluent-bit/tests/internal/data/config_format/yaml/parsers/parsers.conf b/src/fluent-bit/tests/internal/data/config_format/yaml/parsers/parsers.conf new file mode 100644 index 000000000..9f3b6b331 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/yaml/parsers/parsers.conf @@ -0,0 +1,6 @@ +[PARSER] + Name docker + Format json + Time_Key time + Time_Format %Y-%m-%dT%H:%M:%S.%L + Time_Keep On diff --git a/src/fluent-bit/tests/internal/data/config_format/yaml/pipelines/slist/even.yaml b/src/fluent-bit/tests/internal/data/config_format/yaml/pipelines/slist/even.yaml new file mode 100644 index 000000000..5d5b7c46f --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/yaml/pipelines/slist/even.yaml @@ -0,0 +1,7 @@ +--- +pipeline: + inputs: + - name: http + success_header: + - foo bar + - bar foo diff --git a/src/fluent-bit/tests/internal/data/config_format/yaml/pipelines/slist/odd.yaml b/src/fluent-bit/tests/internal/data/config_format/yaml/pipelines/slist/odd.yaml new file mode 100644 index 000000000..a7d2058c9 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/yaml/pipelines/slist/odd.yaml @@ -0,0 +1,8 @@ +--- +pipeline: + inputs: + - name: http + success_header: + - foo bar + - bar foo + - foobar barfoo diff --git a/src/fluent-bit/tests/internal/data/config_format/yaml/service.yaml b/src/fluent-bit/tests/internal/data/config_format/yaml/service.yaml new file mode 100644 index 000000000..712d455b8 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/yaml/service.yaml @@ -0,0 +1,5 @@ +env: + observability: calyptia + +includes: + - test/nested.yaml diff --git a/src/fluent-bit/tests/internal/data/config_format/yaml/test.yaml b/src/fluent-bit/tests/internal/data/config_format/yaml/test.yaml new file mode 100644 index 000000000..26a3f9f7b --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/yaml/test.yaml @@ -0,0 +1,31 @@ +env: + flush_interval: 1 + my_api_key: abcdefghijk + +#includes: + #- dummy_pipeline.yaml + #- opensearch_pipeline.yaml + +service: + flush_interval: ${flush_interval} + log_level: info + +#customs: +# calyptia: +# api_key: ${my_api_key} + +pipeline: + inputs: + tail: + path: ./test.log + parser: json + read_from_head: true + + filters: + record_modifier: + match: "*" + record: powered_by calyptia + + outputs: + stdout: + match: "*" diff --git a/src/fluent-bit/tests/internal/data/config_format/yaml/test/dummy_pipeline.yaml b/src/fluent-bit/tests/internal/data/config_format/yaml/test/dummy_pipeline.yaml new file mode 100644 index 000000000..770ab99a9 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/yaml/test/dummy_pipeline.yaml @@ -0,0 +1,13 @@ +pipeline: + inputs: + - name: dummy + tag: success + group1: + a: b + c: d + outputs: + - name: stdout + match: "*" + +unknown: + a: b diff --git a/src/fluent-bit/tests/internal/data/config_format/yaml/test/nested.yaml b/src/fluent-bit/tests/internal/data/config_format/yaml/test/nested.yaml new file mode 100644 index 000000000..f47076490 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/config_format/yaml/test/nested.yaml @@ -0,0 +1,7 @@ +service: + flush: ${flush_interval} + log_level: debug + http_server: on + +includes: + - dummy_pipeline.yaml diff --git a/src/fluent-bit/tests/internal/data/file/empty_file.txt b/src/fluent-bit/tests/internal/data/file/empty_file.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/fluent-bit/tests/internal/data/file/text_file.txt b/src/fluent-bit/tests/internal/data/file/text_file.txt new file mode 100644 index 000000000..8c8e5543c --- /dev/null +++ b/src/fluent-bit/tests/internal/data/file/text_file.txt @@ -0,0 +1,5 @@ +Some text file + +line 3 + +line 5 diff --git a/src/fluent-bit/tests/internal/data/input_chunk/log/a_thousand_plus_one_bytes.log b/src/fluent-bit/tests/internal/data/input_chunk/log/a_thousand_plus_one_bytes.log new file mode 100644 index 000000000..ce6ec2202 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/input_chunk/log/a_thousand_plus_one_bytes.log @@ -0,0 +1,2 @@ +{"log":"zmHw8IQgSHIR9f4QkIYYZGVBoFhozS6r0EWwuJhTslZeDvYte8r4HwfwYt0clr3gENB9Tpc0vSdbxn7D3xmUFjXlBFgI01cKTcJh4XUUMkNPpcxidVQpSkvxzLiJXHbOiVc0C6AmiLbTP4XSgUiMWS0p42ZkH373JVYIeqa850MVCJUR0Zkx3Uhwq01zOR4eXTKa8UU5t31RV9ghuT2BnR3Aipt0vZk2eBydBLtDonnSHjVFYMwyq2uPmpIGi9V2MbczoTL7sPiFtiRkPHauosLkMtaN1jQCqeQnJ9db8LuTXSRbtqdFh0p7pdpUG29vFgSsbYhS3Yto1gLiqBZSnuLl9mgMYICRQ42OhGvhQE7SByAp7VMpUaA42H3xWH7daNVgHkHFr16LeMQNcGgZ3pZGpfxMd8Ugs5xNIDzrrArtAqaKxAc3BMGLP4d35ipGGIhDQymWhnkJXauM6fSljSmnuqj6kEavdRQ2HJ9WaH108OfKcaIYV5CgjZWqW2ZGSz4NQ9tutKURAntQ3GjvEdaVa3ShCE1mNEWTArch7NN6K3LC8F5mbKiIP79QZ12VyvVcEr98XQAgORykZh4EMBSNwKxEiHDL6BmcFiBkS4DLUBKmlVebRSrAvwoY8cgL17YQXcZHsMOUDLBw4jPxzy5b2A9IFIj10f6QH0D4H2TsSi7wl70EmxjT6UfYhY0SZvzjCl8209QPHtON5KCknB3CJlpGhr9SCvhC7hbguS1IowuvFeTcMgiuy2MGJtl4wKS2gZxFe9C6kLo0krCLF14xhG1b9kBwGD1sFOuDUJ3hxGRpHLPbHQZ99QltqS4LhUuzbzivd5JjxAVGu1gSqAzd5EYU8XaQjPX4FxUUJjbj4CW06lFjAX0sFhfQVkdJ04kMKDLGjMcYaPJwyFBXrQZWR49jD83Xgtp3PU3nR7qlrIYi0OCA1IGgtZrDTjeJXoO9ZK8NcZJ1F3h9hZqN5ba"} + diff --git a/src/fluent-bit/tests/internal/data/input_chunk/log/test_buffer_drop_chunks.h b/src/fluent-bit/tests/internal/data/input_chunk/log/test_buffer_drop_chunks.h new file mode 100644 index 000000000..f1c897866 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/input_chunk/log/test_buffer_drop_chunks.h @@ -0,0 +1,27 @@ +#define TEST_BUFFER_DROP_CHUNKS "[" \ + "1598279645," \ + "{" \ + "\"key_0\": false," \ + "\"key_1\": false," \ + "\"key_2\": false," \ + "\"key_3\": false," \ + "\"key_4\": false," \ + "\"key_5\": false," \ + "\"key_6\": false," \ + "\"key_7\": false," \ + "\"key_8\": false," \ + "\"key_9\": false," \ + "\"key_10\": false," \ + "\"key_11\": false," \ + "\"key_12\": false," \ + "\"key_13\": false," \ + "\"key_14\": false," \ + "\"key_15\": false," \ + "\"key_16\": false," \ + "\"key_17\": false," \ + "\"key_18\": false," \ + "\"key_19\": false," \ + "\"key_20\": false," \ + "\"END_KEY\": \"JSON_END\"" \ + "}]" + diff --git a/src/fluent-bit/tests/internal/data/input_chunk/log/test_buffer_valid.log b/src/fluent-bit/tests/internal/data/input_chunk/log/test_buffer_valid.log new file mode 100644 index 000000000..a5a05ee46 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/input_chunk/log/test_buffer_valid.log @@ -0,0 +1,3 @@ +{"log":"Single log\n"} +{"log":"Second log\n"} +{"log":"Third log\n"} diff --git a/src/fluent-bit/tests/internal/data/input_chunk/out/a_thousand_plus_one_bytes.out b/src/fluent-bit/tests/internal/data/input_chunk/out/a_thousand_plus_one_bytes.out new file mode 100644 index 000000000..e69de29bb diff --git a/src/fluent-bit/tests/internal/data/input_chunk/out/test_buffer_valid.out b/src/fluent-bit/tests/internal/data/input_chunk/out/test_buffer_valid.out new file mode 100644 index 000000000..a5a05ee46 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/input_chunk/out/test_buffer_valid.out @@ -0,0 +1,3 @@ +{"log":"Single log\n"} +{"log":"Second log\n"} +{"log":"Third log\n"} diff --git a/src/fluent-bit/tests/internal/data/input_chunk/parser.conf b/src/fluent-bit/tests/internal/data/input_chunk/parser.conf new file mode 100644 index 000000000..28bde4751 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/input_chunk/parser.conf @@ -0,0 +1,10 @@ +[PARSER] + Name docker + Format json + Time_Key time + Time_Format %Y-%m-%dT%H:%M:%S.%L%z + +[PARSER] + Name docker_multiline + Format regex + Regex (?^{"log":"\d{4}-\d{2}-\d{2}.*) diff --git a/src/fluent-bit/tests/internal/data/mp/apache_10k.mp b/src/fluent-bit/tests/internal/data/mp/apache_10k.mp new file mode 100644 index 000000000..d3e55e747 Binary files /dev/null and b/src/fluent-bit/tests/internal/data/mp/apache_10k.mp differ diff --git a/src/fluent-bit/tests/internal/data/pack/README.md b/src/fluent-bit/tests/internal/data/pack/README.md new file mode 100644 index 000000000..49b00c1bb --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/README.md @@ -0,0 +1,3 @@ +Data samples on this directory are generated by Python scripts taken as source the .txt files. + +Note that utf-8 files with Unicode characters > 0xffff generate an invalid JSON representation 'FOR THE TEST' purposes. diff --git a/src/fluent-bit/tests/internal/data/pack/bug342.json b/src/fluent-bit/tests/internal/data/pack/bug342.json new file mode 100644 index 000000000..1f9e5544a --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/bug342.json @@ -0,0 +1,240 @@ +{"num": 1} +{"num": 2} +{"num": 3} +{"num": 4} +{"num": 5} +{"num": 6} +{"num": 7} +{"num": 8} +{"num": 9} +{"num": 10} +{"num": 11} +{"num": 12} +{"num": 13} +{"num": 14} +{"num": 15} +{"num": 16} +{"num": 17} +{"num": 18} +{"num": 19} +{"num": 20} +{"num": 21} +{"num": 22} +{"num": 23} +{"num": 24} +{"num": 25} +{"num": 26} +{"num": 27} +{"num": 28} +{"num": 29} +{"num": 30} +{"num": 31} +{"num": 32} +{"num": 33} +{"num": 34} +{"num": 35} +{"num": 36} +{"num": 37} +{"num": 38} +{"num": 39} +{"num": 40} +{"num": 41} +{"num": 42} +{"num": 43} +{"num": 44} +{"num": 45} +{"num": 46} +{"num": 47} +{"num": 48} +{"num": 49} +{"num": 50} +{"num": 51} +{"num": 52} +{"num": 53} +{"num": 54} +{"num": 55} +{"num": 56} +{"num": 57} +{"num": 58} +{"num": 59} +{"num": 60} +{"num": 61} +{"num": 62} +{"num": 63} +{"num": 64} +{"num": 65} +{"num": 66} +{"num": 67} +{"num": 68} +{"num": 69} +{"num": 70} +{"num": 71} +{"num": 72} +{"num": 73} +{"num": 74} +{"num": 75} +{"num": 76} +{"num": 77} +{"num": 78} +{"num": 79} +{"num": 80} +{"num": 81} +{"num": 82} +{"num": 83} +{"num": 84} +{"num": 85} +{"num": 86} +{"num": 87} +{"num": 88} +{"num": 89} +{"num": 90} +{"num": 91} +{"num": 92} +{"num": 93} +{"num": 94} +{"num": 95} +{"num": 96} +{"num": 97} +{"num": 98} +{"num": 99} +{"num": 100} +{"num": 101} +{"num": 102} +{"num": 103} +{"num": 104} +{"num": 105} +{"num": 106} +{"num": 107} +{"num": 108} +{"num": 109} +{"num": 110} +{"num": 111} +{"num": 112} +{"num": 113} +{"num": 114} +{"num": 115} +{"num": 116} +{"num": 117} +{"num": 118} +{"num": 119} +{"num": 120} +{"num": 121} +{"num": 122} +{"num": 123} +{"num": 124} +{"num": 125} +{"num": 126} +{"num": 127} +{"num": 128} +{"num": 129} +{"num": 130} +{"num": 131} +{"num": 132} +{"num": 133} +{"num": 134} +{"num": 135} +{"num": 136} +{"num": 137} +{"num": 138} +{"num": 139} +{"num": 140} +{"num": 141} +{"num": 142} +{"num": 143} +{"num": 144} +{"num": 145} +{"num": 146} +{"num": 147} +{"num": 148} +{"num": 149} +{"num": 150} +{"num": 151} +{"num": 152} +{"num": 153} +{"num": 154} +{"num": 155} +{"num": 156} +{"num": 157} +{"num": 158} +{"num": 159} +{"num": 160} +{"num": 161} +{"num": 162} +{"num": 163} +{"num": 164} +{"num": 165} +{"num": 166} +{"num": 167} +{"num": 168} +{"num": 169} +{"num": 170} +{"num": 171} +{"num": 172} +{"num": 173} +{"num": 174} +{"num": 175} +{"num": 176} +{"num": 177} +{"num": 178} +{"num": 179} +{"num": 180} +{"num": 181} +{"num": 182} +{"num": 183} +{"num": 184} +{"num": 185} +{"num": 186} +{"num": 187} +{"num": 188} +{"num": 189} +{"num": 190} +{"num": 191} +{"num": 192} +{"num": 193} +{"num": 194} +{"num": 195} +{"num": 196} +{"num": 197} +{"num": 198} +{"num": 199} +{"num": 200} +{"num": 201} +{"num": 202} +{"num": 203} +{"num": 204} +{"num": 205} +{"num": 206} +{"num": 207} +{"num": 208} +{"num": 209} +{"num": 210} +{"num": 211} +{"num": 212} +{"num": 213} +{"num": 214} +{"num": 215} +{"num": 216} +{"num": 217} +{"num": 218} +{"num": 219} +{"num": 220} +{"num": 221} +{"num": 222} +{"num": 223} +{"num": 224} +{"num": 225} +{"num": 226} +{"num": 227} +{"num": 228} +{"num": 229} +{"num": 230} +{"num": 231} +{"num": 232} +{"num": 233} +{"num": 234} +{"num": 235} +{"num": 236} +{"num": 237} +{"num": 238} +{"num": 239} +{"num": 240} diff --git a/src/fluent-bit/tests/internal/data/pack/dup_keys_in.json b/src/fluent-bit/tests/internal/data/pack/dup_keys_in.json new file mode 100644 index 000000000..bdfb9d7cb --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/dup_keys_in.json @@ -0,0 +1 @@ +[1601487301, {"date": 872835240, "map": {"sub1": false, "sub2": "aaa", "sub3": "bbb", "sub1": null, "sub1": true}, "key1": 12345, "key2": 444, "date": 1059113640, "key1": 333}] diff --git a/src/fluent-bit/tests/internal/data/pack/dup_keys_out.json b/src/fluent-bit/tests/internal/data/pack/dup_keys_out.json new file mode 100644 index 000000000..5bb557eb7 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/dup_keys_out.json @@ -0,0 +1 @@ +{"map":{"sub2":"aaa","sub3":"bbb","sub1":true},"key2":444,"date":1059113640,"key1":333} diff --git a/src/fluent-bit/tests/internal/data/pack/json_single_map_001.json b/src/fluent-bit/tests/internal/data/pack/json_single_map_001.json new file mode 100644 index 000000000..6833b3929 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/json_single_map_001.json @@ -0,0 +1,5 @@ +{"key001": 123456789, + "key002": 0.999887766, + "key003": "abcdefghijk", + "key004": [{"a": 1, "b": 2}, {"c": 3, "d": 4}] +} diff --git a/src/fluent-bit/tests/internal/data/pack/json_single_map_002.json b/src/fluent-bit/tests/internal/data/pack/json_single_map_002.json new file mode 100644 index 000000000..d5a3709ed --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/json_single_map_002.json @@ -0,0 +1,4 @@ +{"AAA": 123456789, + "BBB": 0.999887766, + "CCC": ["aa", "bb", "cc", [1, 2, 3]] +} diff --git a/src/fluent-bit/tests/internal/data/pack/mixed.py b/src/fluent-bit/tests/internal/data/pack/mixed.py new file mode 100644 index 000000000..7ad0a6149 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/mixed.py @@ -0,0 +1,31 @@ +# Fluent Bit / Pack mixed samples to JSON +# ======================================= +# This script generate the JSON formatted strings for the mixed_ABC.txt samples. + +import os +import json +import msgpack + +def gen_json(f): + raw = open(f, 'r') + data = raw.read() + raw.close() + + out_mp = f[:-4] + ".mp" + out_json = f[:-4] + ".json" + + # Write messagepack + fmp = open(out_mp, 'w') + fmp.write(msgpack.packb(data)) + fmp.close() + + fjson = open(out_json, 'w') + fjson.write(json.dumps(data)) + fjson.close() + +for fn in os.listdir('.'): + if not os.path.isfile(fn): + continue + + if fn.startswith('mixed_') and fn.endswith('.txt'): + gen_json(fn) diff --git a/src/fluent-bit/tests/internal/data/pack/mixed_001.json b/src/fluent-bit/tests/internal/data/pack/mixed_001.json new file mode 100644 index 000000000..10f7faadb --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/mixed_001.json @@ -0,0 +1 @@ +"mixed_001 => \u001b[1;34mI\u001b[0m test\n" \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/mixed_001.mp b/src/fluent-bit/tests/internal/data/pack/mixed_001.mp new file mode 100644 index 000000000..587dc63f2 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/mixed_001.mp @@ -0,0 +1 @@ +¿mixed_001 => I test diff --git a/src/fluent-bit/tests/internal/data/pack/mixed_001.txt b/src/fluent-bit/tests/internal/data/pack/mixed_001.txt new file mode 100644 index 000000000..d217bff81 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/mixed_001.txt @@ -0,0 +1 @@ +mixed_001 => I test diff --git a/src/fluent-bit/tests/internal/data/pack/mixed_002.json b/src/fluent-bit/tests/internal/data/pack/mixed_002.json new file mode 100644 index 000000000..e32314b0a --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/mixed_002.json @@ -0,0 +1 @@ +"mixed_002 =>\n\n áéíóú\n\n\n'\n\\t\n" \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/mixed_002.mp b/src/fluent-bit/tests/internal/data/pack/mixed_002.mp new file mode 100644 index 000000000..1bf975535 Binary files /dev/null and b/src/fluent-bit/tests/internal/data/pack/mixed_002.mp differ diff --git a/src/fluent-bit/tests/internal/data/pack/mixed_002.txt b/src/fluent-bit/tests/internal/data/pack/mixed_002.txt new file mode 100644 index 000000000..a85912bb6 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/mixed_002.txt @@ -0,0 +1,7 @@ +mixed_002 => + + áéíóú + + +' +\t diff --git a/src/fluent-bit/tests/internal/data/pack/mixed_003.json b/src/fluent-bit/tests/internal/data/pack/mixed_003.json new file mode 100644 index 000000000..167c89b8a --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/mixed_003.json @@ -0,0 +1 @@ +"á\n" \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/mixed_003.mp b/src/fluent-bit/tests/internal/data/pack/mixed_003.mp new file mode 100644 index 000000000..760f5e18c --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/mixed_003.mp @@ -0,0 +1 @@ +£Ã¡ diff --git a/src/fluent-bit/tests/internal/data/pack/mixed_003.txt b/src/fluent-bit/tests/internal/data/pack/mixed_003.txt new file mode 100644 index 000000000..072d59379 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/mixed_003.txt @@ -0,0 +1 @@ +á diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_bell.json b/src/fluent-bit/tests/internal/data/pack/utf8_bell.json new file mode 100644 index 000000000..ced4da0cf --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_bell.json @@ -0,0 +1 @@ +"🔔" \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_bell.mp b/src/fluent-bit/tests/internal/data/pack/utf8_bell.mp new file mode 100644 index 000000000..ea4ce5c07 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_bell.mp @@ -0,0 +1 @@ +¤ðŸ”” \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_bell.txt b/src/fluent-bit/tests/internal/data/pack/utf8_bell.txt new file mode 100644 index 000000000..89b9de00e --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_bell.txt @@ -0,0 +1 @@ +🔔 \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_copyright.json b/src/fluent-bit/tests/internal/data/pack/utf8_copyright.json new file mode 100644 index 000000000..4d52a66f3 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_copyright.json @@ -0,0 +1 @@ +"©" \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_copyright.mp b/src/fluent-bit/tests/internal/data/pack/utf8_copyright.mp new file mode 100644 index 000000000..6bd6a103e --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_copyright.mp @@ -0,0 +1 @@ +¢Â© \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_copyright.txt b/src/fluent-bit/tests/internal/data/pack/utf8_copyright.txt new file mode 100644 index 000000000..5f8778c57 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_copyright.txt @@ -0,0 +1 @@ +© \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_gen.py b/src/fluent-bit/tests/internal/data/pack/utf8_gen.py new file mode 100644 index 000000000..606e8cc2d --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_gen.py @@ -0,0 +1,32 @@ +# Fluent Bit / Pack utf-8 samples to JSON +# ======================================= + +import os +import json +import msgpack + +def gen_json(f): + + print f + + with io.open(f, 'rb') as raw: + data = raw.read() + + out_mp = f[:-4] + ".mp" + out_json = f[:-4] + ".json" + + # Write messagepack + fmp = open(out_mp, 'w') + fmp.write(msgpack.packb(data)) + fmp.close() + + fjson = open(out_json, 'w') + fjson.write(json.dumps(data).encode('utf8')) + fjson.close() + +for fn in os.listdir('.'): + if not os.path.isfile(fn): + continue + + if fn.startswith('utf8_') and fn.endswith('.txt'): + gen_json(fn) diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_hokke.json b/src/fluent-bit/tests/internal/data/pack/utf8_hokke.json new file mode 100644 index 000000000..d93624bf2 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_hokke.json @@ -0,0 +1 @@ +"𩸽" \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_hokke.mp b/src/fluent-bit/tests/internal/data/pack/utf8_hokke.mp new file mode 100644 index 000000000..704885a88 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_hokke.mp @@ -0,0 +1 @@ +¤ð©¸½ \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_hokke.txt b/src/fluent-bit/tests/internal/data/pack/utf8_hokke.txt new file mode 100644 index 000000000..f1d17d763 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_hokke.txt @@ -0,0 +1 @@ +𩸽 \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_relaxed.json b/src/fluent-bit/tests/internal/data/pack/utf8_relaxed.json new file mode 100644 index 000000000..4526bf40f --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_relaxed.json @@ -0,0 +1 @@ +"☺" \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_relaxed.mp b/src/fluent-bit/tests/internal/data/pack/utf8_relaxed.mp new file mode 100644 index 000000000..1fcce51e1 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_relaxed.mp @@ -0,0 +1 @@ +£â˜º \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/pack/utf8_relaxed.txt b/src/fluent-bit/tests/internal/data/pack/utf8_relaxed.txt new file mode 100644 index 000000000..e2890a9c1 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/pack/utf8_relaxed.txt @@ -0,0 +1 @@ +☺ \ No newline at end of file diff --git a/src/fluent-bit/tests/internal/data/parser/json.conf b/src/fluent-bit/tests/internal/data/parser/json.conf new file mode 100644 index 000000000..198bbf3ca --- /dev/null +++ b/src/fluent-bit/tests/internal/data/parser/json.conf @@ -0,0 +1,200 @@ +# Parser: no_year +# =============== +# the given format don't contain the Year, this is a common +# case on old Syslog implementations. +# +[PARSER] + Name no_year + Format json + Time_Key time + Time_Format %b %d %H:%M:%S + Time_Keep On + +# Parser: no_year_N +# ================= +# Just for compatibility, check a string with no year but including Nanoseconds. +# +[PARSER] + Name no_year_N + Format json + Time_Key time + Time_Format %b %d %H:%M:%S.%L + Time_Keep On + +# Parser: no_year_NC +# ================= +# Just for compatibility, check a string with no year but including Nanoseconds with comma as fractional separator. +# +[PARSER] + Name no_year_NC + Format json + Time_Key time + Time_Format %b %d %H:%M:%S,%L + Time_Keep On + +# Parser: no_year_TZ +# ================= +# Time string with no year and including timezone +# +[PARSER] + Name no_year_TZ + Format json + Time_Key time + Time_Format %b %d %H:%M:%S %z + Time_Keep On + +# Parser: no_year_N_TZ +# ==================== +# Time string with no year, nanoseconds and timezone +# +[PARSER] + Name no_year_N_TZ + Format json + Time_Key time + Time_Format %b %d %H:%M:%S.%L %z + Time_Keep On + + +# Parser: no_year_NC_TZ +# ==================== +# Time string with no year, nanoseconds and timezone with comma as fractional separator. +# +[PARSER] + Name no_year_NC_TZ + Format json + Time_Key time + Time_Format %b %d %H:%M:%S,%L %z + Time_Keep On + + +# Parser: default_UTC +# =================== +# Time string with timezone in UTC +# +[PARSER] + Name default_UTC + Format json + Time_Key time + Time_Format %m/%d/%Y %H:%M:%S + Time_Keep On + +# Parser: default_UTC_Z +# ===================== +# Time string with timezone in UTC and ending Z +# +[PARSER] + Name default_UTC_Z + Format json + Time_Key time + Time_Format %m/%d/%Y %H:%M:%SZ + Time_Keep On + +# Parser: default_UTC_N_Z +# ======================= +# Time string with timezone in UTC, nanoseconds and ending Z +# +[PARSER] + Name default_UTC_N_Z + Format json + Time_Key time + Time_Format %m/%d/%Y %H:%M:%S.%LZ + Time_Keep On + +# Parser: default_UTC_NC_Z +# ======================= +# Time string with timezone in UTC, nanoseconds with comma as fractional separator and ending Z +# +[PARSER] + Name default_UTC_NC_Z + Format json + Time_Key time + Time_Format %m/%d/%Y %H:%M:%S,%LZ + Time_Keep On + +# Parser: generic_TZ +# ================== +# Generic date with timezone +# +[PARSER] + Name generic_TZ + Format json + Time_Key time + Time_Format %m/%d/%Y %H:%M:%S %z + Time_Keep On + +# Parser: generic +# =============== +# Generic date +# +[PARSER] + Name generic + Format json + Time_Key time + Time_Format %m/%d/%Y %H:%M:%S + Time_Keep On + +# Parser: generic_N +# =============== +# Generic date with nanoseconds +# +[PARSER] + Name generic_N + Format json + Time_Key time + Time_Format %m/%d/%Y %H:%M:%S.%L + Time_Keep On + +# Parser: generic_NC +# =============== +# Generic date with nanoseconds with comma as fractional separator +# +[PARSER] + Name generic_NC + Format json + Time_Key time + Time_Format %m/%d/%Y %H:%M:%S,%L + Time_Keep On + +# Parser: generic_N_TZ +# ==================== +# Generic date with nanoseconds and timezone +# +[PARSER] + Name generic_N_TZ + Format json + Time_Key time + Time_Format %m/%d/%Y %H:%M:%S.%L %z + Time_Keep On + +# Parser: generic_NC_TZ +# ==================== +# Generic date with nanoseconds with comma as fractional separator and timezone +# +[PARSER] + Name generic_NC_TZ + Format json + Time_Key time + Time_Format %m/%d/%Y %H:%M:%S,%L %z + Time_Keep On + +# Parser: generic_NL_TZ +# ==================== +# Generic date with nanoseconds with colon as fractional separator and timezone +# +[PARSER] + Name generic_NL_TZ + Format json + Time_Key time + Time_Format %m/%d/%Y %H:%M:%S:%L %z + Time_Keep On + +# Parser: apache_error +# ==================== +# Apache error log time format +# +[PARSER] + Name apache_error + Format json + Time_Key time + Time_Format %a %b %d %H:%M:%S.%L %Y + Time_Keep On diff --git a/src/fluent-bit/tests/internal/data/parser/regex.conf b/src/fluent-bit/tests/internal/data/parser/regex.conf new file mode 100644 index 000000000..5b340dc37 --- /dev/null +++ b/src/fluent-bit/tests/internal/data/parser/regex.conf @@ -0,0 +1,234 @@ +# Parser: no_year +# =============== +# the given format don't contain the Year, this is a common +# case on old Syslog implementations. +# +[PARSER] + Name no_year + Format regex + Regex ^(?[^ ]*) (?[^ ]*) (?