blob: d24edc9b58fee17a844a1907948e5d956be5ef48 [file]
/**
*
* 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 "minifi-cpp/FlowFileRecord.h"
#include "catch2/generators/catch_generators.hpp"
#include "processors/SplitContent.h"
#include "unit/Catch.h"
#include "unit/SingleProcessorTestController.h"
#include "unit/TestBase.h"
#include "utils/ConfigurationUtils.h"
#include "unit/TestUtils.h"
namespace org::apache::nifi::minifi::processors::test {
template<typename... Bytes>
std::vector<std::byte> createByteVector(Bytes... bytes) {
return {static_cast<std::byte>(bytes)...};
}
TEST_CASE("WithoutByteSequence") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceLocation::Leading)}));
REQUIRE_THROWS_WITH(controller.trigger("rub-a-dub-dub"), "Expected valid value from \"Byte Sequence\", but got PropertyNotSet (Property Error:2)");
}
TEST_CASE("EmptyFlowFile") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "ub"));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceLocation::Leading)}));
auto trigger_results = controller.trigger("");
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.empty());
CHECK(controller.plan->getContent(original[0]).empty());
}
TEST_CASE("TextFormatLeadingPosition", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "ub"));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceLocation::Leading)}));
auto trigger_results = controller.trigger("rub-a-dub-dub");
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 4);
CHECK(controller.plan->getContent(original[0]) == "rub-a-dub-dub");
CHECK(controller.plan->getContent(splits[0]) == "r");
CHECK(controller.plan->getContent(splits[1]) == "ub-a-d");
CHECK(controller.plan->getContent(splits[2]) == "ub-d");
CHECK(controller.plan->getContent(splits[3]) == "ub");
}
TEST_CASE("TextFormatTrailingPosition", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "ub"));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceLocation::Trailing)}));
auto trigger_results = controller.trigger("rub-a-dub-dub");
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 3);
CHECK(controller.plan->getContent(original[0]) == "rub-a-dub-dub");
CHECK(controller.plan->getContent(splits[0]) == "rub");
CHECK(controller.plan->getContent(splits[1]) == "-a-dub");
CHECK(controller.plan->getContent(splits[2]) == "-dub");
}
TEST_CASE("TextFormatSplits", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "test"));
constexpr std::string_view input_1 = "This is a test. This is another test. And this is yet another test. Finally this is the last Test.";
constexpr std::string_view input_2 = "This is a test. This is another test. And this is yet another test. Finally this is the last test";
const auto [keep_byte_sequence, byte_sequence_location, input, expected_splits] = GENERATE_REF(
std::make_tuple("true", "Leading", input_1, std::vector<std::string_view>{"This is a ", "test. This is another ", "test. And this is yet another ", "test. Finally this is the last Test."}),
std::make_tuple("false", "Leading", input_1, std::vector<std::string_view>{"This is a ", ". This is another ", ". And this is yet another ", ". Finally this is the last Test."}),
std::make_tuple("true", "Trailing", input_1, std::vector<std::string_view>{"This is a test", ". This is another test", ". And this is yet another test", ". Finally this is the last Test."}),
std::make_tuple("false", "Trailing", input_1, std::vector<std::string_view>{"This is a ", ". This is another ", ". And this is yet another ", ". Finally this is the last Test."}),
std::make_tuple("true", "Leading", input_2, std::vector<std::string_view>{"This is a ", "test. This is another ", "test. And this is yet another ", "test. Finally this is the last ", "test"}),
std::make_tuple("true", "Trailing", input_2, std::vector<std::string_view>{"This is a test", ". This is another test", ". And this is yet another test", ". Finally this is the last test"}));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, keep_byte_sequence));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, byte_sequence_location));
auto trigger_results = controller.trigger(input);
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == expected_splits.size());
CHECK(controller.plan->getContent(original[0]) == input);
for (size_t i = 0; i < expected_splits.size(); ++i) {
auto split_i = controller.plan->getContent(splits[i]);
auto expected_i = expected_splits[i];
CHECK(split_i == expected_i);
}
}
TEST_CASE("SmallSplits", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "false"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "FFFF"));
const auto input_data = createByteVector(1, 2, 3, 4, 5, 0xFF, 0xFF, 0xFF, 5, 4, 3, 2, 1);
std::string_view input(reinterpret_cast<const char*>(input_data.data()), input_data.size());
auto trigger_results = controller.trigger(input);
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 2);
const auto expected_split_1 = createByteVector(1, 2, 3, 4, 5);
const auto expected_split_2 = createByteVector(0xFF, 5, 4, 3, 2, 1);
CHECK(controller.plan->getContentAsBytes(*splits[0]) == expected_split_1);
CHECK(controller.plan->getContentAsBytes(*splits[1]) == expected_split_2);
}
TEST_CASE("WithSingleByteSplit", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "false"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "FF"));
const auto input_data = createByteVector(1, 2, 3, 4, 5, 0xFF, 5, 4, 3, 2, 1);
std::string_view input(reinterpret_cast<const char*>(input_data.data()), input_data.size());
auto trigger_results = controller.trigger(input);
const auto original = trigger_results.at(processors::SplitContent::Original);
const auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 2);
const auto expected_split_1 = createByteVector(1, 2, 3, 4, 5);
const auto expected_split_2 = createByteVector(5, 4, 3, 2, 1);
CHECK(controller.plan->getContentAsBytes(*splits[0]) == expected_split_1);
CHECK(controller.plan->getContentAsBytes(*splits[1]) == expected_split_2);
}
TEST_CASE("WithLargerSplit", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "false"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "05050505"));
const auto input_data = createByteVector(1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 4, 3, 2, 1);
std::string_view input(reinterpret_cast<const char*>(input_data.data()), input_data.size());
auto trigger_results = controller.trigger(input);
const auto original = trigger_results.at(processors::SplitContent::Original);
const auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 2);
const auto expected_split_1 = createByteVector(1, 2, 3, 4);
const auto expected_split_2 = createByteVector(5, 5, 4, 3, 2, 1);
CHECK(controller.plan->getContentAsBytes(*splits[0]) == expected_split_1);
CHECK(controller.plan->getContentAsBytes(*splits[1]) == expected_split_2);
}
TEST_CASE("KeepingSequence", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "05050505"));
const auto input_data = createByteVector(1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 4, 3, 2, 1);
std::string_view input(reinterpret_cast<const char*>(input_data.data()), input_data.size());
auto trigger_results = controller.trigger(input);
const auto original = trigger_results.at(processors::SplitContent::Original);
const auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 2);
const auto expected_split_1 = createByteVector(1, 2, 3, 4, 5, 5, 5, 5);
const auto expected_split_2 = createByteVector(5, 5, 4, 3, 2, 1);
CHECK(controller.plan->getContentAsBytes(*splits[0]) == expected_split_1);
CHECK(controller.plan->getContentAsBytes(*splits[1]) == expected_split_2);
}
TEST_CASE("EndsWithSequence", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "false"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "05050505"));
const auto input_data = createByteVector(1, 2, 3, 4, 5, 5, 5, 5);
std::string_view input(reinterpret_cast<const char*>(input_data.data()), input_data.size());
auto trigger_results = controller.trigger(input);
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 1);
auto expected_split = createByteVector(1, 2, 3, 4);
CHECK(controller.plan->getContentAsBytes(*splits[0]) == expected_split);
}
TEST_CASE("EndsWithSequenceAndKeepSequence", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "05050505"));
const auto input_data = createByteVector(1, 2, 3, 4, 5, 5, 5, 5);
std::string_view input(reinterpret_cast<const char*>(input_data.data()), input_data.size());
auto trigger_results = controller.trigger(input);
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 1);
auto expected_split_1 = createByteVector(1, 2, 3, 4, 5, 5, 5, 5);
CHECK(controller.plan->getContentAsBytes(*splits[0]) == expected_split_1);
}
TEST_CASE("StartsWithSequence", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "false"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "05050505"));
const auto input_data = createByteVector(5, 5, 5, 5, 1, 2, 3, 4);
std::string_view input(reinterpret_cast<const char*>(input_data.data()), input_data.size());
auto trigger_results = controller.trigger(input);
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 1);
auto expected_split = createByteVector(1, 2, 3, 4);
CHECK(controller.plan->getContentAsBytes(*splits[0]) == expected_split);
}
TEST_CASE("StartsWithSequenceAndKeepTrailingSequence", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "05050505"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, "Trailing"));
const auto input_data = createByteVector(5, 5, 5, 5, 1, 2, 3, 4);
std::string_view input(reinterpret_cast<const char*>(input_data.data()), input_data.size());
auto trigger_results = controller.trigger(input);
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 2);
auto expected_split_1 = createByteVector(5, 5, 5, 5);
auto expected_split_2 = createByteVector(1, 2, 3, 4);
CHECK(controller.plan->getContentAsBytes(*splits[0]) == expected_split_1);
CHECK(controller.plan->getContentAsBytes(*splits[1]) == expected_split_2);
}
TEST_CASE("StartsWithSequenceAndKeepLeadingSequence") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "05050505"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, "Leading"));
const auto input_data = createByteVector(5, 5, 5, 5, 1, 2, 3, 4);
std::string_view input(reinterpret_cast<const char*>(input_data.data()), input_data.size());
auto trigger_results = controller.trigger(input);
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 1);
CHECK(controller.plan->getContentAsBytes(*splits[0]) == input_data);
}
TEST_CASE("StartsWithDoubleSequenceAndKeepLeadingSequence") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "05050505"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, "Leading"));
const auto input_data = createByteVector(5, 5, 5, 5, 5, 5, 5, 5, 1, 2, 3, 4);
std::string_view input(reinterpret_cast<const char*>(input_data.data()), input_data.size());
auto trigger_results = controller.trigger(input);
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
auto expected_split_1 = createByteVector(5, 5, 5, 5);
auto expected_split_2 = createByteVector(5, 5, 5, 5, 1, 2, 3, 4);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 2);
CHECK(controller.plan->getContentAsBytes(*splits[0]) == expected_split_1);
CHECK(controller.plan->getContentAsBytes(*splits[1]) == expected_split_2);
}
TEST_CASE("NoSplitterInString", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, ","));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "false"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceLocation::Trailing)}));
constexpr std::string_view input = "UVAT";
auto trigger_results = controller.trigger(input);
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(splits.size() == 1);
REQUIRE(original.size() == 1);
CHECK(splits[0]->getAttribute("fragment.identifier").has_value());
CHECK(splits[0]->getAttribute("segment.original.filename").has_value());
CHECK(splits[0]->getAttribute("fragment.count").value() == "1");
CHECK(splits[0]->getAttribute("fragment.index").value() == "1");
CHECK(controller.plan->getContent(splits[0]) == input);
CHECK(controller.plan->getContent(original[0]) == input);
}
TEST_CASE("ByteSequenceAtBufferTargetSize") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
static_assert(utils::configuration::DEFAULT_BUFFER_SIZE >= 10);
auto x = utils::configuration::DEFAULT_BUFFER_SIZE - 10;
auto [pre_fix_size, separator_size, post_fix_size] = GENERATE_COPY(
std::make_tuple(x, x, x),
std::make_tuple(10, 10, x),
std::make_tuple(10, x, 10),
std::make_tuple(10, 10, x),
std::make_tuple(10, x, x),
std::make_tuple(x, 10, x),
std::make_tuple(x, x, 10),
std::make_tuple(2*x, x, 10));
const std::string pre_fix = utils::string::repeat("a", pre_fix_size);
const std::string separator = utils::string::repeat("b", separator_size);
const std::string post_fix = utils::string::repeat("c", post_fix_size);
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, separator));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, "Trailing"));
auto input = pre_fix + separator + post_fix;
auto trigger_results = controller.trigger(input);
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(splits.size() == 2);
REQUIRE(original.size() == 1);
CHECK(controller.plan->getContent(splits[0]) == std::string(pre_fix) + std::string(separator));
CHECK(controller.plan->getContent(splits[1]) == post_fix);
CHECK(controller.plan->getContent(original[0]) == input);
}
TEST_CASE("TrickyWithLeading", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "aab"));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceLocation::Leading)}));
auto trigger_results = controller.trigger("aaabc");
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 2);
CHECK(controller.plan->getContent(original[0]) == "aaabc");
CHECK(controller.plan->getContent(splits[0]) == "a");
CHECK(controller.plan->getContent(splits[1]) == "aabc");
}
TEST_CASE("TrickyWithTrailing", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "aab"));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceLocation::Trailing)}));
auto trigger_results = controller.trigger("aaabc");
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 2);
CHECK(controller.plan->getContent(original[0]) == "aaabc");
CHECK(controller.plan->getContent(splits[0]) == "aaab");
CHECK(controller.plan->getContent(splits[1]) == "c");
}
TEST_CASE("TrickierWithLeading", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "abcd"));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceLocation::Leading)}));
auto trigger_results = controller.trigger("abcabcabcdabc");
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 2);
CHECK(controller.plan->getContent(original[0]) == "abcabcabcdabc");
CHECK(controller.plan->getContent(splits[0]) == "abcabc");
CHECK(controller.plan->getContent(splits[1]) == "abcdabc");
}
TEST_CASE("TrickierWithTrailing", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "abcd"));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceLocation::Trailing)}));
auto trigger_results = controller.trigger("abcabcabcdabc");
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 2);
CHECK(controller.plan->getContent(original[0]) == "abcabcabcdabc");
CHECK(controller.plan->getContent(splits[0]) == "abcabcabcd");
CHECK(controller.plan->getContent(splits[1]) == "abc");
}
TEST_CASE("OnlyByteSequencesNoKeep", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "ab"));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "false"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceLocation::Trailing)}));
auto trigger_results = controller.trigger("ababab");
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.empty());
}
TEST_CASE("OnlyByteSequencesTrailing", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "ab"));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceLocation::Trailing)}));
auto trigger_results = controller.trigger("ababab");
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 3);
CHECK(controller.plan->getContent(splits[0]) == "ab");
CHECK(controller.plan->getContent(splits[1]) == "ab");
CHECK(controller.plan->getContent(splits[2]) == "ab");
}
TEST_CASE("OnlyByteSequencesLeading", "[NiFi]") {
minifi::test::SingleProcessorTestController controller{minifi::test::utils::make_processor<SplitContent>("SplitContent")};
const auto split_content = controller.getProcessor();
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceFormatProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceFormat::Text)}));
REQUIRE(split_content->setProperty(SplitContent::ByteSequence.name, "ab"));
REQUIRE(split_content->setProperty(SplitContent::KeepByteSequence.name, "true"));
REQUIRE(split_content->setProperty(SplitContent::ByteSequenceLocationProperty.name, std::string{magic_enum::enum_name(SplitContent::ByteSequenceLocation::Leading)}));
auto trigger_results = controller.trigger("ababab");
auto original = trigger_results.at(processors::SplitContent::Original);
auto splits = trigger_results.at(processors::SplitContent::Splits);
REQUIRE(original.size() == 1);
REQUIRE(splits.size() == 3);
CHECK(controller.plan->getContent(splits[0]) == "ab");
CHECK(controller.plan->getContent(splits[1]) == "ab");
CHECK(controller.plan->getContent(splits[2]) == "ab");
}
} // namespace org::apache::nifi::minifi::processors::test