[dockyard] Check for port bind errors on startup
SystemMonitorDockyardTest.ServerListening is flaking (see fxb/54034).
Suspecting failure of the gRPC server to bind to the port. This cl
catches that condition and logs it.
TEST: covered by existing tests
Change-Id: Ie57f81923a6bfe8d30f2d2fa1607ec7d14b3aef2
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/404804
Testability-Review: Jeremy Manson <jeremymanson@google.com>
Commit-Queue: Jayson Adams <shrike@google.com>
Reviewed-by: Andy Weiss <dragonbear@google.com>
diff --git a/src/developer/system_monitor/lib/dockyard/dockyard.cc b/src/developer/system_monitor/lib/dockyard/dockyard.cc
index 50e5aa9..c5d7685 100644
--- a/src/developer/system_monitor/lib/dockyard/dockyard.cc
+++ b/src/developer/system_monitor/lib/dockyard/dockyard.cc
@@ -454,7 +454,9 @@
return false;
}
ResetHarvesterData();
- Initialize();
+ if (!Initialize()) {
+ return false;
+ }
on_connection_request_ = request;
on_connection_handler_ = callback;
server_thread_ = std::thread([this]() { RunGrpcServer(); });
@@ -488,11 +490,11 @@
}
}
-void Dockyard::Initialize() {
+bool Dockyard::Initialize() {
std::lock_guard<std::mutex> guard(mutex_);
if (server_thread_.joinable()) {
GT_LOG(INFO) << "Dockyard server already initialized";
- return;
+ return true;
}
GT_LOG(INFO) << "Starting dockyard server";
@@ -502,16 +504,27 @@
std::string server_address(DEFAULT_SERVER_ADDRESS);
grpc::ServerBuilder builder;
+ int selected_port = -1;
// Listen on the given address without any authentication mechanism.
- builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials(),
+ &selected_port);
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to a *synchronous* service. The
// builder (and server) will hold a weak pointer to the service.
builder.RegisterService(protocol_buffer_service_.get());
// Finally assemble the server.
std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
+ if (selected_port <= 0) {
+ GT_LOG(ERROR) << "Error binding the gRPC server to the port";
+ return false;
+ } else if (server.get() == nullptr) {
+ // All other start errors are flagged by a null server.
+ GT_LOG(ERROR) << "Error starting the gRPC server";
+ return false;
+ }
grpc_server_ = std::move(server);
GT_LOG(INFO) << "Server listening on " << server_address;
+ return true;
}
void Dockyard::RunGrpcServer() {
diff --git a/src/developer/system_monitor/lib/dockyard/dockyard.h b/src/developer/system_monitor/lib/dockyard/dockyard.h
index 1cec2a1..7bb4cc6 100644
--- a/src/developer/system_monitor/lib/dockyard/dockyard.h
+++ b/src/developer/system_monitor/lib/dockyard/dockyard.h
@@ -680,7 +680,9 @@
const std::string& ending);
// Listen for incoming samples.
- void Initialize();
+ //
+ // Returns |false| on problems with starting the gRPC server.
+ bool Initialize();
// A private version of MatchPaths that expects that a lock has already been
// acquired.