diff options
author | Lang Hames <lhames@gmail.com> | 2017-04-13 03:51:35 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2017-04-13 03:51:35 +0000 |
commit | ffad0103c7b7c964e8b25a80b36f3a122347f3bc (patch) | |
tree | 3f6f21a2b76f4a6cbf1b26e67f65d4f6b59bff84 /llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp | |
parent | 80dcad097740d2abddb616fe92edf561e63d6a99 (diff) | |
download | bcm5719-llvm-ffad0103c7b7c964e8b25a80b36f3a122347f3bc.tar.gz bcm5719-llvm-ffad0103c7b7c964e8b25a80b36f3a122347f3bc.zip |
[ORC] Add RPC and serialization support for Errors and Expecteds.
This patch allows Error and Expected types to be passed to and returned from
RPC functions.
Serializers and deserializers for custom error types (types deriving from the
ErrorInfo class template) can be registered with the SerializationTraits for
a given channel type (see registerStringError in RPCSerialization.h for an
example), allowing a given custom type to be sent/received. Unregistered types
will be serialized/deserialized as StringErrors using the custom type's log
message as the error string.
llvm-svn: 300167
Diffstat (limited to 'llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp')
-rw-r--r-- | llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp index a84610f5eb4..095bf25291b 100644 --- a/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp @@ -47,6 +47,54 @@ namespace rpc { class RPCBar {}; +class DummyError : public ErrorInfo<DummyError> { +public: + + static char ID; + + DummyError(uint32_t Val) : Val(Val) {} + + std::error_code convertToErrorCode() const override { + // Use a nonsense error code - we want to verify that errors + // transmitted over the network are replaced with + // OrcErrorCode::UnknownErrorCodeFromRemote. + return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist); + } + + void log(raw_ostream &OS) const override { + OS << "Dummy error " << Val; + } + + uint32_t getValue() const { return Val; } + +public: + uint32_t Val; +}; + +char DummyError::ID = 0; + +template <typename ChannelT> +void registerDummyErrorSerialization() { + static bool AlreadyRegistered = false; + if (!AlreadyRegistered) { + SerializationTraits<ChannelT, Error>:: + template registerErrorType<DummyError>( + "DummyError", + [](ChannelT &C, const DummyError &DE) { + return serializeSeq(C, DE.getValue()); + }, + [](ChannelT &C, Error &Err) -> Error { + ErrorAsOutParameter EAO(&Err); + uint32_t Val; + if (auto Err = deserializeSeq(C, Val)) + return Err; + Err = make_error<DummyError>(Val); + return Error::success(); + }); + AlreadyRegistered = true; + } +} + namespace llvm { namespace orc { namespace rpc { @@ -98,6 +146,16 @@ namespace DummyRPCAPI { static const char* getName() { return "CustomType"; } }; + class ErrorFunc : public Function<ErrorFunc, Error()> { + public: + static const char* getName() { return "ErrorFunc"; } + }; + + class ExpectedFunc : public Function<ExpectedFunc, Expected<uint32_t>()> { + public: + static const char* getName() { return "ExpectedFunc"; } + }; + } class DummyRPCEndpoint : public SingleThreadedRPCEndpoint<QueueChannel> { @@ -493,6 +551,140 @@ TEST(DummyRPC, TestWithAltCustomType) { ServerThread.join(); } +TEST(DummyRPC, ReturnErrorSuccess) { + registerDummyErrorSerialization<QueueChannel>(); + + auto Channels = createPairedQueueChannels(); + DummyRPCEndpoint Client(*Channels.first); + DummyRPCEndpoint Server(*Channels.second); + + std::thread ServerThread([&]() { + Server.addHandler<DummyRPCAPI::ErrorFunc>( + []() { + return Error::success(); + }); + + // Handle the negotiate plus one call. + for (unsigned I = 0; I != 2; ++I) + cantFail(Server.handleOne()); + }); + + cantFail(Client.callAsync<DummyRPCAPI::ErrorFunc>( + [&](Error Err) { + EXPECT_FALSE(!!Err) << "Expected success value"; + return Error::success(); + })); + + cantFail(Client.handleOne()); + + ServerThread.join(); +} + +TEST(DummyRPC, ReturnErrorFailure) { + registerDummyErrorSerialization<QueueChannel>(); + + auto Channels = createPairedQueueChannels(); + DummyRPCEndpoint Client(*Channels.first); + DummyRPCEndpoint Server(*Channels.second); + + std::thread ServerThread([&]() { + Server.addHandler<DummyRPCAPI::ErrorFunc>( + []() { + return make_error<DummyError>(42); + }); + + // Handle the negotiate plus one call. + for (unsigned I = 0; I != 2; ++I) + cantFail(Server.handleOne()); + }); + + cantFail(Client.callAsync<DummyRPCAPI::ErrorFunc>( + [&](Error Err) { + EXPECT_TRUE(Err.isA<DummyError>()) + << "Incorrect error type"; + return handleErrors( + std::move(Err), + [](const DummyError &DE) { + EXPECT_EQ(DE.getValue(), 42ULL) + << "Incorrect DummyError serialization"; + }); + })); + + cantFail(Client.handleOne()); + + ServerThread.join(); +} + +TEST(DummyRPC, RPCExpectedSuccess) { + registerDummyErrorSerialization<QueueChannel>(); + + auto Channels = createPairedQueueChannels(); + DummyRPCEndpoint Client(*Channels.first); + DummyRPCEndpoint Server(*Channels.second); + + std::thread ServerThread([&]() { + Server.addHandler<DummyRPCAPI::ExpectedFunc>( + []() -> uint32_t { + return 42; + }); + + // Handle the negotiate plus one call. + for (unsigned I = 0; I != 2; ++I) + cantFail(Server.handleOne()); + }); + + cantFail(Client.callAsync<DummyRPCAPI::ExpectedFunc>( + [&](Expected<uint32_t> ValOrErr) { + EXPECT_TRUE(!!ValOrErr) + << "Expected success value"; + EXPECT_EQ(*ValOrErr, 42ULL) + << "Incorrect Expected<uint32_t> deserialization"; + return Error::success(); + })); + + cantFail(Client.handleOne()); + + ServerThread.join(); +}; + +TEST(DummyRPC, RPCExpectedFailure) { + registerDummyErrorSerialization<QueueChannel>(); + + auto Channels = createPairedQueueChannels(); + DummyRPCEndpoint Client(*Channels.first); + DummyRPCEndpoint Server(*Channels.second); + + std::thread ServerThread([&]() { + Server.addHandler<DummyRPCAPI::ExpectedFunc>( + []() -> Expected<uint32_t> { + return make_error<DummyError>(7); + }); + + // Handle the negotiate plus one call. + for (unsigned I = 0; I != 2; ++I) + cantFail(Server.handleOne()); + }); + + cantFail(Client.callAsync<DummyRPCAPI::ExpectedFunc>( + [&](Expected<uint32_t> ValOrErr) { + EXPECT_FALSE(!!ValOrErr) + << "Expected failure value"; + auto Err = ValOrErr.takeError(); + EXPECT_TRUE(Err.isA<DummyError>()) + << "Incorrect error type"; + return handleErrors( + std::move(Err), + [](const DummyError &DE) { + EXPECT_EQ(DE.getValue(), 7ULL) + << "Incorrect DummyError serialization"; + }); + })); + + cantFail(Client.handleOne()); + + ServerThread.join(); +}; + TEST(DummyRPC, TestParallelCallGroup) { auto Channels = createPairedQueueChannels(); DummyRPCEndpoint Client(*Channels.first); |