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.
178 lines
5.8 KiB
C++
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);
|
|
}
|