blob: 88eb38ab3c2dab598dd1b6bea448edf89db4a94c [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 "ConsumeWindowsEventLog.h"
#include "core/ConfigurableComponent.h"
#include "processors/LogAttribute.h"
#include "processors/PutFile.h"
#include "unit/TestBase.h"
#include "unit/Catch.h"
#include "unit/TestUtils.h"
#include "utils/file/FileUtils.h"
#include "wel/UniqueEvtHandle.h"
#include "rapidjson/document.h"
#include "CWELTestUtils.h"
// generated from the manifest file "custom-provider/unit-test-provider.man"
// using the command "mc -um unit-test-provider.man"
#include "custom-provider/unit-test-provider.h"
namespace org::apache::nifi::minifi::test {
namespace {
struct CustomEventData {
std::wstring first;
std::wstring second;
std::wstring third;
int binary_length;
const unsigned char* binary_data;
};
const std::string CUSTOM_PROVIDER_NAME = "minifi_unit_test_provider";
const std::string CUSTOM_CHANNEL = CUSTOM_PROVIDER_NAME + "/Log";
bool dispatchCustomEvent(const CustomEventData& event) {
static auto provider_initialized = EventRegisterminifi_unit_test_provider();
REQUIRE(provider_initialized == ERROR_SUCCESS);
auto result = EventWriteCustomEvent(
event.first.c_str(),
event.second.c_str(),
event.third.c_str(),
event.binary_length,
event.binary_data);
return result == ERROR_SUCCESS;
}
using org::apache::nifi::minifi::wel::unique_evt_handle;
bool advanceBookmark(const unique_evt_handle& hBookmark, const std::string& channel, const std::string& query, bool advance_to_last = false) {
const auto hEventResults = unique_evt_handle{ EvtQuery(0, std::wstring{channel.begin(), channel.end()}.c_str(), std::wstring{query.begin(), query.end()}.c_str(), EvtQueryChannelPath) };
if (!hEventResults) {
return false;
}
if (advance_to_last) {
if (!EvtSeek(hEventResults.get(), 0, 0, 0, EvtSeekRelativeToLast)) {
return false;
}
} else {
if (!EvtSeek(hEventResults.get(), 1, hBookmark.get(), 0, EvtSeekRelativeToBookmark)) {
return false;
}
}
const unique_evt_handle hEvent = [&hEventResults] {
DWORD dwReturned{};
EVT_HANDLE hEvent{ nullptr };
EvtNext(hEventResults.get(), 1, &hEvent, INFINITE, 0, &dwReturned);
return unique_evt_handle{ hEvent };
}();
if (!hEvent) {
return false;
}
REQUIRE(EvtUpdateBookmark(hBookmark.get(), hEvent.get()));
return true;
}
class CustomProviderController : public OutputFormatTestController {
public:
CustomProviderController(std::string format, std::string json_format) : OutputFormatTestController(CUSTOM_CHANNEL, "*", std::move(format), std::move(json_format)) {
bookmark_.reset(EvtCreateBookmark(0));
advanceBookmark(bookmark_, channel_, query_, true);
REQUIRE(bookmark_);
}
protected:
void dispatchBookmarkEvent() override {
auto binary = reinterpret_cast<const unsigned char*>("\x0c\x10");
REQUIRE(dispatchCustomEvent({L"Bookmark", L"Second", L"Third", 2, binary}));
REQUIRE(checkNewEventAvailable());
}
void dispatchCollectedEvent() override {
auto binary = reinterpret_cast<const unsigned char*>("\x09\x01");
REQUIRE(dispatchCustomEvent({L"Actual event", L"Second", L"Third", 2, binary}));
REQUIRE(checkNewEventAvailable());
}
private:
bool checkNewEventAvailable() {
return org::apache::nifi::utils::verifyEventHappenedInPollTime(std::chrono::seconds{5}, [&] {
return advanceBookmark(bookmark_, channel_, query_);
});
}
unique_evt_handle bookmark_;
};
const std::string EVENT_DATA_JSON = R"(
[{
"Type": "Data",
"Content": "Actual event",
"Name": "param1"
}, {
"Type": "Data",
"Content": "Second",
"Name": "param2"
}, {
"Type": "Data",
"Content": "Third",
"Name": "Channel"
}, {
"Type": "Binary",
"Content": "0901",
"Name": ""
}]
)";
} // namespace
TEST_CASE("ConsumeWindowsEventLog prints events in JSON::Simple correctly custom provider", "[onTrigger]") {
std::string event = CustomProviderController{"JSON", "Simple"}.run();
utils::verifyJSON(event, R"(
{
"System": {
"Provider": {
"Name": ")" + CUSTOM_PROVIDER_NAME + R"("
},
"Channel": ")" + CUSTOM_CHANNEL + R"("
},
"EventData": )" + EVENT_DATA_JSON + R"(
}
)");
}
TEST_CASE("ConsumeWindowsEventLog prints events in JSON::Flattened correctly custom provider", "[onTrigger]") {
std::string event = CustomProviderController{"JSON", "Flattened"}.run();
utils::verifyJSON(event, R"(
{
"Name": ")" + CUSTOM_PROVIDER_NAME + R"(",
"Channel": ")" + CUSTOM_CHANNEL /* Channel is not overwritten by data named "Channel" */ + R"(",
"EventData.param1": "Actual event",
"EventData.param2": "Second",
"EventData.Channel": "Third",
"EventData": "0901"
}
)");
}
} // namespace org::apache::nifi::minifi::test