llvm-project/orc-rt/unittests/AllocActionTest.cpp
Lang Hames dc30321b47
[orc-rt] Add unit test utility: MakeAllocAction. (#162229)
MakeAllocAction can be used to construct AllocActions with less
boilerplate than the previous option (spsSerialize + AllocAction
constructor call). This will be used to simplify upcoming unit tests
that use AllocActions.

The existing AllocActionsTest is updated to use the new utility.
2025-10-07 17:46:27 +11:00

178 lines
5.8 KiB
C++

//===- AllocActionTest.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Tests for orc-rt's AllocAction.h APIs.
//
//===----------------------------------------------------------------------===//
#include "orc-rt/AllocAction.h"
#include "orc-rt/ExecutorAddress.h"
#include "orc-rt/SPSAllocAction.h"
#include "AllocActionTestUtils.h"
#include "gtest/gtest.h"
using namespace orc_rt;
TEST(AllocActionTest, DefaultConstruct) {
AllocAction AA;
EXPECT_FALSE(AA);
}
static orc_rt_WrapperFunctionBuffer noopAction(const char *ArgData,
size_t ArgSize) {
return WrapperFunctionBuffer().release();
}
TEST(AllocActionTest, ConstructWithAction) {
AllocAction AA(noopAction, WrapperFunctionBuffer());
EXPECT_TRUE(AA);
}
// Increments int via pointer.
static orc_rt_WrapperFunctionBuffer
increment_sps_allocaction(const char *ArgData, size_t ArgSize) {
return SPSAllocActionFunction<SPSExecutorAddr>::handle(
ArgData, ArgSize,
[](ExecutorAddr IntPtr) {
*IntPtr.toPtr<int *>() += 1;
return WrapperFunctionBuffer();
})
.release();
}
// Increments int via pointer.
static orc_rt_WrapperFunctionBuffer
decrement_sps_allocaction(const char *ArgData, size_t ArgSize) {
return SPSAllocActionFunction<SPSExecutorAddr>::handle(
ArgData, ArgSize,
[](ExecutorAddr IntPtr) {
*IntPtr.toPtr<int *>() -= 1;
return WrapperFunctionBuffer();
})
.release();
}
template <typename T>
static WrapperFunctionBuffer makeExecutorAddrBuffer(T *P) {
return *spsSerialize<SPSArgList<SPSExecutorAddr>>(ExecutorAddr::fromPtr(P));
}
TEST(AllocActionTest, RunBasicAction) {
int Val = 0;
AllocAction IncVal(increment_sps_allocaction, makeExecutorAddrBuffer(&Val));
EXPECT_TRUE(IncVal);
auto B = IncVal();
EXPECT_TRUE(B.empty());
EXPECT_EQ(Val, 1);
}
TEST(AllocActionTest, RunFinalizationActionsComplete) {
int Val = 0;
std::vector<AllocActionPair> InitialActions;
auto MakeAAOnVal = [&](AllocActionFn Fn) {
return *MakeAllocAction<SPSExecutorAddr>::from(Fn,
ExecutorAddr::fromPtr(&Val));
};
InitialActions.push_back({MakeAAOnVal(increment_sps_allocaction),
MakeAAOnVal(decrement_sps_allocaction)});
InitialActions.push_back({MakeAAOnVal(increment_sps_allocaction),
MakeAAOnVal(decrement_sps_allocaction)});
auto DeallocActions = cantFail(runFinalizeActions(std::move(InitialActions)));
EXPECT_EQ(Val, 2);
runDeallocActions(std::move(DeallocActions));
EXPECT_EQ(Val, 0);
}
static orc_rt_WrapperFunctionBuffer fail_sps_allocaction(const char *ArgData,
size_t ArgSize) {
return WrapperFunctionBuffer::createOutOfBandError("failed").release();
}
TEST(AllocActionTest, RunFinalizeActionsFail) {
int Val = 0;
std::vector<AllocActionPair> InitialActions;
auto MakeAAOnVal = [&](AllocActionFn Fn) {
return *MakeAllocAction<SPSExecutorAddr>::from(Fn,
ExecutorAddr::fromPtr(&Val));
};
InitialActions.push_back({MakeAAOnVal(increment_sps_allocaction),
MakeAAOnVal(decrement_sps_allocaction)});
InitialActions.push_back({*MakeAllocAction<>::from(fail_sps_allocaction),
MakeAAOnVal(decrement_sps_allocaction)});
auto DeallocActions = runFinalizeActions(std::move(InitialActions));
if (DeallocActions) {
ADD_FAILURE() << "Failed to report error from runFinalizeActions";
return;
}
EXPECT_EQ(toString(DeallocActions.takeError()), std::string("failed"));
// Check that we ran the decrement corresponding to the first increment.
EXPECT_EQ(Val, 0);
}
TEST(AllocActionTest, RunFinalizeActionsNullFinalize) {
int Val = 0;
std::vector<AllocActionPair> InitialActions;
auto MakeAAOnVal = [&](AllocActionFn Fn) {
return *MakeAllocAction<SPSExecutorAddr>::from(Fn,
ExecutorAddr::fromPtr(&Val));
};
InitialActions.push_back({MakeAAOnVal(increment_sps_allocaction),
MakeAAOnVal(decrement_sps_allocaction)});
InitialActions.push_back({*MakeAllocAction<>::from(nullptr),
MakeAAOnVal(decrement_sps_allocaction)});
auto DeallocActions = cantFail(runFinalizeActions(std::move(InitialActions)));
// Both dealloc actions should be included in the returned list, despite one
// of them having a null finalize action.
EXPECT_EQ(DeallocActions.size(), 2U);
runDeallocActions(std::move(DeallocActions));
EXPECT_EQ(Val, -1);
}
TEST(AllocActionTest, RunFinalizeActionsNullDealloc) {
int Val = 0;
std::vector<AllocActionPair> InitialActions;
auto MakeAAOnVal = [&](AllocActionFn Fn) {
return *MakeAllocAction<SPSExecutorAddr>::from(Fn,
ExecutorAddr::fromPtr(&Val));
};
InitialActions.push_back({MakeAAOnVal(increment_sps_allocaction),
MakeAAOnVal(decrement_sps_allocaction)});
InitialActions.push_back({MakeAAOnVal(increment_sps_allocaction),
*MakeAllocAction<>::from(nullptr)});
auto DeallocActions = cantFail(runFinalizeActions(std::move(InitialActions)));
// Null dealloc actions should be filtered out of the returned list.
EXPECT_EQ(DeallocActions.size(), 1U);
runDeallocActions(std::move(DeallocActions));
EXPECT_EQ(Val, 1);
}