This repository has been archived by the owner on Mar 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use 'exec*()' to perform client and server death tests
Before this commit we tried to perform the death part of the client or server death tests in the forked child process created from 'ASSERT_DEATH()'. This has "worked" but investigating ongoing flaky tests suggests this approach is insufficient. This commit does less in the forked child by immediately doing an 'exec*()'.
- Loading branch information
Showing
7 changed files
with
324 additions
and
94 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#include "eventuals/grpc/client.h" | ||
#include "eventuals/terminal.h" | ||
#include "eventuals/then.h" | ||
#include "examples/protos/helloworld.grpc.pb.h" | ||
|
||
using helloworld::Greeter; | ||
using helloworld::HelloReply; | ||
using helloworld::HelloRequest; | ||
|
||
using stout::Borrowable; | ||
|
||
using eventuals::Eventual; | ||
using eventuals::Terminate; | ||
using eventuals::Then; | ||
|
||
using eventuals::grpc::Client; | ||
using eventuals::grpc::CompletionPool; | ||
|
||
// Should only be run from tests! | ||
// | ||
// Expects two arguments. | ||
// | ||
// Expects 'argv[1]' to be a string representing the file descriptor | ||
// that this process has inherited from its parent (the test) that can | ||
// be used to indicate that forking has completed and the test can | ||
// continue. | ||
// | ||
// Expects 'argv[2]' to be a string representing the file descriptor | ||
// that this process has inherited from its parent (the test) that can | ||
// be used to read the bound port of the gRPC server to connect to. | ||
// | ||
// See 'client-death-test.cc' for more details. | ||
int main(int argc, char** argv) { | ||
// TODO(benh): use stout-flags! | ||
CHECK_EQ(argc, 3) | ||
<< "expecting 'pipe_fork' and 'pipe_port' to be passed as arguments"; | ||
|
||
int pipe_fork = atoi(argv[1]); | ||
int pipe_port = atoi(argv[2]); | ||
|
||
auto NotifyForked = [&]() { | ||
int one = 1; | ||
CHECK_GT(write(pipe_fork, &one, sizeof(int)), 0); | ||
}; | ||
|
||
auto WaitForPort = [&]() { | ||
int port; | ||
CHECK_GT(read(pipe_port, &port, sizeof(int)), 0); | ||
return port; | ||
}; | ||
|
||
NotifyForked(); | ||
|
||
int port = WaitForPort(); | ||
|
||
Borrowable<CompletionPool> pool; | ||
|
||
Client client( | ||
"0.0.0.0:" + std::to_string(port), | ||
grpc::InsecureChannelCredentials(), | ||
pool.Borrow()); | ||
|
||
auto call = [&]() { | ||
return client.Call<Greeter, HelloRequest, HelloReply>("SayHello") | ||
| Then([](auto&& call) { | ||
// NOTE: to avoid false positives with, for example, one | ||
// of the 'CHECK()'s failing above, the 'ClientDeathTest' | ||
// expects the string 'connected' to be written to stderr. | ||
std::cerr << "connected" << std::endl; | ||
exit(1); | ||
}); | ||
}; | ||
|
||
*call(); | ||
|
||
return 0; | ||
} |
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,75 @@ | ||
#include "eventuals/grpc/server.h" | ||
#include "eventuals/head.h" | ||
#include "eventuals/terminal.h" | ||
#include "eventuals/then.h" | ||
#include "examples/protos/helloworld.grpc.pb.h" | ||
|
||
using helloworld::Greeter; | ||
using helloworld::HelloReply; | ||
using helloworld::HelloRequest; | ||
|
||
using eventuals::Head; | ||
using eventuals::Terminate; | ||
using eventuals::Then; | ||
|
||
using eventuals::grpc::Server; | ||
using eventuals::grpc::ServerBuilder; | ||
|
||
// Should only be run from tests! | ||
// | ||
// Expects one argument. | ||
// | ||
// Expects as 'argv[1]' a string representing the file descriptor that | ||
// this process has inherited from its parent (the test) that can be | ||
// used to send the bound port of the gRPC server. | ||
// | ||
// See 'server-death-test.cc' for more details. | ||
int main(int argc, char** argv) { | ||
// TODO(benh): use stout-flags! | ||
CHECK_EQ(argc, 2) << "expecting 'pipe' to be passed as an argument"; | ||
|
||
int pipe = atoi(argv[1]); | ||
|
||
auto SendPort = [&](int port) { | ||
CHECK_GT(write(pipe, &port, sizeof(port)), 0); | ||
}; | ||
|
||
ServerBuilder builder; | ||
|
||
int port = 0; | ||
|
||
builder.AddListeningPort( | ||
"0.0.0.0:0", | ||
grpc::InsecureServerCredentials(), | ||
&port); | ||
|
||
auto build = builder.BuildAndStart(); | ||
|
||
CHECK(build.status.ok()); | ||
|
||
auto server = std::move(build.server); | ||
|
||
CHECK(server); | ||
|
||
auto serve = [&]() { | ||
return server->Accept<Greeter, HelloRequest, HelloReply>("SayHello") | ||
| Head() | ||
| Then([](auto&& call) { | ||
// NOTE: to avoid false positives with, for example, one | ||
// of the 'CHECK()'s failing above, the 'ServerDeathTest' | ||
// expects the string 'accepted' to be written to stderr. | ||
std::cerr << "accepted" << std::endl; | ||
exit(1); | ||
}); | ||
}; | ||
|
||
auto [future, k] = Terminate(serve()); | ||
|
||
k.Start(); | ||
|
||
// NOTE: sending this _after_ we start the eventual so that we're | ||
// ready to accept clients! | ||
SendPort(port); | ||
|
||
future.get(); | ||
} |
Oops, something went wrong.