From ce1a3eeb386c9cb57b7bfa582fbe264b92c3310a Mon Sep 17 00:00:00 2001 From: soumyaduriseti Date: Thu, 12 Sep 2024 01:35:53 -0700 Subject: [PATCH] dylib library changes + tests --- .../presto_cpp/main/CMakeLists.txt | 7 ++- .../presto_cpp/main/PrestoServer.cpp | 29 +++++++++- .../presto_cpp/main/PrestoServer.h | 2 + .../presto_cpp/main/common/Configs.cpp | 5 ++ .../presto_cpp/main/common/Configs.h | 4 ++ .../presto_cpp/main/functions/CMakeLists.txt | 13 +++++ .../main/functions/DynamicLibraryLoader.cpp | 45 +++++++++++++++ .../main/functions/DynamicLibraryLoader.h | 37 ++++++++++++ .../presto_cpp/main/functions/README.md | 23 ++++++++ .../RemoteFunctionRegisterer.cpp | 2 +- .../RemoteFunctionRegisterer.h | 0 .../main/functions/tests/CMakeLists.txt | 27 +++++++++ .../main/functions/tests/DynamicLinkTest.cpp | 57 +++++++++++++++++++ .../functions/tests/MyDynamicTestFunction.cpp | 46 +++++++++++++++ .../tests/RemoteFunctionRegistererTest.cpp | 2 +- .../nativeworker/ContainerQueryRunner.java | 1 + .../ContainerQueryRunnerUtils.java | 2 + .../TestPrestoNativeDynamicLibrary.java | 42 ++++++++++++++ 18 files changed, 338 insertions(+), 6 deletions(-) create mode 100644 presto-native-execution/presto_cpp/main/functions/CMakeLists.txt create mode 100644 presto-native-execution/presto_cpp/main/functions/DynamicLibraryLoader.cpp create mode 100644 presto-native-execution/presto_cpp/main/functions/DynamicLibraryLoader.h create mode 100644 presto-native-execution/presto_cpp/main/functions/README.md rename presto-native-execution/presto_cpp/main/{ => functions}/RemoteFunctionRegisterer.cpp (98%) rename presto-native-execution/presto_cpp/main/{ => functions}/RemoteFunctionRegisterer.h (100%) create mode 100644 presto-native-execution/presto_cpp/main/functions/tests/CMakeLists.txt create mode 100644 presto-native-execution/presto_cpp/main/functions/tests/DynamicLinkTest.cpp create mode 100644 presto-native-execution/presto_cpp/main/functions/tests/MyDynamicTestFunction.cpp rename presto-native-execution/presto_cpp/main/{ => functions}/tests/RemoteFunctionRegistererTest.cpp (98%) create mode 100644 presto-native-execution/src/test/java/com/facebook/presto/nativeworker/TestPrestoNativeDynamicLibrary.java diff --git a/presto-native-execution/presto_cpp/main/CMakeLists.txt b/presto-native-execution/presto_cpp/main/CMakeLists.txt index 14d288ebca64..7ea78506be9a 100644 --- a/presto-native-execution/presto_cpp/main/CMakeLists.txt +++ b/presto-native-execution/presto_cpp/main/CMakeLists.txt @@ -11,6 +11,7 @@ # limitations under the License. add_subdirectory(operators) add_subdirectory(types) +add_subdirectory(functions) add_subdirectory(http) add_subdirectory(common) add_subdirectory(thrift) @@ -74,7 +75,8 @@ target_link_libraries( ${FOLLY_WITH_DEPENDENCIES} ${GLOG} ${GFLAGS_LIBRARIES} - pthread) + pthread + presto_dynamic_function_loader) # Enabling Parquet causes build errors with missing symbols on MacOS. This is # likely due to a conflict between Arrow Thrift from velox_hive_connector and @@ -96,8 +98,7 @@ target_link_libraries(presto_server presto_server_lib velox_hive_connector velox_tpch_connector) if(PRESTO_ENABLE_REMOTE_FUNCTIONS) - add_library(presto_server_remote_function JsonSignatureParser.cpp - RemoteFunctionRegisterer.cpp) + add_library(presto_server_remote_function JsonSignatureParser.cpp) target_link_libraries(presto_server_remote_function velox_expression velox_functions_remote ${FOLLY_WITH_DEPENDENCIES}) diff --git a/presto-native-execution/presto_cpp/main/PrestoServer.cpp b/presto-native-execution/presto_cpp/main/PrestoServer.cpp index 5ee52935cc22..fd3616e1bb5d 100644 --- a/presto-native-execution/presto_cpp/main/PrestoServer.cpp +++ b/presto-native-execution/presto_cpp/main/PrestoServer.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "CoordinatorDiscoverer.h" #include "presto_cpp/main/Announcer.h" #include "presto_cpp/main/PeriodicTaskManager.h" @@ -25,6 +26,7 @@ #include "presto_cpp/main/common/ConfigReader.h" #include "presto_cpp/main/common/Counters.h" #include "presto_cpp/main/common/Utils.h" +#include "presto_cpp/main/functions/DynamicLibraryLoader.h" #include "presto_cpp/main/http/filters/AccessLogFilter.h" #include "presto_cpp/main/http/filters/HttpEndpointLatencyFilter.h" #include "presto_cpp/main/http/filters/InternalAuthenticationFilter.h" @@ -62,7 +64,7 @@ #include "velox/serializers/PrestoSerializer.h" #ifdef PRESTO_ENABLE_REMOTE_FUNCTIONS -#include "presto_cpp/main/RemoteFunctionRegisterer.h" +#include "presto_cpp/main/functions/RemoteFunctionRegisterer.h" #endif #ifdef __linux__ @@ -403,6 +405,8 @@ void PrestoServer::run() { registerRemoteFunctions(); registerVectorSerdes(); registerPrestoPlanNodeSerDe(); + PRESTO_STARTUP_LOG(INFO) << "heeere 1111!!!"; + registerDynamicFunctions(); const auto numExchangeHttpClientIoThreads = std::max( systemConfig->exchangeHttpClientNumIoThreadsHwMultiplier() * @@ -1444,5 +1448,28 @@ protocol::NodeStatus PrestoServer::fetchNodeStatus() { return nodeStatus; } +void PrestoServer::registerDynamicFunctions() { + auto systemConfig = SystemConfig::instance(); + PRESTO_STARTUP_LOG(INFO) << "heeere!!!"; + if (!systemConfig->pluginDir().empty()) { + // if it's a valid directory, traverse and call dynamic function loader on + // it + const fs::path path(systemConfig->pluginDir()); + PRESTO_STARTUP_LOG(INFO) << path; + std::error_code + ec; // For using the non-throwing overloads of functions below. + if (fs::is_directory(path, ec)) { + using recursive_directory_iterator = + std::filesystem::recursive_directory_iterator; + for (const auto& dirEntry : recursive_directory_iterator(path)) { + if (!fs::is_directory(dirEntry, ec)) { + loadDynamicLibraryFunctions(dirEntry.path().c_str()); + std::cout << "LOADED DYLLIB 2" << std::endl; + PRESTO_STARTUP_LOG(INFO) << "LOADED DYLLIB 2"; + } + } + } + } +} } // namespace facebook::presto diff --git a/presto-native-execution/presto_cpp/main/PrestoServer.h b/presto-native-execution/presto_cpp/main/PrestoServer.h index bee2d8d43391..92f95d4bfe2c 100644 --- a/presto-native-execution/presto_cpp/main/PrestoServer.h +++ b/presto-native-execution/presto_cpp/main/PrestoServer.h @@ -186,6 +186,8 @@ class PrestoServer { VeloxPlanValidator* getVeloxPlanValidator(); + virtual void registerDynamicFunctions(); + /// Invoked to get the list of filters passed to the http server. std::vector> getHttpServerFilters(); diff --git a/presto-native-execution/presto_cpp/main/common/Configs.cpp b/presto-native-execution/presto_cpp/main/common/Configs.cpp index 35c068009e55..ca0c6e0bdaa0 100644 --- a/presto-native-execution/presto_cpp/main/common/Configs.cpp +++ b/presto-native-execution/presto_cpp/main/common/Configs.cpp @@ -233,6 +233,7 @@ SystemConfig::SystemConfig() { STR_PROP(kCacheVeloxTtlCheckInterval, "1h"), BOOL_PROP(kEnableRuntimeMetricsCollection, false), BOOL_PROP(kPlanValidatorFailOnNestedLoopJoin, false), + STR_PROP(kPluginDir, ""), }; } @@ -734,6 +735,10 @@ bool SystemConfig::enableRuntimeMetricsCollection() const { return optionalProperty(kEnableRuntimeMetricsCollection).value(); } +std::string SystemConfig::pluginDir() const { + return optionalProperty(kPluginDir).value(); +} + NodeConfig::NodeConfig() { registeredProps_ = std::unordered_map>{ diff --git a/presto-native-execution/presto_cpp/main/common/Configs.h b/presto-native-execution/presto_cpp/main/common/Configs.h index b088fdc65cf2..2933d3d497eb 100644 --- a/presto-native-execution/presto_cpp/main/common/Configs.h +++ b/presto-native-execution/presto_cpp/main/common/Configs.h @@ -617,6 +617,8 @@ class SystemConfig : public ConfigBase { static constexpr std::string_view kInternalCommunicationJwtExpirationSeconds{ "internal-communication.jwt.expiration-seconds"}; + /// Optional string containing the path to the plugin directory + static constexpr std::string_view kPluginDir{"plugin.dir"}; /// Below are the Presto properties from config.properties that get converted /// to their velox counterparts in BaseVeloxQueryConfig and used solely from /// BaseVeloxQueryConfig. @@ -856,6 +858,8 @@ class SystemConfig : public ConfigBase { bool enableRuntimeMetricsCollection() const; bool prestoNativeSidecar() const; + + std::string pluginDir() const; }; /// Provides access to node properties defined in node.properties file. diff --git a/presto-native-execution/presto_cpp/main/functions/CMakeLists.txt b/presto-native-execution/presto_cpp/main/functions/CMakeLists.txt new file mode 100644 index 000000000000..57b85814e822 --- /dev/null +++ b/presto-native-execution/presto_cpp/main/functions/CMakeLists.txt @@ -0,0 +1,13 @@ +add_library(presto_dynamic_function_loader OBJECT DynamicLibraryLoader.cpp) + +if(PRESTO_ENABLE_TESTING) + add_subdirectory(tests) +endif() + +if(PRESTO_ENABLE_REMOTE_FUNCTIONS) + add_library(presto_server_remote_function RemoteFunctionRegisterer.cpp) + + target_link_libraries(presto_server_remote_function velox_expression + velox_functions_remote ${FOLLY_WITH_DEPENDENCIES}) + target_link_libraries(presto_server_lib presto_server_remote_function) +endif() diff --git a/presto-native-execution/presto_cpp/main/functions/DynamicLibraryLoader.cpp b/presto-native-execution/presto_cpp/main/functions/DynamicLibraryLoader.cpp new file mode 100644 index 000000000000..ca679089cc0a --- /dev/null +++ b/presto-native-execution/presto_cpp/main/functions/DynamicLibraryLoader.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * 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. + */ + +#include "presto_cpp/main/functions/DynamicLibraryLoader.h" +#include +#include +#include "velox/common/base/Exceptions.h" +namespace facebook::presto { + +static constexpr const char* kSymbolName = "registry"; + +void loadDynamicLibraryFunctions(const char* fileName) { + // Try to dynamically load the shared library. + void* handler = dlopen(fileName, RTLD_NOW); + + if (handler == nullptr) { + VELOX_USER_FAIL("Error while loading shared library: {}", dlerror()); + } + + // Lookup the symbol. + void* registrySymbol = dlsym(handler, kSymbolName); + auto registryFunction = reinterpret_cast(registrySymbol); + char* error = dlerror(); + + if (error != nullptr) { + VELOX_USER_FAIL("Couldn't find Velox registry symbol: {}", error); + } + registryFunction(); + std::cout << "LOADED DYLLIB 1" << std::endl; +} + +} // namespace facebook::presto diff --git a/presto-native-execution/presto_cpp/main/functions/DynamicLibraryLoader.h b/presto-native-execution/presto_cpp/main/functions/DynamicLibraryLoader.h new file mode 100644 index 000000000000..ab52c0ce4f8a --- /dev/null +++ b/presto-native-execution/presto_cpp/main/functions/DynamicLibraryLoader.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * 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. + */ + +#pragma once + +namespace facebook::presto { + +/// Dynamically opens and registers functions defined in a shared library (.so) +/// +/// Given a shared library name (.so), this function will open it using dlopen, +/// search for a "void registry()" C function containing the registration code +/// for the functions defined in library, and execute it. +/// +/// The library being linked needs to provide a function with the following +/// signature: +/// +/// void registry(); +/// +/// The registration function needs to be defined in the top-level namespace, +/// and be enclosed by a extern "C" directive to prevent the compiler from +/// mangling the symbol name. +void loadDynamicLibraryFunctions(const char* fileName); + +} // namespace facebook::presto diff --git a/presto-native-execution/presto_cpp/main/functions/README.md b/presto-native-execution/presto_cpp/main/functions/README.md new file mode 100644 index 000000000000..11059cab57f2 --- /dev/null +++ b/presto-native-execution/presto_cpp/main/functions/README.md @@ -0,0 +1,23 @@ +# Prestissimo: Dynamically Loading Function Library + +This library adds the ability to load User Defined Functions (UDFs) without having to fork and build Prestissimo through the use of shared libraries. The Prestissimo worker is to access said code. The dynamic functions are to be loaded upon running an instance of the presto server. In the presto server instance, it will search for any .so or .dylib files and load them using this library. + +## Getting started + +The Process can be roughly broken down into the steps below: +### 1. Create a cpp file for your dynamic library +For dynamically loaded function registration, the format followed is mirrored of that of built-in function registration with some noted differences. For instance, the below example function uses the extern "C" keyword to protect against name mangling. Additionally, a registry() function call is also necessary here. + +### 2. Register functions dynamically by creating .dylib or .so shared libraries and dropping them in a plugin directory. +These shared libraries may be made using CMakeLists like the following: +``` +add_library(name_of_dynamic_fn SHARED TestFunction.cpp) +target_link_libraries(name_of_dynamic_fn PRIVATE xsimd fmt::fmt velox_expression) +``` + +### 3. In the prestissimo worker's config.properties file, set the plugin.dir property +This is where you will be dropping your shared library. +``` +plugin.dir="User\Test\Path\plugin" +``` +### 4. Upon start of the Presto Server, this directory will be scanned and all shared libraries will be attempted to be dynamically loaded when the worker or the sidecar process starts. \ No newline at end of file diff --git a/presto-native-execution/presto_cpp/main/RemoteFunctionRegisterer.cpp b/presto-native-execution/presto_cpp/main/functions/RemoteFunctionRegisterer.cpp similarity index 98% rename from presto-native-execution/presto_cpp/main/RemoteFunctionRegisterer.cpp rename to presto-native-execution/presto_cpp/main/functions/RemoteFunctionRegisterer.cpp index 1c8aa30b0bac..22f506d66295 100644 --- a/presto-native-execution/presto_cpp/main/RemoteFunctionRegisterer.cpp +++ b/presto-native-execution/presto_cpp/main/functions/RemoteFunctionRegisterer.cpp @@ -12,7 +12,7 @@ * limitations under the License. */ -#include "presto_cpp/main/RemoteFunctionRegisterer.h" +#include "presto_cpp/main/functions/RemoteFunctionRegisterer.h" #include #include "presto_cpp/main/JsonSignatureParser.h" #include "velox/common/base/Exceptions.h" diff --git a/presto-native-execution/presto_cpp/main/RemoteFunctionRegisterer.h b/presto-native-execution/presto_cpp/main/functions/RemoteFunctionRegisterer.h similarity index 100% rename from presto-native-execution/presto_cpp/main/RemoteFunctionRegisterer.h rename to presto-native-execution/presto_cpp/main/functions/RemoteFunctionRegisterer.h diff --git a/presto-native-execution/presto_cpp/main/functions/tests/CMakeLists.txt b/presto-native-execution/presto_cpp/main/functions/tests/CMakeLists.txt new file mode 100644 index 000000000000..d887ce4dde20 --- /dev/null +++ b/presto-native-execution/presto_cpp/main/functions/tests/CMakeLists.txt @@ -0,0 +1,27 @@ +# To test functions being added by dynamically linked libraries, we compile +# `MyDynamicTestFunction.cpp` as a small .so library, and use the +# MY_DYNAMIC_FUNCTION_LIBRARY_PATH macro to locate the .so binary. +add_compile_definitions( + MY_DYNAMIC_FUNCTION_LIBRARY_PATH="${CMAKE_CURRENT_BINARY_DIR}") +add_library(presto_function_my_dynamic SHARED MyDynamicTestFunction.cpp) +target_link_libraries(presto_function_my_dynamic PRIVATE xsimd fmt::fmt + velox_expression) + +# Here's the actual test which will dynamically load the library defined above. +add_executable(presto_function_dynamic_link_test DynamicLinkTest.cpp) + +add_test(NAME presto_function_dynamic_link_test + COMMAND presto_function_dynamic_link_test) + +target_link_libraries( + presto_function_dynamic_link_test + velox_functions_test_lib + presto_dynamic_function_loader + velox_function_registry + xsimd + gmock + ${GTEST_BOTH_LIBRARIES}) + +# these are the testing flags all in a dynamic library +add_library(presto_flags SHARED FlagLibrary.cpp) +target_link_libraries(presto_flags gflags::gflags) diff --git a/presto-native-execution/presto_cpp/main/functions/tests/DynamicLinkTest.cpp b/presto-native-execution/presto_cpp/main/functions/tests/DynamicLinkTest.cpp new file mode 100644 index 000000000000..72a9b94e216c --- /dev/null +++ b/presto-native-execution/presto_cpp/main/functions/tests/DynamicLinkTest.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * 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. + */ + +#include +#include + +#include "presto_cpp/main/functions/DynamicLibraryLoader.h" +#include "velox/common/base/Exceptions.h" +#include "velox/functions/FunctionRegistry.h" +#include "velox/functions/prestosql/tests/utils/FunctionBaseTest.h" + +using namespace facebook::velox::functions::test; +using namespace facebook::velox; +using namespace facebook::presto; +namespace facebook::presto::functions::test { + +class DynamicLinkTest : public FunctionBaseTest {}; + +TEST_F(DynamicLinkTest, dynamicLoad) { + const auto dynamicFunction = [&](std::optional a) { + return evaluateOnce("dynamic_123()", a); + }; + + auto signaturesBefore = getFunctionSignatures().size(); + + // Function does not exist yet. + EXPECT_THROW(dynamicFunction(0), VeloxUserError); + + // Dynamically load the library. + std::string libraryPath = MY_DYNAMIC_FUNCTION_LIBRARY_PATH; + libraryPath += + "/libpresto_function_my_dynamic.dylib"; // building on MacOS leads to + // .dylib file not .so file + + loadDynamicLibraryFunctions(libraryPath.data()); + + auto signaturesAfter = getFunctionSignatures().size(); + EXPECT_EQ(signaturesAfter, signaturesBefore + 1); + + // Make sure the function exists now. + EXPECT_EQ(123, dynamicFunction(0)); +} + +} // namespace facebook::presto::functions::test diff --git a/presto-native-execution/presto_cpp/main/functions/tests/MyDynamicTestFunction.cpp b/presto-native-execution/presto_cpp/main/functions/tests/MyDynamicTestFunction.cpp new file mode 100644 index 000000000000..94616b7ccf63 --- /dev/null +++ b/presto-native-execution/presto_cpp/main/functions/tests/MyDynamicTestFunction.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * 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. + */ + +#include "velox/functions/Udf.h" + +// This file defines a mock function that will be dynamically linked and +// registered. There are no restrictions as to how the function needs to be +// defined, but the library (.so) needs to provide a `void registry()` C +// function in the top-level namespace. +// +// (note the extern "C" directive to prevent the compiler from mangling the +// symbol name). + +namespace facebook::presto::functions { + +template +struct Dynamic123Function { + FOLLY_ALWAYS_INLINE bool call(int64_t& result) { + result = 123; + return true; + } +}; + +} // namespace facebook::presto::functions + +extern "C" { + +void registry() { + facebook::velox::registerFunction< + facebook::presto::functions::Dynamic123Function, + int64_t>({"dynamic_123"}); +} +} diff --git a/presto-native-execution/presto_cpp/main/tests/RemoteFunctionRegistererTest.cpp b/presto-native-execution/presto_cpp/main/functions/tests/RemoteFunctionRegistererTest.cpp similarity index 98% rename from presto-native-execution/presto_cpp/main/tests/RemoteFunctionRegistererTest.cpp rename to presto-native-execution/presto_cpp/main/functions/tests/RemoteFunctionRegistererTest.cpp index 7788cc22c38e..c786c07bd96f 100644 --- a/presto-native-execution/presto_cpp/main/tests/RemoteFunctionRegistererTest.cpp +++ b/presto-native-execution/presto_cpp/main/functions/tests/RemoteFunctionRegistererTest.cpp @@ -12,7 +12,7 @@ * limitations under the License. */ -#include "presto_cpp/main/RemoteFunctionRegisterer.h" +#include "presto_cpp/main/functions/RemoteFunctionRegisterer.h" #include #include #include "velox/common/base/Fs.h" diff --git a/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/ContainerQueryRunner.java b/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/ContainerQueryRunner.java index 09cd72184cac..d90de7604b2c 100644 --- a/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/ContainerQueryRunner.java +++ b/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/ContainerQueryRunner.java @@ -129,6 +129,7 @@ private GenericContainer createNativeWorker(int port, String nodeId) .withNetwork(network).withNetworkAliases(nodeId) .withFileSystemBind(BASE_DIR + "/testcontainers/" + nodeId + "/etc", "/opt/presto-server/etc", BindMode.READ_ONLY) .withFileSystemBind(BASE_DIR + "/testcontainers/" + nodeId + "/entrypoint.sh", "/opt/entrypoint.sh", BindMode.READ_ONLY) + .withFileSystemBind(BASE_DIR + "/testcontainers/plugin/libpresto_function_my_dynamic.dylib", "/opt/plugin/libpresto_function_my_dynamic.dylib", BindMode.READ_ONLY) .waitingFor(Wait.forLogMessage(".*Announcement succeeded: HTTP 202.*", 1)); } diff --git a/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/ContainerQueryRunnerUtils.java b/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/ContainerQueryRunnerUtils.java index 268ec713ba51..b2cd0075a90d 100644 --- a/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/ContainerQueryRunnerUtils.java +++ b/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/ContainerQueryRunnerUtils.java @@ -68,6 +68,7 @@ public static void createNativeWorkerConfigProperties(int coordinatorPort, Strin properties.setProperty("discovery.uri", "http://presto-coordinator:" + coordinatorPort); properties.setProperty("system-memory-gb", "2"); properties.setProperty("native.sidecar", "false"); + properties.setProperty("plugin.dir", "plugin"); createPropertiesFile("testcontainers/" + nodeId + "/etc/config.properties", properties); } @@ -81,6 +82,7 @@ public static void createCoordinatorConfigProperties(int port) properties.setProperty("http-server.http.port", Integer.toString(port)); properties.setProperty("discovery-server.enabled", "true"); properties.setProperty("discovery.uri", "http://presto-coordinator:" + port); + properties.setProperty("plugin.dir", "plugin"); // Get native worker system properties and add them to the coordinator properties Map nativeWorkerProperties = NativeQueryRunnerUtils.getNativeWorkerSystemProperties(); diff --git a/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/TestPrestoNativeDynamicLibrary.java b/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/TestPrestoNativeDynamicLibrary.java new file mode 100644 index 000000000000..6c81424e0fc1 --- /dev/null +++ b/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/TestPrestoNativeDynamicLibrary.java @@ -0,0 +1,42 @@ +/* + * 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. + */ +package com.facebook.presto.nativeworker; +import com.facebook.presto.tests.AbstractTestQueryFramework; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import static org.testng.Assert.assertTrue; + +@Test(singleThreaded = true) +public class TestPrestoNativeDynamicLibrary + extends AbstractTestQueryFramework +{ + @Override + protected ContainerQueryRunner createQueryRunner() + throws Exception + { + return new ContainerQueryRunner(); + } + @Test + public void testShowFunctions() + throws IOException, InterruptedException + { + TimeUnit.SECONDS.sleep(20); + String sql = "SHOW FUNCTIONS"; + assertTrue( + computeActual(sql).toString().contains("dynamic_123"), "dynamic function was not loaded"); + } +}