#include <mutex>
#include <random>
#include <set>
+#include <string>
#include <thread>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
#include "src/core/ext/filters/client_channel/backup_poller.h"
#include "src/core/ext/filters/client_channel/global_subchannel_pool.h"
-#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
#include "src/core/ext/filters/client_channel/server_address.h"
+#include "src/core/lib/address_utils/parse_address.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
#include "src/cpp/client/secure_credentials.h"
#include "src/cpp/server/secure_server_credentials.h"
-
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
+#include "test/core/util/resolve_localhost_ip46.h"
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h"
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
using grpc::testing::EchoRequest;
using grpc::testing::EchoResponse;
-using std::chrono::system_clock;
namespace grpc {
namespace testing {
request_count_ = 0;
}
- std::set<grpc::string> clients() {
+ std::set<std::string> clients() {
grpc::internal::MutexLock lock(&clients_mu_);
return clients_;
}
private:
- void AddClient(const grpc::string& client) {
+ void AddClient(const std::string& client) {
grpc::internal::MutexLock lock(&clients_mu_);
clients_.insert(client);
}
grpc::internal::Mutex mu_;
int request_count_;
grpc::internal::Mutex clients_mu_;
- std::set<grpc::string> clients_;
+ std::set<std::string> clients_;
};
class ServiceConfigEnd2endTest : public ::testing::Test {
grpc_init();
response_generator_ =
grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>();
+ bool localhost_resolves_to_ipv4 = false;
+ bool localhost_resolves_to_ipv6 = false;
+ grpc_core::LocalhostResolves(&localhost_resolves_to_ipv4,
+ &localhost_resolves_to_ipv6);
+ ipv6_only_ = !localhost_resolves_to_ipv4 && localhost_resolves_to_ipv6;
}
void TearDown() override {
stub_.reset();
servers_.clear();
creds_.reset();
- grpc_shutdown_blocking();
+ grpc_shutdown();
}
void CreateServers(size_t num_servers,
grpc_core::Resolver::Result BuildFakeResults(const std::vector<int>& ports) {
grpc_core::Resolver::Result result;
for (const int& port : ports) {
- char* lb_uri_str;
- gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port);
- grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true);
- GPR_ASSERT(lb_uri != nullptr);
+ std::string lb_uri_str =
+ absl::StrCat(ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port);
+ absl::StatusOr<grpc_core::URI> lb_uri = grpc_core::URI::Parse(lb_uri_str);
+ GPR_ASSERT(lb_uri.ok());
grpc_resolved_address address;
- GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
+ GPR_ASSERT(grpc_parse_uri(*lb_uri, &address));
result.addresses.emplace_back(address.addr, address.len,
nullptr /* args */);
- grpc_uri_destroy(lb_uri);
- gpr_free(lb_uri_str);
}
return result;
}
void SetNextResolutionValidServiceConfig(const std::vector<int>& ports) {
grpc_core::ExecCtx exec_ctx;
grpc_core::Resolver::Result result = BuildFakeResults(ports);
- result.service_config =
- grpc_core::ServiceConfig::Create("{}", &result.service_config_error);
+ result.service_config = grpc_core::ServiceConfig::Create(
+ nullptr, "{}", &result.service_config_error);
response_generator_->SetResponse(result);
}
void SetNextResolutionInvalidServiceConfig(const std::vector<int>& ports) {
grpc_core::ExecCtx exec_ctx;
grpc_core::Resolver::Result result = BuildFakeResults(ports);
- result.service_config =
- grpc_core::ServiceConfig::Create("{", &result.service_config_error);
+ result.service_config = grpc_core::ServiceConfig::Create(
+ nullptr, "{", &result.service_config_error);
response_generator_->SetResponse(result);
}
const char* svc_cfg) {
grpc_core::ExecCtx exec_ctx;
grpc_core::Resolver::Result result = BuildFakeResults(ports);
- result.service_config =
- grpc_core::ServiceConfig::Create(svc_cfg, &result.service_config_error);
+ result.service_config = grpc_core::ServiceConfig::Create(
+ nullptr, svc_cfg, &result.service_config_error);
response_generator_->SetResponse(result);
}
}
struct ServerData {
- int port_;
+ const int port_;
std::unique_ptr<Server> server_;
MyTestServiceImpl service_;
std::unique_ptr<std::thread> thread_;
- bool server_ready_ = false;
- bool started_ = false;
- explicit ServerData(int port = 0) {
- port_ = port > 0 ? port : grpc_pick_unused_port_or_die();
- }
+ grpc::internal::Mutex mu_;
+ grpc::internal::CondVar cond_;
+ bool server_ready_ ABSL_GUARDED_BY(mu_) = false;
+ bool started_ ABSL_GUARDED_BY(mu_) = false;
- void Start(const grpc::string& server_host) {
+ explicit ServerData(int port = 0)
+ : port_(port > 0 ? port : grpc_pick_unused_port_or_die()) {}
+
+ void Start(const std::string& server_host) {
gpr_log(GPR_INFO, "starting server on port %d", port_);
+ grpc::internal::MutexLock lock(&mu_);
started_ = true;
- grpc::internal::Mutex mu;
- grpc::internal::MutexLock lock(&mu);
- grpc::internal::CondVar cond;
- thread_.reset(new std::thread(
- std::bind(&ServerData::Serve, this, server_host, &mu, &cond)));
- cond.WaitUntil(&mu, [this] { return server_ready_; });
+ thread_ = absl::make_unique<std::thread>(
+ std::bind(&ServerData::Serve, this, server_host));
+ while (!server_ready_) {
+ cond_.Wait(&mu_);
+ }
server_ready_ = false;
gpr_log(GPR_INFO, "server startup complete");
}
- void Serve(const grpc::string& server_host, grpc::internal::Mutex* mu,
- grpc::internal::CondVar* cond) {
+ void Serve(const std::string& server_host) {
std::ostringstream server_address;
server_address << server_host << ":" << port_;
ServerBuilder builder;
builder.AddListeningPort(server_address.str(), std::move(creds));
builder.RegisterService(&service_);
server_ = builder.BuildAndStart();
- grpc::internal::MutexLock lock(mu);
+ grpc::internal::MutexLock lock(&mu_);
server_ready_ = true;
- cond->Signal();
+ cond_.Signal();
}
void Shutdown() {
+ grpc::internal::MutexLock lock(&mu_);
if (!started_) return;
server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0));
thread_->join();
started_ = false;
}
- void SetServingStatus(const grpc::string& service, bool serving) {
+ void SetServingStatus(const std::string& service, bool serving) {
server_->GetHealthCheckService()->SetServingStatus(service, serving);
}
};
return "{\"version\": \"invalid_default\"";
}
- const grpc::string server_host_;
+ bool ipv6_only_ = false;
+ const std::string server_host_;
std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
std::vector<std::unique_ptr<ServerData>> servers_;
grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator>
response_generator_;
- const grpc::string kRequestMessage_;
+ const std::string kRequestMessage_;
std::shared_ptr<ChannelCredentials> creds_;
};
auto stub = BuildStub(channel);
SetNextResolutionNoServiceConfig(GetServersPorts());
CheckRpcSendOk(stub, DEBUG_LOCATION);
- EXPECT_STREQ("", channel->GetServiceConfigJSON().c_str());
+ EXPECT_STREQ("{}", channel->GetServiceConfigJSON().c_str());
}
TEST_F(ServiceConfigEnd2endTest, NoServiceConfigWithDefaultConfigTest) {
CheckRpcSendFailure(stub);
}
-TEST_F(ServiceConfigEnd2endTest, InvalidServiceConfigWithDefaultConfigTest) {
- StartServers(1);
- auto channel = BuildChannelWithDefaultServiceConfig();
- auto stub = BuildStub(channel);
- SetNextResolutionInvalidServiceConfig(GetServersPorts());
- CheckRpcSendOk(stub, DEBUG_LOCATION);
- EXPECT_STREQ(ValidDefaultServiceConfig(),
- channel->GetServiceConfigJSON().c_str());
-}
-
TEST_F(ServiceConfigEnd2endTest, ValidServiceConfigUpdatesTest) {
StartServers(1);
auto channel = BuildChannel();
EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str());
SetNextResolutionNoServiceConfig(GetServersPorts());
CheckRpcSendOk(stub, DEBUG_LOCATION);
- EXPECT_STREQ("", channel->GetServiceConfigJSON().c_str());
+ EXPECT_STREQ("{}", channel->GetServiceConfigJSON().c_str());
}
TEST_F(ServiceConfigEnd2endTest,
CheckRpcSendFailure(stub);
SetNextResolutionNoServiceConfig(GetServersPorts());
CheckRpcSendOk(stub, DEBUG_LOCATION);
- EXPECT_STREQ("", channel->GetServiceConfigJSON().c_str());
+ EXPECT_STREQ("{}", channel->GetServiceConfigJSON().c_str());
}
TEST_F(ServiceConfigEnd2endTest,