-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
179 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
|
||
#ifndef TEST_NET_REMOTE_COMMON_HXX | ||
#define TEST_NET_REMOTE_COMMON_HXX | ||
|
||
#include <chrono> | ||
#include <string_view> | ||
|
||
namespace Microsoft::Net::Remote::Test | ||
{ | ||
using namespace std::chrono_literals; | ||
|
||
constexpr auto RemoteServiceAddressHttp = "localhost:5047"; | ||
constexpr auto RemoteServiceConnectionTimeout = 3s; | ||
} // namespace Micosoft::Net::Remote::Test | ||
|
||
#endif // TEST_NET_REMOTE_COMMON_HXX |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
|
||
#include <algorithm> | ||
#include <optional> | ||
#include <ranges> | ||
#include <tuple> | ||
#include <vector> | ||
|
||
#include <catch2/catch_test_macros.hpp> | ||
#include <catch2/generators/catch_generators_range.hpp> | ||
#include <grpcpp/create_channel.h> | ||
#include <magic_enum.hpp> | ||
#include <microsoft/net/remote/NetRemoteServer.hxx> | ||
#include <NetRemoteService.grpc.pb.h> | ||
|
||
#include "TestNetRemoteCommon.hxx" | ||
|
||
TEST_CASE("Create a NetRemoteServer instance", "[basic][rpc][remote]") | ||
{ | ||
using namespace Microsoft::Net::Remote; | ||
|
||
SECTION("Create doesn't cause a crash") | ||
{ | ||
REQUIRE_NOTHROW(NetRemoteServer{ Test::RemoteServiceAddressHttp }); | ||
} | ||
} | ||
|
||
TEST_CASE("Destroy a NetRemoteServer instance", "[basic][rpc][remote]") | ||
{ | ||
using namespace Microsoft::Net::Remote; | ||
|
||
SECTION("Destroy doesn't cause a crash") | ||
{ | ||
std::optional<NetRemoteServer> server{ Test::RemoteServiceAddressHttp }; | ||
REQUIRE_NOTHROW(server.reset()); | ||
} | ||
|
||
SECTION("Destroy doesn't cause a crash with no connected clients") | ||
{ | ||
std::optional<NetRemoteServer> server{ Test::RemoteServiceAddressHttp }; | ||
REQUIRE_NOTHROW(server.reset()); | ||
} | ||
} | ||
|
||
TEST_CASE("NetRemoteServer can be reached", "[basic][rpc][remote]") | ||
{ | ||
using namespace Microsoft::Net::Remote; | ||
using namespace Microsoft::Net::Remote::Service; | ||
|
||
NetRemoteServer server{ Test::RemoteServiceAddressHttp }; | ||
server.Run(); | ||
|
||
SECTION("Can be reached using insecure channel") | ||
{ | ||
auto channel = grpc::CreateChannel(Test::RemoteServiceAddressHttp, grpc::InsecureChannelCredentials()); | ||
auto client = NetRemote::NewStub(channel); | ||
|
||
REQUIRE(channel->WaitForConnected(std::chrono::system_clock::now() + Test::RemoteServiceConnectionTimeout)); | ||
} | ||
} | ||
|
||
TEST_CASE("NetRemoteServer shuts down correctly", "[basic][rpc][remote]") | ||
{ | ||
using namespace Microsoft::Net::Remote; | ||
using namespace Microsoft::Net::Remote::Service; | ||
|
||
NetRemoteServer server{ Test::RemoteServiceAddressHttp }; | ||
server.Run(); | ||
|
||
SECTION("Stop() doesn't cause a crash with no connected clients") | ||
{ | ||
REQUIRE_NOTHROW(server.Stop()); | ||
} | ||
|
||
SECTION("Stop() severs connections for connected clients") | ||
{ | ||
// Vary the number of connected clients and validate test section for each. | ||
const auto numClientsToCreate = Catch::Generators::range(1, 3); | ||
|
||
// Establish client connections to the server. | ||
std::vector<std::tuple<std::shared_ptr<grpc::Channel>, std::unique_ptr<NetRemote::Stub>>> clients(static_cast<std::size_t>(numClientsToCreate.get())); | ||
std::ranges::transform(clients, std::begin(clients), [&](auto&&) | ||
{ | ||
auto channel = grpc::CreateChannel(Test::RemoteServiceAddressHttp, grpc::InsecureChannelCredentials()); | ||
auto client = NetRemote::NewStub(channel); | ||
REQUIRE(channel->WaitForConnected(std::chrono::system_clock::now() + Test::RemoteServiceConnectionTimeout)); | ||
|
||
return std::make_tuple(channel, std::move(client)); | ||
}); | ||
|
||
// Stop the server. | ||
REQUIRE_NOTHROW(server.Stop()); | ||
|
||
// Validate each channel is in IDLE state. | ||
for (const auto& [channel, _] : clients) | ||
{ | ||
REQUIRE(channel->GetState(false) == GRPC_CHANNEL_IDLE); | ||
} | ||
} | ||
|
||
SECTION("Stop() invalidates gRPC server instance with no connected clients") | ||
{ | ||
REQUIRE_NOTHROW(server.Stop()); | ||
REQUIRE(server.GetGrpcServer() == nullptr); | ||
} | ||
|
||
SECTION("Stop() invalidates gRPC server instance with connected clients") | ||
{ | ||
// Vary the number of connected clients and validate test section for each. | ||
const auto numClientsToCreate = Catch::Generators::range(1, 3); | ||
|
||
std::vector<std::tuple<std::shared_ptr<grpc::Channel>, std::unique_ptr<NetRemote::Stub>>> clients(static_cast<std::size_t>(numClientsToCreate.get())); | ||
std::ranges::transform(clients, std::begin(clients), [&](auto&&) | ||
{ | ||
auto channel = grpc::CreateChannel(Test::RemoteServiceAddressHttp, grpc::InsecureChannelCredentials()); | ||
auto client = NetRemote::NewStub(channel); | ||
REQUIRE(channel->WaitForConnected(std::chrono::system_clock::now() + Test::RemoteServiceConnectionTimeout)); | ||
|
||
return std::make_tuple(channel, std::move(client)); | ||
}); | ||
|
||
REQUIRE_NOTHROW(server.Stop()); | ||
REQUIRE(server.GetGrpcServer() == nullptr); | ||
} | ||
} | ||
|
||
TEST_CASE("NetRemoteServer can be cycled through run/stop states", "[basic][rpc][remote]") | ||
{ | ||
using namespace Microsoft::Net::Remote; | ||
using namespace Microsoft::Net::Remote::Service; | ||
|
||
NetRemoteServer server{ Test::RemoteServiceAddressHttp }; | ||
REQUIRE_NOTHROW(server.Run()); | ||
|
||
SECTION("Can be cycled multiple times") | ||
{ | ||
const auto numCycles = Catch::Generators::range(1, 3); | ||
|
||
for ([[maybe_unused]] auto _ : std::views::iota(0, numCycles.get())) | ||
{ | ||
REQUIRE_NOTHROW(server.Stop()); | ||
REQUIRE_NOTHROW(server.Run()); | ||
|
||
auto channel = grpc::CreateChannel(Test::RemoteServiceAddressHttp, grpc::InsecureChannelCredentials()); | ||
auto client = NetRemote::NewStub(channel); | ||
REQUIRE(channel->WaitForConnected(std::chrono::system_clock::now() + Test::RemoteServiceConnectionTimeout)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters