| /** @file | |
| Catch-based tests for LogFieldFallback parsing helpers. | |
| @section license License | |
| Licensed to the Apache Software Foundation (ASF) under one | |
| or more contributor license agreements. See the NOTICE file | |
| distributed with this work for additional information | |
| regarding copyright ownership. The ASF licenses this file | |
| to you under the Apache License, Version 2.0 (the | |
| "License"); you may not use this file except in compliance | |
| with the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| */ | |
| #include <string> | |
| #include <catch2/catch_test_macros.hpp> | |
| #include "LogFieldFallback.h" | |
| using LogFieldFallback::ParseResult; | |
| namespace | |
| { | |
| ParseResult | |
| require_parse(std::string_view symbol) | |
| { | |
| std::string error; | |
| auto parsed = LogFieldFallback::parse(symbol, error); | |
| INFO(error); | |
| REQUIRE(parsed.has_value()); | |
| return std::move(*parsed); | |
| } | |
| } // namespace | |
| TEST_CASE("Field fallback detection ignores quoted separators", "[LogFieldFallback]") | |
| { | |
| REQUIRE_FALSE(LogFieldFallback::has_fallback("{field}cqh")); | |
| REQUIRE(LogFieldFallback::has_fallback("{field}cqh??{other}pqh")); | |
| REQUIRE(LogFieldFallback::has_fallback("{field}cqh??chi")); | |
| REQUIRE(LogFieldFallback::has_fallback("{field}cqh??\"default??value\"")); | |
| REQUIRE_FALSE(LogFieldFallback::has_fallback("\"default??value\"")); | |
| } | |
| TEST_CASE("Field fallback parsing preserves containers and slices", "[LogFieldFallback]") | |
| { | |
| auto parsed = require_parse(" {x-primary-id}cqh[0:8] ?? {x-secondary-id}epqh[0:16] "); | |
| REQUIRE(parsed.header_fields.size() == 2); | |
| REQUIRE_FALSE(parsed.fallback_symbol.has_value()); | |
| REQUIRE_FALSE(parsed.fallback_default.has_value()); | |
| CHECK(parsed.header_fields[0].name == "x-primary-id"); | |
| CHECK(parsed.header_fields[0].container == LogField::CQH); | |
| CHECK(parsed.header_fields[0].slice.m_enable); | |
| CHECK(parsed.header_fields[0].slice.m_start == 0); | |
| CHECK(parsed.header_fields[0].slice.m_end == 8); | |
| CHECK(parsed.header_fields[1].name == "x-secondary-id"); | |
| CHECK(parsed.header_fields[1].container == LogField::EPQH); | |
| CHECK(parsed.header_fields[1].slice.m_enable); | |
| CHECK(parsed.header_fields[1].slice.m_start == 0); | |
| CHECK(parsed.header_fields[1].slice.m_end == 16); | |
| } | |
| TEST_CASE("Field fallback parsing supports final plain symbols", "[LogFieldFallback]") | |
| { | |
| auto parsed = require_parse("{x-primary-id}cqh??{x-secondary-id}cqh??cqup[0:7]"); | |
| REQUIRE(parsed.header_fields.size() == 2); | |
| REQUIRE(parsed.fallback_symbol.has_value()); | |
| CHECK(parsed.fallback_symbol == std::optional<std::string>{"cqup[0:7]"}); | |
| REQUIRE_FALSE(parsed.fallback_default.has_value()); | |
| } | |
| TEST_CASE("Field fallback parsing supports quoted defaults", "[LogFieldFallback]") | |
| { | |
| auto parsed = require_parse("{x-primary-id}cqh??{x-secondary-id}cqh??\"missing\\\"id\\\\tail\""); | |
| REQUIRE(parsed.header_fields.size() == 2); | |
| REQUIRE_FALSE(parsed.fallback_symbol.has_value()); | |
| REQUIRE(parsed.fallback_default.has_value()); | |
| CHECK(parsed.fallback_default == std::optional<std::string>{"missing\"id\\tail"}); | |
| } | |
| TEST_CASE("Field fallback parsing rejects malformed chains", "[LogFieldFallback]") | |
| { | |
| std::string error; | |
| auto parsed = LogFieldFallback::parse("{x-primary-id}cqh??\"missing\"??{x-secondary-id}cqh", error); | |
| REQUIRE_FALSE(parsed.has_value()); | |
| CHECK(error.find("default literal must be the final term") != std::string::npos); | |
| parsed = LogFieldFallback::parse("{x-primary-id}record??{x-secondary-id}cqh", error); | |
| REQUIRE_FALSE(parsed.has_value()); | |
| CHECK(error.find("record is not a supported header container") != std::string::npos); | |
| parsed = LogFieldFallback::parse("{x-primary-id}cqh????{x-secondary-id}cqh", error); | |
| REQUIRE_FALSE(parsed.has_value()); | |
| CHECK(error.find("empty candidate") != std::string::npos); | |
| parsed = LogFieldFallback::parse("{x-primary-id}cqh??chi??\"missing\"", error); | |
| REQUIRE_FALSE(parsed.has_value()); | |
| CHECK(error.find("plain field symbols must be the final term") != std::string::npos); | |
| parsed = LogFieldFallback::parse("{x-primary-id}cqh??SUM(psql)", error); | |
| REQUIRE_FALSE(parsed.has_value()); | |
| CHECK(error.find("aggregate expressions are not supported in fallback chains") != std::string::npos); | |
| } |