14eb9fe2eSLang Hames //===----- WrapperFunctionUtilsTest.cpp - Test Wrapper-Function utils -----===//
24eb9fe2eSLang Hames //
34eb9fe2eSLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44eb9fe2eSLang Hames // See https://llvm.org/LICENSE.txt for license information.
54eb9fe2eSLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64eb9fe2eSLang Hames //
74eb9fe2eSLang Hames //===----------------------------------------------------------------------===//
84eb9fe2eSLang Hames
94eb9fe2eSLang Hames #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
1039f64c4cSLang Hames #include "llvm/ADT/FunctionExtras.h"
11*8abf46d3SLang Hames #include "llvm/Testing/Support/Error.h"
124eb9fe2eSLang Hames #include "gtest/gtest.h"
134eb9fe2eSLang Hames
1439f64c4cSLang Hames #include <future>
1539f64c4cSLang Hames
164eb9fe2eSLang Hames using namespace llvm;
17a01f772dSLang Hames using namespace llvm::orc;
184eb9fe2eSLang Hames using namespace llvm::orc::shared;
194eb9fe2eSLang Hames
204eb9fe2eSLang Hames namespace {
214eb9fe2eSLang Hames constexpr const char *TestString = "test string";
224eb9fe2eSLang Hames } // end anonymous namespace
234eb9fe2eSLang Hames
TEST(WrapperFunctionUtilsTest,DefaultWrapperFunctionResult)244eb9fe2eSLang Hames TEST(WrapperFunctionUtilsTest, DefaultWrapperFunctionResult) {
254eb9fe2eSLang Hames WrapperFunctionResult R;
264eb9fe2eSLang Hames EXPECT_TRUE(R.empty());
274eb9fe2eSLang Hames EXPECT_EQ(R.size(), 0U);
284eb9fe2eSLang Hames EXPECT_EQ(R.getOutOfBandError(), nullptr);
294eb9fe2eSLang Hames }
304eb9fe2eSLang Hames
TEST(WrapperFunctionUtilsTest,WrapperFunctionResultFromRange)314eb9fe2eSLang Hames TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromRange) {
324eb9fe2eSLang Hames auto R = WrapperFunctionResult::copyFrom(TestString, strlen(TestString) + 1);
334eb9fe2eSLang Hames EXPECT_EQ(R.size(), strlen(TestString) + 1);
344eb9fe2eSLang Hames EXPECT_TRUE(strcmp(R.data(), TestString) == 0);
354eb9fe2eSLang Hames EXPECT_FALSE(R.empty());
364eb9fe2eSLang Hames EXPECT_EQ(R.getOutOfBandError(), nullptr);
374eb9fe2eSLang Hames }
384eb9fe2eSLang Hames
TEST(WrapperFunctionUtilsTest,WrapperFunctionResultFromCString)394eb9fe2eSLang Hames TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromCString) {
404eb9fe2eSLang Hames auto R = WrapperFunctionResult::copyFrom(TestString);
414eb9fe2eSLang Hames EXPECT_EQ(R.size(), strlen(TestString) + 1);
424eb9fe2eSLang Hames EXPECT_TRUE(strcmp(R.data(), TestString) == 0);
434eb9fe2eSLang Hames EXPECT_FALSE(R.empty());
444eb9fe2eSLang Hames EXPECT_EQ(R.getOutOfBandError(), nullptr);
454eb9fe2eSLang Hames }
464eb9fe2eSLang Hames
TEST(WrapperFunctionUtilsTest,WrapperFunctionResultFromStdString)474eb9fe2eSLang Hames TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromStdString) {
484eb9fe2eSLang Hames auto R = WrapperFunctionResult::copyFrom(std::string(TestString));
494eb9fe2eSLang Hames EXPECT_EQ(R.size(), strlen(TestString) + 1);
504eb9fe2eSLang Hames EXPECT_TRUE(strcmp(R.data(), TestString) == 0);
514eb9fe2eSLang Hames EXPECT_FALSE(R.empty());
524eb9fe2eSLang Hames EXPECT_EQ(R.getOutOfBandError(), nullptr);
534eb9fe2eSLang Hames }
544eb9fe2eSLang Hames
TEST(WrapperFunctionUtilsTest,WrapperFunctionResultFromOutOfBandError)554eb9fe2eSLang Hames TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromOutOfBandError) {
564eb9fe2eSLang Hames auto R = WrapperFunctionResult::createOutOfBandError(TestString);
574eb9fe2eSLang Hames EXPECT_FALSE(R.empty());
584eb9fe2eSLang Hames EXPECT_TRUE(strcmp(R.getOutOfBandError(), TestString) == 0);
594eb9fe2eSLang Hames }
604eb9fe2eSLang Hames
voidNoop()615a28bdeeSLang Hames static void voidNoop() {}
625a28bdeeSLang Hames
63a01f772dSLang Hames class AddClass {
64a01f772dSLang Hames public:
AddClass(int32_t X)65a01f772dSLang Hames AddClass(int32_t X) : X(X) {}
addMethod(int32_t Y)66a01f772dSLang Hames int32_t addMethod(int32_t Y) { return X + Y; }
67a01f772dSLang Hames private:
68a01f772dSLang Hames int32_t X;
69a01f772dSLang Hames };
70a01f772dSLang Hames
voidNoopWrapper(const char * ArgData,size_t ArgSize)714eb9fe2eSLang Hames static WrapperFunctionResult voidNoopWrapper(const char *ArgData,
724eb9fe2eSLang Hames size_t ArgSize) {
734eb9fe2eSLang Hames return WrapperFunction<void()>::handle(ArgData, ArgSize, voidNoop);
744eb9fe2eSLang Hames }
754eb9fe2eSLang Hames
addWrapper(const char * ArgData,size_t ArgSize)764eb9fe2eSLang Hames static WrapperFunctionResult addWrapper(const char *ArgData, size_t ArgSize) {
774eb9fe2eSLang Hames return WrapperFunction<int32_t(int32_t, int32_t)>::handle(
784eb9fe2eSLang Hames ArgData, ArgSize, [](int32_t X, int32_t Y) -> int32_t { return X + Y; });
794eb9fe2eSLang Hames }
804eb9fe2eSLang Hames
addMethodWrapper(const char * ArgData,size_t ArgSize)81a01f772dSLang Hames static WrapperFunctionResult addMethodWrapper(const char *ArgData,
82a01f772dSLang Hames size_t ArgSize) {
83ef391df2SLang Hames return WrapperFunction<int32_t(SPSExecutorAddr, int32_t)>::handle(
84a01f772dSLang Hames ArgData, ArgSize, makeMethodWrapperHandler(&AddClass::addMethod));
85a01f772dSLang Hames }
86a01f772dSLang Hames
TEST(WrapperFunctionUtilsTest,WrapperFunctionCallAndHandleVoid)8739f64c4cSLang Hames TEST(WrapperFunctionUtilsTest, WrapperFunctionCallAndHandleVoid) {
885a28bdeeSLang Hames EXPECT_FALSE(!!WrapperFunction<void()>::call(voidNoopWrapper));
894eb9fe2eSLang Hames }
904eb9fe2eSLang Hames
TEST(WrapperFunctionUtilsTest,WrapperFunctionCallAndHandleRet)9139f64c4cSLang Hames TEST(WrapperFunctionUtilsTest, WrapperFunctionCallAndHandleRet) {
924eb9fe2eSLang Hames int32_t Result;
934eb9fe2eSLang Hames EXPECT_FALSE(!!WrapperFunction<int32_t(int32_t, int32_t)>::call(
944eb9fe2eSLang Hames addWrapper, Result, 1, 2));
954eb9fe2eSLang Hames EXPECT_EQ(Result, (int32_t)3);
964eb9fe2eSLang Hames }
9739f64c4cSLang Hames
TEST(WrapperFunctionUtilsTest,WrapperFunctionMethodCallAndHandleRet)98a01f772dSLang Hames TEST(WrapperFunctionUtilsTest, WrapperFunctionMethodCallAndHandleRet) {
99a01f772dSLang Hames int32_t Result;
100a01f772dSLang Hames AddClass AddObj(1);
101ef391df2SLang Hames EXPECT_FALSE(!!WrapperFunction<int32_t(SPSExecutorAddr, int32_t)>::call(
102ef391df2SLang Hames addMethodWrapper, Result, ExecutorAddr::fromPtr(&AddObj), 2));
103a01f772dSLang Hames EXPECT_EQ(Result, (int32_t)3);
104a01f772dSLang Hames }
105a01f772dSLang Hames
voidNoopAsync(unique_function<void (SPSEmpty)> SendResult)10639f64c4cSLang Hames static void voidNoopAsync(unique_function<void(SPSEmpty)> SendResult) {
10739f64c4cSLang Hames SendResult(SPSEmpty());
10839f64c4cSLang Hames }
10939f64c4cSLang Hames
voidNoopAsyncWrapper(const char * ArgData,size_t ArgSize)11039f64c4cSLang Hames static WrapperFunctionResult voidNoopAsyncWrapper(const char *ArgData,
11139f64c4cSLang Hames size_t ArgSize) {
11239f64c4cSLang Hames std::promise<WrapperFunctionResult> RP;
11339f64c4cSLang Hames auto RF = RP.get_future();
11439f64c4cSLang Hames
11539f64c4cSLang Hames WrapperFunction<void()>::handleAsync(
11639f64c4cSLang Hames ArgData, ArgSize, voidNoopAsync,
11739f64c4cSLang Hames [&](WrapperFunctionResult R) { RP.set_value(std::move(R)); });
11839f64c4cSLang Hames
11939f64c4cSLang Hames return RF.get();
12039f64c4cSLang Hames }
12139f64c4cSLang Hames
addAsyncWrapper(const char * ArgData,size_t ArgSize)12239f64c4cSLang Hames static WrapperFunctionResult addAsyncWrapper(const char *ArgData,
12339f64c4cSLang Hames size_t ArgSize) {
12439f64c4cSLang Hames std::promise<WrapperFunctionResult> RP;
12539f64c4cSLang Hames auto RF = RP.get_future();
12639f64c4cSLang Hames
12739f64c4cSLang Hames WrapperFunction<int32_t(int32_t, int32_t)>::handleAsync(
12839f64c4cSLang Hames ArgData, ArgSize,
12939f64c4cSLang Hames [](unique_function<void(int32_t)> SendResult, int32_t X, int32_t Y) {
13039f64c4cSLang Hames SendResult(X + Y);
13139f64c4cSLang Hames },
13239f64c4cSLang Hames [&](WrapperFunctionResult R) { RP.set_value(std::move(R)); });
13339f64c4cSLang Hames return RF.get();
13439f64c4cSLang Hames }
13539f64c4cSLang Hames
TEST(WrapperFunctionUtilsTest,WrapperFunctionCallAndHandleAsyncVoid)13639f64c4cSLang Hames TEST(WrapperFunctionUtilsTest, WrapperFunctionCallAndHandleAsyncVoid) {
13739f64c4cSLang Hames EXPECT_FALSE(!!WrapperFunction<void()>::call(voidNoopAsyncWrapper));
13839f64c4cSLang Hames }
13939f64c4cSLang Hames
TEST(WrapperFunctionUtilsTest,WrapperFunctionCallAndHandleAsyncRet)14039f64c4cSLang Hames TEST(WrapperFunctionUtilsTest, WrapperFunctionCallAndHandleAsyncRet) {
14139f64c4cSLang Hames int32_t Result;
14239f64c4cSLang Hames EXPECT_FALSE(!!WrapperFunction<int32_t(int32_t, int32_t)>::call(
14339f64c4cSLang Hames addAsyncWrapper, Result, 1, 2));
14439f64c4cSLang Hames EXPECT_EQ(Result, (int32_t)3);
14539f64c4cSLang Hames }
146*8abf46d3SLang Hames
failingWrapper(const char * ArgData,size_t ArgSize)147*8abf46d3SLang Hames static WrapperFunctionResult failingWrapper(const char *ArgData,
148*8abf46d3SLang Hames size_t ArgSize) {
149*8abf46d3SLang Hames return WrapperFunctionResult::createOutOfBandError("failed");
150*8abf46d3SLang Hames }
151*8abf46d3SLang Hames
asyncFailingWrapperCaller(unique_function<void (WrapperFunctionResult)> F,const char * ArgData,size_t ArgSize)152*8abf46d3SLang Hames void asyncFailingWrapperCaller(unique_function<void(WrapperFunctionResult)> F,
153*8abf46d3SLang Hames const char *ArgData, size_t ArgSize) {
154*8abf46d3SLang Hames F(failingWrapper(ArgData, ArgSize));
155*8abf46d3SLang Hames }
156*8abf46d3SLang Hames
TEST(WrapperFunctionUtilsTest,WrapperFunctionCallFailingAsync)157*8abf46d3SLang Hames TEST(WrapperFunctionUtilsTest, WrapperFunctionCallFailingAsync) {
158*8abf46d3SLang Hames WrapperFunction<void()>::callAsync(asyncFailingWrapperCaller, [](Error Err) {
159*8abf46d3SLang Hames EXPECT_THAT_ERROR(std::move(Err), Failed());
160*8abf46d3SLang Hames });
161*8abf46d3SLang Hames }
162