This is an automated email from the ASF dual-hosted git repository. martinzink pushed a commit to branch controller_c_api_requirements in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git
commit 85abf463c18c72c0b736fc24a6a2323fb6745985 Author: Adam Debreceni <[email protected]> AuthorDate: Mon Mar 2 14:03:04 2026 +0100 MINIFICPP-2715 - Add extension loading tests for version verification --- Extensions.md | 2 +- cmake/Extensions.cmake | 3 +- extensions/python/pythonloader/PyProcLoader.cpp | 2 +- libminifi/include/core/extension/ApiVersion.h | 37 +++++++++ libminifi/include/core/extension/Extension.h | 11 +-- libminifi/src/core/extension/ApiVersion.cpp | 33 ++++++++ libminifi/src/core/extension/Extension.cpp | 20 ++--- libminifi/test/integration/CMakeLists.txt | 2 + .../extension-verification-test/CApiExtension.cpp | 39 ++++++++++ .../extension-verification-test/CMakeLists.txt | 79 +++++++++++++++++++ .../CppApiExtension.cpp | 34 +++----- .../ExtensionVerificationTests.cpp | 90 ++++++++++++++++++++++ .../InvalidMissingInitExtension.cpp | 17 ++++ .../extension-verification-test/dummy-cpp-api.def | 3 + 14 files changed, 326 insertions(+), 46 deletions(-) diff --git a/Extensions.md b/Extensions.md index 0bfbd5bd9..159232f9a 100644 --- a/Extensions.md +++ b/Extensions.md @@ -82,7 +82,7 @@ extern "C" MinifiExtension* MinifiInitCppExtension(MinifiConfig* /*config*/) { .processors_count = 0, .processors_ptr = nullptr }; - return MinifiCreateCppExtension(&ext_create_info); + return minifi::utils::MinifiCreateCppExtension(&ext_create_info); } ``` diff --git a/cmake/Extensions.cmake b/cmake/Extensions.cmake index 6ea93f1cb..6e25d288b 100644 --- a/cmake/Extensions.cmake +++ b/cmake/Extensions.cmake @@ -31,8 +31,7 @@ macro(register_extension extension-name extension-display-name extension-guard d target_sources(${extension-name} PRIVATE ${CMAKE_SOURCE_DIR}/extensions/ExtensionInitializer.cpp) endif() target_compile_definitions(${extension-name} - PRIVATE "MODULE_NAME=${extension-name}" - PRIVATE "BUILD_ID_VARIABLE_NAME=${build-id-variable-name}") + PRIVATE "MODULE_NAME=${extension-name}") set_target_properties(${extension-name} PROPERTIES ENABLE_EXPORTS True POSITION_INDEPENDENT_CODE ON) diff --git a/extensions/python/pythonloader/PyProcLoader.cpp b/extensions/python/pythonloader/PyProcLoader.cpp index cd9cbb998..d4edf9cf2 100644 --- a/extensions/python/pythonloader/PyProcLoader.cpp +++ b/extensions/python/pythonloader/PyProcLoader.cpp @@ -49,5 +49,5 @@ extern "C" MinifiExtension* MinifiInitCppExtension(MinifiConfig* config) { .processors_count = 0, .processors_ptr = nullptr }; - return minifi::utils::MinifiCreateCppExtension( &ext_create_info); + return minifi::utils::MinifiCreateCppExtension(&ext_create_info); } diff --git a/libminifi/include/core/extension/ApiVersion.h b/libminifi/include/core/extension/ApiVersion.h new file mode 100644 index 000000000..01acb82cb --- /dev/null +++ b/libminifi/include/core/extension/ApiVersion.h @@ -0,0 +1,37 @@ +/** +* 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. + */ + +#pragma once + +#include <string> + +namespace org::apache::nifi::minifi::core::extension { + +struct ApiVersion { + int major; + int minor; + int patch; + + std::string str() const { + return std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(patch); + } +}; + +ApiVersion getAgentApiVersion(); +void setAgentApiVersion(ApiVersion api_version); + +} // namespace org::apache::nifi::minifi::core::extension diff --git a/libminifi/include/core/extension/Extension.h b/libminifi/include/core/extension/Extension.h index 2a71a6fbc..356efed4c 100644 --- a/libminifi/include/core/extension/Extension.h +++ b/libminifi/include/core/extension/Extension.h @@ -25,6 +25,7 @@ #include "minifi-c/minifi-c.h" #include "minifi-cpp/core/logging/Logger.h" #include "minifi-cpp/properties/Configure.h" +#include "ApiVersion.h" namespace org::apache::nifi::minifi::core::extension { @@ -39,12 +40,6 @@ class Extension { void* user_data; }; - struct Version { - int major{MINIFI_API_MAJOR_VERSION}; - int minor{MINIFI_API_MINOR_VERSION}; - int patch{MINIFI_API_PATCH_VERSION}; - }; - Extension(std::string name, std::filesystem::path library_path); Extension(const Extension&) = delete; @@ -56,7 +51,7 @@ class Extension { bool initialize(const std::shared_ptr<minifi::Configure>& configure); - Version version() const {return version_;} + [[nodiscard]] ApiVersion apiVersion() const {return api_version_;} private: #ifdef WIN32 @@ -80,7 +75,7 @@ class Extension { std::filesystem::path library_path_; gsl::owner<void*> handle_ = nullptr; - Version version_{}; + ApiVersion api_version_; std::unique_ptr<Info> info_; const std::shared_ptr<logging::Logger> logger_; diff --git a/libminifi/src/core/extension/ApiVersion.cpp b/libminifi/src/core/extension/ApiVersion.cpp new file mode 100644 index 000000000..1f515b25b --- /dev/null +++ b/libminifi/src/core/extension/ApiVersion.cpp @@ -0,0 +1,33 @@ +/** +* 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 "core/extension/ApiVersion.h" +#include "minifi-c/minifi-c.h" + +namespace org::apache::nifi::minifi::core::extension { + +static ApiVersion agent_api_version{.major = MINIFI_API_MAJOR_VERSION, .minor = MINIFI_API_MINOR_VERSION, .patch = MINIFI_API_PATCH_VERSION}; + +ApiVersion getAgentApiVersion() { + return agent_api_version; +} + +void setAgentApiVersion(ApiVersion api_version) { + agent_api_version = api_version; +} + +} // namespace org::apache::nifi::minifi::core::extension \ No newline at end of file diff --git a/libminifi/src/core/extension/Extension.cpp b/libminifi/src/core/extension/Extension.cpp index 35d0634b9..9073b6c9a 100644 --- a/libminifi/src/core/extension/Extension.cpp +++ b/libminifi/src/core/extension/Extension.cpp @@ -45,6 +45,7 @@ namespace org::apache::nifi::minifi::core::extension { Extension::Extension(std::string name, std::filesystem::path library_path) : name_(std::move(name)), library_path_(std::move(library_path)), + api_version_(getAgentApiVersion()), logger_(logging::LoggerFactory<Extension>::getLogger()) { } @@ -65,7 +66,7 @@ bool Extension::load(bool global) { return true; } if (!findSymbol("MinifiInitExtension")) { - logger_->log_error("Failed to load c extension '{}' at '{}': No initializer found", name_, library_path_); + logger_->log_error("Failed to load as c extension '{}' at '{}': No initializer found", name_, library_path_); return false; } auto api_version = reinterpret_cast<const char* const*>(findSymbol("MinifiApiVersion")); @@ -79,21 +80,21 @@ bool Extension::load(bool global) { return false; } gsl_Assert(match.size() == 4); - version_.major = std::stoi(match[1]); - version_.minor = std::stoi(match[2]); - version_.patch = std::stoi(match[3]); - if (version_.major != MINIFI_API_MAJOR_VERSION) { + api_version_.major = std::stoi(match[1]); + api_version_.minor = std::stoi(match[2]); + api_version_.patch = std::stoi(match[3]); + if (api_version_.major != getAgentApiVersion().major) { logger_->log_error("Failed to load c extension '{}' at '{}': Api major version mismatch, application is '{}' while extension is '{}'", - name_, library_path_, MINIFI_API_VERSION, *api_version); + name_, library_path_, getAgentApiVersion().str(), *api_version); return false; } - if (version_.minor > MINIFI_API_MINOR_VERSION) { + if (api_version_.minor > getAgentApiVersion().minor) { logger_->log_error("Failed to load c extension '{}' at '{}': Extension is built for a newer version, application is '{}' while extension is '{}'", - name_, library_path_, MINIFI_API_VERSION, *api_version); + name_, library_path_, getAgentApiVersion().str(), *api_version); return false; } logger_->log_debug("Loaded c extension '{}' at '{}': Application version is '{}', extension version is '{}'", - name_, library_path_, MINIFI_API_VERSION, *api_version); + name_, library_path_, getAgentApiVersion().str(), *api_version); return true; } @@ -163,6 +164,7 @@ bool Extension::initialize(const std::shared_ptr<minifi::Configure>& configure) logger_->log_error("Failed to initialize extension '{}'", name_); return false; } + logger_->log_debug("Initialized extension '{}'", name_); return true; } diff --git a/libminifi/test/integration/CMakeLists.txt b/libminifi/test/integration/CMakeLists.txt index 3fb3fd88a..44e98f76a 100644 --- a/libminifi/test/integration/CMakeLists.txt +++ b/libminifi/test/integration/CMakeLists.txt @@ -45,3 +45,5 @@ ENDFOREACH() target_link_libraries(OnScheduleErrorHandlingTests minifi-test-processors) message("-- Finished building ${INT_TEST_COUNT} integration test file(s)...") + +add_subdirectory(extension-verification-test) diff --git a/libminifi/test/integration/extension-verification-test/CApiExtension.cpp b/libminifi/test/integration/extension-verification-test/CApiExtension.cpp new file mode 100644 index 000000000..e6fd7cfbc --- /dev/null +++ b/libminifi/test/integration/extension-verification-test/CApiExtension.cpp @@ -0,0 +1,39 @@ +/** +* + * 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 "api/core/Resource.h" +#include "api/utils/minifi-c-utils.h" + +#define MKSOC(x) #x +#define MAKESTRING(x) MKSOC(x) // NOLINT(cppcoreguidelines-macro-usage) + +namespace minifi = org::apache::nifi::minifi; + +extern "C" const char* const MinifiApiVersion = MINIFI_TEST_API_VERSION; + +extern "C" MinifiExtension* MinifiInitExtension(MinifiConfig* /*config*/) { + MinifiExtensionCreateInfo ext_create_info{ + .name = minifi::api::utils::toStringView(MAKESTRING(EXTENSION_NAME)), + .version = minifi::api::utils::toStringView(MAKESTRING(EXTENSION_VERSION)), + .deinit = nullptr, + .user_data = nullptr, + .processors_count = 0, + .processors_ptr = nullptr, + }; + return MinifiCreateExtension(&ext_create_info); +} \ No newline at end of file diff --git a/libminifi/test/integration/extension-verification-test/CMakeLists.txt b/libminifi/test/integration/extension-verification-test/CMakeLists.txt new file mode 100644 index 000000000..32c068106 --- /dev/null +++ b/libminifi/test/integration/extension-verification-test/CMakeLists.txt @@ -0,0 +1,79 @@ +# 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. +# + +add_minifi_executable(ExtensionVerificationTests ExtensionVerificationTests.cpp) +createIntegrationTests(ExtensionVerificationTests) +target_link_libraries(${testfilename} core-minifi Catch2WithMain Threads::Threads) +add_test(NAME ExtensionVerificationTests COMMAND ExtensionVerificationTests) + +function(create_loading_test_extension extension-name extension-main) + add_library(${extension-name} SHARED ${extension-main}) + add_dependencies(ExtensionVerificationTests ${extension-name}) + target_compile_definitions(${extension-name} PRIVATE MODULE_NAME=${extension-name}) + set_target_properties(${extension-name} PROPERTIES ENABLE_EXPORTS True POSITION_INDEPENDENT_CODE ON) + if(WIN32) + set_target_properties(${extension-name} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" + WINDOWS_EXPORT_ALL_SYMBOLS TRUE) + else() + set_target_properties(${extension-name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") + endif() +endfunction() + +function(create_c_test_extension extension-name custom_api_version) + set(extension-name "test-extension-loading-${extension-name}") + create_loading_test_extension(${extension-name} CApiExtension.cpp) + target_link_libraries(${extension-name} minifi-cpp-extension-lib) + target_compile_definitions(${extension-name} PRIVATE MINIFI_TEST_API_VERSION="${custom_api_version}") + target_compile_definitions(${extension-name} + PRIVATE "EXTENSION_NAME=${extension-name}" "EXTENSION_VERSION=${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") +endfunction() + +add_library(dummy-core-minifi INTERFACE) +target_include_directories(dummy-core-minifi INTERFACE $<TARGET_PROPERTY:minifi-extension-framework,INTERFACE_INCLUDE_DIRECTORIES>) +if (WIN32) + set(DUMMY_IMPORT_LIB_FILE ${CMAKE_CURRENT_BINARY_DIR}/dummy-cpp-api.lib) + add_custom_target(dummy_cpp_api_import_lib + COMMAND lib.exe /def:${CMAKE_CURRENT_SOURCE_DIR}/dummy-cpp-api.def /out:${IMPORT_LIB_FILE} /machine:x64 + BYPRODUCTS ${IMPORT_LIB_FILE} + ) + + add_dependencies(dummy-core-minifi dummy_cpp_api_import_lib) + target_link_libraries(dummy-core-minifi INTERFACE ${IMPORT_LIB_FILE}) +elseif (APPLE) + target_link_options(dummy-core-minifi INTERFACE -undefined dynamic_lookup) +endif() + +create_loading_test_extension(test-extension-loading-invalid-build-id-cpp CppApiExtension.cpp) +target_link_libraries(test-extension-loading-invalid-build-id-cpp dummy-core-minifi) +target_compile_definitions(test-extension-loading-invalid-build-id-cpp PRIVATE MINIFI_CREATE_EXTENSION_FN=MinifiCreateCppExtension_NonMatchingBuildId) + +create_loading_test_extension(test-extension-loading-valid-build-id-cpp CppApiExtension.cpp) +target_link_libraries(test-extension-loading-valid-build-id-cpp dummy-core-minifi) +target_compile_definitions(test-extension-loading-valid-build-id-cpp PRIVATE MINIFI_CREATE_EXTENSION_FN=MinifiCreateCppExtension_${BUILD_IDENTIFIER}) + +create_c_test_extension(same-version "1.1.1") +create_c_test_extension(greater-major-version "2.0.0") +create_c_test_extension(smaller-major-version "0.1.0") +create_c_test_extension(greater-minor-version "1.2.0") +create_c_test_extension(smaller-minor-version "1.0.1") +create_c_test_extension(greater-patch-version "1.1.2") +create_c_test_extension(smaller-patch-version "1.1.0") +create_loading_test_extension(test-extension-loading-missing-init InvalidMissingInitExtension.cpp) diff --git a/extensions/python/pythonloader/PyProcLoader.cpp b/libminifi/test/integration/extension-verification-test/CppApiExtension.cpp similarity index 53% copy from extensions/python/pythonloader/PyProcLoader.cpp copy to libminifi/test/integration/extension-verification-test/CppApiExtension.cpp index cd9cbb998..0503a8c17 100644 --- a/extensions/python/pythonloader/PyProcLoader.cpp +++ b/libminifi/test/integration/extension-verification-test/CppApiExtension.cpp @@ -1,5 +1,5 @@ /** - * +* * 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. @@ -15,39 +15,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "minifi-c/minifi-c.h" -#include "utils/ExtensionInitUtils.h" -#include "PythonCreator.h" -#include "minifi-cpp/agent/agent_version.h" -#include "PythonBindings.h" -#include "core/Resource.h" -namespace minifi = org::apache::nifi::minifi; +#include <string_view> +#include "utils/ExtensionInitUtils.h" -static minifi::extensions::python::PythonCreator& getPythonCreator() { - static minifi::extensions::python::PythonCreator instance("PythonCreator"); - return instance; -} +#define MKSOC(x) #x +#define MAKESTRING(x) MKSOC(x) // NOLINT(cppcoreguidelines-macro-usage) -// request this module (shared library) to be opened into the global namespace, exposing -// the symbols of the python library -extern "C" const int LOAD_MODULE_AS_GLOBAL = 1; +namespace minifi = org::apache::nifi::minifi; -extern "C" MinifiExtension* MinifiInitCppExtension(MinifiConfig* config) { - getPythonCreator().configure([&] (std::string_view key) -> std::optional<std::string> { - std::optional<std::string> result; - MinifiConfigGet(config, minifi::utils::toStringView(key), [] (void* user_data, MinifiStringView value) { - *static_cast<std::optional<std::string>*>(user_data) = std::string{value.data, value.length}; - }, &result); - return result; - }); +extern "C" MinifiExtension* MinifiInitCppExtension(MinifiConfig* /*config*/) { MinifiExtensionCreateInfo ext_create_info{ .name = minifi::utils::toStringView(MAKESTRING(MODULE_NAME)), - .version = minifi::utils::toStringView(minifi::AgentBuild::VERSION), + .version = minifi::utils::toStringView("1.0.0"), .deinit = nullptr, .user_data = nullptr, .processors_count = 0, .processors_ptr = nullptr }; - return minifi::utils::MinifiCreateCppExtension( &ext_create_info); + return minifi::utils::MinifiCreateCppExtension(&ext_create_info); } diff --git a/libminifi/test/integration/extension-verification-test/ExtensionVerificationTests.cpp b/libminifi/test/integration/extension-verification-test/ExtensionVerificationTests.cpp new file mode 100644 index 000000000..6fa304691 --- /dev/null +++ b/libminifi/test/integration/extension-verification-test/ExtensionVerificationTests.cpp @@ -0,0 +1,90 @@ +/** +* + * 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. + */ + +#define CUSTOM_EXTENSION_INIT + +#include "unit/TestBase.h" +#include "unit/Catch.h" +#include "unit/TestUtils.h" +#include "core/extension/ExtensionManager.h" +#include "core/extension/ApiVersion.h" + +namespace minifi = org::apache::nifi::minifi; + +class ExtensionLoadingTestController { + public: + ExtensionLoadingTestController(std::string pattern): extension_manager_{[&] () { + LogTestController::getInstance().clear(); + LogTestController::getInstance().setTrace<core::extension::ExtensionManager>(); + LogTestController::getInstance().setTrace<core::extension::Extension>(); + minifi::core::extension::setAgentApiVersion({.major = 1, .minor = 1, .patch = 1}); + auto config = minifi::Configure::create(); + config->set(minifi::Configuration::nifi_extension_path, pattern); + return config; + }()} {} + + core::extension::ExtensionManager extension_manager_; +}; + +TEST_CASE("Can load cpp-api extensions with same build id") { + ExtensionLoadingTestController controller{"*test-extension-loading-valid-build-id-cpp*"}; + REQUIRE(minifi::test::utils::verifyLogLinePresenceInPollTime(0s, "Loaded cpp extension 'test-extension-loading-valid-build-id-cpp'")); +} + +TEST_CASE("Can load c-api extensions with same version") { + ExtensionLoadingTestController controller{"*test-extension-loading-same-version*"}; + REQUIRE(minifi::test::utils::verifyLogLinePresenceInPollTime(0s, "Loaded c extension 'test-extension-loading-same-version'")); +} + +TEST_CASE("Can't load cpp-api extensions with different build id") { + ExtensionLoadingTestController controller{"*test-extension-loading-invalid-build-id-cpp*"}; + REQUIRE(minifi::test::utils::verifyLogLinePresenceInPollTime(0s, "Failed to load extension 'test-extension-loading-invalid-build-id-cpp'")); +} + +TEST_CASE("Can't load c-api extensions with greater major version") { + ExtensionLoadingTestController controller{"*test-extension-loading-greater-major-version*"}; + REQUIRE(minifi::test::utils::verifyLogLinePresenceInPollTime(0s, "Failed to load c extension 'test-extension-loading-greater-major-version'")); + REQUIRE(minifi::test::utils::verifyLogLinePresenceInPollTime(0s, "Api major version mismatch, application is '1.1.1' while extension is '2.0.0'")); +} + +TEST_CASE("Can't load c-api extensions with smaller major version") { + ExtensionLoadingTestController controller{"*test-extension-loading-smaller-major-version*"}; + REQUIRE(minifi::test::utils::verifyLogLinePresenceInPollTime(0s, "Failed to load c extension 'test-extension-loading-smaller-major-version'")); + REQUIRE(minifi::test::utils::verifyLogLinePresenceInPollTime(0s, "Api major version mismatch, application is '1.1.1' while extension is '0.1.0'")); +} + +TEST_CASE("Can't load c-api extensions with greater minor version") { + ExtensionLoadingTestController controller{"*test-extension-loading-greater-minor-version*"}; + REQUIRE(minifi::test::utils::verifyLogLinePresenceInPollTime(0s, "Failed to load c extension 'test-extension-loading-greater-minor-version'")); + REQUIRE(minifi::test::utils::verifyLogLinePresenceInPollTime(0s, "Extension is built for a newer version")); +} + +TEST_CASE("Can load c-api extensions with smaller minor version") { + ExtensionLoadingTestController controller{"*test-extension-loading-smaller-minor-version*"}; + REQUIRE(minifi::test::utils::verifyLogLinePresenceInPollTime(0s, "Loaded c extension 'test-extension-loading-smaller-minor-version'")); +} + +TEST_CASE("Can load c-api extensions with greater patch version") { + ExtensionLoadingTestController controller{"*test-extension-loading-greater-patch-version*"}; + REQUIRE(minifi::test::utils::verifyLogLinePresenceInPollTime(0s, "Loaded c extension 'test-extension-loading-greater-patch-version'")); +} + +TEST_CASE("Can load c-api extensions with smaller patch version") { + ExtensionLoadingTestController controller{"*test-extension-loading-smaller-patch-version*"}; + REQUIRE(minifi::test::utils::verifyLogLinePresenceInPollTime(0s, "Loaded c extension 'test-extension-loading-smaller-patch-version'")); +} diff --git a/libminifi/test/integration/extension-verification-test/InvalidMissingInitExtension.cpp b/libminifi/test/integration/extension-verification-test/InvalidMissingInitExtension.cpp new file mode 100644 index 000000000..3fbb5023e --- /dev/null +++ b/libminifi/test/integration/extension-verification-test/InvalidMissingInitExtension.cpp @@ -0,0 +1,17 @@ +/** +* + * 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. + */ \ No newline at end of file diff --git a/libminifi/test/integration/extension-verification-test/dummy-cpp-api.def b/libminifi/test/integration/extension-verification-test/dummy-cpp-api.def new file mode 100644 index 000000000..8da19c75e --- /dev/null +++ b/libminifi/test/integration/extension-verification-test/dummy-cpp-api.def @@ -0,0 +1,3 @@ +LIBRARY core-minifi.dll +EXPORTS + MinifiCreateCppExtension_NonMatchingBuildId
