aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD3
-rw-r--r--CMakeLists.txt37
-rw-r--r--Makefile48
-rw-r--r--README.md2
-rw-r--r--build.yaml13
-rw-r--r--gRPC-C++.podspec2
-rw-r--r--gRPC-Core.podspec2
-rw-r--r--grpc.gemspec1
-rw-r--r--package.xml1
-rw-r--r--src/compiler/objective_c_generator.cc104
-rw-r--r--src/compiler/objective_c_generator.h10
-rw-r--r--src/compiler/objective_c_generator_helpers.h40
-rw-r--r--src/compiler/objective_c_plugin.cc145
-rw-r--r--src/core/ext/filters/client_channel/backup_poller.cc19
-rw-r--r--src/core/ext/filters/client_channel/backup_poller.h2
-rw-r--r--src/core/lib/security/credentials/fake/fake_credentials.cc3
-rw-r--r--src/core/lib/security/credentials/fake/fake_credentials.h3
-rw-r--r--src/core/lib/security/security_connector/security_connector.cc9
-rw-r--r--src/core/lib/slice/slice_weak_hash_table.h105
-rw-r--r--test/core/slice/BUILD40
-rw-r--r--test/core/slice/slice_weak_hash_table_test.cc105
-rw-r--r--test/cpp/end2end/grpclb_end2end_test.cc66
-rw-r--r--tools/doxygen/Doxyfile.c++.internal1
-rw-r--r--tools/doxygen/Doxyfile.core.internal1
-rw-r--r--tools/run_tests/generated/sources_and_headers.json19
-rw-r--r--tools/run_tests/generated/tests.json24
26 files changed, 662 insertions, 143 deletions
diff --git a/BUILD b/BUILD
index 9f16f7f3ed..4d0b1ef2db 100644
--- a/BUILD
+++ b/BUILD
@@ -55,7 +55,7 @@ config_setting(
config_setting(
name = "windows",
- values = { "cpu": "x64_windows" },
+ values = {"cpu": "x64_windows"},
)
config_setting(
@@ -907,6 +907,7 @@ grpc_cc_library(
"src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_internal.h",
"src/core/lib/slice/slice_string_helpers.h",
+ "src/core/lib/slice/slice_weak_hash_table.h",
"src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h",
"src/core/lib/surface/call_test_only.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ad4503299f..09306d4df6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -594,6 +594,7 @@ add_dependencies(buildtests_cxx server_early_return_test)
add_dependencies(buildtests_cxx server_request_call_test)
add_dependencies(buildtests_cxx shutdown_test)
add_dependencies(buildtests_cxx slice_hash_table_test)
+add_dependencies(buildtests_cxx slice_weak_hash_table_test)
add_dependencies(buildtests_cxx stats_test)
add_dependencies(buildtests_cxx status_metadata_test)
add_dependencies(buildtests_cxx status_test)
@@ -12157,6 +12158,42 @@ target_link_libraries(slice_hash_table_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(slice_weak_hash_table_test
+ test/core/slice/slice_weak_hash_table_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(slice_weak_hash_table_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+ PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+ PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+ PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+ PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(slice_weak_hash_table_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_test_util
+ grpc
+ gpr_test_util
+ gpr
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(stats_test
test/core/debug/stats_test.cc
third_party/googletest/googletest/src/gtest-all.cc
diff --git a/Makefile b/Makefile
index e86dbe87ac..731fca8cb6 100644
--- a/Makefile
+++ b/Makefile
@@ -1181,6 +1181,7 @@ server_early_return_test: $(BINDIR)/$(CONFIG)/server_early_return_test
server_request_call_test: $(BINDIR)/$(CONFIG)/server_request_call_test
shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test
slice_hash_table_test: $(BINDIR)/$(CONFIG)/slice_hash_table_test
+slice_weak_hash_table_test: $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test
stats_test: $(BINDIR)/$(CONFIG)/stats_test
status_metadata_test: $(BINDIR)/$(CONFIG)/status_metadata_test
status_test: $(BINDIR)/$(CONFIG)/status_test
@@ -1641,6 +1642,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/server_request_call_test \
$(BINDIR)/$(CONFIG)/shutdown_test \
$(BINDIR)/$(CONFIG)/slice_hash_table_test \
+ $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test \
$(BINDIR)/$(CONFIG)/stats_test \
$(BINDIR)/$(CONFIG)/status_metadata_test \
$(BINDIR)/$(CONFIG)/status_test \
@@ -1788,6 +1790,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/server_request_call_test \
$(BINDIR)/$(CONFIG)/shutdown_test \
$(BINDIR)/$(CONFIG)/slice_hash_table_test \
+ $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test \
$(BINDIR)/$(CONFIG)/stats_test \
$(BINDIR)/$(CONFIG)/status_metadata_test \
$(BINDIR)/$(CONFIG)/status_test \
@@ -2215,6 +2218,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/shutdown_test || ( echo test shutdown_test failed ; exit 1 )
$(E) "[RUN] Testing slice_hash_table_test"
$(Q) $(BINDIR)/$(CONFIG)/slice_hash_table_test || ( echo test slice_hash_table_test failed ; exit 1 )
+ $(E) "[RUN] Testing slice_weak_hash_table_test"
+ $(Q) $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test || ( echo test slice_weak_hash_table_test failed ; exit 1 )
$(E) "[RUN] Testing stats_test"
$(Q) $(BINDIR)/$(CONFIG)/stats_test || ( echo test stats_test failed ; exit 1 )
$(E) "[RUN] Testing status_metadata_test"
@@ -17974,6 +17979,49 @@ endif
endif
+SLICE_WEAK_HASH_TABLE_TEST_SRC = \
+ test/core/slice/slice_weak_hash_table_test.cc \
+
+SLICE_WEAK_HASH_TABLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SLICE_WEAK_HASH_TABLE_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: $(PROTOBUF_DEP) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/slice/slice_weak_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_slice_weak_hash_table_test: $(SLICE_WEAK_HASH_TABLE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(SLICE_WEAK_HASH_TABLE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
STATS_TEST_SRC = \
test/core/debug/stats_test.cc \
diff --git a/README.md b/README.md
index fc72c7c1ba..e045e331f2 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,3 @@
-[![Build Status](https://grpc-testing.appspot.com/job/gRPC_master/badge/icon)](https://grpc-testing.appspot.com/job/gRPC_master)
-
[gRPC - An RPC library and framework](http://github.com/grpc/grpc)
===================================
diff --git a/build.yaml b/build.yaml
index abd4a8220a..56f1b40d63 100644
--- a/build.yaml
+++ b/build.yaml
@@ -404,6 +404,7 @@ filegroups:
- src/core/lib/slice/slice_hash_table.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_string_helpers.h
+ - src/core/lib/slice/slice_weak_hash_table.h
- src/core/lib/surface/api_trace.h
- src/core/lib/surface/call.h
- src/core/lib/surface/call_test_only.h
@@ -4833,6 +4834,18 @@ targets:
- gpr_test_util
- gpr
uses_polling: false
+- name: slice_weak_hash_table_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - test/core/slice/slice_weak_hash_table_test.cc
+ deps:
+ - grpc_test_util
+ - grpc
+ - gpr_test_util
+ - gpr
+ uses_polling: false
- name: stats_test
gtest: true
build: test
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index be1eccb8f9..e7b0e8c5ea 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -409,6 +409,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_hash_table.h',
'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_string_helpers.h',
+ 'src/core/lib/slice/slice_weak_hash_table.h',
'src/core/lib/surface/api_trace.h',
'src/core/lib/surface/call.h',
'src/core/lib/surface/call_test_only.h',
@@ -587,6 +588,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_hash_table.h',
'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_string_helpers.h',
+ 'src/core/lib/slice/slice_weak_hash_table.h',
'src/core/lib/surface/api_trace.h',
'src/core/lib/surface/call.h',
'src/core/lib/surface/call_test_only.h',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 41f61d9cb8..dafd50a095 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -421,6 +421,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_hash_table.h',
'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_string_helpers.h',
+ 'src/core/lib/slice/slice_weak_hash_table.h',
'src/core/lib/surface/api_trace.h',
'src/core/lib/surface/call.h',
'src/core/lib/surface/call_test_only.h',
@@ -914,6 +915,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_hash_table.h',
'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_string_helpers.h',
+ 'src/core/lib/slice/slice_weak_hash_table.h',
'src/core/lib/surface/api_trace.h',
'src/core/lib/surface/call.h',
'src/core/lib/surface/call_test_only.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 90cf3fb0af..090e73041f 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -347,6 +347,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/slice/slice_hash_table.h )
s.files += %w( src/core/lib/slice/slice_internal.h )
s.files += %w( src/core/lib/slice/slice_string_helpers.h )
+ s.files += %w( src/core/lib/slice/slice_weak_hash_table.h )
s.files += %w( src/core/lib/surface/api_trace.h )
s.files += %w( src/core/lib/surface/call.h )
s.files += %w( src/core/lib/surface/call_test_only.h )
diff --git a/package.xml b/package.xml
index 99badc438f..61fcd259a8 100644
--- a/package.xml
+++ b/package.xml
@@ -354,6 +354,7 @@
<file baseinstalldir="/" name="src/core/lib/slice/slice_hash_table.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_internal.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_string_helpers.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/slice/slice_weak_hash_table.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/api_trace.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/call.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/call_test_only.h" role="src" />
diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc
index ab7d869758..ffdeb8f6b0 100644
--- a/src/compiler/objective_c_generator.cc
+++ b/src/compiler/objective_c_generator.cc
@@ -212,37 +212,49 @@ void PrintMethodImplementations(Printer* printer,
return output;
}
-::grpc::string GetHeader(const ServiceDescriptor* service) {
+::grpc::string GetProtocol(const ServiceDescriptor* service) {
::grpc::string output;
- {
- // Scope the output stream so it closes and finalizes output to the string.
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- Printer printer(&output_stream, '$');
-
- map< ::grpc::string, ::grpc::string> vars = {
- {"service_class", ServiceClassName(service)}};
- printer.Print(vars, "@protocol $service_class$ <NSObject>\n\n");
+ // Scope the output stream so it closes and finalizes output to the string.
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ Printer printer(&output_stream, '$');
- for (int i = 0; i < service->method_count(); i++) {
- PrintMethodDeclarations(&printer, service->method(i));
- }
- printer.Print("@end\n\n");
+ map< ::grpc::string, ::grpc::string> vars = {
+ {"service_class", ServiceClassName(service)}};
- printer.Print(
- "/**\n"
- " * Basic service implementation, over gRPC, that only does\n"
- " * marshalling and parsing.\n"
- " */\n");
- printer.Print(vars,
- "@interface $service_class$ :"
- " GRPCProtoService<$service_class$>\n");
- printer.Print(
- "- (instancetype)initWithHost:(NSString *)host"
- " NS_DESIGNATED_INITIALIZER;\n");
- printer.Print("+ (instancetype)serviceWithHost:(NSString *)host;\n");
- printer.Print("@end\n");
+ printer.Print(vars, "@protocol $service_class$ <NSObject>\n\n");
+ for (int i = 0; i < service->method_count(); i++) {
+ PrintMethodDeclarations(&printer, service->method(i));
}
+ printer.Print("@end\n\n");
+
+ return output;
+}
+
+::grpc::string GetInterface(const ServiceDescriptor* service) {
+ ::grpc::string output;
+
+ // Scope the output stream so it closes and finalizes output to the string.
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ Printer printer(&output_stream, '$');
+
+ map< ::grpc::string, ::grpc::string> vars = {
+ {"service_class", ServiceClassName(service)}};
+
+ printer.Print(vars,
+ "/**\n"
+ " * Basic service implementation, over gRPC, that only does\n"
+ " * marshalling and parsing.\n"
+ " */\n");
+ printer.Print(vars,
+ "@interface $service_class$ :"
+ " GRPCProtoService<$service_class$>\n");
+ printer.Print(
+ "- (instancetype)initWithHost:(NSString *)host"
+ " NS_DESIGNATED_INITIALIZER;\n");
+ printer.Print("+ (instancetype)serviceWithHost:(NSString *)host;\n");
+ printer.Print("@end\n");
+
return output;
}
@@ -258,26 +270,32 @@ void PrintMethodImplementations(Printer* printer,
{"service_class", ServiceClassName(service)},
{"package", service->file()->package()}};
- printer.Print(vars, "@implementation $service_class$\n\n");
+ printer.Print(vars,
+ "@implementation $service_class$\n\n"
+ "// Designated initializer\n"
+ "- (instancetype)initWithHost:(NSString *)host {\n"
+ " self = [super initWithHost:host\n"
+ " packageName:@\"$package$\"\n"
+ " serviceName:@\"$service_name$\"];\n"
+ " return self;\n"
+ "}\n\n");
- printer.Print("// Designated initializer\n");
- printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
- printer.Print(
- vars,
- " return (self = [super initWithHost:host"
- " packageName:@\"$package$\" serviceName:@\"$service_name$\"]);\n");
- printer.Print("}\n\n");
printer.Print(
"// Override superclass initializer to disallow different"
- " package and service names.\n");
- printer.Print("- (instancetype)initWithHost:(NSString *)host\n");
- printer.Print(" packageName:(NSString *)packageName\n");
- printer.Print(" serviceName:(NSString *)serviceName {\n");
- printer.Print(" return [self initWithHost:host];\n");
- printer.Print("}\n\n");
- printer.Print("+ (instancetype)serviceWithHost:(NSString *)host {\n");
- printer.Print(" return [[self alloc] initWithHost:host];\n");
- printer.Print("}\n\n\n");
+ " package and service names.\n"
+ "- (instancetype)initWithHost:(NSString *)host\n"
+ " packageName:(NSString *)packageName\n"
+ " serviceName:(NSString *)serviceName {\n"
+ " return [self initWithHost:host];\n"
+ "}\n\n");
+
+ printer.Print(
+ "#pragma mark - Class Methods\n\n"
+ "+ (instancetype)serviceWithHost:(NSString *)host {\n"
+ " return [[self alloc] initWithHost:host];\n"
+ "}\n\n");
+
+ printer.Print("#pragma mark - Method Implementations\n\n");
for (int i = 0; i < service->method_count(); i++) {
PrintMethodImplementations(&printer, service->method(i));
diff --git a/src/compiler/objective_c_generator.h b/src/compiler/objective_c_generator.h
index d3aed76c4f..eb1c7ff005 100644
--- a/src/compiler/objective_c_generator.h
+++ b/src/compiler/objective_c_generator.h
@@ -31,9 +31,13 @@ using ::grpc::string;
// Returns forward declaration of classes in the generated header file.
string GetAllMessageClasses(const FileDescriptor* file);
-// Returns the content to be included in the "global_scope" insertion point of
-// the generated header file.
-string GetHeader(const ServiceDescriptor* service);
+// Returns the content to be included defining the @protocol segment at the
+// insertion point of the generated implementation file.
+string GetProtocol(const ServiceDescriptor* service);
+
+// Returns the content to be included defining the @interface segment at the
+// insertion point of the generated implementation file.
+string GetInterface(const ServiceDescriptor* service);
// Returns the content to be included in the "global_scope" insertion point of
// the generated implementation file.
diff --git a/src/compiler/objective_c_generator_helpers.h b/src/compiler/objective_c_generator_helpers.h
index 4004e6aef8..a284da97f4 100644
--- a/src/compiler/objective_c_generator_helpers.h
+++ b/src/compiler/objective_c_generator_helpers.h
@@ -40,5 +40,45 @@ inline string ServiceClassName(const ServiceDescriptor* service) {
string prefix = file->options().objc_class_prefix();
return prefix + service->name();
}
+
+inline ::grpc::string LocalImport(const ::grpc::string& import) {
+ return ::grpc::string("#import \"" + import + "\"\n");
+}
+
+inline ::grpc::string SystemImport(const ::grpc::string& import) {
+ return ::grpc::string("#import <" + import + ">\n");
+}
+
+inline ::grpc::string PreprocConditional(::grpc::string symbol, bool invert) {
+ return invert ? "!defined(" + symbol + ") || !" + symbol
+ : "defined(" + symbol + ") && " + symbol;
+}
+
+inline ::grpc::string PreprocIf(const ::grpc::string& symbol,
+ const ::grpc::string& if_true) {
+ return ::grpc::string("#if " + PreprocConditional(symbol, false) + "\n" +
+ if_true + "#endif\n");
+}
+
+inline ::grpc::string PreprocIfNot(const ::grpc::string& symbol,
+ const ::grpc::string& if_true) {
+ return ::grpc::string("#if " + PreprocConditional(symbol, true) + "\n" +
+ if_true + "#endif\n");
+}
+
+inline ::grpc::string PreprocIfElse(const ::grpc::string& symbol,
+ const ::grpc::string& if_true,
+ const ::grpc::string& if_false) {
+ return ::grpc::string("#if " + PreprocConditional(symbol, false) + "\n" +
+ if_true + "#else\n" + if_false + "#endif\n");
+}
+
+inline ::grpc::string PreprocIfNotElse(const ::grpc::string& symbol,
+ const ::grpc::string& if_true,
+ const ::grpc::string& if_false) {
+ return ::grpc::string("#if " + PreprocConditional(symbol, true) + "\n" +
+ if_true + "#else\n" + if_false + "#endif\n");
+}
+
} // namespace grpc_objective_c_generator
#endif // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H
diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc
index d5d488e84d..76703d79cd 100644
--- a/src/compiler/objective_c_plugin.cc
+++ b/src/compiler/objective_c_plugin.cc
@@ -29,12 +29,42 @@
using ::google::protobuf::compiler::objectivec::
IsProtobufLibraryBundledProtoFile;
using ::google::protobuf::compiler::objectivec::ProtobufLibraryFrameworkName;
+using ::grpc_objective_c_generator::LocalImport;
+using ::grpc_objective_c_generator::PreprocIfElse;
+using ::grpc_objective_c_generator::PreprocIfNot;
+using ::grpc_objective_c_generator::SystemImport;
+
+namespace {
+
+inline ::grpc::string ImportProtoHeaders(
+ const grpc::protobuf::FileDescriptor* dep, const char* indent) {
+ ::grpc::string header = grpc_objective_c_generator::MessageHeaderName(dep);
+
+ if (!IsProtobufLibraryBundledProtoFile(dep)) {
+ return indent + LocalImport(header);
+ }
+
+ ::grpc::string base_name = header;
+ grpc_generator::StripPrefix(&base_name, "google/protobuf/");
+ // create the import code snippet
+ ::grpc::string framework_header =
+ ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name;
+
+ static const ::grpc::string kFrameworkImportsCondition =
+ "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS";
+ return PreprocIfElse(kFrameworkImportsCondition,
+ indent + SystemImport(framework_header),
+ indent + LocalImport(header));
+}
+
+} // namespace
class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
public:
ObjectiveCGrpcGenerator() {}
virtual ~ObjectiveCGrpcGenerator() {}
+ public:
virtual bool Generate(const grpc::protobuf::FileDescriptor* file,
const ::grpc::string& parameter,
grpc::protobuf::compiler::GeneratorContext* context,
@@ -44,97 +74,68 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
return true;
}
+ static const ::grpc::string kNonNullBegin = "NS_ASSUME_NONNULL_BEGIN\n";
+ static const ::grpc::string kNonNullEnd = "NS_ASSUME_NONNULL_END\n";
+ static const ::grpc::string kProtocolOnly = "GPB_GRPC_PROTOCOL_ONLY";
+ static const ::grpc::string kForwardDeclare =
+ "GPB_GRPC_FORWARD_DECLARE_MESSAGE_PROTO";
+
::grpc::string file_name =
google::protobuf::compiler::objectivec::FilePath(file);
- ::grpc::string prefix = file->options().objc_class_prefix();
{
// Generate .pbrpc.h
- ::grpc::string imports =
- ::grpc::string("#if !GPB_GRPC_FORWARD_DECLARE_MESSAGE_PROTO\n") +
- "#import \"" + file_name +
- ".pbobjc.h\"\n"
- "#endif\n\n"
- "#import <ProtoRPC/ProtoService.h>\n"
- "#import <ProtoRPC/ProtoRPC.h>\n"
- "#import <RxLibrary/GRXWriteable.h>\n"
- "#import <RxLibrary/GRXWriter.h>\n";
-
- ::grpc::string proto_imports;
- proto_imports += "#if GPB_GRPC_FORWARD_DECLARE_MESSAGE_PROTO\n" +
- grpc_objective_c_generator::GetAllMessageClasses(file) +
- "#else\n";
+ ::grpc::string imports = LocalImport(file_name + ".pbobjc.h");
+
+ ::grpc::string system_imports = SystemImport("ProtoRPC/ProtoService.h") +
+ SystemImport("ProtoRPC/ProtoRPC.h") +
+ SystemImport("RxLibrary/GRXWriteable.h") +
+ SystemImport("RxLibrary/GRXWriter.h");
+
+ ::grpc::string forward_declarations = "@class GRPCProtoCall;\n\n";
+
+ ::grpc::string class_declarations =
+ grpc_objective_c_generator::GetAllMessageClasses(file);
+
+ ::grpc::string class_imports;
for (int i = 0; i < file->dependency_count(); i++) {
- ::grpc::string header =
- grpc_objective_c_generator::MessageHeaderName(file->dependency(i));
- const grpc::protobuf::FileDescriptor* dependency = file->dependency(i);
- if (IsProtobufLibraryBundledProtoFile(dependency)) {
- ::grpc::string base_name = header;
- grpc_generator::StripPrefix(&base_name, "google/protobuf/");
- // create the import code snippet
- proto_imports +=
- " #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n"
- " #import <" +
- ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name +
- ">\n"
- " #else\n"
- " #import \"" +
- header +
- "\"\n"
- " #endif\n";
- } else {
- proto_imports += ::grpc::string(" #import \"") + header + "\"\n";
- }
+ class_imports += ImportProtoHeaders(file->dependency(i), " ");
}
- proto_imports += "#endif\n";
- ::grpc::string declarations;
+ ::grpc::string protocols;
for (int i = 0; i < file->service_count(); i++) {
const grpc::protobuf::ServiceDescriptor* service = file->service(i);
- declarations += grpc_objective_c_generator::GetHeader(service);
+ protocols += grpc_objective_c_generator::GetProtocol(service);
}
- static const ::grpc::string kNonNullBegin =
- "\nNS_ASSUME_NONNULL_BEGIN\n\n";
- static const ::grpc::string kNonNullEnd = "\nNS_ASSUME_NONNULL_END\n";
+ ::grpc::string interfaces;
+ for (int i = 0; i < file->service_count(); i++) {
+ const grpc::protobuf::ServiceDescriptor* service = file->service(i);
+ interfaces += grpc_objective_c_generator::GetInterface(service);
+ }
Write(context, file_name + ".pbrpc.h",
- imports + '\n' + proto_imports + '\n' + kNonNullBegin +
- declarations + kNonNullEnd);
+ PreprocIfNot(kForwardDeclare, imports) + "\n" +
+ PreprocIfNot(kProtocolOnly, system_imports) + "\n" +
+ PreprocIfElse(kForwardDeclare, class_declarations,
+ class_imports) +
+ "\n" + forward_declarations + "\n" + kNonNullBegin + "\n" +
+ protocols + "\n" + PreprocIfNot(kProtocolOnly, interfaces) +
+ "\n" + kNonNullEnd + "\n");
}
{
// Generate .pbrpc.m
- ::grpc::string imports = ::grpc::string("#import \"") + file_name +
- ".pbrpc.h\"\n"
- "#import \"" +
- file_name +
- ".pbobjc.h\"\n\n"
- "#import <ProtoRPC/ProtoRPC.h>\n"
- "#import <RxLibrary/GRXWriter+Immediate.h>\n";
+ ::grpc::string imports = LocalImport(file_name + ".pbrpc.h") +
+ LocalImport(file_name + ".pbobjc.h") +
+ SystemImport("ProtoRPC/ProtoRPC.h") +
+ SystemImport("RxLibrary/GRXWriter+Immediate.h");
+
+ ::grpc::string class_imports;
for (int i = 0; i < file->dependency_count(); i++) {
- ::grpc::string header =
- grpc_objective_c_generator::MessageHeaderName(file->dependency(i));
- const grpc::protobuf::FileDescriptor* dependency = file->dependency(i);
- if (IsProtobufLibraryBundledProtoFile(dependency)) {
- ::grpc::string base_name = header;
- grpc_generator::StripPrefix(&base_name, "google/protobuf/");
- // create the import code snippet
- imports +=
- "#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n"
- " #import <" +
- ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name +
- ">\n"
- "#else\n"
- " #import \"" +
- header +
- "\"\n"
- "#endif\n";
- } else {
- imports += ::grpc::string("#import \"") + header + "\"\n";
- }
+ class_imports += ImportProtoHeaders(file->dependency(i), "");
}
::grpc::string definitions;
@@ -143,7 +144,9 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
definitions += grpc_objective_c_generator::GetSource(service);
}
- Write(context, file_name + ".pbrpc.m", imports + '\n' + definitions);
+ Write(context, file_name + ".pbrpc.m",
+ PreprocIfNot(kProtocolOnly,
+ imports + "\n" + class_imports + "\n" + definitions));
}
return true;
diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc
index e7d72d1fde..3e2faa57bc 100644
--- a/src/core/ext/filters/client_channel/backup_poller.cc
+++ b/src/core/ext/filters/client_channel/backup_poller.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -127,13 +127,7 @@ static void run_poller(void* arg, grpc_error* error) {
&p->run_poller_closure);
}
-void grpc_client_channel_start_backup_polling(
- grpc_pollset_set* interested_parties) {
- gpr_once_init(&g_once, init_globals);
- if (g_poll_interval_ms == 0) {
- return;
- }
- gpr_mu_lock(&g_poller_mu);
+static void g_poller_init_locked() {
if (g_poller == nullptr) {
g_poller = static_cast<backup_poller*>(gpr_zalloc(sizeof(backup_poller)));
g_poller->pollset =
@@ -149,7 +143,16 @@ void grpc_client_channel_start_backup_polling(
grpc_core::ExecCtx::Get()->Now() + g_poll_interval_ms,
&g_poller->run_poller_closure);
}
+}
+void grpc_client_channel_start_backup_polling(
+ grpc_pollset_set* interested_parties) {
+ gpr_once_init(&g_once, init_globals);
+ if (g_poll_interval_ms == 0) {
+ return;
+ }
+ gpr_mu_lock(&g_poller_mu);
+ g_poller_init_locked();
gpr_ref(&g_poller->refs);
/* Get a reference to g_poller->pollset before releasing g_poller_mu to make
* TSAN happy. Otherwise, reading from g_poller (i.e g_poller->pollset) after
diff --git a/src/core/ext/filters/client_channel/backup_poller.h b/src/core/ext/filters/client_channel/backup_poller.h
index 45bdf10d6c..7285b9b93e 100644
--- a/src/core/ext/filters/client_channel/backup_poller.h
+++ b/src/core/ext/filters/client_channel/backup_poller.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.cc b/src/core/lib/security/credentials/fake/fake_credentials.cc
index 46311fa122..858ab6b41b 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.cc
+++ b/src/core/lib/security/credentials/fake/fake_credentials.cc
@@ -32,9 +32,6 @@
/* -- Fake transport security credentials. -- */
-#define GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS \
- "grpc.fake_security.expected_targets"
-
static grpc_security_status fake_transport_security_create_security_connector(
grpc_channel_credentials* c, grpc_call_credentials* call_creds,
const char* target, const grpc_channel_args* args,
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.h b/src/core/lib/security/credentials/fake/fake_credentials.h
index 5166e43167..e89e6e24cc 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.h
+++ b/src/core/lib/security/credentials/fake/fake_credentials.h
@@ -23,6 +23,9 @@
#include "src/core/lib/security/credentials/credentials.h"
+#define GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS \
+ "grpc.fake_security.expected_targets"
+
/* -- Fake transport security credentials. -- */
/* Creates a fake transport security credentials object for testing. */
diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc
index a57c895374..3cc151bec7 100644
--- a/src/core/lib/security/security_connector/security_connector.cc
+++ b/src/core/lib/security/security_connector/security_connector.cc
@@ -463,6 +463,15 @@ static bool fake_channel_check_call_host(grpc_channel_security_connector* sc,
grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked,
grpc_error** error) {
+ grpc_fake_channel_security_connector* c =
+ reinterpret_cast<grpc_fake_channel_security_connector*>(sc);
+ if (c->is_lb_channel) {
+ // TODO(dgq): verify that the host (ie, authority header) matches that of
+ // the LB, as opposed to that of the backends.
+ } else {
+ // TODO(dgq): verify that the host (ie, authority header) matches that of
+ // the backend, not the LB's.
+ }
return true;
}
diff --git a/src/core/lib/slice/slice_weak_hash_table.h b/src/core/lib/slice/slice_weak_hash_table.h
new file mode 100644
index 0000000000..9d0ddfc2d2
--- /dev/null
+++ b/src/core/lib/slice/slice_weak_hash_table.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GRPC_CORE_LIB_SLICE_SLICE_WEAK_HASH_TABLE_H
+#define GRPC_CORE_LIB_SLICE_SLICE_WEAK_HASH_TABLE_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/gprpp/memory.h"
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
+#include "src/core/lib/slice/slice_internal.h"
+
+/// Weak hash table implementation.
+///
+/// This entries in this table are weak: an entry may be removed at any time due
+/// to a number of reasons: memory pressure, hash collisions, etc.
+///
+/// The keys are \a grpc_slice objects. The values are of arbitrary type.
+///
+/// This class is thread unsafe. It's the caller's responsibility to ensure
+/// proper locking when accessing its methods.
+
+namespace grpc_core {
+
+template <typename T, size_t Size>
+class SliceWeakHashTable : public RefCounted<SliceWeakHashTable<T, Size>> {
+ public:
+ /// Creates a new table of at most \a size entries.
+ static RefCountedPtr<SliceWeakHashTable> Create() {
+ return MakeRefCounted<SliceWeakHashTable<T, Size>>();
+ }
+
+ /// Add a mapping from \a key to \a value, taking ownership of \a key. This
+ /// operation will always succeed. It may discard older entries.
+ void Add(grpc_slice key, T value) {
+ const size_t idx = grpc_slice_hash(key) % Size;
+ entries_[idx].Set(key, std::move(value));
+ return;
+ }
+
+ /// Returns the value from the table associated with / \a key or null if not
+ /// found.
+ const T* Get(const grpc_slice key) const {
+ const size_t idx = grpc_slice_hash(key) % Size;
+ const auto& entry = entries_[idx];
+ return grpc_slice_eq(entry.key(), key) ? entry.value() : nullptr;
+ }
+
+ private:
+ // So New() can call our private ctor.
+ template <typename T2, typename... Args>
+ friend T2* New(Args&&... args);
+
+ SliceWeakHashTable() = default;
+ ~SliceWeakHashTable() = default;
+
+ /// The type of the table "rows".
+ class Entry {
+ public:
+ Entry() = default;
+ ~Entry() {
+ if (is_set_) grpc_slice_unref_internal(key_);
+ }
+ grpc_slice key() const { return key_; }
+
+ /// Return the entry's value, or null if unset.
+ const T* value() const {
+ if (!is_set_) return nullptr;
+ return &value_;
+ }
+
+ /// Set the \a key and \a value (which is moved) for the entry.
+ void Set(grpc_slice key, T&& value) {
+ if (is_set_) grpc_slice_unref_internal(key_);
+ key_ = key;
+ value_ = std::move(value);
+ is_set_ = true;
+ }
+
+ private:
+ grpc_slice key_;
+ T value_;
+ bool is_set_ = false;
+ };
+
+ Entry entries_[Size];
+};
+
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_SLICE_SLICE_WEAK_HASH_TABLE_H */
diff --git a/test/core/slice/BUILD b/test/core/slice/BUILD
index 226aed1db9..9a1a506a43 100644
--- a/test/core/slice/BUILD
+++ b/test/core/slice/BUILD
@@ -23,8 +23,8 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
grpc_fuzzer(
name = "percent_encode_fuzzer",
srcs = ["percent_encode_fuzzer.cc"],
- language = "C++",
corpus = "percent_encode_corpus",
+ language = "C++",
deps = [
"//:gpr",
"//:grpc",
@@ -35,8 +35,8 @@ grpc_fuzzer(
grpc_fuzzer(
name = "percent_decode_fuzzer",
srcs = ["percent_decode_fuzzer.cc"],
- language = "C++",
corpus = "percent_decode_corpus",
+ language = "C++",
deps = [
"//:gpr",
"//:grpc",
@@ -59,8 +59,13 @@ grpc_cc_test(
grpc_cc_test(
name = "slice_test",
srcs = ["slice_test.cc"],
- deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
)
grpc_cc_test(
@@ -78,18 +83,43 @@ grpc_cc_test(
grpc_cc_test(
name = "slice_buffer_test",
srcs = ["slice_buffer_test.cc"],
- deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
)
grpc_cc_test(
name = "slice_hash_table_test",
srcs = ["slice_hash_table_test.cc"],
- deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+ external_deps = [
+ "gtest",
+ ],
language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
+ name = "slice_weak_hash_table_test",
+ srcs = ["slice_weak_hash_table_test.cc"],
external_deps = [
"gtest",
],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
)
grpc_cc_test(
diff --git a/test/core/slice/slice_weak_hash_table_test.cc b/test/core/slice/slice_weak_hash_table_test.cc
new file mode 100644
index 0000000000..4711d2fd26
--- /dev/null
+++ b/test/core/slice/slice_weak_hash_table_test.cc
@@ -0,0 +1,105 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/lib/slice/slice_weak_hash_table.h"
+
+#include <cstring>
+#include <sstream>
+
+#include <gtest/gtest.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "test/core/util/test_config.h"
+
+namespace grpc_core {
+namespace {
+
+grpc_slice BuildRefCountedKey(const char* key_str) {
+ const size_t key_length = strlen(key_str);
+ grpc_slice key = grpc_slice_malloc_large(key_length);
+ memcpy(GRPC_SLICE_START_PTR(key), key_str, key_length);
+ return key;
+}
+
+TEST(SliceWeakHashTable, Basic) {
+ auto table = SliceWeakHashTable<UniquePtr<char>, 10>::Create();
+ // Single key-value insertion.
+ grpc_slice key = BuildRefCountedKey("key");
+ grpc_slice_ref(key); // Get doesn't own.
+ table->Add(key, UniquePtr<char>(gpr_strdup("value")));
+ ASSERT_NE(table->Get(key), nullptr);
+ ASSERT_STREQ(table->Get(key)->get(), "value");
+ grpc_slice_unref(key);
+ // Unknown key.
+ ASSERT_EQ(table->Get(grpc_slice_from_static_string("unknown_key")), nullptr);
+}
+
+TEST(SliceWeakHashTable, ValueTypeConstructor) {
+ struct Value {
+ Value() : a(123) {}
+ int a;
+ };
+ auto table = SliceWeakHashTable<Value, 1>::Create();
+ grpc_slice key = BuildRefCountedKey("key");
+ grpc_slice_ref(key); // Get doesn't own.
+ table->Add(key, Value());
+ ASSERT_EQ(table->Get(key)->a, 123);
+ grpc_slice_unref(key);
+}
+
+TEST(SliceWeakHashTable, ForceOverload) {
+ constexpr int kTableSize = 10;
+ auto table = SliceWeakHashTable<UniquePtr<char>, kTableSize>::Create();
+ // Insert a multiple of the maximum size table.
+ for (int i = 0; i < kTableSize * 2; ++i) {
+ std::ostringstream oss;
+ oss << "key-" << i;
+ grpc_slice key = BuildRefCountedKey(oss.str().c_str());
+ oss.clear();
+ oss << "value-" << i;
+ table->Add(key, UniquePtr<char>(gpr_strdup(oss.str().c_str())));
+ }
+ // Verify that some will have been replaced.
+ int num_missing = 0;
+ for (int i = 0; i < kTableSize * 2; ++i) {
+ std::ostringstream oss;
+ oss << "key-" << i;
+ grpc_slice key = BuildRefCountedKey(oss.str().c_str());
+ if (table->Get(key) == nullptr) num_missing++;
+ grpc_slice_unref(key);
+ }
+ // At least kTableSize elements will be missing.
+ ASSERT_GE(num_missing, kTableSize);
+}
+
+} // namespace
+} // namespace grpc_core
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ grpc_test_init(argc, argv);
+ grpc_core::ExecCtx::GlobalInit();
+ int result = RUN_ALL_TESTS();
+ grpc_core::ExecCtx::GlobalShutdown();
+ return result;
+}
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
index eb354907f6..fcfe860b1c 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -37,6 +37,10 @@
#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/security/credentials/fake/fake_credentials.h"
+#include "src/cpp/server/secure_server_credentials.h"
+
+#include "src/cpp/client/secure_credentials.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@@ -380,15 +384,21 @@ class GrpclbEnd2endTest : public ::testing::Test {
SetNextResolution(addresses);
}
- void ResetStub(int fallback_timeout = 0) {
+ void ResetStub(int fallback_timeout = 0, grpc::string expected_targets = "") {
ChannelArguments args;
args.SetGrpclbFallbackTimeout(fallback_timeout);
args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR,
response_generator_.get());
+ if (!expected_targets.empty()) {
+ args.SetString(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS, expected_targets);
+ }
std::ostringstream uri;
- uri << "fake:///servername_not_used";
- channel_ =
- CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args);
+ uri << "fake:///" << kApplicationTargetName_;
+ // TODO(dgq): templatize tests to run everything using both secure and
+ // insecure channel credentials.
+ std::shared_ptr<ChannelCredentials> creds(new SecureChannelCredentials(
+ grpc_fake_transport_security_credentials_create()));
+ channel_ = CreateCustomChannel(uri.str(), creds, args);
stub_ = grpc::testing::EchoTestService::NewStub(channel_);
}
@@ -566,8 +576,9 @@ class GrpclbEnd2endTest : public ::testing::Test {
std::ostringstream server_address;
server_address << server_host << ":" << port_;
ServerBuilder builder;
- builder.AddListeningPort(server_address.str(),
- InsecureServerCredentials());
+ std::shared_ptr<ServerCredentials> creds(new SecureServerCredentials(
+ grpc_fake_transport_security_server_credentials_create()));
+ builder.AddListeningPort(server_address.str(), creds);
builder.RegisterService(service_);
server_ = builder.BuildAndStart();
cond->notify_one();
@@ -600,6 +611,7 @@ class GrpclbEnd2endTest : public ::testing::Test {
grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator>
response_generator_;
const grpc::string kRequestMessage_ = "Live long and prosper.";
+ const grpc::string kApplicationTargetName_ = "application_target_name";
};
class SingleBalancerTest : public GrpclbEnd2endTest {
@@ -635,6 +647,48 @@ TEST_F(SingleBalancerTest, Vanilla) {
EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName());
}
+TEST_F(SingleBalancerTest, SecureNaming) {
+ ResetStub(0, kApplicationTargetName_ + ";lb");
+ SetNextResolution({AddressData{balancer_servers_[0].port_, true, "lb"}});
+ const size_t kNumRpcsPerAddress = 100;
+ ScheduleResponseForBalancer(
+ 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}),
+ 0);
+ // Make sure that trying to connect works without a call.
+ channel_->GetState(true /* try_to_connect */);
+ // We need to wait for all backends to come online.
+ WaitForAllBackends();
+ // Send kNumRpcsPerAddress RPCs per server.
+ CheckRpcSendOk(kNumRpcsPerAddress * num_backends_);
+
+ // Each backend should have gotten 100 requests.
+ for (size_t i = 0; i < backends_.size(); ++i) {
+ EXPECT_EQ(kNumRpcsPerAddress,
+ backend_servers_[i].service_->request_count());
+ }
+ balancers_[0]->NotifyDoneWithServerlists();
+ // The balancer got a single request.
+ EXPECT_EQ(1U, balancer_servers_[0].service_->request_count());
+ // and sent a single response.
+ EXPECT_EQ(1U, balancer_servers_[0].service_->response_count());
+ // Check LB policy name for the channel.
+ EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName());
+}
+
+TEST_F(SingleBalancerTest, SecureNamingDeathTest) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ // Make sure that we blow up (via abort() from the security connector) when
+ // the name from the balancer doesn't match expectations.
+ ASSERT_DEATH(
+ {
+ ResetStub(0, kApplicationTargetName_ + ";lb");
+ SetNextResolution(
+ {AddressData{balancer_servers_[0].port_, true, "woops"}});
+ channel_->WaitForConnected(grpc_timeout_seconds_to_deadline(1));
+ },
+ "");
+}
+
TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) {
SetNextResolutionAllBalancers();
const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor();
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 60d8975e52..5d67e35d40 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -1125,6 +1125,7 @@ src/core/lib/slice/percent_encoding.h \
src/core/lib/slice/slice_hash_table.h \
src/core/lib/slice/slice_internal.h \
src/core/lib/slice/slice_string_helpers.h \
+src/core/lib/slice/slice_weak_hash_table.h \
src/core/lib/surface/api_trace.h \
src/core/lib/surface/call.h \
src/core/lib/surface/call_test_only.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 84e020fb7f..bf3de8ab22 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1335,6 +1335,7 @@ src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_internal.h \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/slice/slice_string_helpers.h \
+src/core/lib/slice/slice_weak_hash_table.h \
src/core/lib/surface/README.md \
src/core/lib/surface/api_trace.cc \
src/core/lib/surface/api_trace.h \
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 6e80d98ed4..06aa989788 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -4175,6 +4175,23 @@
"gpr",
"gpr_test_util",
"grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "slice_weak_hash_table_test",
+ "src": [
+ "test/core/slice/slice_weak_hash_table_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
"grpc++_test_util",
"grpc_test_util"
],
@@ -8790,6 +8807,7 @@
"src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_internal.h",
"src/core/lib/slice/slice_string_helpers.h",
+ "src/core/lib/slice/slice_weak_hash_table.h",
"src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h",
"src/core/lib/surface/call_test_only.h",
@@ -8933,6 +8951,7 @@
"src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_internal.h",
"src/core/lib/slice/slice_string_helpers.h",
+ "src/core/lib/slice/slice_weak_hash_table.h",
"src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h",
"src/core/lib/surface/call_test_only.h",
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 6748d1c4c6..6ce7ec28c4 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -4465,6 +4465,30 @@
"windows"
],
"cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
+ "name": "slice_weak_hash_table_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
"exclude_configs": [
"tsan"
],