diff --git a/BUILD b/BUILD
index 8600d1f7e86..c8c1d72af9d 100644
--- a/BUILD
+++ b/BUILD
@@ -227,11 +227,11 @@ config_setting(
python_config_settings()
# This should be updated along with build_handwritten.yaml
-g_stands_for = "gesundheit" # @unused
+g_stands_for = "groovy" # @unused
-core_version = "43.0.0" # @unused
+core_version = "44.0.0" # @unused
-version = "1.67.0-dev" # @unused
+version = "1.68.0-dev" # @unused
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",
diff --git a/BoringSSL-Package.swift b/BoringSSL-Package.swift
index 1300fb1aec7..f2e70808d8e 100644
--- a/BoringSSL-Package.swift
+++ b/BoringSSL-Package.swift
@@ -142,6 +142,8 @@ let package = Package(
"src/crypto/kyber/kyber.c",
"src/crypto/lhash/lhash.c",
"src/crypto/mem.c",
+ "src/crypto/mldsa/mldsa.c",
+ "src/crypto/mlkem/mlkem.cc",
"src/crypto/obj/obj.c",
"src/crypto/obj/obj_xref.c",
"src/crypto/pem/pem_all.c",
@@ -162,12 +164,14 @@ let package = Package(
"src/crypto/poly1305/poly1305_vec.c",
"src/crypto/pool/pool.c",
"src/crypto/rand_extra/deterministic.c",
+ "src/crypto/rand_extra/fork_detect.c",
"src/crypto/rand_extra/forkunsafe.c",
"src/crypto/rand_extra/getentropy.c",
"src/crypto/rand_extra/ios.c",
"src/crypto/rand_extra/passive.c",
"src/crypto/rand_extra/rand_extra.c",
"src/crypto/rand_extra/trusty.c",
+ "src/crypto/rand_extra/urandom.c",
"src/crypto/rand_extra/windows.c",
"src/crypto/rc4/rc4.c",
"src/crypto/refcount.c",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3766545debc..169d6d553e3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,11 +25,11 @@
cmake_minimum_required(VERSION 3.13)
set(PACKAGE_NAME "grpc")
-set(PACKAGE_VERSION "1.67.0-dev")
-set(gRPC_CORE_VERSION "43.0.0")
-set(gRPC_CORE_SOVERSION "43")
-set(gRPC_CPP_VERSION "1.67.0-dev")
-set(gRPC_CPP_SOVERSION "1.67")
+set(PACKAGE_VERSION "1.68.0-dev")
+set(gRPC_CORE_VERSION "44.0.0")
+set(gRPC_CORE_SOVERSION "44")
+set(gRPC_CPP_VERSION "1.68.0-dev")
+set(gRPC_CPP_SOVERSION "1.68")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@@ -1591,7 +1591,7 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx xds_fallback_end2end_test)
endif()
- if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx xds_fault_injection_end2end_test)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@@ -35482,7 +35482,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
endif()
endif()
if(gRPC_BUILD_TESTS)
-if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_executable(xds_fault_injection_end2end_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc
diff --git a/Makefile b/Makefile
index 35f58665d34..767a9f3a335 100644
--- a/Makefile
+++ b/Makefile
@@ -367,8 +367,8 @@ E = @echo
Q = @
endif
-CORE_VERSION = 43.0.0
-CPP_VERSION = 1.67.0-dev
+CORE_VERSION = 44.0.0
+CPP_VERSION = 1.68.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -404,7 +404,7 @@ SHARED_EXT_CORE = dll
SHARED_EXT_CPP = dll
SHARED_PREFIX =
-SHARED_VERSION_CORE = -43
+SHARED_VERSION_CORE = -44
SHARED_VERSION_CPP = -1
else ifeq ($(SYSTEM),Darwin)
EXECUTABLE_SUFFIX =
@@ -1848,8 +1848,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libcares.a $(OPENSSL_MERGE_LIBS) $(ZLIB_MERGE_LIBS) $(LDLIBS_SECURE) $(LDLIBS)
else
- $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.43 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libcares.a $(OPENSSL_MERGE_LIBS) $(ZLIB_MERGE_LIBS) $(LDLIBS_SECURE) $(LDLIBS)
- $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.43
+ $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.44 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libcares.a $(OPENSSL_MERGE_LIBS) $(ZLIB_MERGE_LIBS) $(LDLIBS_SECURE) $(LDLIBS)
+ $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.44
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
endif
endif
@@ -1984,6 +1984,8 @@ LIBBORINGSSL_SRC = \
third_party/boringssl-with-bazel/src/crypto/kyber/kyber.c \
third_party/boringssl-with-bazel/src/crypto/lhash/lhash.c \
third_party/boringssl-with-bazel/src/crypto/mem.c \
+ third_party/boringssl-with-bazel/src/crypto/mldsa/mldsa.c \
+ third_party/boringssl-with-bazel/src/crypto/mlkem/mlkem.cc \
third_party/boringssl-with-bazel/src/crypto/obj/obj.c \
third_party/boringssl-with-bazel/src/crypto/obj/obj_xref.c \
third_party/boringssl-with-bazel/src/crypto/pem/pem_all.c \
@@ -2004,12 +2006,14 @@ LIBBORINGSSL_SRC = \
third_party/boringssl-with-bazel/src/crypto/poly1305/poly1305_vec.c \
third_party/boringssl-with-bazel/src/crypto/pool/pool.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/deterministic.c \
+ third_party/boringssl-with-bazel/src/crypto/rand_extra/fork_detect.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/forkunsafe.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/getentropy.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/ios.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/passive.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/rand_extra.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/trusty.c \
+ third_party/boringssl-with-bazel/src/crypto/rand_extra/urandom.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/windows.c \
third_party/boringssl-with-bazel/src/crypto/rc4/rc4.c \
third_party/boringssl-with-bazel/src/crypto/refcount.c \
diff --git a/_metadata.py b/_metadata.py
index 4e8ea328708..26d84a74ff4 100644
--- a/_metadata.py
+++ b/_metadata.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/_metadata.py.template`!!!
-__version__ = """1.67.0.dev0"""
+__version__ = """1.68.0.dev0"""
diff --git a/bazel/experiments.bzl b/bazel/experiments.bzl
index 5ae6526b4ad..1fc7f607ea8 100644
--- a/bazel/experiments.bzl
+++ b/bazel/experiments.bzl
@@ -34,6 +34,7 @@ EXPERIMENT_ENABLES = {
"server_privacy": "server_privacy",
"tcp_frame_size_tuning": "tcp_frame_size_tuning",
"tcp_rcv_lowat": "tcp_rcv_lowat",
+ "time_caching_in_party": "time_caching_in_party",
"trace_record_callops": "trace_record_callops",
"unconstrained_max_quota_buffer_size": "unconstrained_max_quota_buffer_size",
"work_serializer_clears_time_cache": "work_serializer_clears_time_cache",
diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl
index f757bea94b0..e6fbf6304d8 100644
--- a/bazel/grpc_deps.bzl
+++ b/bazel/grpc_deps.bzl
@@ -35,11 +35,11 @@ def grpc_deps():
name = "boringssl",
# Use github mirror instead of https://boringssl.googlesource.com/boringssl
# to obtain a boringssl archive with consistent sha256
- sha256 = "7a35bebd0e1eecbc5bf5bbf5eec03e86686c356802b5540872119bd26f84ecc7",
- strip_prefix = "boringssl-16c8d3db1af20fcc04b5190b25242aadcb1fbb30",
+ sha256 = "c70d519e4ee709b7a74410a5e3a937428b8198d793a3d771be3dd2086ae167c8",
+ strip_prefix = "boringssl-b8b3e6e11166719a8ebfa43c0cde9ad7d57a84f6",
urls = [
- "https://storage.googleapis.com/grpc-bazel-mirror/github.com/google/boringssl/archive/16c8d3db1af20fcc04b5190b25242aadcb1fbb30.tar.gz",
- "https://github.com/google/boringssl/archive/16c8d3db1af20fcc04b5190b25242aadcb1fbb30.tar.gz",
+ "https://storage.googleapis.com/grpc-bazel-mirror/github.com/google/boringssl/archive/b8b3e6e11166719a8ebfa43c0cde9ad7d57a84f6.tar.gz",
+ "https://github.com/google/boringssl/archive/b8b3e6e11166719a8ebfa43c0cde9ad7d57a84f6.tar.gz",
],
)
diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml
index 8f5100705fb..2d75546550c 100644
--- a/build_autogenerated.yaml
+++ b/build_autogenerated.yaml
@@ -21871,7 +21871,6 @@ targets:
platforms:
- linux
- posix
- - mac
- name: xds_gcp_authn_end2end_test
gtest: true
build: test
diff --git a/build_config.rb b/build_config.rb
index 2524b03b765..dec15b3d5ca 100644
--- a/build_config.rb
+++ b/build_config.rb
@@ -13,5 +13,5 @@
# limitations under the License.
module GrpcBuildConfig
- CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-43.dll'
+ CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-44.dll'
end
diff --git a/build_handwritten.yaml b/build_handwritten.yaml
index 67062727e94..c7d5040889f 100644
--- a/build_handwritten.yaml
+++ b/build_handwritten.yaml
@@ -12,11 +12,11 @@ settings:
'#08': Use "-preN" suffixes to identify pre-release versions
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
- core_version: 43.0.0
+ core_version: 44.0.0
csharp_major_version: 2
- g_stands_for: gesundheit
+ g_stands_for: groovy
protobuf_version: 3.27.2
- version: 1.67.0-dev
+ version: 1.68.0-dev
configs:
asan:
CC: clang
diff --git a/config.m4 b/config.m4
index 903e5727bbb..4f5d7504dc7 100644
--- a/config.m4
+++ b/config.m4
@@ -1160,6 +1160,8 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl-with-bazel/src/crypto/kyber/kyber.c \
third_party/boringssl-with-bazel/src/crypto/lhash/lhash.c \
third_party/boringssl-with-bazel/src/crypto/mem.c \
+ third_party/boringssl-with-bazel/src/crypto/mldsa/mldsa.c \
+ third_party/boringssl-with-bazel/src/crypto/mlkem/mlkem.cc \
third_party/boringssl-with-bazel/src/crypto/obj/obj.c \
third_party/boringssl-with-bazel/src/crypto/obj/obj_xref.c \
third_party/boringssl-with-bazel/src/crypto/pem/pem_all.c \
@@ -1180,12 +1182,14 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl-with-bazel/src/crypto/poly1305/poly1305_vec.c \
third_party/boringssl-with-bazel/src/crypto/pool/pool.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/deterministic.c \
+ third_party/boringssl-with-bazel/src/crypto/rand_extra/fork_detect.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/forkunsafe.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/getentropy.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/ios.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/passive.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/rand_extra.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/trusty.c \
+ third_party/boringssl-with-bazel/src/crypto/rand_extra/urandom.c \
third_party/boringssl-with-bazel/src/crypto/rand_extra/windows.c \
third_party/boringssl-with-bazel/src/crypto/rc4/rc4.c \
third_party/boringssl-with-bazel/src/crypto/refcount.c \
@@ -1396,7 +1400,7 @@ if test "$PHP_GRPC" != "no"; then
-D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0 \
-DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1 \
-DGRPC_XDS_USER_AGENT_NAME_SUFFIX='"\"PHP\""' \
- -DGRPC_XDS_USER_AGENT_VERSION_SUFFIX='"\"1.67.0dev\""')
+ -DGRPC_XDS_USER_AGENT_VERSION_SUFFIX='"\"1.68.0dev\""')
PHP_ADD_BUILD_DIR($ext_builddir/src/core/channelz)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/client_channel)
@@ -1681,6 +1685,8 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl-with-bazel/src/crypto/keccak)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl-with-bazel/src/crypto/kyber)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl-with-bazel/src/crypto/lhash)
+ PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl-with-bazel/src/crypto/mldsa)
+ PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl-with-bazel/src/crypto/mlkem)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl-with-bazel/src/crypto/obj)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl-with-bazel/src/crypto/pem)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl-with-bazel/src/crypto/pkcs7)
diff --git a/config.w32 b/config.w32
index 0734ce7cfaf..08788eafbb5 100644
--- a/config.w32
+++ b/config.w32
@@ -1125,6 +1125,8 @@ if (PHP_GRPC != "no") {
"third_party\\boringssl-with-bazel\\src\\crypto\\kyber\\kyber.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\lhash\\lhash.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\mem.c " +
+ "third_party\\boringssl-with-bazel\\src\\crypto\\mldsa\\mldsa.c " +
+ "third_party\\boringssl-with-bazel\\src\\crypto\\mlkem\\mlkem.cc " +
"third_party\\boringssl-with-bazel\\src\\crypto\\obj\\obj.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\obj\\obj_xref.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\pem\\pem_all.c " +
@@ -1145,12 +1147,14 @@ if (PHP_GRPC != "no") {
"third_party\\boringssl-with-bazel\\src\\crypto\\poly1305\\poly1305_vec.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\pool\\pool.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\rand_extra\\deterministic.c " +
+ "third_party\\boringssl-with-bazel\\src\\crypto\\rand_extra\\fork_detect.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\rand_extra\\forkunsafe.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\rand_extra\\getentropy.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\rand_extra\\ios.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\rand_extra\\passive.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\rand_extra\\rand_extra.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\rand_extra\\trusty.c " +
+ "third_party\\boringssl-with-bazel\\src\\crypto\\rand_extra\\urandom.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\rand_extra\\windows.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\rc4\\rc4.c " +
"third_party\\boringssl-with-bazel\\src\\crypto\\refcount.c " +
@@ -1836,6 +1840,8 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl-with-bazel\\src\\crypto\\keccak");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl-with-bazel\\src\\crypto\\kyber");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl-with-bazel\\src\\crypto\\lhash");
+ FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl-with-bazel\\src\\crypto\\mldsa");
+ FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl-with-bazel\\src\\crypto\\mlkem");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl-with-bazel\\src\\crypto\\obj");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl-with-bazel\\src\\crypto\\pem");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl-with-bazel\\src\\crypto\\pkcs7");
diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md
index b11b6438d9b..54fafcb5a52 100644
--- a/doc/g_stands_for.md
+++ b/doc/g_stands_for.md
@@ -66,4 +66,5 @@
- 1.64 'g' stands for ['grateful'](https://github.com/grpc/grpc/tree/v1.64.x)
- 1.65 'g' stands for ['gnarly'](https://github.com/grpc/grpc/tree/v1.65.x)
- 1.66 'g' stands for ['gladiator'](https://github.com/grpc/grpc/tree/v1.66.x)
-- 1.67 'g' stands for ['gesundheit'](https://github.com/grpc/grpc/tree/master)
+- 1.67 'g' stands for ['gesundheit'](https://github.com/grpc/grpc/tree/v1.67.x)
+- 1.68 'g' stands for ['groovy'](https://github.com/grpc/grpc/tree/master)
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index 388db1822d3..350aedf9150 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
- version = '1.67.0-dev'
+ version = '1.68.0-dev'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 3427505b1c3..cff65146c64 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
- version = '1.67.0-dev'
+ version = '1.68.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'
@@ -199,7 +199,7 @@ Pod::Spec.new do |s|
ss.libraries = 'z'
ss.dependency "#{s.name}/Interface", version
ss.dependency "#{s.name}/Privacy", version
- ss.dependency 'BoringSSL-GRPC', '0.0.36'
+ ss.dependency 'BoringSSL-GRPC', '0.0.37'
ss.dependency 'abseil/algorithm/container', abseil_version
ss.dependency 'abseil/base/base', abseil_version
ss.dependency 'abseil/base/config', abseil_version
diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec
index a53a69dfaee..0e3597a65a3 100644
--- a/gRPC-ProtoRPC.podspec
+++ b/gRPC-ProtoRPC.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
- version = '1.67.0-dev'
+ version = '1.68.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'
diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec
index 59c41799e95..0df0aae5152 100644
--- a/gRPC-RxLibrary.podspec
+++ b/gRPC-RxLibrary.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
- version = '1.67.0-dev'
+ version = '1.68.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'https://grpc.io'
diff --git a/gRPC.podspec b/gRPC.podspec
index a5e82d19c36..839b72b339d 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
- version = '1.67.0-dev'
+ version = '1.68.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'
diff --git a/grpc.gemspec b/grpc.gemspec
index b56dffe06e6..ba4316386ff 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -2514,6 +2514,7 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl-with-bazel/src/crypto/asn1/tasn_typ.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/asn1/tasn_utl.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/base64/base64.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/bcm_support.h )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/bio/bio.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/bio/bio_mem.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/bio/connect.c )
@@ -2608,107 +2609,104 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl-with-bazel/src/crypto/evp/scrypt.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/evp/sign.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/ex_data.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/aes.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/aes_nohw.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/aes.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/aes_nohw.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/key_wrap.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/mode_wrappers.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/key_wrap.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/mode_wrappers.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bcm.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/add.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/asm/x86_64-gcc.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/bn.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/bytes.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/cmp.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/ctx.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/div.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/div_extra.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/exponentiation.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/gcd.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/gcd_extra.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/generic.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bcm_interface.h )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/add.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/asm/x86_64-gcc.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/bn.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/bytes.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/cmp.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/ctx.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/div.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/div_extra.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/exponentiation.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/gcd.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/gcd_extra.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/generic.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/internal.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/jacobi.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/montgomery.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/montgomery_inv.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/mul.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/prime.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/random.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/rsaz_exp.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/jacobi.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/montgomery.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/montgomery_inv.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/mul.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/prime.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/random.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/rsaz_exp.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/rsaz_exp.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/shift.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/sqrt.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/aead.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/cipher.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/e_aes.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/e_aesccm.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/shift.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/sqrt.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/aead.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/cipher.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/e_aes.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/e_aesccm.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/internal.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/cmac/cmac.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/cmac/cmac.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/delocate.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/dh/check.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/dh/dh.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/dh/check.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/dh/dh.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/dh/internal.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/digest.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/digests.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/digest.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/digests.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/internal.h )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/md32_common.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/digestsign/digestsign.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/digestsign/digestsign.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/builtin_curves.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec_key.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec_montgomery.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/felem.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec_key.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec_montgomery.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/felem.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/internal.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/oct.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p224-64.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/oct.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p224-64.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256-nistz-table.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256-nistz.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256-nistz.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256-nistz.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256_table.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/scalar.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/simple.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/simple_mul.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/util.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/wnaf.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdh/ecdh.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdsa/ecdsa.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/scalar.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/simple.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/simple_mul.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/util.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/wnaf.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdh/ecdh.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdsa/ecdsa.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdsa/internal.h )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/fips_shared_support.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/hkdf/hkdf.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/hmac/hmac.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/md4/md4.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/hkdf/hkdf.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/hmac/hmac.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/md4/md4.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/md5/internal.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/md5/md5.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/cbc.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/cfb.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/ctr.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/gcm.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/gcm_nohw.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/md5/md5.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/cbc.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/cfb.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/ctr.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/gcm.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/gcm_nohw.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/internal.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/ofb.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/polyval.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/ctrdrbg.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/fork_detect.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/fork_detect.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/getrandom_fillin.h )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/ofb.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/polyval.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/ctrdrbg.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/internal.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/rand.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/urandom.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/blinding.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/rand.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/blinding.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/internal.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/padding.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa_impl.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/self_check/fips.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/self_check/self_check.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/padding.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa_impl.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/self_check/fips.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/self_check/self_check.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/service_indicator/internal.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/service_indicator/service_indicator.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/service_indicator/service_indicator.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/internal.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha1.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha256.c )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha512.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha1.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha256.c.inc )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha512.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/tls/internal.h )
- s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/tls/kdf.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/fipsmodule/tls/kdf.c.inc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/hpke/hpke.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/hrss/hrss.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/hrss/internal.h )
@@ -2720,6 +2718,10 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl-with-bazel/src/crypto/lhash/internal.h )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/lhash/lhash.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/mem.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/mldsa/internal.h )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/mldsa/mldsa.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/mlkem/internal.h )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/mlkem/mlkem.cc )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/obj/obj.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/obj/obj_dat.h )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/obj/obj_xref.c )
@@ -2745,12 +2747,16 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl-with-bazel/src/crypto/pool/internal.h )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/pool/pool.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/rand_extra/deterministic.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/rand_extra/fork_detect.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/rand_extra/forkunsafe.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/rand_extra/getentropy.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/rand_extra/getrandom_fillin.h )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/rand_extra/ios.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/rand_extra/passive.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/rand_extra/rand_extra.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/rand_extra/sysrand_internal.h )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/rand_extra/trusty.c )
+ s.files += %w( third_party/boringssl-with-bazel/src/crypto/rand_extra/urandom.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/rand_extra/windows.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/rc4/rc4.c )
s.files += %w( third_party/boringssl-with-bazel/src/crypto/refcount.c )
@@ -2908,6 +2914,8 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl-with-bazel/src/include/openssl/md4.h )
s.files += %w( third_party/boringssl-with-bazel/src/include/openssl/md5.h )
s.files += %w( third_party/boringssl-with-bazel/src/include/openssl/mem.h )
+ s.files += %w( third_party/boringssl-with-bazel/src/include/openssl/mldsa.h )
+ s.files += %w( third_party/boringssl-with-bazel/src/include/openssl/mlkem.h )
s.files += %w( third_party/boringssl-with-bazel/src/include/openssl/nid.h )
s.files += %w( third_party/boringssl-with-bazel/src/include/openssl/obj.h )
s.files += %w( third_party/boringssl-with-bazel/src/include/openssl/obj_mac.h )
diff --git a/include/grpcpp/version_info.h b/include/grpcpp/version_info.h
index f3785e640cb..e9de5915e61 100644
--- a/include/grpcpp/version_info.h
+++ b/include/grpcpp/version_info.h
@@ -19,9 +19,9 @@
#define GRPCPP_VERSION_INFO_H
#define GRPC_CPP_VERSION_MAJOR 1
-#define GRPC_CPP_VERSION_MINOR 67
+#define GRPC_CPP_VERSION_MINOR 68
#define GRPC_CPP_VERSION_PATCH 0
#define GRPC_CPP_VERSION_TAG "dev"
-#define GRPC_CPP_VERSION_STRING "1.67.0-dev"
+#define GRPC_CPP_VERSION_STRING "1.68.0-dev"
#endif // GRPCPP_VERSION_INFO_H
diff --git a/package.xml b/package.xml
index 6a05e868d26..d9b37b47eec 100644
--- a/package.xml
+++ b/package.xml
@@ -13,8 +13,8 @@
2019-09-24
- 1.67.0dev
- 1.67.0dev
+ 1.68.0dev
+ 1.68.0dev
beta
@@ -22,7 +22,7 @@
Apache 2.0
-- gRPC Core 1.67.0 update
+- gRPC Core 1.68.0 update
@@ -2518,6 +2518,7 @@
+
@@ -2612,107 +2613,104 @@
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
-
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
+
+
+
-
+
@@ -2724,6 +2722,10 @@
+
+
+
+
@@ -2749,12 +2751,16 @@
+
+
+
+
@@ -2912,6 +2918,8 @@
+
+
diff --git a/src/boringssl/boringssl_prefix_symbols.h b/src/boringssl/boringssl_prefix_symbols.h
index 3d9b880017f..47e53df886f 100644
--- a/src/boringssl/boringssl_prefix_symbols.h
+++ b/src/boringssl/boringssl_prefix_symbols.h
@@ -1,4 +1,4 @@
-// generated by generate_boringssl_prefix_header.sh on BoringSSL commit: 16c8d3db1af20fcc04b5190b25242aadcb1fbb30
+// generated by generate_boringssl_prefix_header.sh on BoringSSL commit: b8b3e6e11166719a8ebfa43c0cde9ad7d57a84f6
// Copyright (c) 2018, Google Inc.
//
@@ -829,6 +829,9 @@
#define BASIC_CONSTRAINTS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BASIC_CONSTRAINTS_free)
#define BASIC_CONSTRAINTS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BASIC_CONSTRAINTS_it)
#define BASIC_CONSTRAINTS_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BASIC_CONSTRAINTS_new)
+#define BCM_rand_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_rand_bytes)
+#define BCM_rand_bytes_hwrng BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_rand_bytes_hwrng)
+#define BCM_rand_bytes_with_additional_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_rand_bytes_with_additional_data)
#define BIO_append_filename BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_append_filename)
#define BIO_callback_ctrl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_callback_ctrl)
#define BIO_clear_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_clear_flags)
@@ -1139,6 +1142,7 @@
#define CBS_asn1_oid_to_text BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_asn1_oid_to_text)
#define CBS_contains_zero_byte BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_contains_zero_byte)
#define CBS_copy_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_copy_bytes)
+#define CBS_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_data)
#define CBS_get_any_asn1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_any_asn1)
#define CBS_get_any_asn1_element BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_any_asn1_element)
#define CBS_get_any_ber_asn1_element BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_get_any_ber_asn1_element)
@@ -1175,6 +1179,7 @@
#define CBS_is_valid_asn1_bitstring BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_is_valid_asn1_bitstring)
#define CBS_is_valid_asn1_integer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_is_valid_asn1_integer)
#define CBS_is_valid_asn1_oid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_is_valid_asn1_oid)
+#define CBS_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_len)
#define CBS_mem_equal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_mem_equal)
#define CBS_parse_generalized_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_parse_generalized_time)
#define CBS_parse_utc_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBS_parse_utc_time)
@@ -1879,6 +1884,7 @@
#define EVP_hpke_aes_256_gcm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_aes_256_gcm)
#define EVP_hpke_chacha20_poly1305 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_chacha20_poly1305)
#define EVP_hpke_hkdf_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_hkdf_sha256)
+#define EVP_hpke_p256_hkdf_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_p256_hkdf_sha256)
#define EVP_hpke_x25519_hkdf_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_x25519_hkdf_sha256)
#define EVP_marshal_digest_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_marshal_digest_algorithm)
#define EVP_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_marshal_private_key)
@@ -1981,6 +1987,40 @@
#define MD5_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD5_Update)
#define METHOD_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, METHOD_ref)
#define METHOD_unref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, METHOD_unref)
+#define MLDSA65_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_generate_key)
+#define MLDSA65_generate_key_external_entropy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_generate_key_external_entropy)
+#define MLDSA65_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_marshal_private_key)
+#define MLDSA65_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_marshal_public_key)
+#define MLDSA65_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_parse_private_key)
+#define MLDSA65_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_parse_public_key)
+#define MLDSA65_private_key_from_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_private_key_from_seed)
+#define MLDSA65_public_from_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_public_from_private)
+#define MLDSA65_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_sign)
+#define MLDSA65_sign_internal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_sign_internal)
+#define MLDSA65_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_verify)
+#define MLDSA65_verify_internal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_verify_internal)
+#define MLKEM1024_decap BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM1024_decap)
+#define MLKEM1024_encap BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM1024_encap)
+#define MLKEM1024_encap_external_entropy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM1024_encap_external_entropy)
+#define MLKEM1024_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM1024_generate_key)
+#define MLKEM1024_generate_key_external_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM1024_generate_key_external_seed)
+#define MLKEM1024_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM1024_marshal_private_key)
+#define MLKEM1024_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM1024_marshal_public_key)
+#define MLKEM1024_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM1024_parse_private_key)
+#define MLKEM1024_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM1024_parse_public_key)
+#define MLKEM1024_private_key_from_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM1024_private_key_from_seed)
+#define MLKEM1024_public_from_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM1024_public_from_private)
+#define MLKEM768_decap BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM768_decap)
+#define MLKEM768_encap BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM768_encap)
+#define MLKEM768_encap_external_entropy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM768_encap_external_entropy)
+#define MLKEM768_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM768_generate_key)
+#define MLKEM768_generate_key_external_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM768_generate_key_external_seed)
+#define MLKEM768_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM768_marshal_private_key)
+#define MLKEM768_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM768_marshal_public_key)
+#define MLKEM768_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM768_parse_private_key)
+#define MLKEM768_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM768_parse_public_key)
+#define MLKEM768_private_key_from_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM768_private_key_from_seed)
+#define MLKEM768_public_from_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLKEM768_public_from_private)
#define NAME_CONSTRAINTS_check BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NAME_CONSTRAINTS_check)
#define NAME_CONSTRAINTS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NAME_CONSTRAINTS_free)
#define NAME_CONSTRAINTS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, NAME_CONSTRAINTS_it)
@@ -2252,7 +2292,6 @@
#define RAND_SSLeay BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_SSLeay)
#define RAND_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_add)
#define RAND_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_bytes)
-#define RAND_bytes_with_additional_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_bytes_with_additional_data)
#define RAND_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_cleanup)
#define RAND_disable_fork_unsafe_buffering BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_disable_fork_unsafe_buffering)
#define RAND_egd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RAND_egd)
@@ -3018,8 +3057,10 @@
#define c2i_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, c2i_ASN1_BIT_STRING)
#define c2i_ASN1_INTEGER BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, c2i_ASN1_INTEGER)
#define c2i_ASN1_OBJECT BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, c2i_ASN1_OBJECT)
-#define chacha20_poly1305_open BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, chacha20_poly1305_open)
-#define chacha20_poly1305_seal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, chacha20_poly1305_seal)
+#define chacha20_poly1305_open_avx2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, chacha20_poly1305_open_avx2)
+#define chacha20_poly1305_open_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, chacha20_poly1305_open_nohw)
+#define chacha20_poly1305_seal_avx2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, chacha20_poly1305_seal_avx2)
+#define chacha20_poly1305_seal_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, chacha20_poly1305_seal_nohw)
#define crypto_gcm_clmul_enabled BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, crypto_gcm_clmul_enabled)
#define d2i_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_BIT_STRING)
#define d2i_ASN1_BMPSTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_BMPSTRING)
@@ -3221,19 +3262,29 @@
#define ec_set_to_safe_point BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_set_to_safe_point)
#define ec_simple_scalar_inv0_montgomery BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_simple_scalar_inv0_montgomery)
#define ec_simple_scalar_to_montgomery_inv_vartime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_simple_scalar_to_montgomery_inv_vartime)
-#define ecdsa_do_verify_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecdsa_do_verify_no_self_test)
-#define ecdsa_sign_with_nonce_for_known_answer_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecdsa_sign_with_nonce_for_known_answer_test)
-#define ecp_nistz256_avx2_select_w7 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_avx2_select_w7)
-#define ecp_nistz256_mul_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_mul_mont)
+#define ecdsa_sign_fixed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecdsa_sign_fixed)
+#define ecdsa_sign_fixed_with_nonce_for_known_answer_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecdsa_sign_fixed_with_nonce_for_known_answer_test)
+#define ecdsa_verify_fixed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecdsa_verify_fixed)
+#define ecdsa_verify_fixed_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecdsa_verify_fixed_no_self_test)
+#define ecp_nistz256_mul_mont_adx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_mul_mont_adx)
+#define ecp_nistz256_mul_mont_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_mul_mont_nohw)
#define ecp_nistz256_neg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_neg)
-#define ecp_nistz256_ord_mul_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_ord_mul_mont)
-#define ecp_nistz256_ord_sqr_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_ord_sqr_mont)
-#define ecp_nistz256_point_add BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_point_add)
-#define ecp_nistz256_point_add_affine BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_point_add_affine)
-#define ecp_nistz256_point_double BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_point_double)
-#define ecp_nistz256_select_w5 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_select_w5)
-#define ecp_nistz256_select_w7 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_select_w7)
-#define ecp_nistz256_sqr_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_sqr_mont)
+#define ecp_nistz256_ord_mul_mont_adx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_ord_mul_mont_adx)
+#define ecp_nistz256_ord_mul_mont_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_ord_mul_mont_nohw)
+#define ecp_nistz256_ord_sqr_mont_adx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_ord_sqr_mont_adx)
+#define ecp_nistz256_ord_sqr_mont_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_ord_sqr_mont_nohw)
+#define ecp_nistz256_point_add_adx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_point_add_adx)
+#define ecp_nistz256_point_add_affine_adx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_point_add_affine_adx)
+#define ecp_nistz256_point_add_affine_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_point_add_affine_nohw)
+#define ecp_nistz256_point_add_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_point_add_nohw)
+#define ecp_nistz256_point_double_adx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_point_double_adx)
+#define ecp_nistz256_point_double_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_point_double_nohw)
+#define ecp_nistz256_select_w5_avx2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_select_w5_avx2)
+#define ecp_nistz256_select_w5_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_select_w5_nohw)
+#define ecp_nistz256_select_w7_avx2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_select_w7_avx2)
+#define ecp_nistz256_select_w7_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_select_w7_nohw)
+#define ecp_nistz256_sqr_mont_adx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_sqr_mont_adx)
+#define ecp_nistz256_sqr_mont_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ecp_nistz256_sqr_mont_nohw)
#define ed25519_asn1_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ed25519_asn1_meth)
#define ed25519_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ed25519_pkey_meth)
#define evp_pkey_set_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, evp_pkey_set_method)
diff --git a/src/compiler/php_generator.cc b/src/compiler/php_generator.cc
index 7d42dc8f1af..7ef2891c488 100644
--- a/src/compiler/php_generator.cc
+++ b/src/compiler/php_generator.cc
@@ -176,7 +176,7 @@ void PrintServerMethod(const MethodDescriptor* method, Printer* out) {
"of \\$input_type_id$\n"
" * @param \\Grpc\\ServerContext $$context server request context\n"
" * @return \\$output_type_id$ for response data, null if if error "
- "occured\n"
+ "occurred\n"
" * initial metadata (if any) and status (if not ok) should be set "
"to $$context\n"
" */\n"
@@ -208,7 +208,7 @@ void PrintServerMethod(const MethodDescriptor* method, Printer* out) {
" * @param \\$input_type_id$ $$request client request\n"
" * @param \\Grpc\\ServerContext $$context server request context\n"
" * @return \\$output_type_id$ for response data, null if if error "
- "occured\n"
+ "occurred\n"
" * initial metadata (if any) and status (if not ok) should be set "
"to $$context\n"
" */\n"
diff --git a/src/core/BUILD b/src/core/BUILD
index dee69ed3bd7..b10dbc28550 100644
--- a/src/core/BUILD
+++ b/src/core/BUILD
@@ -3606,7 +3606,10 @@ grpc_cc_library(
grpc_cc_library(
name = "subchannel_interface",
hdrs = ["load_balancing/subchannel_interface.h"],
- external_deps = ["absl/status"],
+ external_deps = [
+ "absl/status",
+ "absl/strings",
+ ],
deps = [
"dual_ref_counted",
"iomgr_fwd",
diff --git a/src/core/client_channel/client_channel.cc b/src/core/client_channel/client_channel.cc
index f700b39463e..d2f3dd5858a 100644
--- a/src/core/client_channel/client_channel.cc
+++ b/src/core/client_channel/client_channel.cc
@@ -57,6 +57,7 @@
#include "src/core/client_channel/subchannel.h"
#include "src/core/client_channel/subchannel_interface_internal.h"
#include "src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h"
+#include "src/core/lib/address_utils/sockaddr_utils.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/config/core_configuration.h"
@@ -167,6 +168,7 @@ class ClientChannel::SubchannelWrapper
void CancelDataWatcher(DataWatcherInterface* watcher) override
ABSL_EXCLUSIVE_LOCKS_REQUIRED(*client_channel_->work_serializer_);
void ThrottleKeepaliveTime(int new_keepalive_time);
+ std::string address() const override { return subchannel_->address(); }
private:
class WatcherWrapper;
diff --git a/src/core/client_channel/client_channel_filter.cc b/src/core/client_channel/client_channel_filter.cc
index f80f20cc88d..6252be05b8e 100644
--- a/src/core/client_channel/client_channel_filter.cc
+++ b/src/core/client_channel/client_channel_filter.cc
@@ -63,6 +63,7 @@
#include "src/core/client_channel/subchannel.h"
#include "src/core/client_channel/subchannel_interface_internal.h"
#include "src/core/handshaker/proxy_mapper_registry.h"
+#include "src/core/lib/address_utils/sockaddr_utils.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/status_util.h"
@@ -616,6 +617,8 @@ class ClientChannelFilter::SubchannelWrapper final
subchannel_->ThrottleKeepaliveTime(new_keepalive_time);
}
+ std::string address() const override { return subchannel_->address(); }
+
private:
// This wrapper provides a bridge between the internal Subchannel API
// and the SubchannelInterface API that we expose to LB policies.
@@ -2518,16 +2521,17 @@ ClientChannelFilter::LoadBalancedCall::PickSubchannel(bool was_queued) {
// updated before we queue it.
// We need to unref pickers in the WorkSerializer.
std::vector> pickers;
- auto cleanup = absl::MakeCleanup([&]() {
- if (IsWorkSerializerDispatchEnabled()) return;
- chand_->work_serializer_->Run(
- [pickers = std::move(pickers)]() mutable {
- for (auto& picker : pickers) {
- picker.reset(DEBUG_LOCATION, "PickSubchannel");
- }
- },
- DEBUG_LOCATION);
- });
+ auto cleanup = absl::MakeCleanup(
+ [work_serializer = chand_->work_serializer_, &pickers]() {
+ if (IsWorkSerializerDispatchEnabled()) return;
+ work_serializer->Run(
+ [pickers = std::move(pickers)]() mutable {
+ for (auto& picker : pickers) {
+ picker.reset(DEBUG_LOCATION, "PickSubchannel");
+ }
+ },
+ DEBUG_LOCATION);
+ });
absl::AnyInvocable)>
set_picker;
if (!IsWorkSerializerDispatchEnabled()) {
diff --git a/src/core/client_channel/subchannel.h b/src/core/client_channel/subchannel.h
index 6ae44a5675e..502df2b4844 100644
--- a/src/core/client_channel/subchannel.h
+++ b/src/core/client_channel/subchannel.h
@@ -33,6 +33,7 @@
#include "src/core/client_channel/connector.h"
#include "src/core/client_channel/subchannel_pool_interface.h"
+#include "src/core/lib/address_utils/sockaddr_utils.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_fwd.h"
@@ -215,7 +216,10 @@ class Subchannel final : public DualRefCounted {
channelz::SubchannelNode* channelz_node();
- const grpc_resolved_address& address() const { return key_.address(); }
+ std::string address() const {
+ return grpc_sockaddr_to_uri(&key_.address())
+ .value_or("");
+ }
// Starts watching the subchannel's connectivity state.
// The first callback to the watcher will be delivered ~immediately.
diff --git a/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc b/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc
index b560b92f59c..6b0582afc0c 100644
--- a/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc
+++ b/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc
@@ -207,7 +207,7 @@ void LegacyMaxAgeFilter::PostInit() {
// OnDone -- close the connection if the promise completed
// successfully.
// (if it did not, it was cancelled)
- if (status.ok()) CloseChannel();
+ if (status.ok()) CloseChannel("max connection age");
},
std::move(arena)));
}
@@ -273,16 +273,16 @@ void LegacyChannelIdleFilter::StartIdleTimer() {
activity_.Set(MakeActivity(
std::move(promise), ExecCtxWakeupScheduler{},
[channel_stack, this](absl::Status status) {
- if (status.ok()) CloseChannel();
+ if (status.ok()) CloseChannel("connection idle");
},
std::move(arena)));
}
-void LegacyChannelIdleFilter::CloseChannel() {
+void LegacyChannelIdleFilter::CloseChannel(absl::string_view reason) {
auto* op = grpc_make_transport_op(nullptr);
op->disconnect_with_error = grpc_error_set_int(
- GRPC_ERROR_CREATE("enter idle"),
- StatusIntProperty::ChannelConnectivityState, GRPC_CHANNEL_IDLE);
+ GRPC_ERROR_CREATE(reason), StatusIntProperty::ChannelConnectivityState,
+ GRPC_CHANNEL_IDLE);
// Pass the transport op down to the channel stack.
auto* elem = grpc_channel_stack_element(channel_stack_, 0);
elem->filter->start_transport_op(elem, op);
diff --git a/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h b/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h
index 9ee7981b2f5..74bf3a2f09b 100644
--- a/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h
+++ b/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h
@@ -69,7 +69,7 @@ class LegacyChannelIdleFilter : public ChannelFilter {
grpc_channel_stack* channel_stack() { return channel_stack_; };
virtual void Shutdown();
- void CloseChannel();
+ void CloseChannel(absl::string_view reason);
void IncreaseCallCount();
void DecreaseCallCount();
diff --git a/src/core/ext/transport/chaotic_good/client/chaotic_good_connector.cc b/src/core/ext/transport/chaotic_good/client/chaotic_good_connector.cc
index d5723e82d4a..be3dfa83f53 100644
--- a/src/core/ext/transport/chaotic_good/client/chaotic_good_connector.cc
+++ b/src/core/ext/transport/chaotic_good/client/chaotic_good_connector.cc
@@ -134,9 +134,12 @@ auto ChaoticGoodConnector::WaitForDataEndpointSetup(
endpoint) mutable {
ExecCtx exec_ctx;
if (!endpoint.ok() || self->handshake_mgr_ == nullptr) {
- ExecCtx::Run(DEBUG_LOCATION,
- std::exchange(self->notify_, nullptr),
- GRPC_ERROR_CREATE("connect endpoint failed"));
+ MutexLock lock(&self->mu_);
+ if (self->notify_ != nullptr) {
+ ExecCtx::Run(DEBUG_LOCATION,
+ std::exchange(self->notify_, nullptr),
+ GRPC_ERROR_CREATE("connect endpoint failed"));
+ }
return;
}
auto* chaotic_good_ext =
@@ -240,9 +243,9 @@ void ChaoticGoodConnector::Connect(const Args& args, Result* result,
GRPC_ERROR_CREATE("connector shutdown"));
return;
}
+ notify_ = notify;
}
args_ = args;
- notify_ = notify;
resolved_addr_ = EventEngine::ResolvedAddress(
reinterpret_cast(args_.address->addr),
args_.address->len);
@@ -253,11 +256,14 @@ void ChaoticGoodConnector::Connect(const Args& args, Result* result,
endpoint) mutable {
ExecCtx exec_ctx;
if (!endpoint.ok() || self->handshake_mgr_ == nullptr) {
- auto endpoint_status = endpoint.status();
- auto error = GRPC_ERROR_CREATE_REFERENCING("connect endpoint failed",
- &endpoint_status, 1);
- ExecCtx::Run(DEBUG_LOCATION, std::exchange(self->notify_, nullptr),
- error);
+ MutexLock lock(&self->mu_);
+ if (self->notify_ != nullptr) {
+ auto endpoint_status = endpoint.status();
+ auto error = GRPC_ERROR_CREATE_REFERENCING(
+ "connect endpoint failed", &endpoint_status, 1);
+ ExecCtx::Run(DEBUG_LOCATION, std::exchange(self->notify_, nullptr),
+ error);
+ }
return;
}
auto* chaotic_good_ext =
@@ -320,8 +326,8 @@ void ChaoticGoodConnector::OnHandshakeDone(
[self = RefAsSubclass()](absl::Status status) {
GRPC_TRACE_LOG(chaotic_good, INFO)
<< "ChaoticGoodConnector::OnHandshakeDone: " << status;
+ MutexLock lock(&self->mu_);
if (status.ok()) {
- MutexLock lock(&self->mu_);
self->result_->transport = new ChaoticGoodClientTransport(
std::move(self->control_endpoint_),
std::move(self->data_endpoint_), self->args_.channel_args,
diff --git a/src/core/ext/transport/chaotic_good/client/chaotic_good_connector.h b/src/core/ext/transport/chaotic_good/client/chaotic_good_connector.h
index d981689f72b..5078d384369 100644
--- a/src/core/ext/transport/chaotic_good/client/chaotic_good_connector.h
+++ b/src/core/ext/transport/chaotic_good/client/chaotic_good_connector.h
@@ -83,7 +83,7 @@ class ChaoticGoodConnector : public SubchannelConnector {
Mutex mu_;
Args args_;
Result* result_ ABSL_GUARDED_BY(mu_);
- grpc_closure* notify_ = nullptr;
+ grpc_closure* notify_ ABSL_GUARDED_BY(mu_) = nullptr;
bool is_shutdown_ ABSL_GUARDED_BY(mu_) = false;
absl::StatusOr
resolved_addr_;
diff --git a/src/core/ext/transport/chaotic_good/client_transport.cc b/src/core/ext/transport/chaotic_good/client_transport.cc
index f4d6a3ab6c2..2c2c208f31d 100644
--- a/src/core/ext/transport/chaotic_good/client_transport.cc
+++ b/src/core/ext/transport/chaotic_good/client_transport.cc
@@ -250,18 +250,20 @@ void ChaoticGoodClientTransport::AbortWithError() {
}
uint32_t ChaoticGoodClientTransport::MakeStream(CallHandler call_handler) {
- ReleasableMutexLock lock(&mu_);
+ MutexLock lock(&mu_);
const uint32_t stream_id = next_stream_id_++;
+ const bool on_done_added =
+ call_handler.OnDone([self = RefAsSubclass(),
+ stream_id](bool cancelled) {
+ if (cancelled) {
+ self->outgoing_frames_.MakeSender().UnbufferedImmediateSend(
+ CancelFrame{stream_id});
+ }
+ MutexLock lock(&self->mu_);
+ self->stream_map_.erase(stream_id);
+ });
+ if (!on_done_added) return 0;
stream_map_.emplace(stream_id, call_handler);
- lock.Release();
- call_handler.OnDone([this, stream_id](bool cancelled) {
- if (cancelled) {
- outgoing_frames_.MakeSender().UnbufferedImmediateSend(
- CancelFrame{stream_id});
- }
- MutexLock lock(&mu_);
- stream_map_.erase(stream_id);
- });
return stream_id;
}
@@ -321,23 +323,30 @@ void ChaoticGoodClientTransport::StartCall(CallHandler call_handler) {
"outbound_loop", [self = RefAsSubclass(),
call_handler]() mutable {
const uint32_t stream_id = self->MakeStream(call_handler);
- return Map(
- self->CallOutboundLoop(stream_id, call_handler),
- [stream_id, sender = self->outgoing_frames_.MakeSender()](
- absl::Status result) mutable {
- GRPC_TRACE_LOG(chaotic_good, INFO)
- << "CHAOTIC_GOOD: Call " << stream_id << " finished with "
- << result.ToString();
- if (!result.ok()) {
- GRPC_TRACE_LOG(chaotic_good, INFO)
- << "CHAOTIC_GOOD: Send cancel";
- if (!sender.UnbufferedImmediateSend(CancelFrame{stream_id})) {
- GRPC_TRACE_LOG(chaotic_good, INFO)
- << "CHAOTIC_GOOD: Send cancel failed";
- }
- }
- return result;
- });
+ return If(
+ stream_id != 0,
+ [stream_id, call_handler = std::move(call_handler),
+ self = std::move(self)]() {
+ return Map(
+ self->CallOutboundLoop(stream_id, call_handler),
+ [stream_id, sender = self->outgoing_frames_.MakeSender()](
+ absl::Status result) mutable {
+ GRPC_TRACE_LOG(chaotic_good, INFO)
+ << "CHAOTIC_GOOD: Call " << stream_id
+ << " finished with " << result.ToString();
+ if (!result.ok()) {
+ GRPC_TRACE_LOG(chaotic_good, INFO)
+ << "CHAOTIC_GOOD: Send cancel";
+ if (!sender.UnbufferedImmediateSend(
+ CancelFrame{stream_id})) {
+ GRPC_TRACE_LOG(chaotic_good, INFO)
+ << "CHAOTIC_GOOD: Send cancel failed";
+ }
+ }
+ return result;
+ });
+ },
+ []() { return absl::OkStatus(); });
});
}
diff --git a/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc b/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc
index 2a707602920..ac044244bd2 100644
--- a/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc
+++ b/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc
@@ -187,11 +187,7 @@ void ChaoticGoodServerListener::ActiveConnection::NewConnectionID() {
connection_id_, std::make_shared>());
}
-void ChaoticGoodServerListener::ActiveConnection::Done(
- absl::optional error) {
- if (error.has_value()) {
- LOG(ERROR) << "ActiveConnection::Done:" << this << " " << *error;
- }
+void ChaoticGoodServerListener::ActiveConnection::Done() {
// Can easily be holding various locks here: bounce through EE to ensure no
// deadlocks.
listener_->event_engine_->Run([self = Ref()]() {
@@ -387,13 +383,15 @@ auto ChaoticGoodServerListener::ActiveConnection::HandshakingState::
void ChaoticGoodServerListener::ActiveConnection::HandshakingState::
OnHandshakeDone(absl::StatusOr result) {
if (!result.ok()) {
- connection_->Done(
- absl::StrCat("Handshake failed: ", result.status().ToString()));
+ LOG_EVERY_N_SEC(ERROR, 5) << "Handshake failed: ", result.status();
+ connection_->Done();
return;
}
CHECK_NE(*result, nullptr);
if ((*result)->endpoint == nullptr) {
- connection_->Done("Server handshake done but has empty endpoint.");
+ LOG_EVERY_N_SEC(ERROR, 5)
+ << "Server handshake done but has empty endpoint.";
+ connection_->Done();
return;
}
CHECK(grpc_event_engine::experimental::grpc_is_event_engine_endpoint(
@@ -429,12 +427,10 @@ void ChaoticGoodServerListener::ActiveConnection::HandshakingState::
EventEngineWakeupScheduler(connection_->listener_->event_engine_),
[self = Ref()](absl::Status status) {
if (!status.ok()) {
- self->connection_->Done(
- absl::StrCat("Server setting frame handling failed: ",
- StatusToString(status)));
- } else {
- self->connection_->Done();
+ GRPC_TRACE_LOG(chaotic_good, ERROR)
+ << "Server setting frame handling failed: " << status;
}
+ self->connection_->Done();
},
connection_->arena_.get());
MutexLock lock(&connection_->mu_);
diff --git a/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h b/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h
index 0b20dcbb363..d5ec23b5de3 100644
--- a/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h
+++ b/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h
@@ -111,7 +111,7 @@ class ChaoticGoodServerListener final : public Server::ListenerInterface {
};
private:
- void Done(absl::optional error = absl::nullopt);
+ void Done();
void NewConnectionID();
RefCountedPtr arena_ = SimpleArenaAllocator()->MakeArena();
const RefCountedPtr listener_;
diff --git a/src/core/ext/transport/chaotic_good/server_transport.cc b/src/core/ext/transport/chaotic_good/server_transport.cc
index 6ffb6b7f067..0261223e823 100644
--- a/src/core/ext/transport/chaotic_good/server_transport.cc
+++ b/src/core/ext/transport/chaotic_good/server_transport.cc
@@ -237,10 +237,11 @@ auto ChaoticGoodServerTransport::DeserializeAndPushFragmentToNewCall(
call_initiator.emplace(std::move(call.initiator));
auto add_result = NewStream(frame_header.stream_id, *call_initiator);
if (add_result.ok()) {
- call_destination_->StartCall(std::move(call.handler));
call_initiator->SpawnGuarded(
"server-write", [this, stream_id = frame_header.stream_id,
- call_initiator = *call_initiator]() {
+ call_initiator = *call_initiator,
+ call_handler = std::move(call.handler)]() mutable {
+ call_destination_->StartCall(std::move(call_handler));
return CallOutboundLoop(stream_id, call_initiator);
});
} else {
@@ -438,8 +439,7 @@ absl::Status ChaoticGoodServerTransport::NewStream(
if (stream_id <= last_seen_new_stream_id_) {
return absl::InternalError("Stream id is not increasing");
}
- stream_map_.emplace(stream_id, call_initiator);
- call_initiator.OnDone(
+ const bool on_done_added = call_initiator.OnDone(
[self = RefAsSubclass(), stream_id](bool) {
GRPC_TRACE_LOG(chaotic_good, INFO)
<< "CHAOTIC_GOOD " << self.get() << " OnDone " << stream_id;
@@ -453,6 +453,10 @@ absl::Status ChaoticGoodServerTransport::NewStream(
});
}
});
+ if (!on_done_added) {
+ return absl::CancelledError();
+ }
+ stream_map_.emplace(stream_id, call_initiator);
return absl::OkStatus();
}
diff --git a/src/core/handshaker/http_connect/http_connect_handshaker.cc b/src/core/handshaker/http_connect/http_connect_handshaker.cc
index 2260224d10d..2954860fe5e 100644
--- a/src/core/handshaker/http_connect/http_connect_handshaker.cc
+++ b/src/core/handshaker/http_connect/http_connect_handshaker.cc
@@ -279,7 +279,7 @@ void HttpConnectHandshaker::DoHandshake(
for (size_t i = 0; i < num_header_strings; ++i) {
char* sep = strchr(header_strings[i], ':');
if (sep == nullptr) {
- LOG(ERROR) << "skipping unparseable HTTP CONNECT header: "
+ LOG(ERROR) << "skipping unparsable HTTP CONNECT header: "
<< header_strings[i];
continue;
}
diff --git a/src/core/lib/event_engine/ares_resolver.cc b/src/core/lib/event_engine/ares_resolver.cc
index 1cd7c73f54e..3fca4efad49 100644
--- a/src/core/lib/event_engine/ares_resolver.cc
+++ b/src/core/lib/event_engine/ares_resolver.cc
@@ -272,7 +272,7 @@ void AresResolver::LookupHostname(
event_engine_->Run(
[callback = std::move(callback),
status = absl::InvalidArgumentError(absl::StrCat(
- "Unparseable name: ", name))]() mutable { callback(status); });
+ "Unparsable name: ", name))]() mutable { callback(status); });
return;
}
if (host.empty()) {
@@ -351,7 +351,7 @@ void AresResolver::LookupSRV(
event_engine_->Run(
[callback = std::move(callback),
status = absl::InvalidArgumentError(absl::StrCat(
- "Unparseable name: ", name))]() mutable { callback(status); });
+ "Unparsable name: ", name))]() mutable { callback(status); });
return;
}
if (host.empty()) {
@@ -386,7 +386,7 @@ void AresResolver::LookupTXT(
event_engine_->Run(
[callback = std::move(callback),
status = absl::InvalidArgumentError(absl::StrCat(
- "Unparseable name: ", name))]() mutable { callback(status); });
+ "Unparsable name: ", name))]() mutable { callback(status); });
return;
}
if (host.empty()) {
diff --git a/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc b/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
index 8c0cd0b694a..adf52ecc2f3 100644
--- a/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
+++ b/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
@@ -43,7 +43,7 @@ void DNSServiceResolverImpl::LookupHostname(
if (!grpc_core::SplitHostPort(name, &host, &port_string)) {
engine_->Run([on_resolve = std::move(on_resolve),
status = absl::InvalidArgumentError(
- absl::StrCat("Unparseable name: ", name))]() mutable {
+ absl::StrCat("Unparsable name: ", name))]() mutable {
on_resolve(status);
});
return;
diff --git a/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc b/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc
index 4e0f66fc1f7..8cde00153a1 100644
--- a/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc
+++ b/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc
@@ -50,7 +50,7 @@ LookupHostnameBlocking(absl::string_view name, absl::string_view default_port) {
// parse name, splitting it into host and port parts
grpc_core::SplitHostPort(name, &host, &port);
if (host.empty()) {
- return absl::InvalidArgumentError(absl::StrCat("Unparseable name: ", name));
+ return absl::InvalidArgumentError(absl::StrCat("Unparsable name: ", name));
}
if (port.empty()) {
if (default_port.empty()) {
diff --git a/src/core/lib/event_engine/posix_engine/posix_endpoint.cc b/src/core/lib/event_engine/posix_engine/posix_endpoint.cc
index 7634bb1334b..c5708db02c5 100644
--- a/src/core/lib/event_engine/posix_engine/posix_endpoint.cc
+++ b/src/core/lib/event_engine/posix_engine/posix_endpoint.cc
@@ -236,7 +236,7 @@ msg_iovlen_type TcpZerocopySendRecord::PopulateIovs(size_t* unwind_slice_idx,
iov_size++) {
MutableSlice& slice = internal::SliceCast(
buf_.MutableSliceAt(out_offset_.slice_idx));
- iov[iov_size].iov_base = slice.begin();
+ iov[iov_size].iov_base = slice.begin() + out_offset_.byte_idx;
iov[iov_size].iov_len = slice.length() - out_offset_.byte_idx;
*sending_length += iov[iov_size].iov_len;
++(out_offset_.slice_idx);
diff --git a/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc b/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc
index ab318238c02..a23ba405ab9 100644
--- a/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc
+++ b/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc
@@ -42,7 +42,7 @@ LookupHostnameBlocking(absl::string_view name, absl::string_view default_port) {
std::string port;
grpc_core::SplitHostPort(name, &host, &port);
if (host.empty()) {
- return absl::InvalidArgumentError(absl::StrCat("Unparseable name: ", name));
+ return absl::InvalidArgumentError(absl::StrCat("Unparsable name: ", name));
}
if (port.empty()) {
if (default_port.empty()) {
diff --git a/src/core/lib/experiments/experiments.cc b/src/core/lib/experiments/experiments.cc
index 8a8b5a445e1..96a2c734308 100644
--- a/src/core/lib/experiments/experiments.cc
+++ b/src/core/lib/experiments/experiments.cc
@@ -79,6 +79,10 @@ const char* const additional_constraints_tcp_frame_size_tuning = "{}";
const char* const description_tcp_rcv_lowat =
"Use SO_RCVLOWAT to avoid wakeups on the read path.";
const char* const additional_constraints_tcp_rcv_lowat = "{}";
+const char* const description_time_caching_in_party =
+ "Disable time caching in exec_ctx, and enable it only in a single party "
+ "execution.";
+const char* const additional_constraints_time_caching_in_party = "{}";
const char* const description_trace_record_callops =
"Enables tracing of call batch initiation and completion.";
const char* const additional_constraints_trace_record_callops = "{}";
@@ -141,6 +145,8 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_tcp_frame_size_tuning, nullptr, 0, false, true},
{"tcp_rcv_lowat", description_tcp_rcv_lowat,
additional_constraints_tcp_rcv_lowat, nullptr, 0, false, true},
+ {"time_caching_in_party", description_time_caching_in_party,
+ additional_constraints_time_caching_in_party, nullptr, 0, true, true},
{"trace_record_callops", description_trace_record_callops,
additional_constraints_trace_record_callops, nullptr, 0, true, true},
{"unconstrained_max_quota_buffer_size",
@@ -216,6 +222,10 @@ const char* const additional_constraints_tcp_frame_size_tuning = "{}";
const char* const description_tcp_rcv_lowat =
"Use SO_RCVLOWAT to avoid wakeups on the read path.";
const char* const additional_constraints_tcp_rcv_lowat = "{}";
+const char* const description_time_caching_in_party =
+ "Disable time caching in exec_ctx, and enable it only in a single party "
+ "execution.";
+const char* const additional_constraints_time_caching_in_party = "{}";
const char* const description_trace_record_callops =
"Enables tracing of call batch initiation and completion.";
const char* const additional_constraints_trace_record_callops = "{}";
@@ -278,6 +288,8 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_tcp_frame_size_tuning, nullptr, 0, false, true},
{"tcp_rcv_lowat", description_tcp_rcv_lowat,
additional_constraints_tcp_rcv_lowat, nullptr, 0, false, true},
+ {"time_caching_in_party", description_time_caching_in_party,
+ additional_constraints_time_caching_in_party, nullptr, 0, true, true},
{"trace_record_callops", description_trace_record_callops,
additional_constraints_trace_record_callops, nullptr, 0, true, true},
{"unconstrained_max_quota_buffer_size",
@@ -353,6 +365,10 @@ const char* const additional_constraints_tcp_frame_size_tuning = "{}";
const char* const description_tcp_rcv_lowat =
"Use SO_RCVLOWAT to avoid wakeups on the read path.";
const char* const additional_constraints_tcp_rcv_lowat = "{}";
+const char* const description_time_caching_in_party =
+ "Disable time caching in exec_ctx, and enable it only in a single party "
+ "execution.";
+const char* const additional_constraints_time_caching_in_party = "{}";
const char* const description_trace_record_callops =
"Enables tracing of call batch initiation and completion.";
const char* const additional_constraints_trace_record_callops = "{}";
@@ -415,6 +431,8 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_tcp_frame_size_tuning, nullptr, 0, false, true},
{"tcp_rcv_lowat", description_tcp_rcv_lowat,
additional_constraints_tcp_rcv_lowat, nullptr, 0, false, true},
+ {"time_caching_in_party", description_time_caching_in_party,
+ additional_constraints_time_caching_in_party, nullptr, 0, true, true},
{"trace_record_callops", description_trace_record_callops,
additional_constraints_trace_record_callops, nullptr, 0, true, true},
{"unconstrained_max_quota_buffer_size",
diff --git a/src/core/lib/experiments/experiments.h b/src/core/lib/experiments/experiments.h
index 0b44aca703f..b6fb4257c58 100644
--- a/src/core/lib/experiments/experiments.h
+++ b/src/core/lib/experiments/experiments.h
@@ -78,6 +78,8 @@ inline bool IsScheduleCancellationOverWriteEnabled() { return false; }
inline bool IsServerPrivacyEnabled() { return false; }
inline bool IsTcpFrameSizeTuningEnabled() { return false; }
inline bool IsTcpRcvLowatEnabled() { return false; }
+#define GRPC_EXPERIMENT_IS_INCLUDED_TIME_CACHING_IN_PARTY
+inline bool IsTimeCachingInPartyEnabled() { return true; }
#define GRPC_EXPERIMENT_IS_INCLUDED_TRACE_RECORD_CALLOPS
inline bool IsTraceRecordCallopsEnabled() { return true; }
inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() { return false; }
@@ -110,6 +112,8 @@ inline bool IsScheduleCancellationOverWriteEnabled() { return false; }
inline bool IsServerPrivacyEnabled() { return false; }
inline bool IsTcpFrameSizeTuningEnabled() { return false; }
inline bool IsTcpRcvLowatEnabled() { return false; }
+#define GRPC_EXPERIMENT_IS_INCLUDED_TIME_CACHING_IN_PARTY
+inline bool IsTimeCachingInPartyEnabled() { return true; }
#define GRPC_EXPERIMENT_IS_INCLUDED_TRACE_RECORD_CALLOPS
inline bool IsTraceRecordCallopsEnabled() { return true; }
inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() { return false; }
@@ -141,6 +145,8 @@ inline bool IsScheduleCancellationOverWriteEnabled() { return false; }
inline bool IsServerPrivacyEnabled() { return false; }
inline bool IsTcpFrameSizeTuningEnabled() { return false; }
inline bool IsTcpRcvLowatEnabled() { return false; }
+#define GRPC_EXPERIMENT_IS_INCLUDED_TIME_CACHING_IN_PARTY
+inline bool IsTimeCachingInPartyEnabled() { return true; }
#define GRPC_EXPERIMENT_IS_INCLUDED_TRACE_RECORD_CALLOPS
inline bool IsTraceRecordCallopsEnabled() { return true; }
inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() { return false; }
@@ -168,6 +174,7 @@ enum ExperimentIds {
kExperimentIdServerPrivacy,
kExperimentIdTcpFrameSizeTuning,
kExperimentIdTcpRcvLowat,
+ kExperimentIdTimeCachingInParty,
kExperimentIdTraceRecordCallops,
kExperimentIdUnconstrainedMaxQuotaBufferSize,
kExperimentIdWorkSerializerClearsTimeCache,
@@ -242,6 +249,10 @@ inline bool IsTcpFrameSizeTuningEnabled() {
inline bool IsTcpRcvLowatEnabled() {
return IsExperimentEnabled();
}
+#define GRPC_EXPERIMENT_IS_INCLUDED_TIME_CACHING_IN_PARTY
+inline bool IsTimeCachingInPartyEnabled() {
+ return IsExperimentEnabled();
+}
#define GRPC_EXPERIMENT_IS_INCLUDED_TRACE_RECORD_CALLOPS
inline bool IsTraceRecordCallopsEnabled() {
return IsExperimentEnabled();
diff --git a/src/core/lib/experiments/experiments.yaml b/src/core/lib/experiments/experiments.yaml
index a74b72dc62f..d4115e8f5e9 100644
--- a/src/core/lib/experiments/experiments.yaml
+++ b/src/core/lib/experiments/experiments.yaml
@@ -42,7 +42,7 @@
# state of each experiment.
- name: call_tracer_in_transport
description: Transport directly passes byte counts to CallTracer.
- expiry: 2024/09/30
+ expiry: 2025/02/01
owner: roth@google.com
test_tags: []
- name: canary_client_privacy
@@ -61,25 +61,25 @@
allow_in_fuzzing_config: false
- name: event_engine_application_callbacks
description: Run application callbacks in EventEngine threads, instead of on the thread-local ApplicationCallbackExecCtx
- expiry: 2024/10/31
+ expiry: 2025/03/01
owner: hork@google.com
- name: event_engine_client
description: Use EventEngine clients instead of iomgr's grpc_tcp_client
- expiry: 2024/10/01
+ expiry: 2025/03/01
owner: hork@google.com
test_tags: ["core_end2end_test", "event_engine_client_test"]
uses_polling: true
- name: event_engine_dns
description:
If set, use EventEngine DNSResolver for client channel resolution
- expiry: 2024/10/01
+ expiry: 2025/03/01
owner: yijiem@google.com
test_tags: ["cancel_ares_query_test", "resolver_component_tests_runner_invoker"]
allow_in_fuzzing_config: false
uses_polling: true
- name: event_engine_listener
description: Use EventEngine listeners instead of iomgr's grpc_tcp_server
- expiry: 2024/12/01
+ expiry: 2025/03/01
owner: vigneshbabu@google.com
test_tags: ["core_end2end_test", "event_engine_listener_test"]
uses_polling: true
@@ -145,6 +145,11 @@
expiry: 2024/12/01
owner: vigneshbabu@google.com
test_tags: ["endpoint_test", "flow_control_test"]
+- name: time_caching_in_party
+ description: Disable time caching in exec_ctx, and enable it only in a single party execution.
+ owner: ctiller@google.com
+ expiry: 2024/12/12
+ test_tags: []
- name: trace_record_callops
description: Enables tracing of call batch initiation and completion.
expiry: 2024/12/01
diff --git a/src/core/lib/experiments/rollouts.yaml b/src/core/lib/experiments/rollouts.yaml
index e3a87d1f62b..661539b1029 100644
--- a/src/core/lib/experiments/rollouts.yaml
+++ b/src/core/lib/experiments/rollouts.yaml
@@ -98,6 +98,8 @@
default: false
- name: tcp_rcv_lowat
default: false
+- name: time_caching_in_party
+ default: true
- name: trace_record_callops
default: true
- name: unconstrained_max_quota_buffer_size
diff --git a/src/core/lib/gprpp/time.h b/src/core/lib/gprpp/time.h
index 0e57349b781..8f1c65cfa34 100644
--- a/src/core/lib/gprpp/time.h
+++ b/src/core/lib/gprpp/time.h
@@ -296,6 +296,14 @@ class Duration {
int64_t millis_;
};
+inline std::ostream& operator<<(std::ostream& out, const Duration& d) {
+ return out << d.ToString();
+}
+
+inline std::ostream& operator<<(std::ostream& out, const Timestamp& d) {
+ return out << d.ToString();
+}
+
inline Duration operator+(Duration lhs, Duration rhs) {
return Duration::Milliseconds(
time_detail::MillisAdd(lhs.millis(), rhs.millis()));
diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h
index ce41e5b92b3..bcdb1a743d7 100644
--- a/src/core/lib/iomgr/exec_ctx.h
+++ b/src/core/lib/iomgr/exec_ctx.h
@@ -35,6 +35,7 @@
#include
#include
+#include "src/core/lib/experiments/experiments.h"
#include "src/core/lib/gprpp/crash.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/fork.h"
@@ -116,6 +117,11 @@ class GRPC_DLL ExecCtx : public latent_see::ParentScope {
ExecCtx()
: latent_see::ParentScope(GRPC_LATENT_SEE_METADATA("ExecCtx")),
flags_(GRPC_EXEC_CTX_FLAG_IS_FINISHED) {
+#if !TARGET_OS_IPHONE
+ if (!IsTimeCachingInPartyEnabled()) {
+ time_cache_.emplace();
+ }
+#endif
Fork::IncExecCtxCount();
Set(this);
}
@@ -126,6 +132,11 @@ class GRPC_DLL ExecCtx : public latent_see::ParentScope {
explicit ExecCtx(uintptr_t fl, latent_see::Metadata* latent_see_metadata)
: latent_see::ParentScope(latent_see_metadata), flags_(fl) {
+#if !TARGET_OS_IPHONE
+ if (!IsTimeCachingInPartyEnabled()) {
+ time_cache_.emplace();
+ }
+#endif
if (!(GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags_)) {
Fork::IncExecCtxCount();
}
@@ -195,23 +206,18 @@ class GRPC_DLL ExecCtx : public latent_see::ParentScope {
Timestamp Now() { return Timestamp::Now(); }
void InvalidateNow() {
-#if !TARGET_OS_IPHONE
- time_cache_.InvalidateCache();
-#endif
+ if (time_cache_.has_value()) time_cache_->InvalidateCache();
}
void SetNowIomgrShutdown() {
-#if !TARGET_OS_IPHONE
// We get to do a test only set now on this path just because iomgr
// is getting removed and no point adding more interfaces for it.
- time_cache_.TestOnlySetNow(Timestamp::InfFuture());
-#endif
+ TestOnlySetNow(Timestamp::InfFuture());
}
void TestOnlySetNow(Timestamp now) {
-#if !TARGET_OS_IPHONE
- time_cache_.TestOnlySetNow(now);
-#endif
+ if (!time_cache_.has_value()) time_cache_.emplace();
+ time_cache_->TestOnlySetNow(now);
}
/// Gets pointer to current exec_ctx.
@@ -237,9 +243,7 @@ class GRPC_DLL ExecCtx : public latent_see::ParentScope {
CombinerData combiner_data_ = {nullptr, nullptr};
uintptr_t flags_;
-#if !TARGET_OS_IPHONE
- ScopedTimeCache time_cache_;
-#endif
+ absl::optional time_cache_;
#if !defined(_WIN32) || !defined(_DLL)
static thread_local ExecCtx* exec_ctx_;
diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc
index f890a349b97..8a161fcc6c4 100644
--- a/src/core/lib/iomgr/resolve_address_posix.cc
+++ b/src/core/lib/iomgr/resolve_address_posix.cc
@@ -106,7 +106,7 @@ NativeDNSResolver::LookupHostnameBlocking(absl::string_view name,
SplitHostPort(name, &host, &port);
if (host.empty()) {
err =
- GRPC_ERROR_CREATE(absl::StrCat("unparseable host:port \"", name, "\""));
+ GRPC_ERROR_CREATE(absl::StrCat("unparsable host:port \"", name, "\""));
goto done;
}
if (port.empty()) {
diff --git a/src/core/lib/iomgr/resolve_address_windows.cc b/src/core/lib/iomgr/resolve_address_windows.cc
index 105dcc85744..6db705774a6 100644
--- a/src/core/lib/iomgr/resolve_address_windows.cc
+++ b/src/core/lib/iomgr/resolve_address_windows.cc
@@ -110,7 +110,7 @@ NativeDNSResolver::LookupHostnameBlocking(absl::string_view name,
SplitHostPort(name, &host, &port);
if (host.empty()) {
error =
- GRPC_ERROR_CREATE(absl::StrFormat("unparseable host:port: '%s'", name));
+ GRPC_ERROR_CREATE(absl::StrFormat("unparsable host:port: '%s'", name));
goto done;
}
if (port.empty()) {
diff --git a/src/core/lib/promise/activity.h b/src/core/lib/promise/activity.h
index 55738c08995..59d504fd6d1 100644
--- a/src/core/lib/promise/activity.h
+++ b/src/core/lib/promise/activity.h
@@ -368,8 +368,8 @@ class FreestandingActivity : public Activity, private Wakeable {
// If more than one action is received during a run, we use max() to resolve
// which one to report (so Cancel overrides Wakeup).
enum class ActionDuringRun : uint8_t {
- kNone, // No action occured during run.
- kWakeup, // A wakeup occured during run.
+ kNone, // No action occurred during run.
+ kWakeup, // A wakeup occurred during run.
kCancel, // Cancel was called during run.
};
@@ -389,7 +389,7 @@ class FreestandingActivity : public Activity, private Wakeable {
// completed.
void WakeupComplete() { Unref(); }
- // Set the action that occured during this run.
+ // Set the action that occurred during this run.
// We use max to combine actions so that cancellation overrides wakeups.
void SetActionDuringRun(ActionDuringRun action)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
diff --git a/src/core/lib/promise/party.cc b/src/core/lib/promise/party.cc
index c8bde2d198f..aaa273d16a2 100644
--- a/src/core/lib/promise/party.cc
+++ b/src/core/lib/promise/party.cc
@@ -41,18 +41,18 @@ namespace grpc_core {
// PartySyncUsingAtomics
GRPC_MUST_USE_RESULT bool Party::RefIfNonZero() {
- auto count = state_.load(std::memory_order_relaxed);
+ auto state = state_.load(std::memory_order_relaxed);
do {
// If zero, we are done (without an increment). If not, we must do a CAS
// to maintain the contract: do not increment the counter if it is already
// zero
- if (count == 0) {
+ if ((state & kRefMask) == 0) {
return false;
}
- } while (!state_.compare_exchange_weak(count, count + kOneRef,
+ } while (!state_.compare_exchange_weak(state, state + kOneRef,
std::memory_order_acq_rel,
std::memory_order_relaxed));
- LogStateChange("RefIfNonZero", count, count + kOneRef);
+ LogStateChange("RefIfNonZero", state, state + kOneRef);
return true;
}
@@ -269,6 +269,12 @@ void Party::RunPartyAndUnref(uint64_t prev_state) {
DCHECK_EQ(prev_state & ~(kRefMask | kAllocatedMask), 0u)
<< "Party should have contained no wakeups on lock";
prev_state |= kLocked;
+ absl::optional time_cache;
+#if !TARGET_OS_IPHONE
+ if (IsTimeCachingInPartyEnabled()) {
+ time_cache.emplace();
+ }
+#endif
for (;;) {
uint64_t keep_allocated_mask = kAllocatedMask;
// For each wakeup bit...
@@ -316,7 +322,7 @@ void Party::RunPartyAndUnref(uint64_t prev_state) {
(prev_state & (kRefMask | keep_allocated_mask)) - kOneRef,
std::memory_order_acq_rel, std::memory_order_acquire)) {
LogStateChange("Run:End", prev_state,
- prev_state & (kRefMask | kAllocatedMask) - kOneRef);
+ (prev_state & (kRefMask | keep_allocated_mask)) - kOneRef);
if ((prev_state & kRefMask) == kOneRef) {
// We're done with the party.
PartyIsOver();
diff --git a/src/core/lib/promise/party.h b/src/core/lib/promise/party.h
index b42c392d51f..d9a2e2ccb57 100644
--- a/src/core/lib/promise/party.h
+++ b/src/core/lib/promise/party.h
@@ -394,7 +394,7 @@ class Party : public Activity, private Wakeable {
const char* op, uint64_t prev_state, uint64_t new_state,
DebugLocation loc = {}) {
GRPC_TRACE_LOG(party_state, INFO).AtLocation(loc.file(), loc.line())
- << DebugTag() << " " << op << " "
+ << this << " " << op << " "
<< absl::StrFormat("%016" PRIx64 " -> %016" PRIx64, prev_state,
new_state);
}
diff --git a/src/core/lib/resource_quota/periodic_update.cc b/src/core/lib/resource_quota/periodic_update.cc
index b4874fea1da..b7f9e9b9c03 100644
--- a/src/core/lib/resource_quota/periodic_update.cc
+++ b/src/core/lib/resource_quota/periodic_update.cc
@@ -68,8 +68,8 @@ bool PeriodicUpdate::MaybeEndPeriod(absl::FunctionRef f) {
expected_updates_per_period_ =
period_.seconds() * expected_updates_per_period_ / time_so_far.seconds();
if (expected_updates_per_period_ < 1) expected_updates_per_period_ = 1;
- period_start_ = now;
f(time_so_far);
+ period_start_ = Timestamp::Now();
updates_remaining_.store(expected_updates_per_period_,
std::memory_order_release);
return true;
diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc
index a347400b981..daa6bacde96 100644
--- a/src/core/lib/surface/version.cc
+++ b/src/core/lib/surface/version.cc
@@ -22,6 +22,6 @@
#include
#include
-const char* grpc_version_string(void) { return "43.0.0"; }
+const char* grpc_version_string(void) { return "44.0.0"; }
-const char* grpc_g_stands_for(void) { return "gesundheit"; }
+const char* grpc_g_stands_for(void) { return "groovy"; }
diff --git a/src/core/lib/transport/call_filters.h b/src/core/lib/transport/call_filters.h
index 1cbe428de5f..7f2b0b2f3a6 100644
--- a/src/core/lib/transport/call_filters.h
+++ b/src/core/lib/transport/call_filters.h
@@ -1485,7 +1485,6 @@ class CallFilters {
std::move(value));
}
}
- call_state_.FinishPullServerTrailingMetadata();
return value;
});
}
@@ -1497,6 +1496,10 @@ class CallFilters {
GRPC_MUST_USE_RESULT auto WasCancelled() {
return [this]() { return call_state_.PollWasCancelled(); };
}
+ // Returns true if server trailing metadata has been pulled
+ bool WasServerTrailingMetadataPulled() const {
+ return call_state_.WasServerTrailingMetadataPulled();
+ }
// Client & server: fill in final_info with the final status of the call.
void Finalize(const grpc_call_final_info* final_info);
diff --git a/src/core/lib/transport/call_spine.h b/src/core/lib/transport/call_spine.h
index 99944b301fc..b1051049a43 100644
--- a/src/core/lib/transport/call_spine.h
+++ b/src/core/lib/transport/call_spine.h
@@ -54,17 +54,23 @@ class CallSpine final : public Party {
CallFilters& call_filters() { return call_filters_; }
- // Add a callback to be called when server trailing metadata is received.
- void OnDone(absl::AnyInvocable fn) {
+ // Add a callback to be called when server trailing metadata is received and
+ // return true.
+ // If CallOnDone has already been invoked, does nothing and returns false.
+ GRPC_MUST_USE_RESULT bool OnDone(absl::AnyInvocable fn) {
+ if (call_filters().WasServerTrailingMetadataPulled()) {
+ return false;
+ }
if (on_done_ == nullptr) {
on_done_ = std::move(fn);
- return;
+ return true;
}
on_done_ = [first = std::move(fn),
next = std::move(on_done_)](bool cancelled) mutable {
first(cancelled);
next(cancelled);
};
+ return true;
}
void CallOnDone(bool cancelled) {
if (on_done_ != nullptr) std::exchange(on_done_, nullptr)(cancelled);
@@ -232,8 +238,8 @@ class CallInitiator {
spine_->PushServerTrailingMetadata(std::move(status));
}
- void OnDone(absl::AnyInvocable fn) {
- spine_->OnDone(std::move(fn));
+ GRPC_MUST_USE_RESULT bool OnDone(absl::AnyInvocable fn) {
+ return spine_->OnDone(std::move(fn));
}
template
@@ -281,8 +287,8 @@ class CallHandler {
spine_->PushServerTrailingMetadata(std::move(status));
}
- void OnDone(absl::AnyInvocable fn) {
- spine_->OnDone(std::move(fn));
+ GRPC_MUST_USE_RESULT bool OnDone(absl::AnyInvocable fn) {
+ return spine_->OnDone(std::move(fn));
}
template
@@ -336,8 +342,8 @@ class UnstartedCallHandler {
spine_->PushServerTrailingMetadata(std::move(status));
}
- void OnDone(absl::AnyInvocable fn) {
- spine_->OnDone(std::move(fn));
+ GRPC_MUST_USE_RESULT bool OnDone(absl::AnyInvocable fn) {
+ return spine_->OnDone(std::move(fn));
}
template
diff --git a/src/core/lib/transport/call_state.h b/src/core/lib/transport/call_state.h
index 3e9acd99c16..67facf8c007 100644
--- a/src/core/lib/transport/call_state.h
+++ b/src/core/lib/transport/call_state.h
@@ -52,7 +52,7 @@ class CallState {
Poll> PollPullServerToClientMessageAvailable();
void FinishPullServerToClientMessage();
Poll PollServerTrailingMetadataAvailable();
- void FinishPullServerTrailingMetadata();
+ bool WasServerTrailingMetadataPulled() const;
Poll PollWasCancelled();
// Debug
std::string DebugString() const;
@@ -147,8 +147,6 @@ class CallState {
kReading,
// Main call loop: processing one message
kProcessingServerToClientMessage,
- // Processing server trailing metadata
- kProcessingServerTrailingMetadata,
kTerminated,
};
static const char* ServerToClientPullStateString(
@@ -172,8 +170,6 @@ class CallState {
return "Reading";
case ServerToClientPullState::kProcessingServerToClientMessage:
return "ProcessingServerToClientMessage";
- case ServerToClientPullState::kProcessingServerTrailingMetadata:
- return "ProcessingServerTrailingMetadata";
case ServerToClientPullState::kTerminated:
return "Terminated";
}
@@ -294,7 +290,6 @@ GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline void CallState::Start() {
case ServerToClientPullState::kReading:
case ServerToClientPullState::kProcessingServerToClientMessage:
LOG(FATAL) << "Start called twice";
- case ServerToClientPullState::kProcessingServerTrailingMetadata:
case ServerToClientPullState::kTerminated:
break;
}
@@ -644,7 +639,6 @@ CallState::PollPullServerInitialMetadataAvailable() {
case ServerToClientPullState::kIdle:
case ServerToClientPullState::kReading:
case ServerToClientPullState::kProcessingServerToClientMessage:
- case ServerToClientPullState::kProcessingServerTrailingMetadata:
LOG(FATAL) << "PollPullServerInitialMetadataAvailable called twice";
case ServerToClientPullState::kTerminated:
return false;
@@ -703,7 +697,6 @@ CallState::FinishPullServerInitialMetadata() {
case ServerToClientPullState::kIdle:
case ServerToClientPullState::kReading:
case ServerToClientPullState::kProcessingServerToClientMessage:
- case ServerToClientPullState::kProcessingServerTrailingMetadata:
LOG(FATAL) << "Out of order FinishPullServerInitialMetadata";
case ServerToClientPullState::kTerminated:
return;
@@ -766,9 +759,6 @@ CallState::PollPullServerToClientMessageAvailable() {
case ServerToClientPullState::kProcessingServerToClientMessage:
LOG(FATAL) << "PollPullServerToClientMessageAvailable called while "
"processing a message";
- case ServerToClientPullState::kProcessingServerTrailingMetadata:
- LOG(FATAL) << "PollPullServerToClientMessageAvailable called while "
- "processing trailing metadata";
case ServerToClientPullState::kTerminated:
return Failure{};
}
@@ -826,9 +816,6 @@ CallState::FinishPullServerToClientMessage() {
server_to_client_pull_state_ = ServerToClientPullState::kIdle;
server_to_client_pull_waiter_.Wake();
break;
- case ServerToClientPullState::kProcessingServerTrailingMetadata:
- LOG(FATAL) << "FinishPullServerToClientMessage called while processing "
- "trailing metadata";
case ServerToClientPullState::kTerminated:
break;
}
@@ -875,10 +862,7 @@ CallState::PollServerTrailingMetadataAvailable() {
case ServerToClientPushState::kFinished:
if (server_trailing_metadata_state_ !=
ServerTrailingMetadataState::kNotPushed) {
- server_to_client_pull_state_ =
- ServerToClientPullState::kProcessingServerTrailingMetadata;
- server_to_client_pull_waiter_.Wake();
- return Empty{};
+ break; // Ready for processing
}
ABSL_FALLTHROUGH_INTENDED;
case ServerToClientPushState::kPushedServerInitialMetadata:
@@ -894,26 +878,14 @@ CallState::PollServerTrailingMetadataAvailable() {
case ServerToClientPullState::kIdle:
if (server_trailing_metadata_state_ !=
ServerTrailingMetadataState::kNotPushed) {
- server_to_client_pull_state_ =
- ServerToClientPullState::kProcessingServerTrailingMetadata;
- server_to_client_pull_waiter_.Wake();
- return Empty{};
+ break; // Ready for processing
}
return server_trailing_metadata_waiter_.pending();
- case ServerToClientPullState::kProcessingServerTrailingMetadata:
- LOG(FATAL) << "PollServerTrailingMetadataAvailable called twice";
case ServerToClientPullState::kTerminated:
- return Empty{};
+ break;
}
- Crash("Unreachable");
-}
-
-GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline void
-CallState::FinishPullServerTrailingMetadata() {
- GRPC_TRACE_LOG(call_state, INFO)
- << "[call_state] FinishPullServerTrailingMetadata: "
- << GRPC_DUMP_ARGS(this, server_trailing_metadata_state_,
- server_trailing_metadata_waiter_.DebugString());
+ server_to_client_pull_state_ = ServerToClientPullState::kTerminated;
+ server_to_client_pull_waiter_.Wake();
switch (server_trailing_metadata_state_) {
case ServerTrailingMetadataState::kNotPushed:
LOG(FATAL) << "FinishPullServerTrailingMetadata called before "
@@ -931,6 +903,21 @@ CallState::FinishPullServerTrailingMetadata() {
case ServerTrailingMetadataState::kPulledCancel:
LOG(FATAL) << "FinishPullServerTrailingMetadata called twice";
}
+ return Empty{};
+}
+
+GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline bool
+CallState::WasServerTrailingMetadataPulled() const {
+ switch (server_trailing_metadata_state_) {
+ case ServerTrailingMetadataState::kNotPushed:
+ case ServerTrailingMetadataState::kPushed:
+ case ServerTrailingMetadataState::kPushedCancel:
+ return false;
+ case ServerTrailingMetadataState::kPulled:
+ case ServerTrailingMetadataState::kPulledCancel:
+ return true;
+ }
+ GPR_UNREACHABLE_CODE(Crash("unreachable"));
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline Poll
diff --git a/src/core/load_balancing/health_check_client.cc b/src/core/load_balancing/health_check_client.cc
index 430c59f28f5..3dd0cefb202 100644
--- a/src/core/load_balancing/health_check_client.cc
+++ b/src/core/load_balancing/health_check_client.cc
@@ -166,11 +166,9 @@ void HealthProducer::HealthChecker::OnHealthWatchStatusChange(
// Prepend the subchannel's address to the status if needed.
absl::Status use_status;
if (!status.ok()) {
- std::string address_str =
- grpc_sockaddr_to_uri(&producer_->subchannel_->address())
- .value_or("");
use_status = absl::Status(
- status.code(), absl::StrCat(address_str, ": ", status.message()));
+ status.code(), absl::StrCat(producer_->subchannel_->address(), ": ",
+ status.message()));
}
work_serializer_->Schedule(
[self = Ref(), state, status = std::move(use_status)]() mutable {
diff --git a/src/core/load_balancing/outlier_detection/outlier_detection.cc b/src/core/load_balancing/outlier_detection/outlier_detection.cc
index 87cffdefe81..bc5a2a01aa8 100644
--- a/src/core/load_balancing/outlier_detection/outlier_detection.cc
+++ b/src/core/load_balancing/outlier_detection/outlier_detection.cc
@@ -159,11 +159,14 @@ class OutlierDetectionLb final : public LoadBalancingPolicy {
class WatcherWrapper final
: public SubchannelInterface::ConnectivityStateWatcherInterface {
public:
- WatcherWrapper(std::shared_ptr<
+ WatcherWrapper(WeakRefCountedPtr subchannel_wrapper,
+ std::shared_ptr<
SubchannelInterface::ConnectivityStateWatcherInterface>
health_watcher,
bool ejected)
- : watcher_(std::move(health_watcher)), ejected_(ejected) {}
+ : subchannel_wrapper_(std::move(subchannel_wrapper)),
+ watcher_(std::move(health_watcher)),
+ ejected_(ejected) {}
void Eject() {
ejected_ = true;
@@ -171,7 +174,8 @@ class OutlierDetectionLb final : public LoadBalancingPolicy {
watcher_->OnConnectivityStateChange(
GRPC_CHANNEL_TRANSIENT_FAILURE,
absl::UnavailableError(
- "subchannel ejected by outlier detection"));
+ absl::StrCat(subchannel_wrapper_->address(),
+ ": subchannel ejected by outlier detection")));
}
}
@@ -192,7 +196,8 @@ class OutlierDetectionLb final : public LoadBalancingPolicy {
if (ejected_) {
new_state = GRPC_CHANNEL_TRANSIENT_FAILURE;
status = absl::UnavailableError(
- "subchannel ejected by outlier detection");
+ absl::StrCat(subchannel_wrapper_->address(),
+ ": subchannel ejected by outlier detection"));
}
watcher_->OnConnectivityStateChange(new_state, status);
}
@@ -203,6 +208,7 @@ class OutlierDetectionLb final : public LoadBalancingPolicy {
}
private:
+ WeakRefCountedPtr subchannel_wrapper_;
std::shared_ptr
watcher_;
absl::optional last_seen_state_;
@@ -463,7 +469,8 @@ void OutlierDetectionLb::SubchannelWrapper::AddDataWatcher(
if (w->type() == HealthProducer::Type()) {
auto* health_watcher = static_cast(watcher.get());
auto watcher_wrapper = std::make_shared(
- health_watcher->TakeWatcher(), ejected_);
+ WeakRefAsSubclass(), health_watcher->TakeWatcher(),
+ ejected_);
watcher_wrapper_ = watcher_wrapper.get();
health_watcher->SetWatcher(std::move(watcher_wrapper));
}
@@ -534,8 +541,8 @@ OutlierDetectionLb::Picker::Picker(OutlierDetectionLb* outlier_detection_lb,
: picker_(std::move(picker)), counting_enabled_(counting_enabled) {
GRPC_TRACE_LOG(outlier_detection_lb, INFO)
<< "[outlier_detection_lb " << outlier_detection_lb
- << "] constructed new picker " << this << " and counting "
- << "is " << (counting_enabled ? "enabled" : "disabled");
+ << "] constructed new picker " << this << " and counting " << "is "
+ << (counting_enabled ? "enabled" : "disabled");
}
LoadBalancingPolicy::PickResult OutlierDetectionLb::Picker::Pick(
@@ -904,8 +911,8 @@ void OutlierDetectionLb::EjectionTimer::OnTimerLocked() {
config.success_rate_ejection->minimum_hosts) {
GRPC_TRACE_LOG(outlier_detection_lb, INFO)
<< "[outlier_detection_lb " << parent_.get()
- << "] running success rate algorithm: "
- << "stdev_factor=" << config.success_rate_ejection->stdev_factor
+ << "] running success rate algorithm: " << "stdev_factor="
+ << config.success_rate_ejection->stdev_factor
<< ", enforcement_percentage="
<< config.success_rate_ejection->enforcement_percentage;
// calculate ejection threshold: (mean - stdev *
@@ -957,8 +964,8 @@ void OutlierDetectionLb::EjectionTimer::OnTimerLocked() {
config.failure_percentage_ejection->minimum_hosts) {
GRPC_TRACE_LOG(outlier_detection_lb, INFO)
<< "[outlier_detection_lb " << parent_.get()
- << "] running failure percentage algorithm: "
- << "threshold=" << config.failure_percentage_ejection->threshold
+ << "] running failure percentage algorithm: " << "threshold="
+ << config.failure_percentage_ejection->threshold
<< ", enforcement_percentage="
<< config.failure_percentage_ejection->enforcement_percentage;
for (auto& candidate : failure_percentage_ejection_candidates) {
diff --git a/src/core/load_balancing/pick_first/pick_first.cc b/src/core/load_balancing/pick_first/pick_first.cc
index c63424cada4..430b150d312 100644
--- a/src/core/load_balancing/pick_first/pick_first.cc
+++ b/src/core/load_balancing/pick_first/pick_first.cc
@@ -648,7 +648,8 @@ void PickFirst::HealthWatcher::OnConnectivityStateChange(
case GRPC_CHANNEL_TRANSIENT_FAILURE:
policy_->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, status,
- MakeRefCounted(status));
+ MakeRefCounted(absl::UnavailableError(
+ absl::StrCat("health watch: ", status.message()))));
break;
case GRPC_CHANNEL_SHUTDOWN:
Crash("health watcher reported state SHUTDOWN");
@@ -1552,7 +1553,8 @@ void OldPickFirst::HealthWatcher::OnConnectivityStateChange(
case GRPC_CHANNEL_TRANSIENT_FAILURE:
policy_->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, status,
- MakeRefCounted(status));
+ MakeRefCounted(absl::UnavailableError(
+ absl::StrCat("health watch: ", status.message()))));
break;
case GRPC_CHANNEL_SHUTDOWN:
Crash("health watcher reported state SHUTDOWN");
@@ -1644,9 +1646,9 @@ void OldPickFirst::SubchannelList::SubchannelData::OnConnectivityStateChange(
// If there is a pending update, switch to the pending update.
if (p->latest_pending_subchannel_list_ != nullptr) {
GRPC_TRACE_LOG(pick_first, INFO)
- << "Pick First " << p << " promoting pending subchannel "
- << "list " << p->latest_pending_subchannel_list_.get()
- << " to replace " << p->subchannel_list_.get();
+ << "Pick First " << p << " promoting pending subchannel list "
+ << p->latest_pending_subchannel_list_.get() << " to replace "
+ << p->subchannel_list_.get();
p->UnsetSelectedSubchannel();
p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
// Set our state to that of the pending subchannel list.
diff --git a/src/core/load_balancing/rls/rls.cc b/src/core/load_balancing/rls/rls.cc
index 0318bd6740f..b425a326a8e 100644
--- a/src/core/load_balancing/rls/rls.cc
+++ b/src/core/load_balancing/rls/rls.cc
@@ -2590,7 +2590,7 @@ class RlsLbFactory final : public LoadBalancingPolicyFactory {
absl::StatusOr>
ParseLoadBalancingConfig(const Json& json) const override {
return LoadFromJson>(
- json, JsonArgs(), "errors validing RLS LB policy config");
+ json, JsonArgs(), "errors validating RLS LB policy config");
}
};
diff --git a/src/core/load_balancing/subchannel_interface.h b/src/core/load_balancing/subchannel_interface.h
index 3610da9a07e..9d49f30ac26 100644
--- a/src/core/load_balancing/subchannel_interface.h
+++ b/src/core/load_balancing/subchannel_interface.h
@@ -21,6 +21,7 @@
#include
#include "absl/status/status.h"
+#include "absl/strings/string_view.h"
#include
#include
@@ -102,6 +103,9 @@ class SubchannelInterface : public DualRefCounted {
// make this API public.
virtual void CancelDataWatcher(DataWatcherInterface* watcher) = 0;
+ // Return the address in URI format.
+ virtual std::string address() const = 0;
+
protected:
void Orphaned() override {}
};
@@ -136,6 +140,10 @@ class DelegatingSubchannel : public SubchannelInterface {
wrapped_subchannel_->CancelDataWatcher(watcher);
}
+ std::string address() const override {
+ return wrapped_subchannel_->address();
+ }
+
private:
RefCountedPtr wrapped_subchannel_;
};
diff --git a/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc
index 50161653ea4..be2116994bb 100644
--- a/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc
+++ b/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc
@@ -388,7 +388,7 @@ static void on_readable(void* arg, grpc_error_handle error) {
// this ev_driver will be cancelled by the following ares_cancel() and the
// on_done callbacks will be invoked with a status of ARES_ECANCELLED. The
// remaining file descriptors in this ev_driver will be cleaned up in the
- // follwing grpc_ares_notify_on_event_locked().
+ // following grpc_ares_notify_on_event_locked().
ares_cancel(ev_driver->channel);
}
grpc_ares_notify_on_event_locked(ev_driver);
@@ -413,7 +413,7 @@ static void on_writable(void* arg, grpc_error_handle error) {
// this ev_driver will be cancelled by the following ares_cancel() and the
// on_done callbacks will be invoked with a status of ARES_ECANCELLED. The
// remaining file descriptors in this ev_driver will be cleaned up in the
- // follwing grpc_ares_notify_on_event_locked().
+ // following grpc_ares_notify_on_event_locked().
ares_cancel(ev_driver->channel);
}
grpc_ares_notify_on_event_locked(ev_driver);
@@ -910,7 +910,7 @@ grpc_error_handle grpc_dns_lookup_ares_continued(
grpc_core::SplitHostPort(name, host, port);
if (host->empty()) {
error =
- GRPC_ERROR_CREATE(absl::StrCat("unparseable host:port \"", name, "\""));
+ GRPC_ERROR_CREATE(absl::StrCat("unparsable host:port \"", name, "\""));
return error;
} else if (check_port && port->empty()) {
if (default_port == nullptr || strlen(default_port) == 0) {
diff --git a/src/core/server/xds_server_config_fetcher.cc b/src/core/server/xds_server_config_fetcher.cc
index 1bd258bd3d3..433f399680a 100644
--- a/src/core/server/xds_server_config_fetcher.cc
+++ b/src/core/server/xds_server_config_fetcher.cc
@@ -677,8 +677,16 @@ void XdsServerConfigFetcher::ListenerWatcher::
// It should get cleaned up eventually. Ignore this update.
return;
}
+ bool first_good_update = filter_chain_match_manager_ == nullptr;
+ // Promote the pending FilterChainMatchManager
+ filter_chain_match_manager_ = std::move(pending_filter_chain_match_manager_);
+ // TODO(yashykt): Right now, the server_config_watcher_ does not invoke
+ // XdsServerConfigFetcher while holding a lock, but that might change in the
+ // future in which case we would want to execute this update outside the
+ // critical region through a WorkSerializer similar to XdsClient.
+ server_config_watcher_->UpdateConnectionManager(filter_chain_match_manager_);
// Let the logger know about the update if there was no previous good update.
- if (filter_chain_match_manager_ == nullptr) {
+ if (first_good_update) {
if (serving_status_notifier_.on_serving_status_update != nullptr) {
serving_status_notifier_.on_serving_status_update(
serving_status_notifier_.user_data, listening_address_.c_str(),
@@ -688,13 +696,6 @@ void XdsServerConfigFetcher::ListenerWatcher::
<< listening_address_;
}
}
- // Promote the pending FilterChainMatchManager
- filter_chain_match_manager_ = std::move(pending_filter_chain_match_manager_);
- // TODO(yashykt): Right now, the server_config_watcher_ does not invoke
- // XdsServerConfigFetcher while holding a lock, but that might change in the
- // future in which case we would want to execute this update outside the
- // critical region through a WorkSerializer similar to XdsClient.
- server_config_watcher_->UpdateConnectionManager(filter_chain_match_manager_);
}
//
diff --git a/src/core/util/log.cc b/src/core/util/log.cc
index 0a1ef08f75c..e2feca75993 100644
--- a/src/core/util/log.cc
+++ b/src/core/util/log.cc
@@ -104,15 +104,15 @@ void gpr_log_verbosity_init(void) {
if (absl::EqualsIgnoreCase(verbosity, "INFO")) {
LOG_FIRST_N(WARNING, 1)
<< "Log level INFO is not suitable for production. Prefer WARNING or "
- "ERROR. However if you see this message in a debug environmenmt or "
- "test environmenmt it is safe to ignore this message.";
+ "ERROR. However if you see this message in a debug environment or "
+ "test environment it is safe to ignore this message.";
absl::SetVLogLevel("*grpc*/*", -1);
absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfo);
} else if (absl::EqualsIgnoreCase(verbosity, "DEBUG")) {
LOG_FIRST_N(WARNING, 1)
<< "Log level DEBUG is not suitable for production. Prefer WARNING or "
- "ERROR. However if you see this message in a debug environmenmt or "
- "test environmenmt it is safe to ignore this message.";
+ "ERROR. However if you see this message in a debug environment or "
+ "test environment it is safe to ignore this message.";
absl::SetVLogLevel("*grpc*/*", 2);
absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfo);
} else if (absl::EqualsIgnoreCase(verbosity, "ERROR")) {
diff --git a/src/core/xds/xds_client/xds_client.cc b/src/core/xds/xds_client/xds_client.cc
index 78ad97b3df0..181bfbd3bba 100644
--- a/src/core/xds/xds_client/xds_client.cc
+++ b/src/core/xds/xds_client/xds_client.cc
@@ -210,6 +210,7 @@ class XdsClient::XdsChannel::AdsCall final
if (timer_handle_.has_value() &&
ads_call_->xds_client()->engine()->Cancel(*timer_handle_)) {
timer_handle_.reset();
+ ads_call_.reset();
}
}
@@ -250,24 +251,28 @@ class XdsClient::XdsChannel::AdsCall final
}
void OnTimer() {
- GRPC_TRACE_LOG(xds_client, INFO)
- << "[xds_client " << ads_call_->xds_client() << "] xds server "
- << ads_call_->xds_channel()->server_.server_uri()
- << ": timeout obtaining resource {type=" << type_->type_url()
- << " name="
- << XdsClient::ConstructFullXdsResourceName(
- name_.authority, type_->type_url(), name_.key)
- << "} from xds server";
{
MutexLock lock(&ads_call_->xds_client()->mu_);
timer_handle_.reset();
- resource_seen_ = true;
auto& authority_state =
ads_call_->xds_client()->authority_state_map_[name_.authority];
ResourceState& state = authority_state.resource_map[type_][name_.key];
- state.meta.client_status = XdsApi::ResourceMetadata::DOES_NOT_EXIST;
- ads_call_->xds_client()->NotifyWatchersOnResourceDoesNotExist(
- state.watchers, ReadDelayHandle::NoWait());
+ // We might have received the resource after the timer fired but before
+ // the callback ran.
+ if (state.resource == nullptr) {
+ GRPC_TRACE_LOG(xds_client, INFO)
+ << "[xds_client " << ads_call_->xds_client() << "] xds server "
+ << ads_call_->xds_channel()->server_.server_uri()
+ << ": timeout obtaining resource {type=" << type_->type_url()
+ << " name="
+ << XdsClient::ConstructFullXdsResourceName(
+ name_.authority, type_->type_url(), name_.key)
+ << "} from xds server";
+ resource_seen_ = true;
+ state.meta.client_status = XdsApi::ResourceMetadata::DOES_NOT_EXIST;
+ ads_call_->xds_client()->NotifyWatchersOnResourceDoesNotExist(
+ state.watchers, ReadDelayHandle::NoWait());
+ }
}
ads_call_->xds_client()->work_serializer_.DrainQueue();
ads_call_.reset();
diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props
index 2a50deac3c1..29dba7a288f 100644
--- a/src/csharp/build/dependencies.props
+++ b/src/csharp/build/dependencies.props
@@ -1,7 +1,7 @@
- 2.67.0-dev
+ 2.68.0-dev
3.27.2
diff --git a/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec
index b407eccc35f..844e08cfcb8 100644
--- a/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec
+++ b/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec
@@ -42,7 +42,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler-gRPCCppPlugin'
- v = '1.67.0-dev'
+ v = '1.68.0-dev'
s.version = v
s.summary = 'The gRPC ProtoC plugin generates C++ files from .proto services.'
s.description = <<-DESC
diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
index 221ef815cb2..91982885509 100644
--- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
+++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
@@ -42,7 +42,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler-gRPCPlugin'
- v = '1.67.0-dev'
+ v = '1.68.0-dev'
s.version = v
s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
s.description = <<-DESC
diff --git a/src/objective-c/BoringSSL-GRPC.podspec b/src/objective-c/BoringSSL-GRPC.podspec
index 260f6c6b908..91dec47c6c3 100644
--- a/src/objective-c/BoringSSL-GRPC.podspec
+++ b/src/objective-c/BoringSSL-GRPC.podspec
@@ -39,7 +39,7 @@
Pod::Spec.new do |s|
s.name = 'BoringSSL-GRPC'
- version = '0.0.36'
+ version = '0.0.37'
s.version = version
s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.'
# Adapted from the homepage:
@@ -76,7 +76,7 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/google/boringssl.git',
- :commit => "16c8d3db1af20fcc04b5190b25242aadcb1fbb30",
+ :commit => "b8b3e6e11166719a8ebfa43c0cde9ad7d57a84f6",
}
s.ios.deployment_target = '10.0'
@@ -132,7 +132,7 @@ Pod::Spec.new do |s|
ss.source_files = 'src/ssl/*.{h,c,cc}',
'src/ssl/**/*.{h,c,cc}',
'src/crypto/*.{h,c,cc}',
- 'src/crypto/**/*.{h,c,cc}',
+ 'src/crypto/**/*.{h,c,cc,inc}',
# We have to include fiat because spake25519 depends on it
'src/third_party/fiat/*.{h,c,cc}',
# Include the err_data.c pre-generated in boringssl's master-with-bazel branch
@@ -143,11 +143,7 @@ Pod::Spec.new do |s|
'src/crypto/*.h',
'src/crypto/**/*.h',
'src/third_party/fiat/*.h'
- # bcm.c includes other source files, creating duplicated symbols. Since it is not used, we
- # explicitly exclude it from the pod.
- # TODO (mxyan): Work with BoringSSL team to remove this hack.
- ss.exclude_files = 'src/crypto/fipsmodule/bcm.c',
- 'src/**/*_test.*',
+ ss.exclude_files = 'src/**/*_test.*',
'src/**/test_*.*',
'src/**/test/*.*'
@@ -177,522 +173,529 @@ Pod::Spec.new do |s|
*) opts="--ignore-garbage" ;;
esac
base64 --decode $opts < src/include/openssl/boringssl_prefix_symbols.h
- H4sICAAAAAAC/2JvcmluZ3NzbF9wcmVmaXhfc3ltYm9scy5oALS9XXPbuJaofT+/wnXm5kzVrpnY6WRn
- v3eKrXQ0cWxvSenpzA2LkiCLOxSpEJRj968/AEmJ+FgL5FrwW7VrpmPpeRYFgPgiCPzXf108ikJUaS02
- F6uX8z+SVVllxaOUeXKoxDZ7TnYi3YjqP+XuoiwuPjafLha3F+tyv8/q/+/i8v36w+btZnWZbq/ebNfr
- N7+t3l3+483q6t3Vb1dpulmvLrer1ds3//Zv//VfF9fl4aXKHnf1xf9d/8fF1ZvLD3+7+L0sH3NxMSvW
- /6m+or/1IKp9JmWm4tXlxVGKv6loh5e/XezLTbZV/z8tNv9VVhebTNZVtjrW4qLeZfJCltv6V1qJi636
- MC1etOtwrA6lFBe/slr9gKr5/+WxvtgKcaGQnaiE/vVVWqiE+NvFoSqfso1KknqX1ur/iIt0VT4JbVqf
- r70o62wt9FW0cQ/99Z4+OhxEWl1kxUWa55rMhDz9uuXn6cXi/tPyfybz6cVscfEwv/9jdjO9ufg/k4X6
- 9/+5mNzdNF+afFt+vp9f3MwW17eT2dfFxeT29kJR88ndcjZdaNf/zJafL+bT3ydzhdwrSvl699317beb
- 2d3vDTj7+nA7U1F6wcX9J+34Op1ff1Z/mXyc3c6W35vwn2bLu+li8Z/KcXF3fzH9Y3q3vFh81h7jyj5O
- L25nk4+304tP6l+Tu+9at3iYXs8mt39T1z2fXi//phSn/1Jfur6/W0z/+U3p1HcubiZfJ7/rC2no0z+b
- H/Z5slzcq7hz9fMW326X+md8mt9/vbi9X+grv/i2mKoYk+VE0yoN1SUv/qa4qbrAub7uifrf9XJ2f6d9
- ClChl/OJvo676e+3s9+nd9dTzd43wPJ+rr77bdExf7uYzGcLHfT+21LT99rZFOH7u7tp85029XV6qGtp
- rmI6VwnxddKIP9m58Z9N+f94P1dOdfskk5ub5GE+/TT78+KQylrIi/pXeaGKXlFn20xUUhUeVfjLQqhM
- qHURU4V6L/UftCir9d2qS1y5vdin66q8EM+HtGgKofpfVsuLtHo87pVPXqyEgkUTSN29//lv/75Rd3Yh
- wMv5v+nfLlb/AX6UzNRPn7dfCDrML16kF//+7xeJ/j+rf+up2X2yTVQtA19D/8f2D3/rgf+wHFLUVEuH
- 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
- zH4XHtP0zp7SdLlyqJBjwzwRxTLtiG1G0CP9EgjKp7/r78zkWZ/hBrM2Sb7fQL4nyff2PPpCd9UFGe6q
- KfrUOpkTcHD2rE2ToQO0WcAKD3N01GYfA1nwUqeiadADtZdJpOv6E1Q9EcUaO+iTHwkjJrwo9Z09qe1y
- Re3Bc21DHUG8ns07CopHoHboD19+++ve7ge16wCmtlLZPdWrPRIM3+myFNv2vMqpc6FvrHkq1o/5FzCB
- X1kfzPSV7csUzaEbdNoTZEUSaJfL8lVkry8jD/j9YA51tIuJzRw/FDGbBQQedqH8aH850mkgui8luMbU
- tN7jO8ydpT7XzIpndV73yOc70EXE6bur7Y7VOwh1pRHXfrbMtGzVqhqYumfkMb9rn6f5w1Mx6rSwQaiP
- HPRTwQdXE9KI23Tdi8qb+qXKy1bZewDxBOHvf/s/JvhepaXSBAA=
+ H4sICAAAAAAC/2JvcmluZ3NzbF9wcmVmaXhfc3ltYm9scy5oALS9W3PbyJamfd+/QjFzMx2xo9uSyy7v
+ 746W6DLbsqQm6Zpy3yBAAhSxDQI0EpSl+vWTCYBAHtZKYK3UF7GjuyzifV4gz+f8z/+8eEyLtIrrNLnY
+ vPT/iDZllRWPQuTRsUp32XO0T+Mkrf5D7C/K4uJj8+tqdXuxLQ+HrP7/LjYfNm/T9+nl5eX7979f/jP+
+ kG528W9vt2+2SfrPOPk9efd7/OG33ft/+7f//M+L6/L4UmWP+/ri/2z//eLqzeWHf1z8UZaPeXqxKLb/
+ IR9RTz2k1SETIpN+dXlxEuk/pNvx5R8XhzLJdvL/x0Xyn2V1kWSirrLNqU4v6n0mLkS5q3/FVXqxkz/G
+ xYtiHU/VsRTpxa+slh9QNf+/PNUXuzS9kJJ9WqXq66u4kAHxj4tjVT5liQySeh/X8v+kF/GmfEoVadu/
+ e1HW2TZVb9H6Hof3Pf90PKZxdZEVF3GeK2WWivPXrT/PL1b3n9b/d7acXyxWFw/L+z8XN/Obi/81W8l/
+ /6+L2d1N89Ds2/rz/fLiZrG6vp0tvq4uZre3F1K1nN2tF/OVYv3fxfrzxXL+x2wpJfdSJXkD++769tvN
+ 4u6PRrj4+nC7kC4D4OL+k2J8nS+vP8u/zD4ubhfr7439p8X6br5a/YdkXNzdX8z/nN+tL1afFUd7s4/z
+ i9vF7OPt/OKT/Nfs7rvCrR7m14vZ7T/key/n1+t/SMT5v+RD1/d3q/l/f5M4+czFzezr7A/1Io36/M/m
+ wz7P1qt76buUn7f6drtWn/Fpef/14vZ+pd784ttqLj1m65lSyzCUr7z6h9TN5Qsu1XvP5P+u14v7O8WT
+ Amm9Xs7Ue9zN/7hd/DG/u54r7X0jWN8v5bPfVp3mHxez5WKlTO+/rZX6XjGbJHx/dzdvnmlDX4WHfJfm
+ LeZLGRBfZw34kxkb/9Gk/4/3S8mU2Sea3dxED8v5p8VfF8dY1Km4qH+VFzLpFXW2y9JKyMQjE39ZpDIS
+ apXEZKI+CPUHBcpqlVtViit3F4d4W5UX6fMxLppEKP+X1eIirh5PB8kTF5tUitPGSObe//i3/53InF2k
+ 4Ov8n/gfF5t/B3+KFvLTl+0DXob+4EV88b//90Wk/s/m3wbV4j7aRbKUgd9h+GP7h38Mgn83GCKtqZRO
+ MnCuP66iJK7jqZDz8yYhK7KaQlDPm4Q8LSgA+figv1nfrqJtnsnojg6pLOKSqShXaVEZOJAj0uoprTg4
+ Q2lRVXkebU67ncwyHDagNx2eLqMrfsi6aoDOxKI8dki7aoceEhL+cHiU+bLODqmqnWlcTelQ97KWzlMm
+ 2BQ7bFYgIF8fEmf+GFPlnSpssjg/f0mUnLrag2qEowbf+XIZ/TFfR7eLj1P5msTlLOezlaxtiahWZdLy
+ Mk4i9bBqN8pGLoVpawfy/cP8Tv2gQoZSGdm6gfgw/xpVaee3kg2xxfTvh7QAeZOVQXRLbzr8qmT7hIt3
+ xBA74PVBwOCh/ni9eJBtwihJxbbKjpSMAqtBuiq14pOsfYosYeB1OcrfqHYgj62kKHebHWXPKeDNBwDq
+ kWSPqagDPAYA6qEKeLGPf6Tdw0wnG4P6sb/F8w0/nqMiPqRMcKf20tlv3YpR9iF+jmTFJXj5yyLgLlkR
+ 6jIQUJeAKPCG/7HaBURAp/bQy7rclnkU4NATUJew0PeFfCaiWNZGDHKnxKibvNz+6EopHl0ngC6ilqVG
+ XCXcpGPoLYf7rw9RnCTRtjwcq7QZmiI2LUcwgN+uSlPgSUF2xECAp0wfb+jhZyhh6qt8CMJBHLOEZZAl
+ CI8bLFCoLOc37ZBdEzkkqilFuco4fSaNw+CEMZci/SVb3Un6HGbVY1A/9USS5uljM8zOMzMYXqfnd2/+
+ GWCi5Chfdv1kBz6tZIrex1nBtLEofrf+o6NtlTYDo3Ee4gvx/G9QbsVRdnfEsSxEGmJtgPyexyp7UvMw
+ P9KXEEcN4/cT2WOhgkRFiurTy2rlcIzyjNgYnkwdfxvZu47i/LGU/bT9oZmFEqGvAiB97xFYEokJJZFo
+ 2k59HHFq5zEY6n1SaXHH9GrFFnv9l2onvGlzdRPrJLorB/mXYfzLCXxeQePKQX5X8mktApkmGUYgB3Fs
+ h1yvZyybsxhmp891FYdFicOAnUT7mRyDTupyt/tUts+5pS0EADzaUQ75bY9VeTqSHUw5wM/TuNJCT5Ad
+ bADmYccT08nBYH6HMkl5FkqJUctmNI757p3YZadFvMnTto6X9dwxl7UN1QJioE5g5SqYljAM9a5zoeKv
+ KFLyoAEGcb12+Unsz1mX/GGmGqBTuzCdxiU1nUgVctku28pSgEq19ZgDucVtKH1UXma29YjDMa7iA4vd
+ KDFqW+IySmxLDvLbjCBqtV6CjtfUCL0p0gUL3UoR7rmqprfcQQLsIv8Un3LZ1oyF+CXLjA3HyIFM9IpO
+ Iq3IrfJRGuzO6QCYUpTLG3wA9JhDYE0NQmCvrNiV0TbO8028/cHxMQCwh8yoefkY5GIhYB81ldDkXm4G
+ MgC4RzNgzhoSxyCIl4y6cC8bgngxWmtnHUwsTgfZGtn+SHnpV5PDfGZLUJPC3J+nTC0v25/qpPzFCnKT
+ ALs0M/Dxnjrz4ahhetdykvlFdnHYcetSYDfiyhxAinBzIUuxLhWoIoAV2S4FdpPZI9u9BJVSFsLrk6TH
+ eh9g0ui9Dtxo1+Quv1lD0z2Rl9uYlQdBiOtVpLJXUx+O0XJFHvzQtRD5Fx34y+VU6aF8SrmDG6bapasf
+ oni7lTFNRWtSLzd6LMskAN7o/Q5VWqSPZZ0xOlcIBvFri6ndKc9ZPoMc42+ifUavzHQtRi5lP3rLi+RO
+ 6yfzo1kHjHiERjTAQRybzk4TXSL7m2dmIjw+zYMbtkcr9/BVXyCA38o9/K6QCbDoCYgLO1N4coTajJPy
+ qK0U4cpW5Ya4HMSUIlwRniLFlBQpwlKkGEuRIixFirEUKYJTpJiQIrtWJS/9nMUQu37TbTSIjmXJqGZM
+ PeLAGisUnrHC9rfz4JDgoXs5wj+3fdljbzAFdLtkh9GlJ4zkb6fqiVPq9FIvlzUsYesRh3S7Z3WQDDHC
+ bmauoizhwXu1jx6A9nP5Ya7pEQfW2PigRKgie4zzR16AdFo/mR8kOgDxCJtbAhCIz2uUNpcTS5tIdufL
+ X9Gp+FGUv9RE/bEbUeNEEg7DvAPdpvBFmquGN6dGtgmwS7vagYXvpB4uN/5H4735PXBYCOMgjs1wfVwk
+ nNUMDgDxaJckMEsBXY7wg+axxIR5LO2ZkIRlEBCX8nDMs7jYprLBlmdbXpzYEMTrVFXqhVT7k/tJJgLz
+ kUn+0KVHnosGgD2CZxnFtFlG8aqzjII4y6g/32XvY1zvRYivzkEcS9GU6LK8bQbneWFrQ2CvNK7yl2Yu
+ tFv3wanSAQrixpuxFb4ZW/XjLs5FqtbkVF31myZRd4hIU3txDMeY8Js8VmksZQFhaRJgl6A5XTE+pyvC
+ 53TFlDldETqnK8bndMVrzOmKaXO658dEKuvnXRU/qqM9uF4GBPEKnT8W0+aPBXP+WKDzx80vIix56fpx
+ hyiuHkNdFAN2KtQMZBuKQW1tiDPmKKI4eVIL1ESaBNtaMMSbP/Mvxmb+1QP8PR0QAPHgrS4QvtUFzRr/
+ tDqc6lQtz0kLwbVwKYhb2PYElIK4iR99qzog4wIY3K87OCPUz8Igft1BZByPVgpzf56ybUD0aHKUH7Ci
+ RUxY0SKCVrSIkRUt7e/bskqGvcoBNRqCwnxr1aMuC9mCFfv46t37qNzpfUfBe4UxKvY2Xf9Attll+XU6
+ pDx3mwK7nauYYXUzs/4AQZhn6MolMXHlkv5cpjZIF7UsTkPcBorfTRU4yT7lrpvyoBDf19kfOErD3UP3
+ A/pRiG9VH1Um32V5ynPTAYhHXWXb4CE1lwK7dUvY1KEHAdWFS8Hc2KnTmxrN8f2QvjBMQl1VI7at59X2
+ eG6DHwRN9QxppuA0v3sd1ycR+rU9ZIoXr5KwGV6nYTVnmJvBmegoXsVPeN1OanBJlj8BVmcE4iPL7GTP
+ wjdKHzUsmZsI3Cfd8t9faXFyJWIuWEq93OCg0RmIU3XiVUONEGbyJwt8swRdK/QVGgYwyevKWn8tRtdf
+ Mzbm9yqAJvPwQ9v7/kKfEDTVY/Rotrq7DLNoEKM+qj0V6KMQsM9yNQsLMAMwwYMdbC5lihs38FwK7Baw
+ FdaSj/LZIWczxp3aaXFu2MGkcdfX8MOdVNevPWy8fon2GX0mAYSYXvPrz9GX+feVOoeBgtd1CJG6hdsQ
+ Isx9LKLkdMy7qCqLXfZIXIY0xkKcD3El9nGuBnaql+5pwfIFSYgrcRuLrkOI9OrLkprc7mjWSF280E+P
+ DtPBFJ8RFOyrzTxv46PqHnIsXQrsRk3Sug4jlodo81LTBjBcNUxvzwAgH5AIyD183tAagvD4sCeFcIrH
+ 7ZgGhJkSj7D1OkAEGRmkMdd2LDrMr2V4nF5nOHIi0vMebV+c7dnKUT5nNQsg9/JZ5xBgDNyJVoOaSpx6
+ UHemVNSFjjABdwmZMPJxcMduiCfPdmmzDo/aNBtj+ZwPKd/pkPrJxLFgQI7zAyPHGyeqIRdYuFkI3Idf
+ pAxqmJ6JdqqO24bR9bADsTGpyWBes8KeV3R0Ui83pFVhIVCfkDJcjJXh4pVKJzG5dBpmf7g+vhQqAkog
+ 4S2BRFgJJMZKICH7EnkSbdTOy+IxT1XPmGUEcGDHuuS36s9aPznalVVAZAMY2I/eYTSVJpV+2AF0xkHA
+ OabeM0wDzi/1nl0acG6p98xSdXhmfGyHMNRiAZkRasqdOT6G66SuY2l31Jw2/0q3tVCJSDbEaXMdfpLr
+ yjod1XMyqvpJjbm90qd4UJZvrh5SF850txORnGzxCDvKy0CDhgC5NGMO3RSJanDkNd3HZUBO9csxZYeV
+ Jh5hM8PKJpgu7bqkfUYKnF5ks9QqrrzZFsA8CxdBWD5qWVp7kCqJPcgsXsjpvSMn99LfEni/kJN5R07l
+ 5Z2Qi52Oyz4Z13MqLuNIGvAkmu2prvdVeXrct/vgUtq8EiA3+Uk5XN1EAes6iygbJozNi5rM5LWjx/0e
+ gW39PCzbVr1XiskYC3Juxq3bZhJtmRUgR/lqV5JqHZCLY4xhOW33vE/QdBYx8MTn8dOeX+2kZ8Ipz8En
+ PE843TmtKtknYF6s54gt9vOxrJrlUarePMiyvSI2iGGC6UKdp3HnZ/qr1tXCseaaKArPVdv0+o2+rZ6W
+ 5l01QNenmFVTRZAdHALkQj2lBTvxOuS0a/9J182vqphoVlSWstVZZbRaGSYgLuz5YZgAuGhbxPpj1Ojp
+ B6QAbuxZt7HZNt7p49jJ48PsVGh/2E/CXLmzeVNm8YZnutuRuttE2pVwTDsQhfnaq++Yng4G8DsXaczh
+ EowBOjU7wqr050lWtfJp4slZKAT0CtmGgiAgn1eZeSXNuD42BwfRz0fVdQ4x6pYwEYFnmcuTDer+PltZ
+ ilMj2tEjDuoYrwCDQQ7z26O22HxNDvNVnMf1qUq1hbZsNxSGeJ+vygyNJhAEe3aTKXwvA+B6MNdaWlKA
+ 237Z5iV6ivMTnW3KUT6j3MD3ODFv1kBv1Qi7UWPsNg3t90omp/LAhLdigN0d5ENfnOWqPfTh+jG2xYDA
+ fWSfLC5CXHoA6CELxSxhoBsdRqRevWoqXer5fB/GPCYgd/nOOArVwQEAHqrzTuYqEcCiz6yjq6K0H6K/
+ 3r35Z7Ra3y/nzRrnLHlmWgAk0JW1Bsu/9qq7vuUgInE6quEMOloTu+wdObfsgHwi/5GJfUpndTqXeD4q
+ lEo86zAiJy8PSpfKPl9p5L6c5ucncv0nJS6nH1qK8pRcFhhil80+k2nkjp3g+3Um3K0TfK/OhDt1OPfp
+ wHfptCe8n8df6FdQQnrXgTFzhN6i06yVPA9YsAYAbbmHz2w823rEgVvAGWKMfVIdurAgshiIU3M6TC0b
+ mqIZGG8GxwTLDyQhrkDvjuUJcCDHIlGj/bzWsqkG6KzLCk0lQNU2XpG5mtZPJi8+BgGuB/9EobH7sZoL
+ JzZZSWUqDUBinUnku2Gr/02oMb1im7LAZzHApjfOKqh1JtKtyjXDXSrNMDWvOeljQc7d8Kp+fgrdEoBA
+ Xu34KqsPbohRttp0z8j7phqjc1qmg9JHbebk+OhGDvFZowXoOK7Yx1WacAd+TDVKZ5yo76ohOq/0w8s9
+ aEg0yR5TeiMbJ01zVR0AVgLysKY5s3IEwgEcuWdCPfrPg9L26sSPaSR+0PZSAHKAz17U4aph+qnIftKH
+ iwclSNXO9OmnexkWEGbMj5OCXYLrEnAlwOgtkSE3RPpvhwy4GdJ7K6T2I33BryMG2Zw6B+2Z/2K0Ln+B
+ rctf9LbaL6it9ksWWSm7QWmqTbraVRa64gFjuE5dT4oK72QmLyuY5wQYQoepHdtOhGpKhyr7+lScklgc
+ ESWy9CFxWonDUXDW8IWtdchtC5GIbEUuC6i21fFWR0ENBA/JdFVtkdMxIY4ZDSqTlmebKq5eyNGv6yyi
+ uhh3mHik9pwAOcBv12C2y2wFGW+oTfohfsy2/XhKf0RpTUovKMT2ao9JUUvi2sVwNBNbbdPVAfvyAbWc
+ jzp84IhNNvdWY/xGY+LOXWfHrjpw3ejck1KFqzbpxzQlNZHU8zaBXK+AdYpsu2/VDY/NQOaxFDVv64AH
+ A/vJIvrybTPZd07O9I2ZYyzH+SlL0vYVqTWoIzbZ7XHjMo33Xx3t8uxxX1NnmrwgwLMZOcvTpzQnuwxS
+ gNs2oHhgTWuSK2KhUTnlBPM6ZfT2ZO0HTo4C5Da/WeSoxaYaOxY0DxBh+wh7ucK/iDuVEITp0x1aPqyE
+ pjg4YputLm+Rznm7XZCGNrU2We13yP5O26OqsjyrM9pQB0zAXAJiG4XYXm05V6UnQWvNmkqbytmfgN2y
+ G3DDrvd23eZH6nRILwJYQfdmTrmht3nmF+eNf0FvfMmKo0skjjg3/KK3+4bc7Ou/1be/lLc7dZBFt/SA
+ A+teX9+dvsz7fNG7fEPu8fXf4dv8ui8ZSCUCWOSdKtg9wNw7gPH7f4Pu/h259zfwzt/R+37D7/qdcs+v
+ 4O0oENiOguZW3GbXaTOOTH1fQwuQeTcCe28D7n4UzZmwqnOxLZP0WBIXD+AU141eQ0RQ/cC5ABa9VTjo
+ Bt6R23fbn9WhBdotP/r+SbqXB4Z5p9tEnR+vKh6enwYAPHj7Ary3CofdKDx2m3DwHb8T7vdtH2mORuAV
+ B4YYYHPv8x25yzf8/tcpd782z7SbzlWLpb3elGxiAyCPXVnJGFLDws14rogfGT4ABPCir21HT4sT5PXa
+ Alivrf4W1FOrx/poddMy2uXxI518FrpM9krrkVts1c//Sn5cXka/yupHLJuJBTmMbb3rwF4nPXJvbfCd
+ tRPuqw2+q3bCPbXBd9ROuJ+WczctfC9tyJ20/vtoQ++iHb+HtnmiPpGh9cnlsLf8j9y8yrx1Fb1xNfy2
+ 1Sk3rYbfsjrlhtVXuF110s2qr3Cr6qQbVZm3qaI3qfbXoOpH9dN30nswiB8vutEbW/sfQxbsoxDES/XW
+ 1GkP2xd+tw8FgZ7M1ZNjN9Hyb6H13UDb/jZMfnBqE1sPObzmPbOcO2YFffW5gFafC946YYGtEw6/p3XK
+ Ha3NM/s00dq59GUFKATy4qV/POW/zuEelBteX+l218k3uwbd6jpyo2t7Dyujd470ysNuhp1yK+zr3KU6
+ 9R5V7WJJ1V8jr9OG9KhDyHphMXW9sAheLywmrBcOvNNz9D5P3l2e2D2egXd4jt7fyb27E7+3k3lnJ3pf
+ Z+hdneP3dLLu6ETu5+TdzYndy/k6d3JOvY8z5C5O/z2cgr42W0Brs1l1NFw/k2sWoFZRf2KcsKrrcCL5
+ mGtHbLLrsm4useOuKoT0pgP/blTfvaiBd6KO3ocaeBfq6D2oQXegjtx/Gn736ZR7T8PvPJ1y32nAXafe
+ e05D7zgdv9809JbR8RtGg28XnXCzqFqRFe3TPC+7E027tX9EG5BhOjHGlcGR5F8xLRDU8zZBDNNGUVY8
+ xTltvQQIsDzUglQSUwkMxtPV2/MwAXl4y9E6ZBYSYXVjjCykoR3I69sV7+MdocmkwyAK64MdoclUd6lG
+ m9NuJxM9gwzIDf7TZXTJDlFX7LJ5UIzGDWFXbLOvQkLhyh8KV0woRgsIhSt/KASEgTcEOECYFPDtyJcn
+ V1mk3Xw1lWnJUB5lLRUgHbjZVcJ5T0uG8ijvCUgHrmxZXC+/P6zvo4/fPn2aL5uOdnsx9O5UbKd6jGDG
+ /NStAK/g12M8fkmaHpsXY1v1BI+LWrFXnPKcbXIG+DxOBz7+dPCQj+WRTZZaH/kk9ny0FHvYYvouMEjr
+ IZOO/oXVBn21XD/I5+/X8+u1ypHyPz8tbuecVDOGmuZLSkkeyiQ3YhrwYUw/tX548fC5L30OR2qZgiEw
+ H3W0f53yDFotSj4dmdjTEWPKPyU8qFJiVE6iddUonZY0DSHGpCZAU4lRqYWELTW4zYG5d7Ovc3ZSRghe
+ F0atjyF8PpzaHkMgPpxaHlAjdGJGMoUIk7Dx3NbhRGrGdMUYm5QtDR1ClO0G0mVSoBhh01oGhg4nhmVK
+ HYB5EI4XdIQIk1pIWUqXGpahx/IyNwnjqZeRcME0y02ueEoV+2xHju9G5LJY0WzF8Oz6WnYYo5v56nq5
+ eGiaXpQPRuRe/vSjX0Cxl00oX2G1Rp+vouuvs+vJvO55k7DdbKO02FYv0y/ptmQWb7e5vPrAQhpKi1pX
+ XKqhNKlJSsZ1EpOTbjecV9NkFo/BgjglOy5KT1yI5vKK5gfKjjpA6nI7Qw5Xk5rcU/Grio9U5KDCaNEx
+ TpLpS7NAscnmvCf8lgHviL/h6u4ymt19p5SPg8TifFyso9VaPd9uQyQRbTHOJlUVgBYnPzbbV2suvJPj
+ fD7aR6VUP67Uwz0dos0L4SpEFIB7EJrPgNTLDYlJAcfk1wd2EjSkKJf6xpoQZZKTh660qff3t/PZHfk9
+ e5nFm999+zpfztbzG3qQWlqc/EhMY6bUy42yon7/WwC9Bfg9TsEmpxGXjB1AvhilJjxTinMFPz6FLz5F
+ aHyK8fgUwfEpJsRnXUYf77gGjdhif2Jm/E9ozv9jfif9bhf/M79ZL77Oozj5F4kM6Ecc6E0SkDDiQi7G
+ IMCIBzESXPkIn5pxAf2Iw7EiLFXDCSMu1IIC0I87EJf6jmBgP26rw5V7+bx0hbVAzJ+ZaQptiSxm77ih
+ YkpRLjE0dCHKpIaCobSpd+v5H2o28XCkMQcdQiRMENo6hEiPI02IMKnNOk2HExkNAEftoZ/C8CcfP+MF
+ R4aFBjmtDjqEKJgxJtAYE0ExJkZiTITFmBiLMXozzVBa1Ltvt7f0jNarIBoxSXUaiERNTGeRxbr/+F/z
+ 63W0rVLCZgBXCVPJYafpYCIx/HoVTKOG4SCzedfr+TDYRqw+bLGPTa1IbLGPTY8tW+2jU2PO1PrI5Fi0
+ xD42tYC1xRb7Qf59Pft4O+cGOQQY8SAGvCsf4VODH9BjDgHh4w0Zdph4QoMfDkAIrOb//W1+dz3nTCRY
+ WozMpQLENe8118gbtsmiDZo4SWhUS+xjb/M0LojlKQSAPai1AFr+n38grI+ydTCRclSfrUOIvNBMsDAk
+ Z3+8VBwmlN6wP7wXo+xI/jk+5eoAOPGDaWEwYKc8LR6n7xt3lTCVWoCh5Xf3A31IShd6mFH6zMZKrZ8c
+ 7Y4hcCmH+dSWBNqGGH54wwS+QYnR5iW6W9wwuZ0ap4fmDjEpd9hPRbHYvoab4sCOsvP4bf3pA8ekkyJc
+ wrkstg4ncjP6WWuR1+8vucW1KUW5xJaFLkSZ1DAwlDaVOZezRudyWBM4yKwNc6oGnZ9pfkiy3Y6OUyqI
+ Rk84yLwOZzIHnsFhTdsgczXMCRp0VoY1FYPMv/SzJcdSZM8sYivFuIzJHP8MjvVrsxw2BN8AIA9ZND+m
+ RVo1V/Uk6jw4uo3LQJyYwX9WIlRlGNUsbCu1ud8f5uSezVkEseg5/6yCaNQJjLMIYpHzfieCWILzXgJ+
+ L3WvBwt2adG+3S3+nC9X/LlQCDDiQSyaXfkInxppgN52WF+zKmNNhxDpVbKhxKiHIyfXu3KET08lmhBh
+ Zrx3zbB3JKeCQYcQ6ZW3oUSo1GJB0+FEToXryh3+pw/sYsLU4mRyMtCUOJWeGHSpxf1zsVoEjN67ci+f
+ GCC22MumBoujtuhJ9kg4xEqTWJy2tVSn0dNbEkzTOcQ6KjeUmzItmcXL6vQQJVcZiXYWISzKCSGOEGMS
+ B7I0HUikR7CmA4knzguewLdTV8hwoqTVIURy/taFCDO7SlhIqUOI1Jys6SAi76OxL2Z9LvKt6mgcVj7p
+ hBiTk09aHURkRQcSF8eY2ELsVRBNHTVOpykVRou29TOPqJQQ9VTwvrnVQUTaKcG2ziIeNt2YAXk2zlBi
+ 1IKPLQBuW33J8P6blqM1nUWUrdlDVmdPKb2YMKU291RHaUkbpe80AIlR2w8yi1fHj1fUbU+dBiDJyCKT
+ pMYmpYdj3pxgSo0EQ6lRv60/S8H6e7S4+3QfdVuqSXSUMOZCCFtEP+ZAKZExAOTxZf59ccMMpUGLkzkh
+ c1biVFZo9NKB+3G2WlxH1/d3skswW9ytaekFVvvo00MD0vrIhBABxRr7+mtUqVtQSZs8TRVGi/a/qund
+ ekiLkpuTTOMkydRh43FOWh8xAaX5Lu6j+HhsLsbL8pRylQYgNbn9HXDbusopVENoMfM0riLS3Y6WDOK1
+ RzYzqZrYYqvDnAp1X0bzCIlsSi0uNTjdUJR/abrTzUVTxOOuUQDi0ZzqHD2eYpko6zRl2VgMwEmlQ8Ig
+ m60ziUl5vumWwhtUJi0tdxSMfNzUq1OvSAsPDJHFygmHt/UCi1HRYtGqR7q/RHGeUylKY5Ka1VmUwlHT
+ uCTibbmWDOSpo5RkVExfHwVpXfL0K0UGBUA5kilHl5IVWU3lKI1LOqjhJEYEnHUw8Ti9iW/JXB47Oj1x
+ yax9LCnGVZdQT79yANK6ZOptNLbOIVI/3PraffqcnA6kxNxJTI6KoIKUlluFTanJdfRZY5JUMmyuCCxo
+ IaTrbKJsDVIL8F4EsChNdU0DkJoj/UibngApxiVGhyFEmIls8lTlCwvbaREyNUMYQoR5PDGZSogwK8LV
+ po4QYZIuDXGVLrWkt500mckjJnYnnatKYJOV0THOKiKo17lERlNVk7k8WtuiVQAUwl1AugYgHcmco0tR
+ ZeLmtKOiOpnLE+X2R0oO9FZl056JnGebcDps0oqcHzUZyFM5StYhDGSnNKmMLhrYOyMcr989bunVAhBS
+ QmgVFqWuyNXKWWORiF2yo9MjoxbubplOTTpummnvrBbFJRXTiAAWZzzKENpMQcuujcBi/OK91S/knQSn
+ 7BZwyS2I5bZwSm1BLrMFUGKrm5cONIgU2Ax66SrAslWk6Q8SRT5vE2QrMC8FLWDOIoAlI6+5d5iaihwx
+ wlZdiSPh7GtQjLDZXJhJ7esLcORG8EZuBDZyI8jjKwIYX2n+Ru3T9yKAdSSDji6FOlYjwLEa0Q2RENtT
+ mgzmpeVOjTycqoKDHdQuvSAsU9E1LqkfGSGnkEHpoRLHaoR3rGb4VRzTbRbnPHQnxtjkLpsldbmc8SWB
+ ji/1ncPubkDS8gsUYHnsy1OeRLKPxglpWwyyyUlukCE84qSUrgOJ9ISg6WxiG5PyNxqwl1m8gt7qP2tM
+ Up3S5i3U8zZBMKqGQWXSTkcZI6TvahUm5Yk6Jvjkjgc+cQL5CQ7lX4zO4i+wt0hOlEBqbDM/ccKqF0Es
+ TjfCVGrU29mX+dXHq3fvJ9N6BUSJPmUFoQCzdCBxQWl2mDKQ9+2YUMaJbaHGvIs+3i7ubtpzOYqnlNC+
+ daUwl5S1LB1M7K5bpgQBqEbpzGDIPKFAGTs1ZQbvev1XlE6/PmpQOBRitJwlDoewxXFQOBRa8HQKhyLq
+ uKK+TaMxSH/M764/NqtwCKhBBLCIYT2IAJaaSIyrRzKu0wFEWtj3GoAkSGmh1xikr/d36yZiKEuPbR1M
+ JEaDoYOJtKDTZShPFaaipmzuRgG4x66sokOZnPKT4LpoCNiHlhh0GcqLcjXGlTCxndqgxxsRZSL6VVYU
+ qqYyaQmJkjhq8ot0EpMjtlebgkJpBAZjkxU0RiswGfIvGYnRCAAG8TocWwcQjzGddowd0nazYb3boLOJ
+ SbqloaTAZuwJ63POApuRp6wP62UujxPqZ5VNOxwzGkgKDEazdpWAaJ53CZQLaHQNQCJWToPIZBGWAd2Z
+ Z2C0/6aWQGeJyaFV3U6NvS1PhSquf0V/p1WpAkyQcI7aoMscQyvbWoHJyJ4ogOzJVlPD+SwxOSdKbBs7
+ VeW/02IfF9s0iQ5ZnquJ8LgpMqvsIPtH9Usz5ELAT8GZ/j9Pcc5q7lhKk/pMCRP5tKEm5kIn/+2q8iCb
+ RUX9WB7S6oWEMpQG9XFLSSryaVN93omu4iKNSJWDo7XIdVTttm/fXb3vHrh89/Y9CQ8BRjyu3vz2IchD
+ AUY83r75/SrIQwFGPH5788+wsFKAEY/3l7/9FuShACMeHy7/GRZWCuB4nN5TX/z03n1TYil7lhgc2Tqi
+ 1RetwGCQJh7v7DnHO9XbkPUYsU81iGxWkT7GausrDXZW2bSS1O1pBQ6jIL6MFNiMY/nrigZRCodCLyU1
+ FUzbxbKmUjMYPKwmt/nEBA71WuXfVEOJRlEKg5KntEzSPG8RyL3Os8TkkO7C7gUA45IMuTQoh7gSe9lS
+ Ia0LM2UWT/ygtoZ7jUkqE+JoRaeAKNHPUzb9jARb5xBpLbhOAVGumvYUndXqICIT6OexmsAwAPcglhOO
+ 1iE3kx2C+sqdCqNFm1xtKUl41LMapZcJl1wCKZ9czgwihHXJgl1iNFa+NLQIOQCMcA+nnIiTCojC63y5
+ YodNbFycJQ5H/KyIGKmAKDUd46Y7cdpQMacNRGEliV7nEBnFlVtKHTNaa6IVmAxaurTTpExS1C/pJAaH
+ Ns1kzy4VhQweil497xKoOWAQmSx1YzitCXOWgBxqABs6l0g6J+MOuv9c/pXWmbF7MsdY1Tiq8RedCnU2
+ Fak+BNQmnTu+5xnJI51Gen7eJVAW+Q4SkyPSU1I2B4BQUIMKo6n/85jymK3WIBNf0Hkz1it53qX9M617
+ auhMIrVlVLmtoorcIqqA1pBIt6cqJRagg8hi1cT5nk7hUBjDL7rM4dHGygQwViboY2UCGiujtW7slg2x
+ VeO0aGitGbslo1oj1DDoJAanLiPrwnUC0RWD7O6WUAa4U9pUVrPZ0BnEE21w4WSPLJxoE5kneybzREsK
+ JzstPMX5KSXW473GIBGH1qxxtf6R3anYqiOsoj2hBALVEP1Hut3GP+jcVocT1UqZstpwwZ3cwyeNq0Ni
+ D1v8PKUpYasEooccRJrvaO0vV6pxv32Kvs6/dseRTUYaKpdGmgrVNC7psSp/UUlKA5PaWw45vFbpUimt
+ g0HictSW2eqJHGidzOQd0gNldr9XmBRRV0RKq3Ao+TauiRglATiElSGDxOEU9M8qoO8q8rSgcnJ9Z//1
+ x4/NUDZliF/XwKRoU5Y5B9cIESbpmnNX6aO2xyzW8SMf3yMQn3Jbk++SQAGYR5a06zBqwpkUOAFxOfEj
+ 4uSLidMrRMVpLC5IAySGyGXlsjdDzzWtyqWJY7xNqbBG5LJOl++pJCkBOd0Np9Gxkj89Tx/K8SBAnzxl
+ kHPo26/IaVNKQE7wt7sIwOftFZn79grkMMJQiQAWPX+foHwt/8h4JyUCWB/IoA8QJThSP0yI0624ijb0
+ L29lAK/evWUBOx1I/MCgASGqenzkErURmSzi7eGaxORQDpI4P28RMuJmaENks8Q2rpJou8/yhMbThCZT
+ /kc2/cyhQQFRKBeKmCqLRjmZthcAjLYeV4Nz08/dBcUmu1lgJ9NvRGgw2zqTSOm6n593CRG5DBpUJo34
+ Yc73EHt/msTkUAaMzs/rhFXXEUgrNT6XpNV0mCOFuFnd3fCxjwVlPBwnAC6qHa3u/CS1w12tSVZngsZZ
+ Ibp9AS+UAgpS2/TjC7V5rKtMGq0UXjml8Krd8Fm8EHumpg4nRmmeHginxWJ62EGlwFAXmwE4cUIGDhV6
+ n90SIkzu949+d5Qdjnm2zehdapyBOdG6u7YSoZ742BPCJWfeXuSy8ljUpCa3IYN4tL6yrnJp5bG7DoOT
+ BQzxCJuVKVzCmAtvcGiMNObKS4IQw3UijUD0EpDD77ChCNAnTxnkPAVYV+RAtUYg+j8Gf7t/BKJ7iDIC
+ 0UtADiMM7RGIFXX7jCYBOWr/o1r6w+CdpSCX8a32yEb3Z3IxC5WwISMbGAFwoY5sGDKAV9RZLrszlSA3
+ EjQpwCWPmJg6kPiBQbNiKhP9sra+jZA+0jo5GMNxag4KsjotRCMI4fPhfY4L8HnIDhKfL8Umm9RvXtn9
+ 5lV7dqXa0Euh9CKT1S5+bDet5tnfMn4p2ypwAuRyqrdM+llpUdP0RxvEpMkbS2gyxY/sSEGp5y1CPX3u
+ /vy8TaDMQQ8KjTJfrhefFtez9fzh/nZxvZjT7vbD9H4HwsgGqPbTCWsOELnG/zq7Jh+ZZIgAFimAdRHA
+ onysprFIpHP5BoVFoZzF1wssxpJymPqgsCi0U/w0ica5v/sU/Tm7/TYnhbGhsmjNmU6poMW/LUSYedmd
+ T88C92qL3haqeUZoAZkyjbe8jW4Wq3X0cE++QRTS4mRCInSUOJWSCFypzv3+sL6PPn779Gm+lE/c3xKD
+ ApR7+aRXh9QYPc7z6Rc5A1KMSxqhdZQYlR/MvhBu5jxk1cojn9UYndICtIUYk50cPCmhObZOLc5hh4RO
+ GHURdVxn2ya2VX8j3qWBpi4QewfaqciQ1iF//bae/0WeZAa0CJk0HWgLEaY68I90cDis9tFp89ywHOGf
+ irD31/R+B/436ADHQzZWv8tWBnW6HRKjbEaq0aUo99Q0tKKN+jzBNDAYjtP683I+u1ncRNtTVVGmeGA5
+ zm8uIemulOaa6Ay/U3E6pFW2DTHqEH6fY6kGOqoQnw7h+Gw328urD2rosno5UuPFFGPstAhgd2KXvduo
+ ny+5dEuO8T+E8UffP4iOsvex/F909YaKPetcYlubqTYi9fodnOC61FVAmBjiEbb6J2EeA0c4PrvsKKLL
+ D++jq+hYURslpthll9UPmdnqdFur/96m0SFOnqJf2TEti+ZHdU6x2i5DGbplsN03ozfkwRZ8c/E3L4Hp
+ Uof7uD2oqIvJjYtBiDF5JacpHmGzUiuEwHx4Oc4Uj7BDvsGf47qHWA0vQ4uRmx7hj/SFxz6rMbqsnKcf
+ rwpIMS5lXN0Wukx1GdtL2/5tL1/mtrI8JK9rd4vya9jaKK9v+6LhpgYHdOQVe4/QzXbmb/119IQTD3AC
+ 6NJUEN3xqVlZMFwsAujShCHlJh1Ii5LVGs2AiLYRoE+9b24tlc8SBvdhucvfx2qtNb2POAgdplqzGosD
+ EdipXFrbwCS3S3udQ2wKV/EiKCeMAFKX21y8ussS2dnM4jzanCgL8j0MxynPNlVcvXDiTZc63ANnJPgA
+ jwG3f+a8oqZ0qemBcO6BIXJYqoDilZ+a0qWeDhFnTKTXOcQypNdX+nt9ZbGlFoxK4nCOZf5y+fbNO16L
+ ylLjdEZqMrQ4+USbagTVLr1KIyGLik35zHp1S+7wq4RRhrUihKVOV6uzY55+oNzd6kG4PimnkOlUAG3X
+ XmYguyyRMm8OASZtEBkD4Z5ZseW6SKnD7Q5V4hecLmCCR9Yu4gm26jiY40lwPZQSoNbtVueAljbIAJ1e
+ pxcjCL0Y8Xq9GEHpxYhX6sWIyb0Ywe7FCE8vprmWOgl5e00N0gNb/2JK61+Etf7FWOuf1wjG2r/d35sx
+ P5GmTGwvR/nZLoqf4iyPN3nK9NARjk+di8u30f5HslMHPKvH5XMpNfARCujGGPU9yzTeehndLD/+Qbu5
+ yVQBNNIorS4CWOe7Usi8sxBgkupJXQSwKEsqNA1AUvtWCTnAlGm8fXyt+rDtKKZMs8/TR0NdKcotyv0v
+ JldJUa4QIn3LBDdaPzn67TkELuUD/2a+Og97T35jXWOS0u3mLbXDZutwImFIDpA6XOaLou/Jf038LZP0
+ Sk3usl7V0jrktwHkt9PJ1OBw5Ra/oKfWs8YkFczvL9BvL/jfXfi+WbVoCJMqmgTkEF9tUMG0U7Hdp5Tr
+ V0Gxyy5lJ+UYV1lN/vBBqVE/k04X7x439M2bEgDN8y4hOp42pOi0dCaxPBxPsktF5A0qjKZGpveEOIXE
+ KJt2gygoNtiU1lr3uKHvb7OjBaMug3kyFcaHtE4rQcl0GMDyqN9EjySmErgM6je3EpdzpFKOAOMn+Yuk
+ BOBU2RPnw846gEjOtLrM5f2kkn7aDHVZ3u//vPwn6d5DQGpwz1dMDemOQHbFBpvQz2ifNtXE+yE0icFp
+ t3ewvs+WGlxBz0sCykuCng8ElA+aoZZm1zGN1IlMVvY3pXxVjxt62rLzXqAzmlAXlJttdY1GWtwu1p8X
+ 377yCn1QPUaXRbdMLupoh7SoK8JevIk4yL/Pi7JEY38kAPF6nTZ5tg206hmQU5cDQ77JQXh8Ar7HJoAu
+ 7a/NHo7uhRhGLgTyUtva6XClwmjNEsjqoOYu6+kLu30MyOkprbIdI/xbnU5czq/X98vvq7US0ZqMgBYn
+ Tx+Yc5U4lVJ5ulKdu3q4nX1fz/9aE8PA1MFEyrfrKphG+mZDZvC6rYzR3ezrnPrNjhYnk77dUuJUWhjY
+ UpDLDAL061kfjnwz73OxL23m446UZXCgWGOvZtFqQSw9NI1LUm17KklpXFJXg1JhnczlUaJikLicpiak
+ khqRyxKM0BJOaJG6Ed3zJqEdkFE1WFyfKtLXWVKTm5QhaFft0EnNgEHicIjVsi6yWLKpf/OZBGoUJoWa
+ H928yOoNWDqEyBsEQgm2C2kYqFcAFPKXO73X81+PZM4Rovykf5fZC+7/Sh0OsoUQkzggZOkA4k8y66dD
+ oS4qsWQgr1/SzoD2WpMcMMwEqhE6o58IyxE+vX8Iqk06sd516lz2ABegBcm8UPX1u4efWSHq6WvLXwWj
+ bBNg2SYYpZIASyXBy6kCy6nUat2t00lDfN3zJoE4yNcrTAq9YQG0KhiDhbpoYM2veXNstg4nNhtZudhG
+ bLAZ/RNTBdNK4g3IkBYiU3o/pgqjRRWPF1UoUTCJ4BcTe2mOEGY+U87acYQQk1ALGSKIReoBWjKIJ1ip
+ RiCppi65afustKnEfpYhAli0ItGS2Tz6i0Fv1YzdNpeBFWpjTLN1IE/jH3r9ztlhz6O7b/d3SnX820lp
+ nGB3wzz649OxuQw3ki2qfZlM59lKh6oGzY9XV7/xyJYaob97H0Lv1SD97yD63xh9ef/tISJsl9M1AInQ
+ iNA1AIlWKWsigNV24tvxgbIiU005xi8rwi0xgBTmtkfS7vL4kYMe1Ah9W+7iLTNMejHGPlVPqUqBPPhZ
+ 7aVTRqsROcJP0kdOChykCJedTNBU0mZrwkVVrhKgqrGIzUtIMDsExIWfTgw1QG9CjDSADUgBrgjKl2Ik
+ X6rf+YWVoUbozZldahO5rIGFutBcNg8OLCeQZLh+mX/vxtlpfTdLiDBJvUxT5xBlhGcyKbWHRKbbavrh
+ xCjA9SDVj53CoRDrxrPE4XCG8QGpl8uJdkcPOKgquSrJwTkIYSZjvA6RI3zymB2shuhNPqTmZUcLktNi
+ 2xRXgkHutTCZNrDnKjEqeSAekTv8TETlMf55ombBXucQZXxeEbbSmyqHdh4yZ1XdMAD14GcX77xB9wxp
+ WOWsgCjslgyoBx3IXTNT6DDLbX1FD9VOBdJUSDNwSubw2kkEdpDacoRPn5ZB5BifnXo98zPnJ+RvjEx9
+ lsE8GR8cnpQ5PG4b1tGCZG5NJLw1kQioiYS3JhLsmkh4aqKmLc5opPQ6kMhPtZYapnMbKKZ4hB3FO/Wj
+ jGvZ0cqKmDSiPI3nvAFtys0QGayv8/Xn+5v2cLkszZOofjlSCkBQbzi0S+rihFKd9BqA1Ozbp/YabCnE
+ JY0b9hqIRFjnb4gAVrLJySipgUgn+vfZ/TX6KlJDBLCacb2Q7OPDTPYjDtiMoQDfTA0q1GSPVgbxRBSr
+ U5XUAWI1PbWZcphfFm2jhgM/awHy4URP0VIDkGgtamC9cP/XpmmoRn/IvF4JUJu/E5tNlhKlbjcbJlUq
+ USqtSWYpAap4ndwtpuZu8Xq5W1Byd9vSOxyrVIg0eRVvHIf41yW/OLD0hkPXscmSq4Jwn5YjBJmilr8l
+ DGYrNJjNzdunLK+zruyhpDNXbLJV+zVSc6YUZi8CWe/eM1jv3kOstx8Y7yVFEOvd1SWdJUUGqzkrVyao
+ Nrqa2eDnQxKJfaz+U4hfJ4LHOMznLT/z/Lj6zzBvAKZ531y9e3f5T9WCP8bZ9MkOU4byzkPx009PQAGu
+ B2ltiKZxScS1E4ZKpy0eZsv1d/LGLUeIMKfvXLJkCI/SFrF0GvHuj8Ud8XsHicNRhVq7OIU4ngfLQf4y
+ hL7E2c3NjucSOS0e5U+C6AAhHB9KvPUKh1Klj7JKSqvm4hZVc+dpTY1CkOE4ibA4FWNxKkLiVGBxulxG
+ q9mf82i1nq2J6duVmlx1oGlaVWVFG+9ylD7qjo/dmdx2BKL5mcLUZBBPvMiEc+BidbVJbz+Ddsm5rcOJ
+ UcFlRoVJbW61aX8SFKaus4inYsv+fEdssps5OWpU9SKEFeXqTxxgo/RRyRkLkLv8In0enmqO6KdauATT
+ Rf6RHYW21iWLl8OmzGnzRa7U4qoa6+PinpOWbS1AVv/BJWtagLyc3d2w0boYYDcH45Vsuik3+cc0/UHP
+ ioMKo5EzoyX1csnZEdIDDnksamZgDFIvlxcsln7cgRdAEMTyKo+qK3iIqx8k+iCzeJVabtZYkpK1rsOJ
+ 0XbDhUqph7s7srm7o8U9cVLcCUxrVRqLsmAX+IAc5DOLfVdt0w/lU9pc50zkDjqQ2B2HzgXrcpsv6rJi
+ vbImNJki5oTBoLJofTOEWiCYSpdKLQLOGo3050M0m89uouv1X1FMuM7ZESJM4q3ckBYhk3pvthBhquYc
+ YT2PK0W4lLPSHaGH2W5RSrIq3VJuchvjII6UMQpLhxDLY8p7aSX0MKPHuN4TdgQgesRBpITdk7bQw4zE
+ Nq5r5mvrAMSjjh9JmzQBLUKm3PvjCAGmWnxCOzkSkAJctdtUVifVnlPS6WKEzQ1hTQuQ2y2IzPDQxSb7
+ o9o4ui6/EBYlGSqTdr14+DxfNpHaXCtP2wKJAVCPbXYkZnBHjLPpdZarxumUVTmuFOfWVc7lSinK7Y6E
+ p7RjMQDqQVt7CGhxMrGVYElRbrPo5nikNelwBOpDbTlYUpz7xChQID3qwCvDQQDqcSgTbuwqKcoltnRM
+ JU7NEi41S1CqurqGm0QaLUoW4WlcTEnj6qGQEqDXex2C06MJ8XqpCwL4BaZGAF2C6teRupUbD3j4h5Q0
+ /lImKEZHYpJZsqClCi/vu/me3uyB2jrN3z5lBa0fo8lQHuF8QVcJURfUCrBXYTTWK3ZCiPmNdIOtrTOJ
+ N+lWpqCPsUjf/0Yh6jqQqHI9A6hkEI+cdjQZxKPG8qCCaPQY0XUQMbkllzOG0GGqFjEnEHsdTiSmb0sK
+ chnRc5ahPN5rgvmw+40V7YPQYmaPqaB9dKOAKPSIHmQo76/7T0ykVKJUaqwYSohKTjq9CqOxXhFON81P
+ K8qaQ0OF0Zjx3UsxLi8sz0qMysg2lhYic6k48U/aik5LhxOZsaWJcTYvxgYtTuaGr6426fO76/ubOWvU
+ xJKiXGK/2lRa1ILVrtFkEI+cFjQZxKPG/6CCaPQ413UQkdGuMYQOk9Wu0XU4kVjuW1KQy4geuF2j/cB7
+ TbB+6n5jRTvWrvn88GXezgxQp3tNJUbNmMwMInJmpQ0hwmSM8NtahJw+H8uqZoFbKcKllsiGEGH+SHYs
+ pNRhxPTAI6YHhMidsQMBiAexVtJ1CJE6r20IESZ11tkQosz6dIziU72PqnSbHbO0qJkeLmjcU6RFQhvN
+ wilT3dqlDmr3Eet0WAbb+2avEezTQjw4sCeE8/9PQcwIXeqKBEMIML/cfIr2suCLDvRiSNMi5IwHBevM
+ L/OvzZksOaMI0rQImfOmjQzh6ecpc9/YYmBOw7kmbCMDAfp8Z7ctNC1GJq4cMIQIk9WuAM4+1H86nzTI
+ 4p7FCJs6H24IESan1dLpEKJas8pCKiHC5LRS3NPb9F84Zx4hesyBfu4RLEf4rFL+LDSZX28C1i45YpDd
+ 5G7BAXdKnEorb7561teefyOWNZoM5RF7xqYSplYpsZwxhCAzke2KquR8fKcEqdRy9iu2Vvkrb0XxV2w9
+ cfcDrVnTi2AWsfTTZCCPWPJ9RVYdd38nr5fRdSCRtX7F1sJkXjmElkCkQ9VMmcNjl5SeUpITinDoqa3f
+ 7WlwDKQpdtjEtRytwqEwQg4MM0acuvH58HEeiWbMkIIaVBbty/Xqw5Wsa7+TaL3Kps2/XzU/0mhnlUtr
+ hweT5LLtlmXFrqSiAQTiQ12XawgRZkKr73UdQqTWT4YQYbanaxMbf67aR69EHJVxeozyeJPmfB+Tgzs2
+ Dx4ed5fEChNjjDg1rxTo1DFGnBgrFjHGmJMQkYjzmtgJ93E8jv09xCHBqEMQr3Z8h7ho0FUjdGILSNfh
+ ROJYjiVFuOKVcqWYnCvlk10hzC1pDMKoi0pzgTYKgftEyV5lJa5HJ/fxm7xaxYfHtKBd5DJKmur68xV9
+ f445p9v2YTW0ybbUIRO81Iv1Bw8Gmxo0jztjhBrSexxUlpS5JDjlWJxpjsfTJn0+voZnSxpxDannxaR6
+ XrxCPS8m1fPiFep5MameF1r93IV24JcZJILrK0Sfi5vuH9LIwXET/F/LeNwxuHUlxltXsRDEBZqaDOVF
+ N5+ZSKn0UFczNnY1w7ntwflcdKvG6Uv+Wy/Bt97EIuU0LzsdRORUNkjNQjlhX9PAJM59KrAc4qux7xAD
+ Uw84JCl91EfT4UTyCLUjBtnqMjgGVclQHvdVey1ObrbypbRlF5AecOi2VZPJnQ4n8oJDFwNs1vgSMrZE
+ urJdFyEsTl3Q6VAio0Q9CzEmsw7QtBh5yX3bJfa2l8wwvUTD9JIbppd4mF4GhOmlN0wvuWF66QvTOhcq
+ n6nl17RbIrwU2C2q4l/cFQIYw+fEWimAIAAfRmMEbIfQ7yl0lAC1beKTka0M5fEKck0LkA+ZbPcVjyGN
+ EhcB+HBGPOHRTjVcGZqWAYbPiZ+WXQTgcx4SItPPQg+Tl2YMNURvTl9snqKnF12Ms9uY4cJbNU5vooML
+ b8QAWzDrSYHWk4JbTwq8nhQB9aTw1pOCW08KvJ4Ur1JPion1ZHNfDXH+3RBCTM5oBzLW0XTRWTm6V4LU
+ vxlf7KxdaP7MCj0k5Ih3EZoygPdE3nCqyVAeLz40LU6u0q3a6sKFd/JRftAX6AzTibVzGtkzzdktDe+T
+ Pv+VuHhRk7k8+oY+bK81cwczuneZt2sZ2688/J0YeoYQYtJDEN/3rC7KaE8EjOI8i0kNFFvrkhPyORKD
+ yqKpE5DjVESXVx+i7Warbn9qaikSHINM9Iqyw1G2ZjLqObmTgOPvoG7aeoUv7jA+v+0h2uSntC5L2vZo
+ nDLVLfrwOn7RhxHHA/m0WQTh86mraH+Iz6HONzM5HsfH7YHtIrV+suycFUlzpGqIx0AZcRMBmazTjzjI
+ XHB5FeTRECa4vA12eYu5/POKH+utFiGrciK4pLUhE72CS1of0PcOr5BjAY7HkRt3ndZPDsyxDmXETQRE
+ lj/Hnp/g51iDMMHlbbALlGO3+1j+7+pNdCzzl8u3b96RXRwC4JLIN0mT9G1Y9gUpU92CMvAoEXiL5/Cg
+ fR4N274dRWP3MoRXVyxeXcG8lHDrjCmDeeQiCm1PtD+UO9b7SRnAk1UYJz5aGcJjxEcrg3mc+GhlMI8T
+ H3BN3/7AiY9W5vK6epfK62QIjx4fnQzmMeKjk8E8RnwgtXf7AyM+OpnJ2+Txj/RqQ2zHDCqTxthqC+6x
+ VYU7MYV0EpdDjMlOAnBoWxc6Cch5ywC9hUmcYDrrECInwDodSGS+ovuG6uCN4pSTBvLOGpOkZsTbUanN
+ C+mGMEDrIdPm1C2py23HvHhvrGs9ZPoba1KcW27+xeVKqcndx6IpzvZxlfyKK1JI2FqLfPyRchs0thYh
+ M6oCWwuQg5q1MAFwaXfmkPu8thYgH9WnheBtAODx3N5fH+LiIkyfQ1zJP+dd0o3i/LGssnpPim2MATsx
+ l2wAcoTPWqjhqi16Qjq6XT5u69/R9O8cfdNjJEIajUk6yi9Ng+IbJkAuzLh2xCCbFc+21iRX26votzfU
+ yn9QuTQGCuD8RmNYaY+abtw004xV7JpDV7vz2raV2uRx2u2yZyoaBTmeV1e/EeFS4VJoxSZUSnazS68U
+ Aj6U4/v2AzUMpMKhvKONLrYKiBLRQ7NTmTQ18KVGwZrNDIeYlElsLUzuyie1NKFKOHgDAHu0v52fFKej
+ Ouw1ZbkhKMy3uUCXse8PJmguf63ndzfzm+ZArW+r2R9z2ip/WO7lE5YlQGIvm7LiFFQP9E+LhxXpMIBe
+ ADAiwnFFhshlnfKUdGO0rbOIP09p9TLU6s3dxydBgsMIy6e5+nlbngrCbLUjtJgirZ6yrdq+k2TbuC6r
+ KN7Jp6JtPL0DPgoa9dykO3UF9SuYaiTL9SmtBOFuYF0zkP6Y382Xs9vobvZ1viJlc1eJUadnbluHEQlZ
+ 2hHCTMreQVuHEAln+dg6hMiNHk/stNt9SnUp8h2hAPEgfD5PcX4K8GjkCJ+XyNA0xk1inhTWLBpnMRsl
+ QhV94Bfc+DMRPh9+/AlP/K2+fVwv57zkrWtxMj1xDEqcykgimnTgfv5yM/nGJ/WsqVTXC8RFQgF0EodT
+ V/G2JoIajUb6OrueTJDPmkrOaaq2DiNOL41tHUQknKJqiBAWYRmtrQOIlIxkiACWGtOefgaEJQN4lCXm
+ hghgETKgrgFIpLNDTZVFIy3ZHhQWZUENpYUbQsTl2brGItEWZWsSi0PZX9ILNMZytVIHCcTTc3KvsChp
+ QaU0CotyPtKcMgDpCC0mfwgbkVt87sApKLbZZf7yVmZW2cuoaVxNCDIPp5wBlKqBtlitvslHo5vFah09
+ 3C/u1qRyEpF7+dPzMCj2sgllH6we6F++f5wvaRlLk9gcUtbSJCBHNTBUszSX/6wrQqXrY9hOnGzsKn3U
+ wM/womzfgDk2FIB6kIsRTG87sOeOEDnCZ74/Xg52v7e/7KryQN3AjAIGj683k6cD5KOGjtY86QUmg9I4
+ OT9vEtaVbKnvyupAwfQik0VrnAwKnfJuuvydoaOG5zs3PN8Rw/OdE57vOOH5Dg7Pd+TwfOeG53z9+f6G
+ smV3UDiUU0HnNBqNdHuzmr1/xyrnIa2fzC7rJ8Fc74Dy3oPw+JDLTJzgurDLfRSAerC/Ay/9+ye0i6ua
+ Mlxdbka2gSCAF7+u8SBcH8rxBboGJsnGfpuwOche7LJpW/tNFUZjv6sl1/lf5l8v31z9Rmt1WzKIR2p9
+ WzKUF1Ck+TmQI6+UhtRj9OF1aNlznAU5B5XTHojXi1HG4QzIKaC8RhEen4Dv8ZXa/TNh5bYXA/qFlN0e
+ iOX1+/sPjIKmVwE0ejHTqzBaWCGDYwA/dhFji0fYAQWMHwX4hhYvCMPnxMuMMALwCStaQALuwv+WkXKl
+ eSS4WEEpkFtgoYIwBqdmQvf6/m61Xs4Wd+tVtN2n2x9TPWC1h04ZpQXFHvb0jjcg9XAJo7OQViPLXz7R
+ gqBX2JTmxpt0WxMWDTlCkFlXhBWIts4m5uX0K1IGBUSJNllJJymVTaNE51mgMebr1fXsYR6tHr7MrmmR
+ 6UpRLiEt20KUSflwRwlTF9HmfdOBISyjxPQ+h/aEP75Dq8ccuJG48MThoskVsuglVEOYHnPgJZIFmkYW
+ 3CSy8KUQERgOYjQcKKMZrhKj0kYfIK1Gvl8vrufyUVpaM1QQjZACNA1EosS8LhpY9x//K9puxBVh/6Ym
+ sTi0RT6axOIcaIyDrSddXTwoTEpC+5LE/gr5H4lKqlmiFmELCsuSotzNSwi6U5v0ZpVnEtcxBdqLHFZ0
+ KpLpkweGyGTlafE4/bS4QWFRCmpCbxUmRf7harvZUDCdxOXkBRWTFy6FsEtak7gcQX4bYb2NxFKDuJO4
+ nPq5pnKkxOQIcowLIMYllorpJC6HGFedROM8zO/UQ+osyzjPhx0eItqWxfS85scAfqJZBE036HQuUe2o
+ KLdUXqsCaLRFq5YM4RHqAFMG8ypSS8JVAlQZV9kjmdioANrxJCsG2XZjfPcgdbmcr4a/V42HPCey/qrp
+ vLPSpapKJ4vfXhGGVAEpwD3U2YH85a0Ko8kc+y8eUSlRapLtdkyskrrcfSz2b6+oyFbl0rogjh6owF4I
+ MNVS2ybdkqG9EqOqC5tKHraRAlwR58XpQGa2Mph33MccnpRBPFa27GQQTxzjbUrnNTKI98x8QazUyPdR
+ kuZpTX7HXggzy6Y+rh452LMWJHOK4U4G8jJZcVY1g9gKQSahS2uqYNrpILvO6fSrUSAtSK7SusrSJ054
+ nqVeLmUmBJED/GZ09ZTldVZ0u4/pIQMwXKcDq213QNp27d9JO1cAKcBNDwm9qdOqXFpRMptjvdBlHkuR
+ PUd1GdXkkl+TutwqZUVQJ3N5It2qa2b5jVwHgHrwkpYhBtg/ZJGcHknbyiAtQubUEr3Qw4yyHRsrtT7y
+ cfq5mKAYZtNzW6sCaWowi4FTMpjHSbc/sNT6g1k/9kKYKSJBOt4E0oJkRs3bqjAa6chFQApz6U3gVgXS
+ jiUnPUoVRmsSA2HPH6yG6Sex52ClDOQR9luaKozWXLq8OxVbHraXw/x9tmO9r9LBxJKVN5UM5JG25ts6
+ kPh3WpUMoJIBvLraxrIWPNBTfK8EqZwyvVGBNDUAwMApGcjLt3HN4CkZwmM0EFoZyCv4kVL4YqXgRUuB
+ xUuRT78V05K5PDVs9Egux1sVQDuoVm7T3CUjBynALfPyV0puBXUyl/fEHUJ/wsfQ+5/IS+RxguvyN6vJ
+ /bfd1l5/ni/Jx+iYKohG6BRqGohEaQLpIo11TAt4WmUyGCXgLu3hz2yLTo7z2/Pw2PxO7vKJB2hZMpRH
+ aiS60oH7MP8azVZ3l81xZ1OJhghhURbGOUKA+UumkJQMbFQYjfWKvdKk/vXuzT+jxd2ne3JAmkoflfq+
+ rtqkb17qVLDIptKkyv9sZjA38fT1urbOIpbRXlpNr6cMkclSk1nqfMrrxYMs3ZrQoVABucmnxr4b502o
+ 3nym3XftCCHmavbQLrP+Mn3gFVbD9Ojh20fCRc+AFOZyg+KsBKjz64Cg0MUgmxsQvRKgPny5Xv1OJjYq
+ hPaBRfuA0eTjiz+bQ02pmQpjQE68gMVDlZ8KvGlgGZTXliN5Tf3ebJ7gws9imM0N5aUvH6vKiExUIoQV
+ zb79xeIpIca8Xt7ymFKIMZfz/+YxpRBgEmtquI4+/5Vfz+hijB2UBxwC7sJNr6Yc54cEkacOUr8H1UM2
+ APUICSBfnaR+59VLvdJD/cCmfvBRA+sphIM58gPeH+phqWY0zSyD8+5yQt4NqsdsAO4REgvLsfKBVa+d
+ hR4mq37TxT42p57TxT42p77TxSab3O0Hevxtl51T1ZlKkMrNKIAc4TOSr61FyOwAgWu19kduleaqYTo7
+ OJCarP2RXI1pMoz3gcf7gPJCAtYCTPCICPsBvBDUi18VoxDQi5lgPKklJCK8cbAMK0+WY+UJt8p11Qid
+ HdpLb2lFrWYHFUajVrCmEqUSq1ZTiVKJlaqp9FGju/n/5ZOVGqITO6nImHr/54C6G++nar+H5bmRnqrx
+ EDt3+PqqxhNBAeWr10O6qzABdwkKJm89z+qyWlIf9wOf+8HLDQ34CfU/8BivDYCAvJ6hbYFJ/XLt0YAE
+ NpK6QiNqNI6W4eXVckp5FdZW8PfPjWeCYmM5Wiry2g5wH938jdeGwHvp1u+stgTeT7d+Z7UpRnrqxu+8
+ toVN0Fxk9r68ih4+ztW6i8lkQ+XQaEcpGCKHRVn0o0kcjpplVidwxUUSbdNq+rIUTO84NAeKEamNxiF1
+ 548SrtZ0hBYz+vrHp0sSrFGYlHcywr/cfLqKKJcFOUIPM1p9nl2ywY3aph836ZU6dEhtjyTtBELkID8t
+ gvi63OT/Hm1ORZKnqtwhJVhDiDBVKs526rrClMfWAYhHFf8K97Ehthe1iPgdKCF+bzI4PZjPKoimyl8e
+ 8azEqPwghQiQS5jDGD0sWUAE24VyTtSgsCn1yzFV+18oR9u4SpTaLHBkchstRu5KlDThwXs5zn9K8/LI
+ 53dyjK/iggtvtX7yrEjmYZ/gckxHq8tELqMgvd+BVvW4aj+dsMYZkdv8rlalUTuRzeoSLI3ViWzW+Yzb
+ PhNwjrKdgLJ92/NoX8HVA9I8728X19/pSdOUgTxCQtRFIIuS7AyVTfvvb7Nb5tcaUpRL/WpNiDLJX68r
+ bSr7bF5E7uVTQwM9oRf4mRwq+Cm93e9fZw8PSkl/bU2JUTlhrUtRLvdlfe9KD1tNOVCXs7ubqNsjMZWn
+ ayyS/Esav5BArcTiEEY4zs9bhGaRPonRKCwK8ZAwXWORkkzEG9lF2pXVj+hUiHiXyl7TbpdSTnYeJ1mu
+ 6SMtHOXzNqF4pdf2gSzPXSYfpFy2baosWtsJKZLokNb7khYelhYgixdRp4fzVQjq86LtSdTNqe7EEBrH
+ Wf7NUS3qs0k2vcqiHcvpu/l7gc0Q6SkpGZlPF1pMylH+vcBh8NOA8KYBUcf1ifatrUTjXE++bVA+auia
+ lyO0OzWJxtGnQyhHeDhCk3me+6AidZ1B/J+ovTenTNT96lH89HxF4AJqgx49rFbRw2w5+0prdQFSlDu9
+ JeAIUSahJeAqTara0Hn8sRWXsrSRf32mcG2tSd5k08fxz89bhDwrEllXRNP3k1oyk9dciiHLwSPpvQYV
+ RKPkRF1ksoj9bU1ic3bxKa+pZZ6jNKnEHrwmMTm7PH4kBX0jsBjEbOrmTesGIArMknq41ETmiG12/Sba
+ VnVEW+0CSAFuQsYlEOVwvKSDpAhk/eSwfkKslAxKAcou3tZlRQ/4TgcQs5+HIxmnRACLWAidNQCpIHMK
+ gEL/MOirjkJw0/sgBbg/ybifDkXmftLEgyUDeeqQLFlzUYskU2uSMxGVx/jniZQJepHJCrgMDZEjfPK1
+ YbDapBObTE47SQUwvVYdVBhNnRSZ8pCN1OUy48eSerlRHlePKf29AYTfRx2jWdUhNi1h1CUN9IC+g5WO
+ TaWPyo4Eh2C6HGWzXrWeVeu+XW1yP5s/RIfHHalO9mDG/FR/JdzuTBlza2YNA71aBu5UlEXKdVBamNx2
+ Jl4hjkDQuCc/5FyK7ca8phIUg2xW7sTvpWx+VYdukXBK4DCa12b0CC0pzGX05SwpzO0v0KQNBKIE3KUu
+ wzzqEnRo45QT7IYSpHIC3VCC1IAghwCoByvAXbnJF/werfD1aAWztybQ3ppg9LAE2MMSvH6DwPoNlHVU
+ 5+ddQtNZotYchhBgVvEvMk5qbNLfKY3yt1VTymRX04edBpVJOx2javrVZ4PCpNDuMxwUECWgwQQCQA9O
+ +rCkIJeYRgbVQKOsSTZXIKt/RZ8ywumag8KiLAgri3uBxVhXcSF2ZXUggXqVRft2TAhr/DWJwbm6+o2A
+ kE/banL49hqHRAzjs8ThkENmEJmsd+8pkHfvbTU9bM4ah0QNm07icDhp0NDhxI95uf0huNxW7dDpcdmL
+ DNbbD5R0Lp+21eS47DUOiRiXZ4nDIYfNIDJY7y6vCBD5tK2OaDmlU0AUcigbOpBIDG1dBvLIoW4KHSbn
+ i+GvZXwp+JWcMsLQOURWmDnhtXj4PFt9jgg1Vq/QKA+zL/Or6Hr9F2ma0ZKBPMLws6lyaP1M4UE8EpG6
+ 1OEeq3KbquYaGaspdepfxqTmdKapw4lt15WyVAgnmC6UftX5eZNAa+MPCo1CWlZpr6hs/009jNtUDbT1
+ 8ttqHa3vv8zvouvbxfxu3QxMEmIVJ3hdNuljVqj7/05xMf3ewFEQwTMqZWhEB5m848fXewGDOuFtqjRJ
+ D8eaEJUTUF5f+fdM7F8j6C3SFNdX+VyH5XcmlPeI3MsnlP+w2ktXI0SiqgJzpEaB3Rar1bf5MiTvmwSv
+ CzdGNLmXrxJkiEGj9zow43xQe+kqYaeHAIMWMMEjuAzEaV53lR4PaR2rgc/ABGejRn0DcpNLgd2ktv0P
+ bko3ALBHkm7LZJgLOwcBxw1BYb7yMaONta2m3002ToJd0+ejfPqQFnX0dMkxMwDjHrLpe9iE+jSQKV5P
+ 5bHahbs1GNiPmxDx9MfpAWB62IFZyKKl61GouOdG7KD20tlRqesHh2+r+fLufr24pl3DZMlA3vRRA0ME
+ sghRZaoG2l9X795dTj7bqH3aVqu0dIyzikY5qxxaN9PZFE5d4UgkAwTN5d2bf/75Npr/tVaHTrQLQtTN
+ wpM9ED3ooE4gCnEw9KADYZefqcJoUZxnseAxWy1K5obCaAi0v0biRwhcykF+cpUxsFIF0ijliSUDeY/T
+ WwGmCqNRDuxzlSA1u+IQpQqkcVMRnoLa6Od9d68FyaQFTLYOJ0a7IxcqpQ63uzmwbQxSRgkwveMgM9kl
+ IxmcZRBPbQEskrhSO9HqtFADbIKOhyigG+nmWluHE6NNWeZcbCP2sOlpz9A6ZGXXxXNN2buMyB1+k5UY
+ BWSvc4hDpLKyoi13+KrUo9cPnQqk8XKgpgSp7LRmij1seuAaWofcLgzNM0HFDkKH2VygXT8TgZ0KpHHq
+ ol5nEqPZ7R/3y4hwzbGpAmmEXcOmCqRRs6YmA3lqKxCDp2QgL6sZtKwGWYS+lakCaYL3pQL70mb4LeER
+ pdBmrtfLxcdv67ksSU8FMRBNLU4mnZIKikfY0eYlulvcBFl0jAlO9x//K9hJMiY41c91sJNkoE7kMkJX
+ olR6WWFIUW67M5Uw5Irp/Q7l5l+yOg3xaAl+F7VTI8RD6VGHjPv6Gf7W5FJRV6JUWShdhsRpr/c7BMWp
+ RrBcrufLtTqIm57kDSVGJUajpsOI1EjUhRiT3Lq2pDZ3cfeJEZ5nFUSjhmOrgUjk8OtENmt5Sz8t01Vi
+ VOr3DjqMSP5uTQgwZV/zTVSlT+WPNCFzdTHMvlS9N+qYgyOG2epXDlbpACK1zd9pAFKS5qnaWMZ4vUEK
+ cUmH91oyiHeif7Hb2lB/ZWUeJN80dapsLamjlslMXexhi7TK4pxNb+UYnzcSBukxhzwWNW2BKabHHAr5
+ EiEOgx5zUKsL4/pUMQ16OcyPlvM/77/MbzjwsxYhc7J1p8OJnG6TK/fzqZ0lV+7nb6uszra8bGUzPE70
+ 3rGj9tCJ44i2FiE3q6oqFriVItywgmC0HAgsBkZLgSEXU+d9YALiQlwvDGkBMqNpB7bqDnG93ZNRjQqg
+ cZqHcMuQ0Zk4qzAaccbMEALMpjcYkAUsPeYQkAksPeYwJOI4fyx5LiZj3Ik8lYZCYK+u4CKdfovpEQdu
+ vhbefE3ZJmGIEBZ1ssMQQsyS0S5WIoBF2/ptyQAebYOIJbN487/W87vV4v5uRS1qDSVGDRivRhgTnKhN
+ MISBOlF7dIYSpZJ7d6YU5TbX9nAajTDC60Me2HTlXj5jWBMCoB7cLODLAdS2gqFEqSI8VsWUWBVhsSrG
+ YlWExqrAYpU33oiNNd7e33/59tAMbCUZrY9hSmHutq5yDlTpYCLlnHdbhxCpYanpYOI+FntucJ61MJl8
+ 1D0ottjN2q/53Xq5mJNrS0uLkb8HVJgYZIoXtcrEIFO8qJO8GAT3olbQphTnknOApcXJrMoT0PsdGAUt
+ SMBdMjbdlyeoVagpxbkiZb+uSGsvNyg2xWhsiuDYFN7YXNyt58u72S0rQjUxxG4mh4q6eqGTe6mXyy48
+ bcKoC6vYtAmjLqwC0yZALtTJuLMIYp3n1HgRq6tBOn1STtOBRE4dgdQObTjTh8xtMcTm1TlYbdMuCSIO
+ khtKhMqN+F6KcZuDydk52iaMurBytE3AXGrmHBQEGPNgf0iNzkQ1j6h2Nx2sVBgtKvOER1RKiMqptOC6
+ itXyQNocZZHmWcHIzJ0QYtKnDwYZyiNcbOIqfVTqzIQthtisNpzbepOpfX5N37Km63Ci2rVRy1JOcNE9
+ APZoymb1Bw6/F6Ns+tpNSwuTqXlrkFm8h28f1X3E5LjTdDCRuOFQk6G8N0zgG5zYHmXM5bZqH5182LkH
+ AftkrGDOkFCmpqtBBvMELxUILBWIoDgTeJwtH+5Xc04iG4Q4s1mRRZ5mhAAeD+LyBFPq4dbVSdRsdKO2
+ 6Gq3Om+E2VBiVGKO0HQYkZordCHAbBaOxnVdkaG90kfltJIhwJgHtZUMAcY8qN13CAB7cBdBuvJRPnnp
+ EIwAfNrrPBjXdeAEwKUbYGClWE0LkelDE4MM4hEHJjoNQOqDnhV5hhqgswo+pMw7txI4sa9pMTJvFawr
+ h/mXUXqIs5zD7qQwl5dYz0IPk1u4WvoRB07Raul9DvTRNleO8ANKVVOO8PkJ3ZvOA9Z5ggTM5dTMGtCX
+ nEEAxIOz5szSAmRGowpsT3GaUnArij5806swGnXwRheizN2RydxB9VLoakyEMe5EX42JQWAvbs4Wvpwt
+ QvOcGM9zIiDPCW+eI6/zPIsQFnmdpy4EmIy1lIPM4TU7Wvg78iAA7kHeI2NpETJzX50rx/jk9m2vQ4iM
+ luggRJghe8wQhs9Jbe/cxupMmxvqCngPx+fY7q67Ox02acX30ym4GzsxwTu6rF95zVkIMe5Db9RCiHEf
+ 1tJOD2fEkdOYBggjLtRdX4Aecch4L59hb0xv4fU6hKhqyVfI5C7G4xecxW2I5bVa/EEve88igEUeuT6L
+ YNaBwzoALGLqaiUAh5qqOo1NWt8v580NL9s8jQtibeqoUTo9Zg0pym3qDfK2c0A/4rCPsyLIQgFGPE5V
+ pU7G3hIXb+MYvx990ggCjHo070JsZqMUv5uoyyoNMWoAfg9ZMakJHOLJGxjE53XZpEvB9+kAIx5hKfty
+ PGVfqqQY9hlS73dgbNYGCT6XZsrxRF8mi0G8XoHRMh4rQzkRVHgaGK9fWlVlQAy1+nEH2WU81vtQn5bi
+ d3umr8oGCWMustJu1wOGWfUY1C8rMm5KyIoMj31yS0VXotTu7m12ydLr/Q4htaQYryWbR7rKQB2pvP0R
+ 4mWAfJ5B5YsYLV+aLQfpLj7ldYBHRxhx4ef2Xu91CCm3xGi5JYJLEjGhJFHPkO4ex/Reh+OpOpYiDfDo
+ CF6XOjuEWCj5KD+Sb5E9B7q0EL8XeSURoPc6dFeVbzcBLj0DdXqNAmy87FIjzczWylmKc1mdrk6JUvOy
+ /MHqUg9ikM3sTaM9ae3cVU4RoctxPrcmHelrPg7nizLf/dL77s3+3bwbI+M4mADQg9dCwlpHzRQjN7QH
+ McY+18vyqXoveBYmw+PEq939NXtIbeivCcNqwbEaMKTG8NcWoTXFeC3BOLVGF1rMP2eM8yvPIoBF7Pf8
+ Ce1GVX+k5uNOY5Pmy8Wn79HDbDn72p7XeizzbEubV8YgI16X0b4kJjAY4fNRg8UVIwtiEJ8XPZnYah/9
+ kVVIwYgxn8DwekRKLuOhrNjLbBwQ/x3A58FoFAF6nwM5G1piH1vVj3y4Uo/RGQtAEcaoU1he7xGjPtkx
+ 0CU7TvCIYrEN9lGQUa+mKM1SEeh2xoz4hZYwYkoJI8JLGDGlhFEPqTTzCl49ZsyP0yTDIGNe5OEJkDDF
+ hTFI4eGMOpIbnjDC8mGvbvOsamt+qtJmiSLjWBNXDvGbj2HjdbVLJ69wgtfgNXeK0tdBDDKQR64AB5nF
+ a8aQOT0DXegw1e6d+AdxyfogA3nbmEHbxiCLXrtrOpBIrsUHGcgj1tZnEcIi18q6EGaqqVpO/LZCkMnd
+ MTa2W6z7nVEBGUqQSi+SNZ1NJB7e457bI//STwaTK0FbDLBZTA+LUX2aUovLXOmMrnBm7AQEdwFSV0i7
+ K6ObkofekR5kFk/+V6LWQXSnRcfyX4zLPVAK4sZZumFpbTI1RICwaAa341O9L2Wv+YWzjgUk+F1kMUXd
+ HA8S/C6MOAUJkAtzLb1/DX17C0pZz3Y1Jw7OSoT6Md1RV6eZUojL2CKE73DVfok2WS3qigvu5BCfvYx4
+ bIdAwN5c777c9sduxxM355h6yKHeCPUKcf5Ipw9aiHzKEkYuUSqXxhmcQncmt1NvW3Gk45TKpUXa0SZU
+ pq4FyOf5KjWJHMVVGpP5DmHMhXqUMQSY4BGlxVOwj4KMeZEPUAYJU1zCP+lM8bid2/wh0aQxACfOuiB8
+ XWHQasKRNYScXVnwbqyAXVje3VcBu668u61Cd1mN767i76ry7abi7qLCd0/1hxUkadLUcycRP6YcuIXA
+ fJrTROjDyIAecODehPPovQVH/coPGl+IcJutnlYrv9Hqa7M2Kz7ytCAzOx1EZDWC0TZwUBN1pIUacKrG
+ 2IkaQadpjJykwT1FAz9BQ22OYyfagyfVHvjJ9oCn20Mz7BMn/6Ixe5nFy4Q6+CFLunkAYkpw1A69L3/I
+ 43qW1kMmH91ri0fY5IN8IYDtQatAnXUMsryQwU6eURlkII88ozLILF6z1LBpwG6rnN7gduUoP4CNcvmv
+ DL8tdRmIu/LjGFcijXZVeYg2p92OWFI5apveLMhqB+VpYE1oM8lnAEHn/7DO/kHO/eEe14yf1Mw6RQg5
+ Qagbr2IMthtKi9rNHjdL1EhQXWgx23spOTWmoUSojBrTlELcgFOZxk9kCj6NacJJTNzdOfienJBbNv03
+ bApuL0DgvQDB7gUITy+AebYVeq5V0OkUI6dSBJ2XNXJWFvecLPyMLPL5WMDZWKxzsZAzsYbclZyIDVFT
+ inLp9Z2ltcladJEbz7bYxyY3nx31GJ3cgAYJjsvxWFZqn1Y/hkL0cPSWA6unhfSzzn+mNmU0nU1sulz0
+ il3TWUTG+idw5RPj7Dnw3LnzPg7qRjtNhxO73fWillnvkYs3IKbX01vO+rlB5dB4qzoMocNkjJYPKozG
+ GDF3xD42cdTcEfvYnJFzmIC6kEfPbe1Ajq+yaPEgAcv5ajUVaYgQVnR3zcJJnUZMxeXVh8ftQWRPkfxH
+ 9GPy8Dgg9XKjtNhGz5cB+I6AuCTplsWWOoSYbjeN5SYvp3e5cQLmIn8/iMfo+TeeRS8f438I439A+D+S
+ HQssdQbx6t17bjq0pV4uPR0iBMSFlg4NHULkpkOEgLlw0iEkH+N/CON/QPi0dGjoDKK617rpNBF6nJbM
+ 5O1/RdvNVn1A9XKsKUhT6VLr6u3V+dc2bgUVDyAcH5kyGW/eqRxalxYZRE3pUnlEP62ZQ63L86dQU4QX
+ 5Hi2+664RpYapGsvw6Br6jF6FOd1mIMijLps4umL5D0I06co+fnV1kLkwDyLQgAvRr7VdQCRGyZ4eASk
+ ekiPODBTPqQ3HLoqZF/Hmzx9TzoSDVbj9CD4GPtY5i9P03tUmB5y6H6K9mVVTB9sxfSGQ5FF8iFGMjeF
+ EJOe0E2hxhTFpVrg3A1ARHlaPE7fngurLXpSRnGyISFbicVRTSzKLgVDBLBIKVYXAawqJR3XausAooif
+ 6DglclllouKGNMwHSC3uYyrTe5xnf6dJM8Aomw/Tj5XGCY6LOp2vzLapLOjydFuXFdHD0QMOuyzNk+hY
+ 09m9EqB2eaItgnZlFdUysgkjhaMgyzMT7SSAeozkoQstZpXumgEjVRg1u5KUdfR3WpUkBxyD+alqrSxS
+ nksnttgiMC2J0bSkLvSlHj3uCCGmaM9zrqipxxZD7GaqOIplGihlGkgruoFNsFxO9ZZZQhjKgbpJ01N0
+ KBNZGKuZQ/UCFWVDJabXHLKyO5JHyMYr9dxMWG3S5Z+KMhL78iTLjyqtqxcK3VWbdLXfWOYyNTmlAq97
+ DfWnOElI3+Enma7qR3pIDSqXpubd5X9TcZ0M5HGDHJBr/CKK1bal00ZdRy5qUmoEtCY5SaJfZTV935Ou
+ MUlCtGvWaiHTfrR5qVMSFJAb/E32KBsNSRYXKq1Q3xlQG/RteXwhQweRwUpk050TU4bOIKbPR5krCKhW
+ YDDOIUv9SENnEtV6vUNZ1I/lIa1eInGI85xChvSGw2Nc79PqHYHZKQyKfPkqLh5T8qebQpMp2q6JzLVk
+ qiW1uVWax3X2lOYvquVESkGA2qD/K96Wm4wAbAUGI5c9PU7qNnQmMRUiqvcya2qJYUlBgwDEgxpdltKg
+ HrI8TyuZSDZZQeryQVoPWbZ7mjNR2fgzwPIoMpnlol9ZMr1XbutMYpm0J/0y0oejBcnU2DN0DlEWk02S
+ IRddrthhd+2/N2025NugHMyRHfqOHnWglkuOFiWLdFuldZCBjnB8crHPduqiFGYYOXrEIdDAwz+c8pBK
+ F0M4Ptz2pqMFyZx83Osc4unyPftdDa1Fbq9Sova6ASnMpdYYug4mqkbFcskMC4ThOhVvqNzijUk55b89
+ N79QQL0IYTGai67YZvNqHV3nELflYRP/RsS1Ipj1gcP6ALAYqUbXOUR6DIPxa0RQMzPFgBp62IFLBonk
+ gvmscUic1AemvGdWpntGct1zULZ79uW7UuadotlkoLo05eYpK09C9mhkwlUHitWUFDrKMp2LZkRwqB0p
+ TrbWIB/LX4zUq6lc2vM7KunZDOdKjbXx+sa21OV27bDmGSpY15rkNDltUxnUWxJzUGE01dk/5jEX28st
+ vsj+ZoStJjN5XeuTDNR1APEc3s0/yFxDDdF5rwu8rdjGdU0ras4Sk9NMsZDfS5dZvJrdm3a0DlnUsu++
+ ZbytKXW4HCBA+ll9UE1SGchFTKnwTCHAJFZVg8hm0VtcgwhmfeCwPgAseovL0DlEaquj1zgkcuo4a2zS
+ Mzt5PKPpg9GDhHuPRn1NDj1AbdBP3MGwEz4SduJ2zE94r/wXeYLhFzDD0ISuCpNhsoVCdNUavVQzzELk
+ qgzetTP8+0O8lXVOfPXu/WQbP8bvF2410eXd5VWgiyQMLturLJqt7i6jj4t1tForxFQ8IAW4i7v1/I/5
+ kgztdADx/uN/za/XZGAr03j7WP7vqrnQ5+Xy7Zt3UXlMiyh+ep4cwB7EqA+lqe9B+HxEKlsNYd/TI0Z9
+ wr6nR2g+arlg2awd3Oaq15oWapnQ5HII0w8OCT/tJ760P/z49YGLPSsh6v397Xx2R2e2OoA4v/v2db6c
+ rec3ZOggBbh/zO/kb7eL/5nfrBdf52S4pccdmKFsqAH6YvaOSe6VEJVWIiZoidj/cvft9paMUyKARStd
+ E6x0HX64Xs/ZuUsXA+wH+ff17OMtPWX1Sh+V+dKWHnBYzf/72/zueh7N7r6T8boYZK+Z2DVCXL+/ZIZE
+ r4SonAIBKQXW3x8YLCkCWN/uFn/Olyt2mWLpIYf1NevjOx1I/PSB+7q9FOD+uVgt+PnAUFv0b+vPUrj+
+ Lgu1T/fR7PqasAccBWAeX+bfFzc8eiO1uKe6fGgPHP4yfdeMqzSpH2erxXV0fX8ng2smyw9SaDhik309
+ X64XnxbXspZ+uL9dXC/mJDogt/jL2+hmsVpHD/fUN7ekJvfmc3OBrqAAzxqYFBGWdNo6i7hYyvrufvmd
+ njksqc1dPdzOvq/nf61pzF5m8VYzXmI1hB4mOUhtsY89/XA6SOuST5s82zIC4qxziMRT8k0VRmMEqaZE
+ qeTAHIQuc7X4g0qTEofDyOBnkcmaXzPeqhfZrAflkNZpJWi4QecQWZlQ1+FEanqxtR4yLc1YUpvLyCy9
+ CGHRPx3NKcNP1I/G8oksjOd3N/Mb1YqIvq1mf5DafK7apHed1+huRmtL6jqcuOIirTp8sVp9kwqtkqeA
+ XbVJv5uvV9ezh3m0evgyu6aQTSVOXXChC5P58OV6NX3kdlBAFGqiH1QgjZbce5HL+p3K+R1gcD7ud/jb
+ PvCLSEDu59MD8YOnrGx+VwMJfza5X/VxyHhTPspnhdD/a+1cmiM1sii8n38yuxayLHtpx9iOjulwe1C7
+ wzsCFVQVoSqgSUqP/vWTCVVFPu5NOBftFILzHTLJdyU3Q8S8jyCnAgLlInp+5oklzxg8FdzZUT2drJvj
+ +jhRB8f0brIRDTeeWVFVY7VUXEEjdVMyiWBmEKl0dpbys7N0zewsjc/O0hWzszQ6O0uFs7OUnZ3ZVyTZ
+ YGsjZDwTLGnAzf56eBiP+n4AsZaSoMJtUcrMUlPxLDWNzFJT6Sw15WepJvokgjL3h4Tsl09/fE5Rzqii
+ aF++pB9//fvLbzjxoqSof/+D8/7+hyCZtT4R7iKkmLrTxnlaRLHSTzgq/UST4HGVI2SYYK2wdQwRqxGW
+ jOANk8qHj5//hJFXZYz6IMc+EFx0ansVESy8CSRPsrxeSH/7HwzTGpokK4kXIcOUlMSzjiEKSuIoI3lf
+ P/8X23Bg6wgiuPh30RCkr7/grYzWECTJO6DzX5D3Tr7vsyGwybFcvv/Y1jik4cSc7PzTyDZffuILpXXJ
+ zbE99eUQgrDNC3OAoQk3ctm+hvjESY5ra24Cc+aqsUgqF2SyLXJZY1YBofkc0cQqN9kfv58/R9Y5sZTm
+ yWhe8XiQ8LSM5m3LQ3k0X09LqFdxjD0eJIUEIIkxYk7H00FuocUx9vh1iRw/6mMO6lsnx2txjG028q57
+ AxcC7WK+gc3arjSNgMTD1tMOwnfLvlWzQREJ20ppY+R+s5ejtZhnr8hmSx7hD/PldUmwGYFTXanenASy
+ aYrSfBF0yDsTgwUtnBwm8FPVsT0MB9tkr7qbarqiqvMeffMMhXNb2fYxlLibsJaTDM5p1zWndgy2eOqe
+ hZnoQeJe6j281JzXEK+il1mMWpassty0cFvTyL0JHRxGxKmp1+SVBeA8hsB/Q6wtmcWkjzsg0Rg4fdzB
+ FAld2te9GBIV9VVZ+e2UH1bYnQmOS741f50jROU17EHqKYfxq0ucPOooos64iy2OtcQuG50W2BqH9Fjt
+ 6tPQLg4NJMDzlAx17LlE2FHqcFd0ctGe7TK7e/nzl98RpiVzeGNng02OrhqChJZ3S0XQRN12tK8eL9bl
+ DgZqDUXS7bQJqpsdc/WEM201QQfC8doaggQ3F7aM4p0ecdjpkSCN3zbqmgTzrkqGKio35LjLjJDsKmki
+ 76J4ljHrBLdMPMTxGo5o1OkdxhlZm9z9mL0ei/P3mJlSLyfAcx4W87796YfL7ebPdd4EbKH33U0y3J4V
+ Xb7tP9y/yzP4UPJZzvMm79kF/jRoqad5Vnna40DnGYQLFez6xHXApB9jHJIA1FA8w4Yn5RzC8YFXY22N
+ SxpGw6Z1MedDIDhHSDCHbvVUm/zvSqXKAoYHBMLFLF1Ilr9ZAOMBt6y+NMpF17VI/ZwDVg5pQNwDr6Uc
+ YsZnWKtaZTMQlriszzh2Ze0yEwXHW7aM5PWXhmPq15WAT2EIP8H4yRW6zPH9C3LFETpMExGrGYbQwwga
+ rsqk3nE4v2lscjSJKNYw0UEPT2DkFF80YQq0LBkPAMcCKI+qfv6wysMDkB4KOkslEFJMN3Isjnb1lAM2
+ YZ1EFAv+Bc3RUUS4Wjs6kghNLycRxRI0ZZ6Soa555UxEROYGU7DlrQaLcn3HtVOVb8/Lm4iRr3XJ45rp
+ +koe40Qc3yUrlxHtpzCbElS1M2dFvCLjZFfHE7OXqt+b/mszHlH1VDcvdZbX6qXswFEzCPaf6bnsqu2b
+ JJ22MkYVzgaiGNtv/BXzu1mquMavzYvX5U4MYM4DCR7EExgXqNNwdQxRjxjX548PWeIlzqeAEnEzsfpW
+ p8yGLPFalTKHwriNw3ITOU+aLIcw7zJOL97B7Apa6inOS5I06/oOdrM+RXMyRxCuy80JssRrZbIsCuN2
+ CRh7B8VoiyBmfcRJchEzPvfr03O/JD3369NzH03P2nZwQRu4vv3j2r4iubu7+Vnww7MvDJn4Aq0vtJjP
+ 7fjvIdKxvtQsHzqF0om7rfLzDptzcopXZM8eI4/z1bdTvvwkXp7guQw/Ikme3xZyTGCXZyCcmCbI4m74
+ +UPX26U8R0SxhrCNOG2QUTykjrkqiqaUKm9x3CDzePp5ezjnLiKKhefcJKN4cM5dVRQNz7lJ5vKG38HA
+ jLtoCBKcbZOKoKGZdhURLDjLJtVE2z8VW7zxdlUTrUpyafRQQkpwwTiZvo4gYrEtPRnBw2J/eTKbt5HG
+ oSWkBBfOyQ2bk4X8SYvYkxbCiLmhkqJiEXN9HUGUlPkiVuaLVRFzOT3vIMxlJmLu9TocMTdUUlS0/BZz
+ 5ReJmOuICBbaqhRcq1LII+aSYoINR8wNlTGq8KHZiLnXOyQRc0kxyf4ixH5hiHDE3FBJUSUNAtMKIBFz
+ HRHBEkbM5fSUAxYx19eRRDRiLiEluKKIubTao6+JmMsCOA8oYi4hdbni2Lak2GWviG3LyD2+LLYtIXW5
+ aGxbW0OTkG/NfZ1HlMW2JaQ+F45t68k8niR6UiCMMOEs5aMnhZeXf9BPaUMyGj3J1wVEMGSGq+Jogiwl
+ owZ51+DMpKIGXS4BgSQsScARVPAwtq35Nxzb1hH5LDy2ra8LiKJKSMe29a+g5YWPbRtcxcoMG9t2vCio
+ LERsW+ffeNLZmiKJbevrPKI4ti2tdumS2La+jic+SJFeHy6PbUurXbostm2o5KkfpdCPLhOLbTspKApa
+ 6KnYttb/seJOxLa9/Pse5dwTDEni7um0WdFjP9bbRkImEPM+eIaGhKjLypTMpmJdCmafvq6KtSk4I+Z9
+ 1qVkJBAusrjDjHyWL8qtWNxh7iZBbkXiDk/3iJ6feWLJMwZPBQ9EqFGIbAjCjT9Egw9m5CEbbXJjzRUN
+ T6zNETc3kZZGMsFjZnepdOac8jPndM3MOY3PnNMVM+c0OnNOhTPnlJ05S+MOU9oIGc8EMu7w+aIg7nCo
+ JKhwW5QyKwipeAUhjawgpNIVhJRfQUDiDl/uDwlY3GFXRdHQuMOhkqIuDxRsawgSGnc4EFJMIO6wI6JY
+ 6ScclX6iSfC4iok77FwCawUdd9i5gtUIMu6wc6F/VCKg1hFEOJJxqIxRH+TYB4KLLmQQkYyv/8YbVTKS
+ 8fUCEMnY1tAkWdkOIxk7lyRlO4hk7FwRlG0/krF1AYpk7OsIIrjUG0Yyvv4XiGRsawiS5B3Q+S/IezLf
+ Je1J0JZ0pbiB8qQ015QaIfcspblCpsdrzLI2Pvx1ZDZPyXdHqdjuKCXcB6TYfUBqzV4bFd9r08v2BfXc
+ vqBn4Xr4M7se/ixdD3/m1sOfhk3sf2ExMhyRxfq16ap6p+/Uw+yHb13/5WVx20Np4+RPyyPDMHKL/7kt
+ a3O5zFVTP/Tm7v/kfb7YgNFzDl/zw2n5F92UNk5G8oaWT/xj8UP2eGg2T1mhU2S+2ysXf3pAaW3y3flq
+ ro4iOq2fHJrxcEu0pfRkE6992qibJKv6ssv7qqlVlm82Zdvnj4fF34/EGIGT2b69W/4yXVVAax/LrKw3
+ 3VuLBUZl5C7/fvgi0HyGXRbDy0Dogdhnt3mnymxf5kD5CJUu9achRUU5pAiBOkKLeXzsm6eyNpHsb3TJ
+ rOrF30QRUo67OVRl3Q/vGA+XsgDF+ersq57L6Walk1/2MmOaxTnromzqSokcqcATeJc+2w8BA8zX9boB
+ l1p5GM6vUupUdu/yHkkU59vpmiCzMUqOaqqujGqUHPVUr6hFZzHNTuT1M8mi3HernwlSP5N3rJ8JVD+T
+ 1fUzWVA/k/epn8nS+pm8X/1MkPqZiOtnEqmfibh+JpH6maypn0mkfraql/afk5Tjvk/95FGc7zvVzwiL
+ c15VPwMC77K2ftIYzu996ieP4nxF9fOq5Kii+nlVclRp/bTFFrs5vGXpN+R7dksycUzoQvOGn7TFEHPr
+ 8bTdlmbOrKcXZhq0+IHnSZar5JSvjj7lq7se2HWOownULErrkvWfuflwuh1//s56nUylU3lELFgI7TWE
+ z+ryF4nFRcuRv5cy6vfSJVb1c36oCrAlC5UuFf6w2hF5rDVvbOZNBZdFQcXmSa7r8G6lRoHYZZ9Dm0np
+ hJzk65K51sNHOD7fs5sPyQ/ZLu/3ZYcFBaLVFN0EAZORL0qKWuuXn3RlIUQ7coqvryXmJiHfkVN8tcn7
+ Xp7pjpzkf+uk6LNyoqqkEv0a4usIouTXEFJssff5TbB0i4TsYAELPJLVJsmcy/IQH5x+zgEJI8IT5lyg
+ ACMRhONjYgWtfPccYt4HyjWGMO8Cvh2WMe+EviEe4niZkylWviMOMe8D5h7LsJye9NSrXDxQPN/u6OtS
+ d9KnwwFgXCQuZ/lZPuPdjrptWkCt7/bVaD5cJCQnK18FKK1yaSe1RzD6dkf/bH5VBADD/RahfR3OksgW
+ B9WeFC7FnBdoZgBtXg0x7jsEGIhdth5IKz0vOC/IVDsE7WsJMrJA4Igo1hPyo6InI3i9LjMmSBpMvAhd
+ plkCMlf0tK0Aym+gdKn7Hs7DsyTgjLMCkDSKXNZwnOg+r2q4MLrKkDrG5xNAr8KQKa04vjYkH/K3Usad
+ lCF1KAkS6FXIMPdltdv3IuooZbhweVeR8j5ce2tLmKc1LqkfysQWAZ0lFGePc/Yk56h2ApRWUbS2E6RP
+ ixiW6NlGHUXsn3Ba/0SSDgLSwSM12amq+x9/gFAXkccSdB10rzHSjc+hrLFfAxi5y39penH/7mtpMtgn
+ WzKCh/Z1V5HLej0qcap9LUFGn/IqmljPSSXaZ+nreOKDFPnAM4GBOSG1uLdZbtaiq8W/mUwKl3LoEcKh
+ d9SPm6ZWgH643yFs2uaAEIb7XUJ3MAv9BXBcsasKaMBMcFIElG7YWQmCRpHPKjCK+4aL8qAn3/rfAOSq
+ cUjlqx7QnQDMKHAYep6p9qXqwQeyZQ6vKloAo+921fW2QeT6dk+/rx5NfOL6DXoMS+bwTAU9qXyHlOSr
+ xiHV+dEcllervsvNoe8A0Je6XJVV+V12qBTSblgqj7YpOwxkBA6j2ajW7KXVJQR5B7Ys5NXN8FstyjvL
+ HJ5usKrNm/BdhGKKfczbtqp3AvBF6VAVWC1UUC8U3DepoG9q9LhYsGXP15HEVZuB5jik47ptQLMg0lOy
+ AYiRk/xVW3HmOKQjsgnHk5E8ZBzqyUgeuPEmVPpUfEucryOJ71D+l+yEs+58j/K/aA+cdau8/Ed2v1k3
+ vEP5X7IPzboTL//EDjTrAl7+ib1n3oXxHL62a5rt9RBVfHcgBCWfRVQX6R1wz21eqmzzuLl8B7MY6gsD
+ Zt/dJteva4YfyxQIJwi+C/itiyPyWaIcYFJv1h3PNlAdpcQU+5IrIrYlntivwmOaXtlTms5XdiVyYrMj
+ olimHRmaEfTQ0AiC8mlv2huzeNYmuMGkjZJvV5BvSfKtubbJ9VBdkOG2mqKPrZM5AQdnT9o4efiRcw1+
+ ACzwQM5Si0JmvNQxPxwux6avMnRIpOvyM5odEcXqG6jLD4QBE96U+sqe1Ha+ojbgydm+jiBeTv/uBcXD
+ U1v0uw8/f70dvgcd9gGMbaUavqle7BFhuE7nrdjDyOt8crB+sMNjvnzOP4Px/IpqZ5avhrFMftg1nb73
+ CFmRBNrlvH0V+daXkXv8tjNnZQ6bic0aPxQxmwV4HsNG+X745UjfA9FdKcE1pqb17l9h7iR1uWZVPKmy
+ qkW6b08XEMd+V9vty1cQaksD7tBtmWXZslYVsHTPyEN+U2/H9cNj3ut7YQNfHzjoVF0PuAfhtjTgHprm
+ SWWH6qnMiloNzwDiCcK///V/4K+mmdHmBAA=
EOF
# PrivacyInfo.xcprivacy is not part of BoringSSL repo, inject it during pod installation
@@ -706,10 +709,10 @@ Pod::Spec.new do |s|
EOF
# We are renaming openssl to openssl_grpc so that there is no conflict with openssl if it exists
- find . -type f \\( -path '*.h' -or -path '*.cc' -or -path '*.c' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include ;#include ;g'
+ find . -type f \\( -path '*.h' -or -path '*.cc' -or -path '*.c' -or -path '*.inc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include ;#include ;g'
END_OF_COMMAND
end
diff --git a/src/objective-c/GRPCClient/version.h b/src/objective-c/GRPCClient/version.h
index 38176102816..46ede4a14bf 100644
--- a/src/objective-c/GRPCClient/version.h
+++ b/src/objective-c/GRPCClient/version.h
@@ -22,4 +22,4 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
-#define GRPC_OBJC_VERSION_STRING @"1.67.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.68.0-dev"
diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile
index 2c39d8ecbac..84f6db830a4 100644
--- a/src/objective-c/tests/Podfile
+++ b/src/objective-c/tests/Podfile
@@ -22,7 +22,7 @@ def grpc_deps
end
target 'TvTests' do
- platform :tvos, '10.0'
+ platform :tvos, '12.0'
grpc_deps
end
diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h
index c277186d3d8..6c71e7cf041 100644
--- a/src/objective-c/tests/version.h
+++ b/src/objective-c/tests/version.h
@@ -22,5 +22,5 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
-#define GRPC_OBJC_VERSION_STRING @"1.67.0-dev"
-#define GRPC_C_VERSION_STRING @"43.0.0"
+#define GRPC_OBJC_VERSION_STRING @"1.68.0-dev"
+#define GRPC_C_VERSION_STRING @"44.0.0"
diff --git a/src/php/composer.json b/src/php/composer.json
index 2dcb272f367..e44d5e7901e 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -2,7 +2,7 @@
"name": "grpc/grpc-dev",
"description": "gRPC library for PHP - for Development use only",
"license": "Apache-2.0",
- "version": "1.67.0",
+ "version": "1.68.0",
"require": {
"php": ">=7.0.0",
"google/protobuf": "^v3.3.0"
diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h
index be2549d1a74..0a1dc021cd2 100644
--- a/src/php/ext/grpc/version.h
+++ b/src/php/ext/grpc/version.h
@@ -20,6 +20,6 @@
#ifndef VERSION_H
#define VERSION_H
-#define PHP_GRPC_VERSION "1.67.0dev"
+#define PHP_GRPC_VERSION "1.68.0dev"
#endif /* VERSION_H */
diff --git a/src/php/tests/generated_code/Math/MathStub.php b/src/php/tests/generated_code/Math/MathStub.php
index babcafe270d..5ab377c6f69 100644
--- a/src/php/tests/generated_code/Math/MathStub.php
+++ b/src/php/tests/generated_code/Math/MathStub.php
@@ -27,7 +27,7 @@ class MathStub {
* and remainder.
* @param \Math\DivArgs $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Math\DivReply for response data, null if if error occured
+ * @return \Math\DivReply for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function Div(
@@ -80,7 +80,7 @@ class MathStub {
* is closed.
* @param \Grpc\ServerCallReader $reader read client request data of \Math\Num
* @param \Grpc\ServerContext $context server request context
- * @return \Math\Num for response data, null if if error occured
+ * @return \Math\Num for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function Sum(
diff --git a/src/php/tests/generated_code/math_server.php b/src/php/tests/generated_code/math_server.php
index 7301f0f12d5..18839ff9411 100644
--- a/src/php/tests/generated_code/math_server.php
+++ b/src/php/tests/generated_code/math_server.php
@@ -63,7 +63,7 @@ class MathService extends Math\MathStub
public function DivMany(
\Grpc\ServerCallReader $reader,
- \Grpc\ServerCallWriter $writter,
+ \Grpc\ServerCallWriter $writer,
\Grpc\ServerContext $context
): void {
while ($divArgs = $reader->read()) {
@@ -74,7 +74,7 @@ class MathService extends Math\MathStub
\Grpc\STATUS_INVALID_ARGUMENT,
'Cannot divide by zero'
));
- $writter->finish();
+ $writer->finish();
return;
}
$quotient = intdiv($dividend, $divisor);
@@ -83,14 +83,14 @@ class MathService extends Math\MathStub
'quotient' => $quotient,
'remainder' => $remainder,
]);
- $writter->write($reply);
+ $writer->write($reply);
}
- $writter->finish();
+ $writer->finish();
}
public function Fib(
\Math\FibArgs $request,
- \Grpc\ServerCallWriter $writter,
+ \Grpc\ServerCallWriter $writer,
\Grpc\ServerContext $context
): void {
$previous = 0;
@@ -99,12 +99,12 @@ class MathService extends Math\MathStub
for ($i = 0; $i < $limit; $i++) {
$num = new \Math\Num();
$num->setNum($current);
- $writter->write($num);
+ $writer->write($num);
$next = $previous + $current;
$previous = $current;
$current = $next;
}
- $writter->finish();
+ $writer->finish();
}
/**
diff --git a/src/php/tests/interop/Grpc/Testing/HookServiceStub.php b/src/php/tests/interop/Grpc/Testing/HookServiceStub.php
index b9590d34b57..c5311b8c101 100644
--- a/src/php/tests/interop/Grpc/Testing/HookServiceStub.php
+++ b/src/php/tests/interop/Grpc/Testing/HookServiceStub.php
@@ -31,7 +31,7 @@ class HookServiceStub {
* to a SetReturnStatus
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
+ * @return \Grpc\Testing\EmptyMessage for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function Hook(
@@ -46,7 +46,7 @@ class HookServiceStub {
* Sets a return status for pending and upcoming calls to Hook
* @param \Grpc\Testing\SetReturnStatusRequest $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
+ * @return \Grpc\Testing\EmptyMessage for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function SetReturnStatus(
@@ -61,7 +61,7 @@ class HookServiceStub {
* Clears the return status. Incoming calls to Hook will "hang"
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
+ * @return \Grpc\Testing\EmptyMessage for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function ClearReturnStatus(
diff --git a/src/php/tests/interop/Grpc/Testing/LoadBalancerStatsServiceStub.php b/src/php/tests/interop/Grpc/Testing/LoadBalancerStatsServiceStub.php
index f99f489d4b8..90b278869cc 100644
--- a/src/php/tests/interop/Grpc/Testing/LoadBalancerStatsServiceStub.php
+++ b/src/php/tests/interop/Grpc/Testing/LoadBalancerStatsServiceStub.php
@@ -30,7 +30,7 @@ class LoadBalancerStatsServiceStub {
* Gets the backend distribution for RPCs sent by a test client.
* @param \Grpc\Testing\LoadBalancerStatsRequest $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\LoadBalancerStatsResponse for response data, null if if error occured
+ * @return \Grpc\Testing\LoadBalancerStatsResponse for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function GetClientStats(
@@ -45,7 +45,7 @@ class LoadBalancerStatsServiceStub {
* Gets the accumulated stats for RPCs sent by a test client.
* @param \Grpc\Testing\LoadBalancerAccumulatedStatsRequest $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\LoadBalancerAccumulatedStatsResponse for response data, null if if error occured
+ * @return \Grpc\Testing\LoadBalancerAccumulatedStatsResponse for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function GetClientAccumulatedStats(
diff --git a/src/php/tests/interop/Grpc/Testing/ReconnectServiceStub.php b/src/php/tests/interop/Grpc/Testing/ReconnectServiceStub.php
index 450ecc0e8a1..21118f9ac2e 100644
--- a/src/php/tests/interop/Grpc/Testing/ReconnectServiceStub.php
+++ b/src/php/tests/interop/Grpc/Testing/ReconnectServiceStub.php
@@ -29,7 +29,7 @@ class ReconnectServiceStub {
/**
* @param \Grpc\Testing\ReconnectParams $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
+ * @return \Grpc\Testing\EmptyMessage for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function Start(
@@ -43,7 +43,7 @@ class ReconnectServiceStub {
/**
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\ReconnectInfo for response data, null if if error occured
+ * @return \Grpc\Testing\ReconnectInfo for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function Stop(
diff --git a/src/php/tests/interop/Grpc/Testing/TestServiceStub.php b/src/php/tests/interop/Grpc/Testing/TestServiceStub.php
index d6c3fac7afe..722e3add6f4 100644
--- a/src/php/tests/interop/Grpc/Testing/TestServiceStub.php
+++ b/src/php/tests/interop/Grpc/Testing/TestServiceStub.php
@@ -31,7 +31,7 @@ class TestServiceStub {
* One empty request followed by one empty response.
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
+ * @return \Grpc\Testing\EmptyMessage for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function EmptyCall(
@@ -46,7 +46,7 @@ class TestServiceStub {
* One request followed by one response.
* @param \Grpc\Testing\SimpleRequest $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\SimpleResponse for response data, null if if error occured
+ * @return \Grpc\Testing\SimpleResponse for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function UnaryCall(
@@ -63,7 +63,7 @@ class TestServiceStub {
* satisfy subsequent requests.
* @param \Grpc\Testing\SimpleRequest $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\SimpleResponse for response data, null if if error occured
+ * @return \Grpc\Testing\SimpleResponse for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function CacheableUnaryCall(
@@ -96,7 +96,7 @@ class TestServiceStub {
* The server returns the aggregated size of client payload as the result.
* @param \Grpc\ServerCallReader $reader read client request data of \Grpc\Testing\StreamingInputCallRequest
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\StreamingInputCallResponse for response data, null if if error occured
+ * @return \Grpc\Testing\StreamingInputCallResponse for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function StreamingInputCall(
@@ -149,7 +149,7 @@ class TestServiceStub {
* to test the behavior when clients call unimplemented methods.
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
+ * @return \Grpc\Testing\EmptyMessage for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function UnimplementedCall(
diff --git a/src/php/tests/interop/Grpc/Testing/UnimplementedServiceStub.php b/src/php/tests/interop/Grpc/Testing/UnimplementedServiceStub.php
index 086cca2fb02..f82e532ab18 100644
--- a/src/php/tests/interop/Grpc/Testing/UnimplementedServiceStub.php
+++ b/src/php/tests/interop/Grpc/Testing/UnimplementedServiceStub.php
@@ -31,7 +31,7 @@ class UnimplementedServiceStub {
* A call that no server should implement
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
+ * @return \Grpc\Testing\EmptyMessage for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function UnimplementedCall(
diff --git a/src/php/tests/interop/Grpc/Testing/XdsUpdateClientConfigureServiceStub.php b/src/php/tests/interop/Grpc/Testing/XdsUpdateClientConfigureServiceStub.php
index fb3bb1ce0bf..8ac84a2d55d 100644
--- a/src/php/tests/interop/Grpc/Testing/XdsUpdateClientConfigureServiceStub.php
+++ b/src/php/tests/interop/Grpc/Testing/XdsUpdateClientConfigureServiceStub.php
@@ -30,7 +30,7 @@ class XdsUpdateClientConfigureServiceStub {
* Update the tes client's configuration.
* @param \Grpc\Testing\ClientConfigureRequest $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\ClientConfigureResponse for response data, null if if error occured
+ * @return \Grpc\Testing\ClientConfigureResponse for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function Configure(
diff --git a/src/php/tests/interop/Grpc/Testing/XdsUpdateHealthServiceStub.php b/src/php/tests/interop/Grpc/Testing/XdsUpdateHealthServiceStub.php
index 759308b1a00..b44b877e940 100644
--- a/src/php/tests/interop/Grpc/Testing/XdsUpdateHealthServiceStub.php
+++ b/src/php/tests/interop/Grpc/Testing/XdsUpdateHealthServiceStub.php
@@ -29,7 +29,7 @@ class XdsUpdateHealthServiceStub {
/**
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
+ * @return \Grpc\Testing\EmptyMessage for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function SetServing(
@@ -43,7 +43,7 @@ class XdsUpdateHealthServiceStub {
/**
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
+ * @return \Grpc\Testing\EmptyMessage for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function SetNotServing(
@@ -57,7 +57,7 @@ class XdsUpdateHealthServiceStub {
/**
* @param \Grpc\Testing\HookRequest $request client request
* @param \Grpc\ServerContext $context server request context
- * @return \Grpc\Testing\HookResponse for response data, null if if error occured
+ * @return \Grpc\Testing\HookResponse for response data, null if if error occurred
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function SendHookRequest(
diff --git a/src/php/tests/interop/interop_server.php b/src/php/tests/interop/interop_server.php
index f280fe7b48f..9abd2b2a868 100644
--- a/src/php/tests/interop/interop_server.php
+++ b/src/php/tests/interop/interop_server.php
@@ -102,7 +102,7 @@ class TestService extends \Grpc\Testing\TestServiceStub
public function StreamingOutputCall(
\Grpc\Testing\StreamingOutputCallRequest $request,
- \Grpc\ServerCallWriter $writter,
+ \Grpc\ServerCallWriter $writer,
\Grpc\ServerContext $context
): void {
$echo_status = $this->maybeEchoStatusAndMessage($request);
@@ -119,10 +119,10 @@ class TestService extends \Grpc\Testing\TestServiceStub
'payload' => $payload,
]);
$options = [];
- $writter->write($response, $options);
+ $writer->write($response, $options);
}
$context->setStatus($echo_status ?? \Grpc\Status::ok());
- $writter->finish();
+ $writer->finish();
}
public function StreamingInputCall(
@@ -142,7 +142,7 @@ class TestService extends \Grpc\Testing\TestServiceStub
public function FullDuplexCall(
\Grpc\ServerCallReader $reader,
- \Grpc\ServerCallWriter $writter,
+ \Grpc\ServerCallWriter $writer,
\Grpc\ServerContext $context
): void {
list($initial_metadata, $trailing_metadata) =
@@ -155,7 +155,7 @@ class TestService extends \Grpc\Testing\TestServiceStub
);
if ($echo_status) {
$context->setStatus($echo_status);
- $writter->finish();
+ $writer->finish();
return;
}
@@ -171,20 +171,20 @@ class TestService extends \Grpc\Testing\TestServiceStub
'payload' => $payload,
]);
$options = [];
- $writter->write($response, $options);
+ $writer->write($response, $options);
}
}
$context->setStatus(\Grpc\Status::ok($trailing_metadata));
- $writter->finish();
+ $writer->finish();
}
public function HalfDuplexCall(
\Grpc\ServerCallReader $reader,
- \Grpc\ServerCallWriter $writter,
+ \Grpc\ServerCallWriter $writer,
\Grpc\ServerContext $context
): void {
$context->setStatus(\Grpc\Status::unimplemented());
- $writter->finish();
+ $writer->finish();
}
public function UnimplementedCall(
diff --git a/src/php/tests/interop/metrics_client.php b/src/php/tests/interop/metrics_client.php
index d5215b826f3..09664a51384 100644
--- a/src/php/tests/interop/metrics_client.php
+++ b/src/php/tests/interop/metrics_client.php
@@ -24,7 +24,7 @@ $server_port = (count($parts) == 2) ? $parts[1] : '';
$socket = socket_create(AF_INET, SOCK_STREAM, 0);
if (@!socket_connect($socket, $server_host, $server_port)) {
- echo "Cannot connect to merics server...\n";
+ echo "Cannot connect to metrics server...\n";
exit(1);
}
socket_write($socket, 'qps');
diff --git a/src/php/tests/unit_tests/ServerCallTest.php b/src/php/tests/unit_tests/ServerCallTest.php
index 9db62ba6fde..b0c97755b8a 100644
--- a/src/php/tests/unit_tests/ServerCallTest.php
+++ b/src/php/tests/unit_tests/ServerCallTest.php
@@ -236,7 +236,7 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
$status = \Grpc\Status::status(
\Grpc\STATUS_INVALID_ARGUMENT,
"invalid argument",
- ['trailiingMeta' => 100]
+ ['trailingMeta' => 100]
);
$this->mockCall->expects($this->once())
@@ -259,7 +259,7 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
{
$metadata = ['a' => 1];
$message = $this->newStringMessage();
- $status = \Grpc\Status::ok(['trailiingMeta' => 100]);
+ $status = \Grpc\Status::ok(['trailingMeta' => 100]);
$this->mockCall->expects($this->once())
->method('startBatch')
diff --git a/src/php/tests/unit_tests/StatusTest.php b/src/php/tests/unit_tests/StatusTest.php
index ce4ee884576..dd148cf2f90 100644
--- a/src/php/tests/unit_tests/StatusTest.php
+++ b/src/php/tests/unit_tests/StatusTest.php
@@ -70,12 +70,12 @@ class StatusTest extends \PHPUnit\Framework\TestCase
$status = [
'code' => \Grpc\STATUS_INVALID_ARGUMENT,
'details' => 'invalid argument',
- 'metadata' => ['trailiingMeta' => 100]
+ 'metadata' => ['trailingMeta' => 100]
];
$return = \Grpc\Status::status(
\Grpc\STATUS_INVALID_ARGUMENT,
"invalid argument",
- ['trailiingMeta' => 100]
+ ['trailingMeta' => 100]
);
$this->assertEquals($status, $return);
}
diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py
index 829c8f8a7d4..84136764929 100644
--- a/src/python/grpcio/grpc/_grpcio_metadata.py
+++ b/src/python/grpcio/grpc/_grpcio_metadata.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
-__version__ = """1.67.0.dev0"""
+__version__ = """1.68.0.dev0"""
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 08aadfbab32..84a9cc37deb 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -1124,6 +1124,8 @@ CORE_SOURCE_FILES = [
'third_party/boringssl-with-bazel/src/crypto/kyber/kyber.c',
'third_party/boringssl-with-bazel/src/crypto/lhash/lhash.c',
'third_party/boringssl-with-bazel/src/crypto/mem.c',
+ 'third_party/boringssl-with-bazel/src/crypto/mldsa/mldsa.c',
+ 'third_party/boringssl-with-bazel/src/crypto/mlkem/mlkem.cc',
'third_party/boringssl-with-bazel/src/crypto/obj/obj.c',
'third_party/boringssl-with-bazel/src/crypto/obj/obj_xref.c',
'third_party/boringssl-with-bazel/src/crypto/pem/pem_all.c',
@@ -1144,12 +1146,14 @@ CORE_SOURCE_FILES = [
'third_party/boringssl-with-bazel/src/crypto/poly1305/poly1305_vec.c',
'third_party/boringssl-with-bazel/src/crypto/pool/pool.c',
'third_party/boringssl-with-bazel/src/crypto/rand_extra/deterministic.c',
+ 'third_party/boringssl-with-bazel/src/crypto/rand_extra/fork_detect.c',
'third_party/boringssl-with-bazel/src/crypto/rand_extra/forkunsafe.c',
'third_party/boringssl-with-bazel/src/crypto/rand_extra/getentropy.c',
'third_party/boringssl-with-bazel/src/crypto/rand_extra/ios.c',
'third_party/boringssl-with-bazel/src/crypto/rand_extra/passive.c',
'third_party/boringssl-with-bazel/src/crypto/rand_extra/rand_extra.c',
'third_party/boringssl-with-bazel/src/crypto/rand_extra/trusty.c',
+ 'third_party/boringssl-with-bazel/src/crypto/rand_extra/urandom.c',
'third_party/boringssl-with-bazel/src/crypto/rand_extra/windows.c',
'third_party/boringssl-with-bazel/src/crypto/rc4/rc4.c',
'third_party/boringssl-with-bazel/src/crypto/refcount.c',
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index f9644d30420..503faf205b0 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
diff --git a/src/python/grpcio_admin/grpc_version.py b/src/python/grpcio_admin/grpc_version.py
index c4ae9dff5fc..844132b9e0b 100644
--- a/src/python/grpcio_admin/grpc_version.py
+++ b/src/python/grpcio_admin/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_admin/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py
index 46b86e616bb..de5e63dddcf 100644
--- a/src/python/grpcio_channelz/grpc_version.py
+++ b/src/python/grpcio_channelz/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
diff --git a/src/python/grpcio_csds/grpc_version.py b/src/python/grpcio_csds/grpc_version.py
index 5003869954a..0e6d18a4863 100644
--- a/src/python/grpcio_csds/grpc_version.py
+++ b/src/python/grpcio_csds/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_csds/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
diff --git a/src/python/grpcio_csm_observability/grpc_version.py b/src/python/grpcio_csm_observability/grpc_version.py
index 5f4a5c4de8f..dc5bed153e4 100644
--- a/src/python/grpcio_csm_observability/grpc_version.py
+++ b/src/python/grpcio_csm_observability/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_csm_observability/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index e85a13a2db1..bf9a787d891 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
diff --git a/src/python/grpcio_observability/grpc_version.py b/src/python/grpcio_observability/grpc_version.py
index 94f6ed339cf..de10177d817 100644
--- a/src/python/grpcio_observability/grpc_version.py
+++ b/src/python/grpcio_observability/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_observability/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py
index 3188e99131d..0993c4a263f 100644
--- a/src/python/grpcio_reflection/grpc_version.py
+++ b/src/python/grpcio_reflection/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py
index b8977a4bf0b..90caee7f2d0 100644
--- a/src/python/grpcio_status/grpc_version.py
+++ b/src/python/grpcio_status/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py
index 289ca84aaa3..f3af99c6478 100644
--- a/src/python/grpcio_testing/grpc_version.py
+++ b/src/python/grpcio_testing/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index a5c243e7c90..53013d83e2b 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
diff --git a/src/python/grpcio_tests/tests/_result.py b/src/python/grpcio_tests/tests/_result.py
index 6f621d7e75e..151c621fb6f 100644
--- a/src/python/grpcio_tests/tests/_result.py
+++ b/src/python/grpcio_tests/tests/_result.py
@@ -15,6 +15,7 @@
from __future__ import absolute_import
import collections
+import datetime
import io
import itertools
import traceback
@@ -295,7 +296,9 @@ class TerminalResult(CoverageResult):
"""See unittest.TestResult.startTestRun."""
super(TerminalResult, self).startTestRun()
self.out.write(
- _Colors.HEADER + "Testing gRPC Python...\n" + _Colors.END
+ _Colors.HEADER
+ + "[{}]Testing gRPC Python...\n".format(datetime.datetime.now())
+ + _Colors.END
)
def stopTestRun(self):
@@ -324,7 +327,11 @@ class TerminalResult(CoverageResult):
"""See unittest.TestResult.addSuccess."""
super(TerminalResult, self).addSuccess(test)
self.out.write(
- _Colors.OK + "SUCCESS {}\n".format(test.id()) + _Colors.END
+ _Colors.OK
+ + "[{}]SUCCESS {}\n".format(
+ datetime.datetime.now(), test.id()
+ )
+ + _Colors.END
)
self.out.flush()
diff --git a/src/python/grpcio_tests/tests_aio/unit/call_test.py b/src/python/grpcio_tests/tests_aio/unit/call_test.py
index 6885f0301e8..b6f09886544 100644
--- a/src/python/grpcio_tests/tests_aio/unit/call_test.py
+++ b/src/python/grpcio_tests/tests_aio/unit/call_test.py
@@ -817,7 +817,6 @@ class TestStreamStreamCall(_MulticallableTestMixin, AioTestBase):
await call.done_writing()
# Cancels the RPC
- self.assertFalse(call.done())
self.assertFalse(call.cancelled())
self.assertTrue(call.cancel())
self.assertTrue(call.cancelled())
diff --git a/src/python/grpcio_tests/tests_aio/unit/connectivity_test.py b/src/python/grpcio_tests/tests_aio/unit/connectivity_test.py
index 9af401a377e..9e3ae3af7b4 100644
--- a/src/python/grpcio_tests/tests_aio/unit/connectivity_test.py
+++ b/src/python/grpcio_tests/tests_aio/unit/connectivity_test.py
@@ -55,7 +55,7 @@ class TestConnectivityState(AioTestBase):
_common.block_until_certain_state(
channel, grpc.ChannelConnectivity.TRANSIENT_FAILURE
),
- test_constants.SHORT_TIMEOUT,
+ test_constants.SHORT_TIMEOUT * 2,
)
async def test_normal_backend(self):
diff --git a/src/ruby/end2end/bad_usage_fork_test.rb b/src/ruby/end2end/bad_usage_fork_test.rb
index f6ba65d34c6..c796b8510a7 100755
--- a/src/ruby/end2end/bad_usage_fork_test.rb
+++ b/src/ruby/end2end/bad_usage_fork_test.rb
@@ -24,6 +24,7 @@ $LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir)
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+require 'sanity_check_dlopen'
require 'grpc'
require 'end2end_common'
diff --git a/src/ruby/end2end/call_credentials_returning_bad_metadata_doesnt_kill_background_thread_test.rb b/src/ruby/end2end/call_credentials_returning_bad_metadata_doesnt_kill_background_thread_test.rb
index eda85c6da09..d6da32a1b86 100755
--- a/src/ruby/end2end/call_credentials_returning_bad_metadata_doesnt_kill_background_thread_test.rb
+++ b/src/ruby/end2end/call_credentials_returning_bad_metadata_doesnt_kill_background_thread_test.rb
@@ -21,6 +21,7 @@ $LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir)
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+require 'sanity_check_dlopen'
require 'grpc'
require 'end2end_common'
diff --git a/src/ruby/end2end/call_credentials_timeout_test.rb b/src/ruby/end2end/call_credentials_timeout_test.rb
index 3d442d854c1..acc81765718 100755
--- a/src/ruby/end2end/call_credentials_timeout_test.rb
+++ b/src/ruby/end2end/call_credentials_timeout_test.rb
@@ -21,6 +21,7 @@ $LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir)
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+require 'sanity_check_dlopen'
require 'grpc'
require 'end2end_common'
diff --git a/src/ruby/end2end/errors_load_before_grpc_lib_test.rb b/src/ruby/end2end/errors_load_before_grpc_lib_test.rb
index 56f7714fc7c..7c753678720 100755
--- a/src/ruby/end2end/errors_load_before_grpc_lib_test.rb
+++ b/src/ruby/end2end/errors_load_before_grpc_lib_test.rb
@@ -18,6 +18,8 @@ this_dir = File.expand_path(File.dirname(__FILE__))
grpc_lib_dir = File.join(File.dirname(this_dir), 'lib')
$LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
+require_relative './sanity_check_dlopen'
+
def check_to_status(error)
my_status = error.to_status
fail('GRPC BadStatus#to_status not expected to return nil') if my_status.nil?
diff --git a/src/ruby/end2end/fork_test.rb b/src/ruby/end2end/fork_test.rb
index 6c92c0893c6..38a8843c985 100755
--- a/src/ruby/end2end/fork_test.rb
+++ b/src/ruby/end2end/fork_test.rb
@@ -24,6 +24,7 @@ $LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir)
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+require 'sanity_check_dlopen'
require 'grpc'
require 'end2end_common'
diff --git a/src/ruby/end2end/load_grpc_with_gc_stress_test.rb b/src/ruby/end2end/load_grpc_with_gc_stress_test.rb
index 9b0ca765f86..4ed3e1af3f6 100755
--- a/src/ruby/end2end/load_grpc_with_gc_stress_test.rb
+++ b/src/ruby/end2end/load_grpc_with_gc_stress_test.rb
@@ -21,6 +21,8 @@ $LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir)
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+require 'sanity_check_dlopen'
+
GC.stress = 0x04
require 'grpc'
diff --git a/src/ruby/end2end/logger_load_before_grpc_lib_test.rb b/src/ruby/end2end/logger_load_before_grpc_lib_test.rb
index 76c37875040..8e58667bff3 100755
--- a/src/ruby/end2end/logger_load_before_grpc_lib_test.rb
+++ b/src/ruby/end2end/logger_load_before_grpc_lib_test.rb
@@ -18,6 +18,8 @@ this_dir = File.expand_path(File.dirname(__FILE__))
grpc_lib_dir = File.join(File.dirname(this_dir), 'lib')
$LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
+require_relative './sanity_check_dlopen'
+
def main
fail('GRPC constant loaded before expected') if Object.const_defined?(:GRPC)
require 'grpc/logconfig'
diff --git a/src/ruby/end2end/prefork_postfork_loop_test.rb b/src/ruby/end2end/prefork_postfork_loop_test.rb
index a09f85bcc77..0613b374b06 100755
--- a/src/ruby/end2end/prefork_postfork_loop_test.rb
+++ b/src/ruby/end2end/prefork_postfork_loop_test.rb
@@ -24,6 +24,7 @@ $LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir)
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+require 'sanity_check_dlopen'
require 'grpc'
require 'end2end_common'
diff --git a/src/ruby/end2end/prefork_without_using_grpc_test.rb b/src/ruby/end2end/prefork_without_using_grpc_test.rb
index f6791b27ad6..ec6736a9031 100755
--- a/src/ruby/end2end/prefork_without_using_grpc_test.rb
+++ b/src/ruby/end2end/prefork_without_using_grpc_test.rb
@@ -24,6 +24,7 @@ $LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir)
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+require 'sanity_check_dlopen'
require 'grpc'
require 'end2end_common'
diff --git a/src/ruby/end2end/sanity_check_dlopen.rb b/src/ruby/end2end/sanity_check_dlopen.rb
new file mode 100755
index 00000000000..e536100bad9
--- /dev/null
+++ b/src/ruby/end2end/sanity_check_dlopen.rb
@@ -0,0 +1,74 @@
+#!/usr/bin/env ruby
+#
+# 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.
+
+# Some tests are flaking by failing to dlopen grpc. Perform some sanity checks.
+this_dir = File.expand_path(File.dirname(__FILE__))
+grpc_bin_dir = File.join(File.join(File.dirname(this_dir), 'lib'), 'grpc')
+grpc_c_sha256_path = File.join(grpc_bin_dir, 'grpc_c_sha256')
+grpc_c_so_path = if RUBY_PLATFORM =~ /darwin/
+ File.join(grpc_bin_dir, 'grpc_c.bundle')
+ else
+ File.join(grpc_bin_dir, 'grpc_c.so')
+ end
+
+require 'digest'
+
+# first try to detect corruption b/t the build and now
+actual_sha256 = Digest::SHA256.file(grpc_c_so_path).hexdigest
+expected_sha256 = File.read(grpc_c_sha256_path).chomp
+raise "detected corruption in #{grpc_c_so_path}: sha256: |#{actual_sha256}| != expected sha256: |#{expected_sha256}|" if actual_sha256 != expected_sha256
+STDERR.puts "verified sha256 of #{grpc_c_so_path}"
+
+def try_command(command)
+ STDERR.puts "==== run |#{command}| BEGIN ===="
+ output = `#{command} || true`
+ STDERR.puts output
+ STDERR.puts "==== run |#{command}| DONE ===="
+end
+
+try_command('vm_stat')
+try_command('free')
+try_command('ulimit -v')
+
+# sanity check that we can load grpc in a child process, log things like available
+# memory on the off chance we might be low.
+pid = fork do
+ STDERR.puts "==== sanity check child process BEGIN ===="
+ def dump(file_path)
+ STDERR.puts "==== dump file: #{file_path} BEGIN ===="
+ if File.exist?(file_path)
+ File.open(file_path, 'r') do |file|
+ file.each_line do |line|
+ puts line
+ end
+ end
+ else
+ STDERR.puts "file: #{file_path} does not exist"
+ end
+ STDERR.puts "==== dump file: #{file_path} DONE ===="
+ end
+ dump("/proc/#{Process.pid}/limits")
+ dump("/proc/#{Process.pid}/status")
+ STDERR.puts "==== sanity check require grpc in child process BEGIN ====="
+ require 'grpc'
+ STDERR.puts "==== sanity check require grpc in child process DONE ====="
+ dump("/proc/#{Process.pid}/limits")
+ dump("/proc/#{Process.pid}/status")
+ STDERR.puts "==== sanity check child process DONE ===="
+end
+_, status = Process.wait2(pid)
+fail "sanity check require grpc in child process FAILED exit code #{status.exitstatus}" unless status.success?
+STDERR.puts "==== sanity check require grpc in child process SUCCESS ====="
diff --git a/src/ruby/end2end/secure_fork_test.rb b/src/ruby/end2end/secure_fork_test.rb
index d6af2fb2024..a37087913de 100755
--- a/src/ruby/end2end/secure_fork_test.rb
+++ b/src/ruby/end2end/secure_fork_test.rb
@@ -24,6 +24,7 @@ $LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir)
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+require 'sanity_check_dlopen'
require 'grpc'
require 'end2end_common'
diff --git a/src/ruby/end2end/simple_fork_test.rb b/src/ruby/end2end/simple_fork_test.rb
index ca5e867457c..999dd378567 100755
--- a/src/ruby/end2end/simple_fork_test.rb
+++ b/src/ruby/end2end/simple_fork_test.rb
@@ -24,6 +24,7 @@ $LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir)
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+require 'sanity_check_dlopen'
require 'grpc'
require 'end2end_common'
diff --git a/src/ruby/end2end/status_codes_load_before_grpc_lib_test.rb b/src/ruby/end2end/status_codes_load_before_grpc_lib_test.rb
index 010c94cb91b..4eca92073d6 100755
--- a/src/ruby/end2end/status_codes_load_before_grpc_lib_test.rb
+++ b/src/ruby/end2end/status_codes_load_before_grpc_lib_test.rb
@@ -18,6 +18,8 @@ this_dir = File.expand_path(File.dirname(__FILE__))
grpc_lib_dir = File.join(File.dirname(this_dir), 'lib')
$LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
+require_relative './sanity_check_dlopen'
+
def main
fail('GRPC constant loaded before expected') if Object.const_defined?(:GRPC)
require 'grpc/core/status_codes'
diff --git a/src/ruby/ext/grpc/rb_compression_options.c b/src/ruby/ext/grpc/rb_compression_options.c
index 7bdc33004e8..a38790faf79 100644
--- a/src/ruby/ext/grpc/rb_compression_options.c
+++ b/src/ruby/ext/grpc/rb_compression_options.c
@@ -296,7 +296,7 @@ VALUE grpc_rb_compression_options_level_value_to_name_internal(
* Fails if the enum value is invalid. */
VALUE grpc_rb_compression_options_algorithm_value_to_name_internal(
grpc_compression_algorithm internal_value) {
- char* algorithm_name = NULL;
+ const char* algorithm_name = NULL;
if (!grpc_compression_algorithm_name(internal_value, &algorithm_name)) {
rb_raise(rb_eArgError, "Failed to convert algorithm value to name");
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index a36b7ff6d23..e74d4085150 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -14,5 +14,5 @@
# GRPC contains the General RPC module.
module GRPC
- VERSION = '1.67.0.dev'
+ VERSION = '1.68.0.dev'
end
diff --git a/src/ruby/nativedebug/version.rb b/src/ruby/nativedebug/version.rb
index bfd6738d998..87243691578 100644
--- a/src/ruby/nativedebug/version.rb
+++ b/src/ruby/nativedebug/version.rb
@@ -14,6 +14,6 @@
module GRPC
module NativeDebug
- VERSION = '1.67.0.dev'
+ VERSION = '1.68.0.dev'
end
end
diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb
index 5cc0679b3c6..62788f75291 100644
--- a/src/ruby/spec/generic/client_stub_spec.rb
+++ b/src/ruby/spec/generic/client_stub_spec.rb
@@ -453,23 +453,23 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
describe '#server_streamer', server_streamer: true do
before(:each) do
@sent_msg = 'a_msg'
- @replys = Array.new(3) { |i| 'reply_' + (i + 1).to_s }
+ @replies = Array.new(3) { |i| 'reply_' + (i + 1).to_s }
end
shared_examples 'server streaming' do
it 'should send a request to/receive replies from a server' do
server_port = create_test_server
host = "localhost:#{server_port}"
- th = run_server_streamer(@sent_msg, @replys, @pass)
+ th = run_server_streamer(@sent_msg, @replies, @pass)
stub = GRPC::ClientStub.new(host, :this_channel_is_insecure)
- expect(get_responses(stub).collect { |r| r }).to eq(@replys)
+ expect(get_responses(stub).collect { |r| r }).to eq(@replies)
th.join
end
it 'should raise an error if the status is not ok' do
server_port = create_test_server
host = "localhost:#{server_port}"
- th = run_server_streamer(@sent_msg, @replys, @fail)
+ th = run_server_streamer(@sent_msg, @replies, @fail)
stub = GRPC::ClientStub.new(host, :this_channel_is_insecure)
e = get_responses(stub)
expect { e.collect { |r| r } }.to raise_error(GRPC::BadStatus)
@@ -479,7 +479,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
it 'should send metadata to the server ok' do
server_port = create_test_server
host = "localhost:#{server_port}"
- th = run_server_streamer(@sent_msg, @replys, @fail,
+ th = run_server_streamer(@sent_msg, @replies, @fail,
expected_metadata: { k1: 'v1', k2: 'v2' })
stub = GRPC::ClientStub.new(host, :this_channel_is_insecure)
e = get_responses(stub)
@@ -502,7 +502,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
server_port = create_test_server
host = "localhost:#{server_port}"
th = run_server_streamer_handle_client_cancellation(
- @sent_msg, @replys)
+ @sent_msg, @replies)
stub = GRPC::ClientStub.new(host, :this_channel_is_insecure)
unmarshal = proc { fail(ArgumentError, 'test unmarshalling error') }
@@ -547,13 +547,13 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
@server_initial_md = { 'sk1' => 'sv1', 'sk2' => 'sv2' }
@server_trailing_md = { 'tk1' => 'tv1', 'tk2' => 'tv2' }
th = run_server_streamer(
- @sent_msg, @replys, @pass,
+ @sent_msg, @replies, @pass,
expected_metadata: @metadata,
server_initial_md: @server_initial_md,
server_trailing_md: @server_trailing_md)
stub = GRPC::ClientStub.new(host, :this_channel_is_insecure)
e = get_responses(stub, run_start_call_first: run_start_call_first)
- expect(e.collect { |r| r }).to eq(@replys)
+ expect(e.collect { |r| r }).to eq(@replies)
th.join
end
@@ -577,7 +577,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
server_port = create_test_server
host = "localhost:#{server_port}"
th = run_server_streamer_handle_client_cancellation(
- @sent_msg, @replys)
+ @sent_msg, @replies)
stub = GRPC::ClientStub.new(host, :this_channel_is_insecure)
resp = get_responses(stub, run_start_call_first: false)
expect(resp.next).to eq('reply_1')
@@ -591,18 +591,18 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
describe '#bidi_streamer', bidi: true do
before(:each) do
@sent_msgs = Array.new(3) { |i| 'msg_' + (i + 1).to_s }
- @replys = Array.new(3) { |i| 'reply_' + (i + 1).to_s }
+ @replies = Array.new(3) { |i| 'reply_' + (i + 1).to_s }
server_port = create_test_server
@host = "localhost:#{server_port}"
end
shared_examples 'bidi streaming' do
it 'supports sending all the requests first' do
- th = run_bidi_streamer_handle_inputs_first(@sent_msgs, @replys,
+ th = run_bidi_streamer_handle_inputs_first(@sent_msgs, @replies,
@pass)
stub = GRPC::ClientStub.new(@host, :this_channel_is_insecure)
e = get_responses(stub)
- expect(e.collect { |r| r }).to eq(@replys)
+ expect(e.collect { |r| r }).to eq(@replies)
th.join
end
@@ -724,7 +724,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
requests_to_push,
request_queue,
expected_error_message)
- # the write loop errror should cancel the call and end the
+ # the write loop error should cancel the call and end the
# server's request stream
th.join
end
@@ -777,7 +777,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
it 'receives a grpc status code when writes to a bidi stream fail' do
# This test tries to trigger the case when a 'SEND_MESSAGE' op
- # and subseqeunt 'SEND_CLOSE_FROM_CLIENT' op of a bidi stream fails.
+ # and subsequent 'SEND_CLOSE_FROM_CLIENT' op of a bidi stream fails.
# In this case, iteration through the response stream should result
# in a grpc status code, and the writer thread should not raise an
# exception.
@@ -942,7 +942,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
end
end
- def run_server_streamer(expected_input, replys, status,
+ def run_server_streamer(expected_input, replies, status,
expected_metadata: {},
server_initial_md: {},
server_trailing_md: {})
@@ -954,19 +954,19 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
expect(c.metadata[k.to_s]).to eq(v)
end
expect(c.remote_read).to eq(expected_input)
- replys.each { |r| c.remote_send(r) }
+ replies.each { |r| c.remote_send(r) }
c.send_status(status, status == @pass ? 'OK' : 'NOK', true,
metadata: server_trailing_md)
close_active_server_call(c)
end
end
- def run_bidi_streamer_handle_inputs_first(expected_inputs, replys,
+ def run_bidi_streamer_handle_inputs_first(expected_inputs, replies,
status)
wakey_thread do |notifier|
c = expect_server_to_be_invoked(notifier)
expected_inputs.each { |i| expect(c.remote_read).to eq(i) }
- replys.each { |r| c.remote_send(r) }
+ replies.each { |r| c.remote_send(r) }
c.send_status(status, status == @pass ? 'OK' : 'NOK', true)
close_active_server_call(c)
end
@@ -1018,12 +1018,12 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
end
def run_server_streamer_handle_client_cancellation(
- expected_input, replys)
+ expected_input, replies)
wakey_thread do |notifier|
c = expect_server_to_be_invoked(notifier)
expect(c.remote_read).to eq(expected_input)
begin
- replys.each { |r| c.remote_send(r) }
+ replies.each { |r| c.remote_send(r) }
rescue GRPC::Core::CallError
# An attempt to write to the client might fail. This is ok
# because the client call is expected to cancel the call,
diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb
index abfb5c3783e..3681d9147d2 100644
--- a/src/ruby/tools/version.rb
+++ b/src/ruby/tools/version.rb
@@ -14,6 +14,6 @@
module GRPC
module Tools
- VERSION = '1.67.0.dev'
+ VERSION = '1.68.0.dev'
end
end
diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template
index 18595b90ce6..b6ffab39cdf 100644
--- a/templates/gRPC-Core.podspec.template
+++ b/templates/gRPC-Core.podspec.template
@@ -199,7 +199,7 @@
ss.libraries = 'z'
ss.dependency "#{s.name}/Interface", version
ss.dependency "#{s.name}/Privacy", version
- ss.dependency 'BoringSSL-GRPC', '0.0.36'
+ ss.dependency 'BoringSSL-GRPC', '0.0.37'
% for abseil_spec in grpc_abseil_specs:
ss.dependency '${abseil_spec}', abseil_version
% endfor
diff --git a/templates/src/objective-c/BoringSSL-GRPC.podspec.template b/templates/src/objective-c/BoringSSL-GRPC.podspec.template
index 05510117732..274cd3c5f14 100644
--- a/templates/src/objective-c/BoringSSL-GRPC.podspec.template
+++ b/templates/src/objective-c/BoringSSL-GRPC.podspec.template
@@ -70,7 +70,7 @@
Pod::Spec.new do |s|
s.name = 'BoringSSL-GRPC'
- version = '0.0.36'
+ version = '0.0.37'
s.version = version
s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.'
# Adapted from the homepage:
@@ -163,7 +163,7 @@
ss.source_files = 'src/ssl/*.{h,c,cc}',
'src/ssl/**/*.{h,c,cc}',
'src/crypto/*.{h,c,cc}',
- 'src/crypto/**/*.{h,c,cc}',
+ 'src/crypto/**/*.{h,c,cc,inc}',
# We have to include fiat because spake25519 depends on it
'src/third_party/fiat/*.{h,c,cc}',
# Include the err_data.c pre-generated in boringssl's master-with-bazel branch
@@ -174,11 +174,7 @@
'src/crypto/*.h',
'src/crypto/**/*.h',
'src/third_party/fiat/*.h'
- # bcm.c includes other source files, creating duplicated symbols. Since it is not used, we
- # explicitly exclude it from the pod.
- # TODO (mxyan): Work with BoringSSL team to remove this hack.
- ss.exclude_files = 'src/crypto/fipsmodule/bcm.c',
- 'src/**/*_test.*',
+ ss.exclude_files = 'src/**/*_test.*',
'src/**/test_*.*',
'src/**/test/*.*'
@@ -221,10 +217,10 @@
EOF
# We are renaming openssl to openssl_grpc so that there is no conflict with openssl if it exists
- find . -type f \\( -path '*.h' -or -path '*.cc' -or -path '*.c' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include ;#include ;g'
+ find . -type f \\( -path '*.h' -or -path '*.cc' -or -path '*.c' -or -path '*.inc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include ;#include ;g'
END_OF_COMMAND
end
diff --git a/test/core/channelz/channelz_registry_test.cc b/test/core/channelz/channelz_registry_test.cc
index 7b193c274fd..29110f3f5c1 100644
--- a/test/core/channelz/channelz_registry_test.cc
+++ b/test/core/channelz/channelz_registry_test.cc
@@ -83,9 +83,9 @@ TEST_F(ChannelzRegistryTest, RegisterManyItems) {
TEST_F(ChannelzRegistryTest, NullIfNotPresentTest) {
RefCountedPtr channelz_channel = CreateTestNode();
// try to pull out a uuid that does not exist.
- RefCountedPtr nonexistant =
+ RefCountedPtr nonexistent =
ChannelzRegistry::Get(channelz_channel->uuid() + 1);
- EXPECT_EQ(nonexistant, nullptr);
+ EXPECT_EQ(nonexistent, nullptr);
RefCountedPtr retrieved =
ChannelzRegistry::Get(channelz_channel->uuid());
EXPECT_EQ(channelz_channel, retrieved);
diff --git a/test/core/client_channel/bm_load_balanced_call_destination.cc b/test/core/client_channel/bm_load_balanced_call_destination.cc
index a9024edb768..f3a52f40ae9 100644
--- a/test/core/client_channel/bm_load_balanced_call_destination.cc
+++ b/test/core/client_channel/bm_load_balanced_call_destination.cc
@@ -80,6 +80,8 @@ class LoadBalancedCallDestinationTraits {
return call_destination_;
}
+ std::string address() const override { return "test"; }
+
private:
const RefCountedPtr call_destination_;
};
diff --git a/test/core/client_channel/load_balanced_call_destination_test.cc b/test/core/client_channel/load_balanced_call_destination_test.cc
index ba92f44958c..399f7bddc5a 100644
--- a/test/core/client_channel/load_balanced_call_destination_test.cc
+++ b/test/core/client_channel/load_balanced_call_destination_test.cc
@@ -118,6 +118,8 @@ class LoadBalancedCallDestinationTest : public YodelTest {
return call_destination_;
}
+ std::string address() const override { return "test"; }
+
private:
const RefCountedPtr call_destination_;
};
diff --git a/test/core/client_channel/retry_service_config_test.cc b/test/core/client_channel/retry_service_config_test.cc
index 34f41a5da9a..410f064c9ec 100644
--- a/test/core/client_channel/retry_service_config_test.cc
+++ b/test/core/client_channel/retry_service_config_test.cc
@@ -473,7 +473,7 @@ TEST_F(RetryParserTest,
<< service_config.status();
}
-TEST_F(RetryParserTest, InvalidRetryPolicyUnparseableRetryableStatusCodes) {
+TEST_F(RetryParserTest, InvalidRetryPolicyUnparsableRetryableStatusCodes) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@@ -614,7 +614,7 @@ TEST_F(RetryParserTest,
EXPECT_TRUE(parsed_config->retryable_status_codes().Empty());
}
-TEST_F(RetryParserTest, InvalidRetryPolicyPerAttemptRecvTimeoutUnparseable) {
+TEST_F(RetryParserTest, InvalidRetryPolicyPerAttemptRecvTimeoutUnparsable) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc
index d9c543fcfed..db615d1b098 100644
--- a/test/core/end2end/bad_server_response_test.cc
+++ b/test/core/end2end/bad_server_response_test.cc
@@ -75,7 +75,7 @@
"application/grpc" \
"\x10\x07:status\x03" #STATUS_CODE
-#define UNPARSEABLE_RESP "Bad Request\n"
+#define UNPARSABLE_RESP "Bad Request\n"
#define HTTP2_DETAIL_MSG(STATUS_CODE) \
"Received http2 header with status: " #STATUS_CODE
@@ -394,10 +394,10 @@ int main(int argc, char** argv) {
GRPC_STATUS_UNAVAILABLE, HTTP2_DETAIL_MSG(503));
run_test(true, true, HTTP2_RESP(504), sizeof(HTTP2_RESP(504)) - 1,
GRPC_STATUS_UNAVAILABLE, HTTP2_DETAIL_MSG(504));
- // unparseable response. RPC should fail immediately due to a connect
+ // unparsable response. RPC should fail immediately due to a connect
// failure.
//
- run_test(false, false, UNPARSEABLE_RESP, sizeof(UNPARSEABLE_RESP) - 1,
+ run_test(false, false, UNPARSABLE_RESP, sizeof(UNPARSABLE_RESP) - 1,
GRPC_STATUS_UNAVAILABLE, nullptr);
// http1 response. RPC should fail immediately due to a connect failure.
diff --git a/test/core/end2end/connection_refused_test.cc b/test/core/end2end/connection_refused_test.cc
index 1e3414b8875..f753cf7a86e 100644
--- a/test/core/end2end/connection_refused_test.cc
+++ b/test/core/end2end/connection_refused_test.cc
@@ -85,8 +85,9 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
grpc_channel_credentials* creds = grpc_insecure_credentials_create();
chan = grpc_channel_create(addr.c_str(), creds, args);
grpc_channel_credentials_release(creds);
- grpc_slice host = grpc_slice_from_static_string("nonexistant");
- gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2);
+ grpc_slice host = grpc_slice_from_static_string("nonexistent");
+ gpr_timespec deadline =
+ grpc_timeout_seconds_to_deadline(wait_for_ready ? 2 : 600);
call =
grpc_channel_create_call(chan, nullptr, GRPC_PROPAGATE_DEFAULTS, cq,
grpc_slice_from_static_string("/service/method"),
diff --git a/test/core/end2end/fixtures/proxy.cc b/test/core/end2end/fixtures/proxy.cc
index febdb809838..fd8a0f59763 100644
--- a/test/core/end2end/fixtures/proxy.cc
+++ b/test/core/end2end/fixtures/proxy.cc
@@ -20,6 +20,7 @@
#include
+#include
#include
#include
@@ -82,6 +83,10 @@ typedef struct {
grpc_metadata_array c2p_initial_metadata;
grpc_metadata_array p2s_initial_metadata;
+ grpc_core::Mutex* initial_metadata_mu;
+ bool p2s_initial_metadata_received ABSL_GUARDED_BY(initial_metadata_mu);
+ grpc_op* deferred_trailing_metadata_op ABSL_GUARDED_BY(initial_metadata_mu);
+
grpc_byte_buffer* c2p_msg;
grpc_byte_buffer* p2s_msg;
@@ -166,6 +171,13 @@ static void unrefpc(proxy_call* pc, const char* /*reason*/) {
grpc_metadata_array_destroy(&pc->p2s_initial_metadata);
grpc_metadata_array_destroy(&pc->p2s_trailing_metadata);
grpc_slice_unref(pc->p2s_status_details);
+ {
+ grpc_core::MutexLock lock(pc->initial_metadata_mu);
+ if (pc->deferred_trailing_metadata_op != nullptr) {
+ gpr_free(pc->deferred_trailing_metadata_op);
+ }
+ }
+ delete pc->initial_metadata_mu;
gpr_free(pc);
}
}
@@ -179,25 +191,45 @@ static void on_c2p_sent_initial_metadata(void* arg, int /*success*/) {
unrefpc(pc, "on_c2p_sent_initial_metadata");
}
+static void on_c2p_sent_status(void* arg, int /*success*/) {
+ proxy_call* pc = static_cast(arg);
+ unrefpc(pc, "on_c2p_sent_status");
+}
+
static void on_p2s_recv_initial_metadata(void* arg, int /*success*/) {
proxy_call* pc = static_cast(arg);
grpc_op op;
grpc_call_error err;
-
memset(&op, 0, sizeof(op));
- if (!pc->proxy->shutdown && !grpc_call_is_trailers_only(pc->p2s)) {
- op.op = GRPC_OP_SEND_INITIAL_METADATA;
- op.flags = 0;
- op.reserved = nullptr;
- op.data.send_initial_metadata.count = pc->p2s_initial_metadata.count;
- op.data.send_initial_metadata.metadata = pc->p2s_initial_metadata.metadata;
- refpc(pc, "on_c2p_sent_initial_metadata");
- err = grpc_call_start_batch(pc->c2p, &op, 1,
- new_closure(on_c2p_sent_initial_metadata, pc),
- nullptr);
- CHECK_EQ(err, GRPC_CALL_OK);
+ if (!pc->proxy->shutdown) {
+ if (!grpc_call_is_trailers_only(pc->p2s)) {
+ op.op = GRPC_OP_SEND_INITIAL_METADATA;
+ op.flags = 0;
+ op.reserved = nullptr;
+ op.data.send_initial_metadata.count = pc->p2s_initial_metadata.count;
+ op.data.send_initial_metadata.metadata =
+ pc->p2s_initial_metadata.metadata;
+ refpc(pc, "on_c2p_sent_initial_metadata");
+ err = grpc_call_start_batch(pc->c2p, &op, 1,
+ new_closure(on_c2p_sent_initial_metadata, pc),
+ nullptr);
+ CHECK_EQ(err, GRPC_CALL_OK);
+ }
+ grpc_op* deferred_trailing_metadata_op = nullptr;
+ {
+ grpc_core::MutexLock lock(pc->initial_metadata_mu);
+ // Start the batch without the mutex held, just in case.
+ // This will be nullptr if the trailing metadata has not yet been seen.
+ deferred_trailing_metadata_op = pc->deferred_trailing_metadata_op;
+ pc->p2s_initial_metadata_received = true;
+ }
+ if (deferred_trailing_metadata_op != nullptr) {
+ refpc(pc, "on_c2p_sent_status");
+ err = grpc_call_start_batch(pc->c2p, deferred_trailing_metadata_op, 1,
+ new_closure(on_c2p_sent_status, pc), nullptr);
+ CHECK_EQ(err, GRPC_CALL_OK);
+ }
}
-
unrefpc(pc, "on_p2s_recv_initial_metadata");
}
@@ -308,11 +340,6 @@ static void on_p2s_recv_msg(void* arg, int success) {
unrefpc(pc, "on_p2s_recv_msg");
}
-static void on_c2p_sent_status(void* arg, int /*success*/) {
- proxy_call* pc = static_cast(arg);
- unrefpc(pc, "on_c2p_sent_status");
-}
-
static void on_p2s_status(void* arg, int success) {
proxy_call* pc = static_cast(arg);
grpc_op op[2]; // Possibly send empty initial metadata also if trailers-only
@@ -340,10 +367,29 @@ static void on_p2s_status(void* arg, int success) {
op[op_count].data.send_status_from_server.status_details =
&pc->p2s_status_details;
op_count++;
- refpc(pc, "on_c2p_sent_status");
- err = grpc_call_start_batch(pc->c2p, op, op_count,
- new_closure(on_c2p_sent_status, pc), nullptr);
- CHECK_EQ(err, GRPC_CALL_OK);
+
+ // TODO(ctiller): The current core implementation requires initial
+ // metadata batches to be started *after* initial metadata batches have
+ // been completed. The C++ Callback API does this accounting too, for
+ // example.
+ //
+ // This entire fixture will need a redesign when the batch API goes away.
+ bool op_deferred = false;
+ {
+ grpc_core::MutexLock lock(pc->initial_metadata_mu);
+ if (!pc->p2s_initial_metadata_received) {
+ op_deferred = true;
+ pc->deferred_trailing_metadata_op =
+ static_cast(gpr_malloc(sizeof(op)));
+ memcpy(pc->deferred_trailing_metadata_op, &op, sizeof(op));
+ }
+ }
+ if (!op_deferred) {
+ refpc(pc, "on_c2p_sent_status");
+ err = grpc_call_start_batch(pc->c2p, op, op_count,
+ new_closure(on_c2p_sent_status, pc), nullptr);
+ CHECK_EQ(err, GRPC_CALL_OK);
+ }
}
unrefpc(pc, "on_p2s_status");
@@ -365,6 +411,12 @@ static void on_new_call(void* arg, int success) {
memset(pc, 0, sizeof(*pc));
pc->proxy = proxy;
std::swap(pc->c2p_initial_metadata, proxy->new_call_metadata);
+ pc->initial_metadata_mu = new grpc_core::Mutex();
+ {
+ grpc_core::MutexLock lock(pc->initial_metadata_mu);
+ pc->p2s_initial_metadata_received = false;
+ pc->deferred_trailing_metadata_op = nullptr;
+ }
pc->c2p = proxy->new_call;
pc->p2s = grpc_channel_create_call(
proxy->client, pc->c2p, GRPC_PROPAGATE_DEFAULTS, proxy->cq,
@@ -374,6 +426,7 @@ static void on_new_call(void* arg, int success) {
op.reserved = nullptr;
+ // Proxy: receive initial metadata from the server
op.op = GRPC_OP_RECV_INITIAL_METADATA;
op.flags = 0;
op.data.recv_initial_metadata.recv_initial_metadata =
@@ -384,6 +437,7 @@ static void on_new_call(void* arg, int success) {
nullptr);
CHECK_EQ(err, GRPC_CALL_OK);
+ // Proxy: send initial metadata to the server
op.op = GRPC_OP_SEND_INITIAL_METADATA;
op.flags = 0;
op.data.send_initial_metadata.count = pc->c2p_initial_metadata.count;
@@ -394,6 +448,7 @@ static void on_new_call(void* arg, int success) {
nullptr);
CHECK_EQ(err, GRPC_CALL_OK);
+ // Client: receive message from the proxy
op.op = GRPC_OP_RECV_MESSAGE;
op.flags = 0;
op.data.recv_message.recv_message = &pc->c2p_msg;
@@ -402,6 +457,7 @@ static void on_new_call(void* arg, int success) {
new_closure(on_c2p_recv_msg, pc), nullptr);
CHECK_EQ(err, GRPC_CALL_OK);
+ // Proxy: receive message from the server
op.op = GRPC_OP_RECV_MESSAGE;
op.flags = 0;
op.data.recv_message.recv_message = &pc->p2s_msg;
@@ -410,6 +466,7 @@ static void on_new_call(void* arg, int success) {
new_closure(on_p2s_recv_msg, pc), nullptr);
CHECK_EQ(err, GRPC_CALL_OK);
+ // Proxy: receive status from the server
op.op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op.flags = 0;
op.data.recv_status_on_client.trailing_metadata =
@@ -421,6 +478,7 @@ static void on_new_call(void* arg, int success) {
nullptr);
CHECK_EQ(err, GRPC_CALL_OK);
+ // Client: receive close-ack from the proxy
op.op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op.flags = 0;
op.data.recv_close_on_server.cancelled = &pc->c2p_server_cancelled;
diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc
index 68173c02155..84050e4c4e0 100644
--- a/test/core/end2end/h2_ssl_cert_test.cc
+++ b/test/core/end2end/h2_ssl_cert_test.cc
@@ -42,6 +42,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/config/config_vars.h"
+#include "src/core/lib/gprpp/time.h"
#include "src/core/util/tmpfile.h"
#include "test/core/end2end/cq_verifier.h"
#include "test/core/end2end/data/ssl_test_data.h"
@@ -196,7 +197,7 @@ static CoreTestConfigWrapper configs[] = {
static void simple_request_body(grpc_core::CoreTestFixture* f,
test_result expected_result) {
grpc_call* c;
- gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
+ gpr_timespec deadline = grpc_timeout_seconds_to_deadline(30);
grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
grpc_core::CqVerifier cqv(cq);
grpc_op ops[6];
@@ -226,13 +227,13 @@ static void simple_request_body(grpc_core::CoreTestFixture* f,
CHECK_EQ(error, GRPC_CALL_OK);
cqv.Expect(grpc_core::CqVerifier::tag(1), expected_result == SUCCESS);
- cqv.Verify();
+ cqv.Verify(grpc_core::Duration::Seconds(60));
grpc_call_unref(c);
grpc_channel_destroy(client);
grpc_server_shutdown_and_notify(server, cq, nullptr);
cqv.Expect(nullptr, true);
- cqv.Verify();
+ cqv.Verify(grpc_core::Duration::Seconds(60));
grpc_server_destroy(server);
grpc_completion_queue_shutdown(cq);
CHECK(grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME),
diff --git a/test/core/end2end/invalid_call_argument_test.cc b/test/core/end2end/invalid_call_argument_test.cc
index 1f086c3f98a..572c441d74d 100644
--- a/test/core/end2end/invalid_call_argument_test.cc
+++ b/test/core/end2end/invalid_call_argument_test.cc
@@ -74,11 +74,11 @@ static void prepare_test(int is_client) {
memset(g_state.ops, 0, sizeof(g_state.ops));
if (is_client) {
- // create a call, channel to a non existant server
+ // create a call, channel to a non existent server
grpc_channel_credentials* creds = grpc_insecure_credentials_create();
- g_state.chan = grpc_channel_create("nonexistant:54321", creds, nullptr);
+ g_state.chan = grpc_channel_create("nonexistent:54321", creds, nullptr);
grpc_channel_credentials_release(creds);
- grpc_slice host = grpc_slice_from_static_string("nonexistant");
+ grpc_slice host = grpc_slice_from_static_string("nonexistent");
g_state.call = grpc_channel_create_call(
g_state.chan, nullptr, GRPC_PROPAGATE_DEFAULTS, g_state.cq,
grpc_slice_from_static_string("/Foo"), &host, g_state.deadline,
diff --git a/test/core/end2end/no_server_test.cc b/test/core/end2end/no_server_test.cc
index 4b14f0a1a72..6f16b24ca6b 100644
--- a/test/core/end2end/no_server_test.cc
+++ b/test/core/end2end/no_server_test.cc
@@ -57,10 +57,10 @@ void run_test(bool wait_for_ready) {
grpc_core::MakeRefCounted();
auto args = grpc_core::ChannelArgs().SetObject(response_generator).ToC();
- // create a call, channel to a non existant server
+ // create a call, channel to a non existent server
grpc_channel_credentials* creds = grpc_insecure_credentials_create();
grpc_channel* chan =
- grpc_channel_create("fake:nonexistant", creds, args.get());
+ grpc_channel_create("fake:nonexistent", creds, args.get());
grpc_channel_credentials_release(creds);
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2);
grpc_call* call = grpc_channel_create_call(
diff --git a/test/core/end2end/tests/max_connection_age.cc b/test/core/end2end/tests/max_connection_age.cc
index f2d0d88a51b..3b13e36458e 100644
--- a/test/core/end2end/tests/max_connection_age.cc
+++ b/test/core/end2end/tests/max_connection_age.cc
@@ -20,6 +20,7 @@
#include
+#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include
@@ -109,6 +110,8 @@ CORE_END2END_TEST(Http2Test, MaxAgeForciblyClose) {
// The connection should be closed immediately after the max age grace period,
// the in-progress RPC should fail.
EXPECT_EQ(server_status.status(), GRPC_STATUS_UNAVAILABLE);
+ EXPECT_THAT(server_status.message(),
+ ::testing::MatchesRegex("max connection age"));
}
CORE_END2END_TEST(Http2Test, MaxAgeGracefullyClose) {
@@ -162,10 +165,12 @@ CORE_END2END_TEST(Http2Test, MaxAgeGracefullyClose) {
Expect(101, false);
}
Step();
- // The connection is closed gracefully with goaway, the rpc should still be
- // completed.
- EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
- EXPECT_EQ(server_status.message(), "xyz");
+ if (got_server) {
+ // The connection is closed gracefully with goaway, the rpc should still be
+ // completed.
+ EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
+ EXPECT_EQ(server_status.message(), "xyz");
+ }
}
} // namespace
diff --git a/test/core/end2end/tests/no_logging.cc b/test/core/end2end/tests/no_logging.cc
index 1ffb8116d8c..c6d9db38d16 100644
--- a/test/core/end2end/tests/no_logging.cc
+++ b/test/core/end2end/tests/no_logging.cc
@@ -99,7 +99,7 @@ class VerifyLogNoiseLogSink : public absl::LogSink {
std::regex("Failed to bind some addresses for.*")},
{"log.cc",
std::regex("Prefer WARNING or ERROR. However if you see this "
- "message in a debug environmenmt or test environmenmt "
+ "message in a debug environment or test environment "
"it is safe to ignore this message.")}});
if (IsVlogWithVerbosityMoreThan1(entry)) {
diff --git a/test/core/event_engine/test_suite/tests/dns_test.cc b/test/core/event_engine/test_suite/tests/dns_test.cc
index 9af554f61e4..635a796a1e4 100644
--- a/test/core/event_engine/test_suite/tests/dns_test.cc
+++ b/test/core/event_engine/test_suite/tests/dns_test.cc
@@ -557,7 +557,7 @@ TEST_F(EventEngineDNSTest, InvalidIPv6Addresses) {
&dns_resolver_signal_, "[2001:db8::11111]:1");
}
-void TestUnparseableHostPort(
+void TestUnparsableHostPort(
std::unique_ptr dns_resolver,
grpc_core::Notification* barrier, absl::string_view target) {
dns_resolver->LookupHostname(
@@ -569,38 +569,38 @@ void TestUnparseableHostPort(
barrier->WaitForNotification();
}
-TEST_F(EventEngineDNSTest, UnparseableHostPortsOnlyBracket) {
- TestUnparseableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
- &dns_resolver_signal_, "[");
+TEST_F(EventEngineDNSTest, UnparsableHostPortsOnlyBracket) {
+ TestUnparsableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
+ &dns_resolver_signal_, "[");
}
-TEST_F(EventEngineDNSTest, UnparseableHostPortsMissingRightBracket) {
- TestUnparseableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
- &dns_resolver_signal_, "[::1");
+TEST_F(EventEngineDNSTest, UnparsableHostPortsMissingRightBracket) {
+ TestUnparsableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
+ &dns_resolver_signal_, "[::1");
}
-TEST_F(EventEngineDNSTest, UnparseableHostPortsBadPort) {
- TestUnparseableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
- &dns_resolver_signal_, "[::1]bad");
+TEST_F(EventEngineDNSTest, UnparsableHostPortsBadPort) {
+ TestUnparsableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
+ &dns_resolver_signal_, "[::1]bad");
}
-TEST_F(EventEngineDNSTest, UnparseableHostPortsBadIPv6) {
- TestUnparseableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
- &dns_resolver_signal_, "[1.2.3.4]");
+TEST_F(EventEngineDNSTest, UnparsableHostPortsBadIPv6) {
+ TestUnparsableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
+ &dns_resolver_signal_, "[1.2.3.4]");
}
-TEST_F(EventEngineDNSTest, UnparseableHostPortsBadLocalhost) {
- TestUnparseableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
- &dns_resolver_signal_, "[localhost]");
+TEST_F(EventEngineDNSTest, UnparsableHostPortsBadLocalhost) {
+ TestUnparsableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
+ &dns_resolver_signal_, "[localhost]");
}
-TEST_F(EventEngineDNSTest, UnparseableHostPortsBadLocalhostWithPort) {
- TestUnparseableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
- &dns_resolver_signal_, "[localhost]:1");
+TEST_F(EventEngineDNSTest, UnparsableHostPortsBadLocalhostWithPort) {
+ TestUnparsableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
+ &dns_resolver_signal_, "[localhost]:1");
}
-TEST_F(EventEngineDNSTest, UnparseableHostPortsEmptyHostname) {
- TestUnparseableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
- &dns_resolver_signal_, ":443");
+TEST_F(EventEngineDNSTest, UnparsableHostPortsEmptyHostname) {
+ TestUnparsableHostPort(CreateDNSResolverWithoutSpecifyingServer(),
+ &dns_resolver_signal_, ":443");
}
// END
diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc
index ec5834646dc..ec18410a267 100644
--- a/test/core/iomgr/resolve_address_test.cc
+++ b/test/core/iomgr/resolve_address_test.cc
@@ -240,7 +240,7 @@ const address_sorting_source_addr_factory_vtable
} // namespace
-TEST_F(ResolveAddressTest, LocalhostResultHasIPv4FirstWhenIPv6IsntAvalailable) {
+TEST_F(ResolveAddressTest, LocalhostResultHasIPv4FirstWhenIPv6IsntAvailable) {
if (std::string(g_resolver_type) != "ares") {
GTEST_SKIP() << "this test is only valid with the c-ares resolver";
}
@@ -326,7 +326,7 @@ TEST_F(ResolveAddressTest, InvalidIPv6Addresses) {
TestInvalidIPAddress(this, "[2001:db8::11111]:1");
}
-void TestUnparseableHostPort(ResolveAddressTest* test, const char* target) {
+void TestUnparsableHostPort(ResolveAddressTest* test, const char* target) {
grpc_core::ExecCtx exec_ctx;
grpc_core::GetDNSResolver()->LookupHostname(
absl::bind_front(&ResolveAddressTest::MustFail, test), target, "1",
@@ -335,28 +335,28 @@ void TestUnparseableHostPort(ResolveAddressTest* test, const char* target) {
test->PollPollsetUntilRequestDone();
}
-TEST_F(ResolveAddressTest, UnparseableHostPortsOnlyBracket) {
- TestUnparseableHostPort(this, "[");
+TEST_F(ResolveAddressTest, UnparsableHostPortsOnlyBracket) {
+ TestUnparsableHostPort(this, "[");
}
-TEST_F(ResolveAddressTest, UnparseableHostPortsMissingRightBracket) {
- TestUnparseableHostPort(this, "[::1");
+TEST_F(ResolveAddressTest, UnparsableHostPortsMissingRightBracket) {
+ TestUnparsableHostPort(this, "[::1");
}
-TEST_F(ResolveAddressTest, UnparseableHostPortsBadPort) {
- TestUnparseableHostPort(this, "[::1]bad");
+TEST_F(ResolveAddressTest, UnparsableHostPortsBadPort) {
+ TestUnparsableHostPort(this, "[::1]bad");
}
-TEST_F(ResolveAddressTest, UnparseableHostPortsBadIPv6) {
- TestUnparseableHostPort(this, "[1.2.3.4]");
+TEST_F(ResolveAddressTest, UnparsableHostPortsBadIPv6) {
+ TestUnparsableHostPort(this, "[1.2.3.4]");
}
-TEST_F(ResolveAddressTest, UnparseableHostPortsBadLocalhost) {
- TestUnparseableHostPort(this, "[localhost]");
+TEST_F(ResolveAddressTest, UnparsableHostPortsBadLocalhost) {
+ TestUnparsableHostPort(this, "[localhost]");
}
-TEST_F(ResolveAddressTest, UnparseableHostPortsBadLocalhostWithPort) {
- TestUnparseableHostPort(this, "[localhost]:1");
+TEST_F(ResolveAddressTest, UnparsableHostPortsBadLocalhostWithPort) {
+ TestUnparsableHostPort(this, "[localhost]:1");
}
// Kick off a simple DNS resolution and then immediately cancel. This
diff --git a/test/core/iomgr/timer_list_test.cc b/test/core/iomgr/timer_list_test.cc
index e3064c299ff..e3c98e83780 100644
--- a/test/core/iomgr/timer_list_test.cc
+++ b/test/core/iomgr/timer_list_test.cc
@@ -47,6 +47,8 @@ static void cb(void* arg, grpc_error_handle error) {
}
static void add_test(void) {
+ if (grpc_core::IsTimeCachingInPartyEnabled()) return;
+
int i;
grpc_timer timers[20];
grpc_core::ExecCtx exec_ctx;
@@ -116,6 +118,8 @@ static void add_test(void) {
// Cleaning up a list with pending timers.
void destruction_test(void) {
+ if (grpc_core::IsTimeCachingInPartyEnabled()) return;
+
grpc_timer timers[5];
grpc_core::ExecCtx exec_ctx;
@@ -173,6 +177,8 @@ void destruction_test(void) {
// 4) Shuts down the timer list
// https://github.com/grpc/grpc/issues/15904
void long_running_service_cleanup_test(void) {
+ if (grpc_core::IsTimeCachingInPartyEnabled()) return;
+
grpc_timer timers[4];
grpc_core::ExecCtx exec_ctx;
diff --git a/test/core/load_balancing/bm_picker.cc b/test/core/load_balancing/bm_picker.cc
index fb16691674e..51aee364d3f 100644
--- a/test/core/load_balancing/bm_picker.cc
+++ b/test/core/load_balancing/bm_picker.cc
@@ -124,6 +124,8 @@ class BenchmarkHelper : public std::enable_shared_from_this {
void CancelDataWatcher(DataWatcherInterface* watcher) override {}
+ std::string address() const override { return "test"; }
+
private:
void AddConnectivityWatcherInternal(
std::shared_ptr watcher) {
diff --git a/test/core/load_balancing/lb_policy_test_lib.h b/test/core/load_balancing/lb_policy_test_lib.h
index fcd85c8928e..3066fbbc590 100644
--- a/test/core/load_balancing/lb_policy_test_lib.h
+++ b/test/core/load_balancing/lb_policy_test_lib.h
@@ -121,6 +121,8 @@ class LoadBalancingPolicyTest : public ::testing::Test {
SubchannelState* state() const { return state_; }
+ std::string address() const override { return state_->address_; }
+
private:
// Converts between
// SubchannelInterface::ConnectivityStateWatcherInterface and
diff --git a/test/core/load_balancing/rls_lb_config_parser_test.cc b/test/core/load_balancing/rls_lb_config_parser_test.cc
index 0c1da6ef8c3..1bfef19d2df 100644
--- a/test/core/load_balancing/rls_lb_config_parser_test.cc
+++ b/test/core/load_balancing/rls_lb_config_parser_test.cc
@@ -90,7 +90,7 @@ TEST_F(RlsConfigParsingTest, TopLevelRequiredFieldsMissing) {
EXPECT_THAT(
service_config.status().message(),
::testing::HasSubstr(
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:childPolicy error:field not present; "
"field:childPolicyConfigTargetFieldName error:field not present; "
"field:routeLookupConfig error:field not present]"))
@@ -115,7 +115,7 @@ TEST_F(RlsConfigParsingTest, TopLevelFieldsWrongTypes) {
EXPECT_EQ(service_config.status().message(),
"errors validating service config: ["
"field:loadBalancingConfig "
- "error:errors validing RLS LB policy config: ["
+ "error:errors validating RLS LB policy config: ["
"field:childPolicy error:is not an array; "
"field:childPolicyConfigTargetFieldName error:is not a string; "
"field:routeLookupChannelServiceConfig error:is not an object; "
@@ -141,7 +141,7 @@ TEST_F(RlsConfigParsingTest, TopLevelFieldsInvalidValues) {
EXPECT_THAT(
service_config.status().message(),
::testing::HasSubstr(
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:childPolicy error:No known policies in list: unknown; "
"field:childPolicyConfigTargetFieldName error:must be non-empty; "
"field:routeLookupConfig error:field not present]"))
@@ -165,7 +165,7 @@ TEST_F(RlsConfigParsingTest, InvalidChildPolicyConfig) {
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
service_config.status().message(),
- ::testing::HasSubstr("errors validing RLS LB policy config: ["
+ ::testing::HasSubstr("errors validating RLS LB policy config: ["
"field:childPolicy error:"
"errors validating grpclb LB policy config: ["
"field:childPolicy error:type should be array]; "
@@ -194,7 +194,7 @@ TEST_F(RlsConfigParsingTest, InvalidRlsChannelServiceConfig) {
EXPECT_EQ(service_config.status().message(),
"errors validating service config: ["
"field:loadBalancingConfig "
- "error:errors validing RLS LB policy config: ["
+ "error:errors validating RLS LB policy config: ["
"field:routeLookupChannelServiceConfig.loadBalancingPolicy "
"error:unknown LB policy \"unknown\"; "
"field:routeLookupConfig error:field not present]]")
@@ -221,7 +221,7 @@ TEST_F(RlsConfigParsingTest, RouteLookupConfigRequiredFieldsMissing) {
EXPECT_THAT(
service_config.status().message(),
::testing::HasSubstr(
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:childPolicy error:field not present; "
"field:childPolicyConfigTargetFieldName error:field not present; "
"field:routeLookupConfig.cacheSizeBytes error:field not present; "
@@ -254,7 +254,7 @@ TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsWrongTypes) {
EXPECT_THAT(
service_config.status().message(),
::testing::HasSubstr(
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:childPolicy error:field not present; "
"field:childPolicyConfigTargetFieldName error:field not present; "
"field:routeLookupConfig.cacheSizeBytes error:"
@@ -286,7 +286,7 @@ TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsInvalidValues) {
EXPECT_THAT(
service_config.status().message(),
::testing::HasSubstr(
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:childPolicy error:field not present; "
"field:childPolicyConfigTargetFieldName error:field not present; "
"field:routeLookupConfig.cacheSizeBytes error:"
@@ -321,7 +321,7 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderRequiredFieldsMissing) {
EXPECT_THAT(
service_config.status().message(),
::testing::HasSubstr(
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:childPolicy error:field not present; "
"field:childPolicyConfigTargetFieldName error:field not present; "
"field:routeLookupConfig.cacheSizeBytes error:field not present; "
@@ -355,7 +355,7 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderWrongFieldTypes) {
EXPECT_THAT(
service_config.status().message(),
::testing::HasSubstr(
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:childPolicy error:field not present; "
"field:childPolicyConfigTargetFieldName error:field not present; "
"field:routeLookupConfig.cacheSizeBytes error:field not present; "
@@ -400,7 +400,7 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidValues) {
EXPECT_THAT(
service_config.status().message(),
::testing::HasSubstr(
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:childPolicy error:field not present; "
"field:childPolicyConfigTargetFieldName error:field not present; "
"field:routeLookupConfig.cacheSizeBytes error:field not present; "
@@ -458,7 +458,7 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidHeaders) {
EXPECT_THAT(
service_config.status().message(),
::testing::HasSubstr(
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:childPolicy error:field not present; "
"field:childPolicyConfigTargetFieldName error:field not present; "
"field:routeLookupConfig.cacheSizeBytes error:field not present; "
@@ -515,7 +515,7 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderNameWrongFieldTypes) {
EXPECT_THAT(
service_config.status().message(),
::testing::HasSubstr(
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:childPolicy error:field not present; "
"field:childPolicyConfigTargetFieldName error:field not present; "
"field:routeLookupConfig.cacheSizeBytes error:field not present; "
@@ -559,7 +559,7 @@ TEST_F(RlsConfigParsingTest, DuplicateMethodNamesInSameKeyBuilder) {
EXPECT_THAT(
service_config.status().message(),
::testing::HasSubstr(
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:childPolicy error:field not present; "
"field:childPolicyConfigTargetFieldName error:field not present; "
"field:routeLookupConfig.cacheSizeBytes error:field not present; "
@@ -603,7 +603,7 @@ TEST_F(RlsConfigParsingTest, DuplicateMethodNamesInDifferentKeyBuilders) {
EXPECT_THAT(
service_config.status().message(),
::testing::HasSubstr(
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:childPolicy error:field not present; "
"field:childPolicyConfigTargetFieldName error:field not present; "
"field:routeLookupConfig.cacheSizeBytes error:field not present; "
diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc
index 721a02f6e33..4a999142988 100644
--- a/test/core/security/credentials_test.cc
+++ b/test/core/security/credentials_test.cc
@@ -213,7 +213,7 @@ const char
"\"headers\":{\"Metadata-Flavor\":\"Google\"}}";
const char
- valid_url_external_account_creds_options_credential_source_with_qurey_params_format_text
+ valid_url_external_account_creds_options_credential_source_with_query_params_format_text
[] = "{\"url\":\"https://foo.com:5555/"
"path/to/url/creds?p1=v1&p2=v2\","
"\"headers\":{\"Metadata-Flavor\":\"Google\"}}";
@@ -2122,7 +2122,7 @@ TEST_F(CredentialsTest, TestAuthMetadataContext) {
}
}
-void validate_external_account_creds_token_exchage_request(
+void validate_external_account_creds_token_exchange_request(
const grpc_http_request* request, const URI& request_uri,
absl::string_view body) {
// Check that the body is constructed properly.
@@ -2154,7 +2154,7 @@ void validate_external_account_creds_token_exchage_request(
"Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=");
}
-void validate_external_account_creds_token_exchage_request_with_url_encode(
+void validate_external_account_creds_token_exchange_request_with_url_encode(
const grpc_http_request* request, const URI& uri, absl::string_view body) {
// Check that the body is constructed properly.
EXPECT_EQ(
@@ -2214,7 +2214,7 @@ int external_acc_creds_serv_acc_imp_custom_lifetime_httpcli_post_success(
Timestamp /*deadline*/, grpc_closure* on_done,
grpc_http_response* response) {
if (uri.path() == "/token") {
- validate_external_account_creds_token_exchage_request(request, uri, body);
+ validate_external_account_creds_token_exchange_request(request, uri, body);
*response = http_response(
200, valid_external_account_creds_token_exchange_response);
} else if (uri.path() == "/service_account_impersonation") {
@@ -2233,7 +2233,7 @@ int external_account_creds_httpcli_post_success(
Timestamp /*deadline*/, grpc_closure* on_done,
grpc_http_response* response) {
if (uri.path() == "/token") {
- validate_external_account_creds_token_exchage_request(request, uri, body);
+ validate_external_account_creds_token_exchange_request(request, uri, body);
*response = http_response(
200, valid_external_account_creds_token_exchange_response);
} else if (uri.path() == "/service_account_impersonation") {
@@ -2243,7 +2243,7 @@ int external_account_creds_httpcli_post_success(
200,
valid_external_account_creds_service_account_impersonation_response);
} else if (uri.path() == "/token_url_encode") {
- validate_external_account_creds_token_exchage_request_with_url_encode(
+ validate_external_account_creds_token_exchange_request_with_url_encode(
request, uri, body);
*response = http_response(
200, valid_external_account_creds_token_exchange_response);
@@ -2291,7 +2291,7 @@ int url_external_account_creds_httpcli_get_success(
return 1;
}
-void validate_aws_external_account_creds_token_exchage_request(
+void validate_aws_external_account_creds_token_exchange_request(
const grpc_http_request* request, const URI& request_uri,
absl::string_view body) {
// Check that the regional_cred_verification_url got constructed
@@ -2380,8 +2380,8 @@ int aws_external_account_creds_httpcli_post_success(
Timestamp /*deadline*/, grpc_closure* on_done,
grpc_http_response* response) {
if (uri.path() == "/token") {
- validate_aws_external_account_creds_token_exchage_request(request, uri,
- body);
+ validate_aws_external_account_creds_token_exchange_request(request, uri,
+ body);
*response = http_response(
200, valid_external_account_creds_token_exchange_response);
}
@@ -2492,6 +2492,7 @@ TEST_F(TokenFetcherCredentialsTest, Basic) {
ExecCtx exec_ctx;
creds_->AddResult(MakeToken("foo", kExpirationTime));
// First request will trigger a fetch.
+ LOG(INFO) << "First request";
auto state = RequestMetadataState::NewInstance(
absl::OkStatus(), "authorization: foo", /*expect_delay=*/true);
state->RunRequestMetadataTest(creds_.get(), kTestUrlScheme, kTestAuthority,
@@ -2499,6 +2500,7 @@ TEST_F(TokenFetcherCredentialsTest, Basic) {
EXPECT_EQ(creds_->num_fetches(), 1);
// Second request while fetch is still outstanding will be delayed but
// will not trigger a new fetch.
+ LOG(INFO) << "Second request";
state = RequestMetadataState::NewInstance(
absl::OkStatus(), "authorization: foo", /*expect_delay=*/true);
state->RunRequestMetadataTest(creds_.get(), kTestUrlScheme, kTestAuthority,
@@ -2507,6 +2509,7 @@ TEST_F(TokenFetcherCredentialsTest, Basic) {
// Now tick to finish the fetch.
event_engine_->TickUntilIdle();
// Next request will be served from cache with no delay.
+ LOG(INFO) << "Third request";
state = RequestMetadataState::NewInstance(
absl::OkStatus(), "authorization: foo", /*expect_delay=*/false);
state->RunRequestMetadataTest(creds_.get(), kTestUrlScheme, kTestAuthority,
@@ -2519,6 +2522,7 @@ TEST_F(TokenFetcherCredentialsTest, Basic) {
// Next request will trigger a new fetch but will still use the
// cached token.
creds_->AddResult(MakeToken("bar"));
+ LOG(INFO) << "Fourth request";
state = RequestMetadataState::NewInstance(
absl::OkStatus(), "authorization: foo", /*expect_delay=*/false);
state->RunRequestMetadataTest(creds_.get(), kTestUrlScheme, kTestAuthority,
@@ -2526,6 +2530,7 @@ TEST_F(TokenFetcherCredentialsTest, Basic) {
EXPECT_EQ(creds_->num_fetches(), 2);
event_engine_->TickUntilIdle();
// Next request will use the new data.
+ LOG(INFO) << "Fifth request";
state = RequestMetadataState::NewInstance(
absl::OkStatus(), "authorization: bar", /*expect_delay=*/false);
state->RunRequestMetadataTest(creds_.get(), kTestUrlScheme, kTestAuthority,
@@ -3200,12 +3205,12 @@ TEST_F(ExternalAccountCredentialsTest,
}
TEST_F(ExternalAccountCredentialsTest,
- UrlExternalAccountCredsSuccessWithQureyParamsFormatText) {
+ UrlExternalAccountCredsSuccessWithQueryParamsFormatText) {
std::map emd = {
{"authorization", "Bearer token_exchange_access_token"}};
ExecCtx exec_ctx;
auto credential_source = JsonParse(
- valid_url_external_account_creds_options_credential_source_with_qurey_params_format_text);
+ valid_url_external_account_creds_options_credential_source_with_query_params_format_text);
ASSERT_TRUE(credential_source.ok()) << credential_source.status();
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
@@ -4464,7 +4469,7 @@ TEST_F(CredentialsTest, TestTlsCredentialsWithVerifierCompareFailure) {
grpc_channel_credentials_release(tls_creds_2);
}
-TEST_F(CredentialsTest, TestXdsCredentialsCompareSucces) {
+TEST_F(CredentialsTest, TestXdsCredentialsCompareSuccess) {
auto* insecure_creds = grpc_insecure_credentials_create();
auto* xds_creds_1 = grpc_xds_credentials_create(insecure_creds);
auto* xds_creds_2 = grpc_xds_credentials_create(insecure_creds);
diff --git a/test/core/surface/server_chttp2_test.cc b/test/core/surface/server_chttp2_test.cc
index d3fd84b544b..9c11f06037d 100644
--- a/test/core/surface/server_chttp2_test.cc
+++ b/test/core/surface/server_chttp2_test.cc
@@ -32,7 +32,7 @@
#include "test/core/test_util/port.h"
#include "test/core/test_util/test_config.h"
-TEST(ServerChttp2, UnparseableTarget) {
+TEST(ServerChttp2, UnparsableTarget) {
grpc_channel_args args = {0, nullptr};
grpc_server* server = grpc_server_create(&args, nullptr);
grpc_server_credentials* server_creds =
diff --git a/test/core/test_util/BUILD b/test/core/test_util/BUILD
index 12ae1064e45..653c1639a25 100644
--- a/test/core/test_util/BUILD
+++ b/test/core/test_util/BUILD
@@ -395,7 +395,10 @@ grpc_cc_library(
testonly = True,
srcs = ["socket_use_after_close_detector.cc"],
hdrs = ["socket_use_after_close_detector.h"],
- external_deps = ["gtest"],
+ external_deps = [
+ "absl/log:log",
+ "gtest",
+ ],
language = "C++",
deps = [
"grpc_test_util",
diff --git a/test/core/test_util/socket_use_after_close_detector.cc b/test/core/test_util/socket_use_after_close_detector.cc
index ab55cbacfae..8d2c77b2555 100644
--- a/test/core/test_util/socket_use_after_close_detector.cc
+++ b/test/core/test_util/socket_use_after_close_detector.cc
@@ -33,6 +33,7 @@
#include
#include
+#include "absl/log/log.h"
#include "gtest/gtest.h"
#include
@@ -40,71 +41,17 @@
#include "src/core/lib/iomgr/sockaddr.h"
#include "test/core/test_util/port.h"
-// TODO(unknown): pull in different headers when enabling this
-// test on windows. Also set BAD_SOCKET_RETURN_VAL
-// to INVALID_SOCKET on windows.
-#ifdef GPR_WINDOWS
-#include "src/core/lib/iomgr/socket_windows.h"
-#include "src/core/lib/iomgr/tcp_windows.h"
-
-#define BAD_SOCKET_RETURN_VAL INVALID_SOCKET
-#else
#define BAD_SOCKET_RETURN_VAL (-1)
-#endif
namespace {
#ifdef GPR_WINDOWS
void OpenAndCloseSocketsStressLoop(int port, gpr_event* done_ev) {
- sockaddr_in6 addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin6_family = AF_INET6;
- addr.sin6_port = htons(port);
- ((char*)&addr.sin6_addr)[15] = 1;
- for (;;) {
- if (gpr_event_get(done_ev)) {
- return;
- }
- std::vector sockets;
- for (size_t i = 0; i < 50; i++) {
- SOCKET s = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0,
- WSA_FLAG_OVERLAPPED);
- ASSERT_TRUE(s != BAD_SOCKET_RETURN_VAL)
- << "Failed to create TCP ipv6 socket";
- char val = 1;
- ASSERT_TRUE(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) !=
- SOCKET_ERROR)
- << "Failed to set socketopt reuseaddr. WSA error: " +
- std::to_string(WSAGetLastError());
- ASSERT_TRUE(grpc_tcp_set_non_block(s) == absl::OkStatus())
- << "Failed to set socket non-blocking";
- ASSERT_TRUE(bind(s, (const sockaddr*)&addr, sizeof(addr)) != SOCKET_ERROR)
- << "Failed to bind socket " + std::to_string(s) +
- " to [::1]:" + std::to_string(port) +
- ". WSA error: " + std::to_string(WSAGetLastError());
- ASSERT_TRUE(listen(s, 1) != SOCKET_ERROR)
- << "Failed to listen on socket " + std::to_string(s) +
- ". WSA error: " + std::to_string(WSAGetLastError());
- sockets.push_back(s);
- }
- // Do a non-blocking accept followed by a close on all of those sockets.
- // Do this in a separate loop to try to induce a time window to hit races.
- for (size_t i = 0; i < sockets.size(); i++) {
- ASSERT_TRUE(accept(sockets[i], nullptr, nullptr) == INVALID_SOCKET)
- << "Accept on phony socket unexpectedly accepted actual connection.";
- ASSERT_TRUE(WSAGetLastError() == WSAEWOULDBLOCK)
- << "OpenAndCloseSocketsStressLoop accept on socket " +
- std::to_string(sockets[i]) +
- " failed in "
- "an unexpected way. "
- "WSA error: " +
- std::to_string(WSAGetLastError()) +
- ". Socket use-after-close bugs are likely.";
- ASSERT_TRUE(closesocket(sockets[i]) != SOCKET_ERROR)
- << "Failed to close socket: " + std::to_string(sockets[i]) +
- ". WSA error: " + std::to_string(WSAGetLastError());
- }
- }
+ // TODO(apolcyn): re-enable this on windows if we can debug the failure.
+ // Previously, this was causing test flakes for a while b/c bind calls
+ // would fail with WSAEACCESS. Not clear if we were just making windows
+ // unhappy.
+ LOG(INFO) << "OpenAndCloseSocketsStressLoop is a no-op for windows";
return;
}
#else
diff --git a/test/core/transport/call_state_test.cc b/test/core/transport/call_state_test.cc
index cc35b5b7ec5..c8dcca2825b 100644
--- a/test/core/transport/call_state_test.cc
+++ b/test/core/transport/call_state_test.cc
@@ -245,7 +245,6 @@ TEST(CallStateTest, ReceiveTrailersOnly) {
EXPECT_THAT(state.PollPullServerInitialMetadataAvailable(), IsReady(false));
state.FinishPullServerInitialMetadata();
EXPECT_THAT(state.PollServerTrailingMetadataAvailable(), IsReady());
- state.FinishPullServerTrailingMetadata();
}
TEST(CallStateTest, ReceiveTrailersOnlySkipsInitialMetadataOnUnstartedCalls) {
@@ -256,7 +255,6 @@ TEST(CallStateTest, ReceiveTrailersOnlySkipsInitialMetadataOnUnstartedCalls) {
EXPECT_THAT(state.PollPullServerInitialMetadataAvailable(), IsReady(false));
state.FinishPullServerInitialMetadata();
EXPECT_THAT(state.PollServerTrailingMetadataAvailable(), IsReady());
- state.FinishPullServerTrailingMetadata();
}
TEST(CallStateTest, RecallNoCancellation) {
@@ -268,8 +266,6 @@ TEST(CallStateTest, RecallNoCancellation) {
EXPECT_THAT(state.PollPullServerInitialMetadataAvailable(), IsReady(false));
state.FinishPullServerInitialMetadata();
EXPECT_THAT(state.PollServerTrailingMetadataAvailable(), IsReady());
- EXPECT_THAT(state.PollWasCancelled(), IsPending());
- EXPECT_WAKEUP(activity, state.FinishPullServerTrailingMetadata());
EXPECT_THAT(state.PollWasCancelled(), IsReady(false));
}
@@ -282,8 +278,6 @@ TEST(CallStateTest, RecallCancellation) {
EXPECT_THAT(state.PollPullServerInitialMetadataAvailable(), IsReady(false));
state.FinishPullServerInitialMetadata();
EXPECT_THAT(state.PollServerTrailingMetadataAvailable(), IsReady());
- EXPECT_THAT(state.PollWasCancelled(), IsPending());
- EXPECT_WAKEUP(activity, state.FinishPullServerTrailingMetadata());
EXPECT_THAT(state.PollWasCancelled(), IsReady(true));
}
diff --git a/test/core/transport/chttp2/too_many_pings_test.cc b/test/core/transport/chttp2/too_many_pings_test.cc
index 8fd0570616f..7d84bdb0bdc 100644
--- a/test/core/transport/chttp2/too_many_pings_test.cc
+++ b/test/core/transport/chttp2/too_many_pings_test.cc
@@ -123,7 +123,7 @@ grpc_status_code PerformCall(grpc_channel* channel, grpc_server* server,
grpc_status_code status;
grpc_call_error error;
grpc_slice details;
- gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
+ gpr_timespec deadline = grpc_timeout_seconds_to_deadline(30);
// Start a call
c = grpc_channel_create_call(channel, nullptr, GRPC_PROPAGATE_DEFAULTS, cq,
grpc_slice_from_static_string("/foo"), nullptr,
diff --git a/test/core/xds/xds_client_test.cc b/test/core/xds/xds_client_test.cc
index a970e217360..9ad6dce3d59 100644
--- a/test/core/xds/xds_client_test.cc
+++ b/test/core/xds/xds_client_test.cc
@@ -3506,7 +3506,7 @@ TEST_F(XdsClientTest, FederationWithUnknownAuthority) {
<< *error;
}
-TEST_F(XdsClientTest, FederationWithUnparseableXdstpResourceName) {
+TEST_F(XdsClientTest, FederationWithUnparsableXdstpResourceName) {
// Note: Not adding authority to bootstrap config.
InitXdsClient();
// Start a watch for the xdstp resource name.
diff --git a/test/core/xds/xds_cluster_resource_type_test.cc b/test/core/xds/xds_cluster_resource_type_test.cc
index 23ce91782d3..2ce68f2e0a3 100644
--- a/test/core/xds/xds_cluster_resource_type_test.cc
+++ b/test/core/xds/xds_cluster_resource_type_test.cc
@@ -136,7 +136,7 @@ TEST_F(XdsClusterTest, Definition) {
EXPECT_TRUE(resource_type->AllResourcesRequiredInSotW());
}
-TEST_F(XdsClusterTest, UnparseableProto) {
+TEST_F(XdsClusterTest, UnparsableProto) {
std::string serialized_resource("\0", 1);
auto* resource_type = XdsClusterResourceType::Get();
auto decode_result =
@@ -586,7 +586,7 @@ TEST_F(ClusterTypeTest, AggregateClusterValid) {
::testing::ElementsAre("bar", "baz", "quux"));
}
-TEST_F(ClusterTypeTest, AggregateClusterUnparseableProto) {
+TEST_F(ClusterTypeTest, AggregateClusterUnparsableProto) {
Cluster cluster;
cluster.set_name("foo");
cluster.mutable_cluster_type()->set_name("envoy.clusters.aggregate");
@@ -1031,7 +1031,7 @@ TEST_F(TlsConfigTest, UnknownTransportSocketType) {
<< decode_result.resource.status();
}
-TEST_F(TlsConfigTest, UnparseableUpstreamTlsContext) {
+TEST_F(TlsConfigTest, UnparsableUpstreamTlsContext) {
Cluster cluster;
cluster.set_name("foo");
cluster.set_type(cluster.EDS);
@@ -1275,7 +1275,7 @@ TEST_F(UpstreamConfigTest, UnknownUpstreamConfigType) {
<< decode_result.resource.status();
}
-TEST_F(UpstreamConfigTest, UnparseableHttpProtocolOptions) {
+TEST_F(UpstreamConfigTest, UnparsableHttpProtocolOptions) {
Cluster cluster;
cluster.set_name("foo");
cluster.set_type(cluster.EDS);
diff --git a/test/core/xds/xds_endpoint_resource_type_test.cc b/test/core/xds/xds_endpoint_resource_type_test.cc
index bd365c63836..353e5727a5f 100644
--- a/test/core/xds/xds_endpoint_resource_type_test.cc
+++ b/test/core/xds/xds_endpoint_resource_type_test.cc
@@ -111,7 +111,7 @@ TEST_F(XdsEndpointTest, Definition) {
EXPECT_FALSE(resource_type->AllResourcesRequiredInSotW());
}
-TEST_F(XdsEndpointTest, UnparseableProto) {
+TEST_F(XdsEndpointTest, UnparsableProto) {
std::string serialized_resource("\0", 1);
auto* resource_type = XdsEndpointResourceType::Get();
auto decode_result =
diff --git a/test/core/xds/xds_http_filters_test.cc b/test/core/xds/xds_http_filters_test.cc
index f1811d7c6ad..c720f72fef5 100644
--- a/test/core/xds/xds_http_filters_test.cc
+++ b/test/core/xds/xds_http_filters_test.cc
@@ -238,7 +238,7 @@ TEST_F(XdsRouterFilterTest, GenerateFilterConfigTypedStruct) {
<< status;
}
-TEST_F(XdsRouterFilterTest, GenerateFilterConfigUnparseable) {
+TEST_F(XdsRouterFilterTest, GenerateFilterConfigUnparsable) {
XdsExtension extension = MakeXdsExtension(Router());
std::string serialized_resource("\0", 1);
extension.value = absl::string_view(serialized_resource);
@@ -469,7 +469,7 @@ TEST_P(XdsFaultInjectionFilterConfigTest, TypedStruct) {
<< status;
}
-TEST_P(XdsFaultInjectionFilterConfigTest, Unparseable) {
+TEST_P(XdsFaultInjectionFilterConfigTest, Unparsable) {
XdsExtension extension = MakeXdsExtension(HTTPFault());
std::string serialized_resource("\0", 1);
extension.value = absl::string_view(serialized_resource);
@@ -544,7 +544,7 @@ TEST_F(XdsRbacFilterTest, GenerateFilterConfigTypedStruct) {
<< status;
}
-TEST_F(XdsRbacFilterTest, GenerateFilterConfigUnparseable) {
+TEST_F(XdsRbacFilterTest, GenerateFilterConfigUnparsable) {
XdsExtension extension = MakeXdsExtension(RBAC());
std::string serialized_resource("\0", 1);
extension.value = absl::string_view(serialized_resource);
@@ -587,7 +587,7 @@ TEST_F(XdsRbacFilterTest, GenerateFilterConfigOverrideTypedStruct) {
<< status;
}
-TEST_F(XdsRbacFilterTest, GenerateFilterConfigOverrideUnparseable) {
+TEST_F(XdsRbacFilterTest, GenerateFilterConfigOverrideUnparsable) {
XdsExtension extension = MakeXdsExtension(RBACPerRoute());
std::string serialized_resource("\0", 1);
extension.value = absl::string_view(serialized_resource);
@@ -1219,7 +1219,7 @@ TEST_F(XdsStatefulSessionFilterTest, GenerateFilterConfigTypedStruct) {
<< status;
}
-TEST_F(XdsStatefulSessionFilterTest, GenerateFilterConfigUnparseable) {
+TEST_F(XdsStatefulSessionFilterTest, GenerateFilterConfigUnparsable) {
XdsExtension extension = MakeXdsExtension(StatefulSession());
std::string serialized_resource("\0", 1);
extension.value = absl::string_view(serialized_resource);
@@ -1254,7 +1254,7 @@ TEST_F(XdsStatefulSessionFilterTest, GenerateFilterConfigOverrideTypedStruct) {
<< status;
}
-TEST_F(XdsStatefulSessionFilterTest, GenerateFilterConfigOverrideUnparseable) {
+TEST_F(XdsStatefulSessionFilterTest, GenerateFilterConfigOverrideUnparsable) {
XdsExtension extension = MakeXdsExtension(StatefulSessionPerRoute());
std::string serialized_resource("\0", 1);
extension.value = absl::string_view(serialized_resource);
@@ -1457,7 +1457,7 @@ TEST_P(XdsStatefulSessionFilterConfigTest, TypedStructSessionState) {
<< status;
}
-TEST_P(XdsStatefulSessionFilterConfigTest, UnparseableSessionState) {
+TEST_P(XdsStatefulSessionFilterConfigTest, UnparsableSessionState) {
StatefulSession stateful_session;
stateful_session.mutable_session_state()->mutable_typed_config()->PackFrom(
CookieBasedSessionState());
diff --git a/test/core/xds/xds_listener_resource_type_test.cc b/test/core/xds/xds_listener_resource_type_test.cc
index 39419318b74..629d069b259 100644
--- a/test/core/xds/xds_listener_resource_type_test.cc
+++ b/test/core/xds/xds_listener_resource_type_test.cc
@@ -134,7 +134,7 @@ TEST_F(XdsListenerTest, Definition) {
EXPECT_TRUE(resource_type->AllResourcesRequiredInSotW());
}
-TEST_F(XdsListenerTest, UnparseableProto) {
+TEST_F(XdsListenerTest, UnparsableProto) {
std::string serialized_resource("\0", 1);
auto* resource_type = XdsListenerResourceType::Get();
auto decode_result =
@@ -911,7 +911,7 @@ TEST_F(ApiListenerTest, DoesNotContainHttpConnectionManager) {
<< decode_result.resource.status();
}
-TEST_F(ApiListenerTest, UnparseableHttpConnectionManagerConfig) {
+TEST_F(ApiListenerTest, UnparsableHttpConnectionManagerConfig) {
Listener listener;
listener.set_name("foo");
auto* any = listener.mutable_api_listener()->mutable_api_listener();
@@ -1753,7 +1753,7 @@ TEST_F(TcpListenerTest, UnknownTransportSocketType) {
<< decode_result.resource.status();
}
-TEST_F(TcpListenerTest, UnparseableDownstreamTlsContext) {
+TEST_F(TcpListenerTest, UnparsableDownstreamTlsContext) {
Listener listener;
listener.set_name("foo");
HttpConnectionManager hcm;
diff --git a/test/core/xds/xds_route_config_resource_type_test.cc b/test/core/xds/xds_route_config_resource_type_test.cc
index de1bb3e245f..4fa3a11bc20 100644
--- a/test/core/xds/xds_route_config_resource_type_test.cc
+++ b/test/core/xds/xds_route_config_resource_type_test.cc
@@ -125,7 +125,7 @@ TEST_F(XdsRouteConfigTest, Definition) {
EXPECT_FALSE(resource_type->AllResourcesRequiredInSotW());
}
-TEST_F(XdsRouteConfigTest, UnparseableProto) {
+TEST_F(XdsRouteConfigTest, UnparsableProto) {
std::string serialized_resource("\0", 1);
auto* resource_type = XdsRouteConfigResourceType::Get();
auto decode_result =
@@ -561,7 +561,7 @@ TEST_P(TypedPerFilterConfigTest, FilterConfigWrapperInTypedStruct) {
<< decode_result.resource.status();
}
-TEST_P(TypedPerFilterConfigTest, FilterConfigWrapperUnparseable) {
+TEST_P(TypedPerFilterConfigTest, FilterConfigWrapperUnparsable) {
auto* typed_per_filter_config_proto =
GetTypedPerFilterConfigProto(&route_config_);
auto& any = (*typed_per_filter_config_proto)["fault"];
@@ -2200,7 +2200,7 @@ TEST_F(RlsTest, InvalidGrpcLbPolicyConfig) {
"errors validating RouteConfiguration resource: ["
"field:cluster_specifier_plugins[0].extension.typed_config "
"error:ClusterSpecifierPlugin returned invalid LB policy config: "
- "errors validing RLS LB policy config: ["
+ "errors validating RLS LB policy config: ["
"field:routeLookupConfig.lookupService error:field not present]]")
<< decode_result.resource.status();
}
@@ -2237,7 +2237,7 @@ TEST_F(RlsTest, RlsInTypedStruct) {
<< decode_result.resource.status();
}
-TEST_F(RlsTest, RlsConfigUnparseable) {
+TEST_F(RlsTest, RlsConfigUnparsable) {
ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_RLS_LB");
RouteConfiguration route_config;
route_config.set_name("foo");
diff --git a/test/cpp/common/alts_util_test.cc b/test/cpp/common/alts_util_test.cc
index b48ac400f55..5fe52338ff4 100644
--- a/test/cpp/common/alts_util_test.cc
+++ b/test/cpp/common/alts_util_test.cc
@@ -85,8 +85,8 @@ TEST(AltsUtilTest, AuthContextWithGoodAltsContextWithoutRpcVersions) {
std::string expected_rp("record protocol");
std::string expected_peer("peer");
std::string expected_local("local");
- std::string expected_peer_atrributes_key("peer");
- std::string expected_peer_atrributes_value("attributes");
+ std::string expected_peer_attributes_key("peer");
+ std::string expected_peer_attributes_value("attributes");
grpc_security_level expected_sl = GRPC_INTEGRITY_ONLY;
upb::Arena context_arena;
grpc_gcp_AltsContext* context = grpc_gcp_AltsContext_new(context_arena.ptr());
@@ -105,10 +105,10 @@ TEST(AltsUtilTest, AuthContextWithGoodAltsContextWithoutRpcVersions) {
expected_local.length()));
grpc_gcp_AltsContext_peer_attributes_set(
context,
- upb_StringView_FromDataAndSize(expected_peer_atrributes_key.data(),
- expected_peer_atrributes_key.length()),
- upb_StringView_FromDataAndSize(expected_peer_atrributes_value.data(),
- expected_peer_atrributes_value.length()),
+ upb_StringView_FromDataAndSize(expected_peer_attributes_key.data(),
+ expected_peer_attributes_key.length()),
+ upb_StringView_FromDataAndSize(expected_peer_attributes_value.data(),
+ expected_peer_attributes_value.length()),
context_arena.ptr());
size_t serialized_ctx_length;
char* serialized_ctx = grpc_gcp_AltsContext_serialize(
@@ -131,8 +131,8 @@ TEST(AltsUtilTest, AuthContextWithGoodAltsContextWithoutRpcVersions) {
EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.minor_version);
EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.major_version);
EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.minor_version);
- EXPECT_EQ(expected_peer_atrributes_value,
- alts_context->peer_attributes().at(expected_peer_atrributes_key));
+ EXPECT_EQ(expected_peer_attributes_value,
+ alts_context->peer_attributes().at(expected_peer_attributes_key));
}
TEST(AltsUtilTest, AuthContextWithGoodAltsContext) {
diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc
index ab21e760b4c..b3d1394480d 100644
--- a/test/cpp/end2end/client_lb_end2end_test.cc
+++ b/test/cpp/end2end/client_lb_end2end_test.cc
@@ -3277,7 +3277,7 @@ TEST_F(WeightedRoundRobinTest, CallAndServerMetric) {
// all of its subchannels every time it saw an update, thus causing the
// WRR policy to re-enter the blackout period for that address.
TEST_F(WeightedRoundRobinTest, WithOutlierDetection) {
- const int kBlackoutPeriodSeconds = 5;
+ const int kBlackoutPeriodSeconds = 10;
const int kNumServers = 3;
StartServers(kNumServers);
// Report server metrics that should give 6:4:3 WRR picks.
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
index a640d8b499a..4734f8cd736 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -952,12 +952,19 @@ TEST_F(GrpclbEnd2endTest, UsePickFirstChildPolicy) {
"}");
SendBalancerResponse(BuildResponseForBackends(GetBackendPorts(), {}));
CheckRpcSendOk(kNumRpcs, 3000 /* timeout_ms */, true /* wait_for_ready */);
- // Check that all requests went to the first backend. This verifies
- // that we used pick_first instead of round_robin as the child policy.
- EXPECT_EQ(backends_[0]->service().request_count(), kNumRpcs);
- for (size_t i = 1; i < backends_.size(); ++i) {
- EXPECT_EQ(backends_[i]->service().request_count(), 0UL);
+ // Check that all requests went to one backend. This verifies that we
+ // used pick_first instead of round_robin as the child policy.
+ bool found = false;
+ for (size_t i = 0; i < backends_.size(); ++i) {
+ if (backends_[i]->service().request_count() > 0) {
+ LOG(INFO) << "backend " << i << " saw traffic";
+ EXPECT_EQ(backends_[i]->service().request_count(), kNumRpcs)
+ << "backend " << i;
+ EXPECT_FALSE(found) << "multiple backends saw traffic";
+ found = true;
+ }
}
+ EXPECT_TRUE(found) << "no backends saw traffic";
// The balancer got a single request.
EXPECT_EQ(1U, balancer_->service().request_count());
// and sent a single response.
@@ -982,21 +989,24 @@ TEST_F(GrpclbEnd2endTest, SwapChildPolicy) {
"}");
SendBalancerResponse(BuildResponseForBackends(GetBackendPorts(), {}));
CheckRpcSendOk(kNumRpcs, 3000 /* timeout_ms */, true /* wait_for_ready */);
- // Check that all requests went to the first backend. This verifies
- // that we used pick_first instead of round_robin as the child policy.
- EXPECT_EQ(backends_[0]->service().request_count(), kNumRpcs);
- for (size_t i = 1; i < backends_.size(); ++i) {
- EXPECT_EQ(backends_[i]->service().request_count(), 0UL);
+ // Check that all requests went to one backend. This verifies that we
+ // used pick_first instead of round_robin as the child policy.
+ bool found = false;
+ for (size_t i = 0; i < backends_.size(); ++i) {
+ if (backends_[i]->service().request_count() > 0) {
+ LOG(INFO) << "backend " << i << " saw traffic";
+ EXPECT_EQ(backends_[i]->service().request_count(), kNumRpcs)
+ << "backend " << i;
+ EXPECT_FALSE(found) << "multiple backends saw traffic";
+ found = true;
+ }
}
+ EXPECT_TRUE(found) << "no backends saw traffic";
// Send new resolution that removes child policy from service config.
SetNextResolutionDefaultBalancer();
+ // We should now be using round_robin, which will send traffic to all
+ // backends.
WaitForAllBackends();
- CheckRpcSendOk(kNumRpcs, 3000 /* timeout_ms */, true /* wait_for_ready */);
- // Check that every backend saw the same number of requests. This verifies
- // that we used round_robin.
- for (size_t i = 0; i < backends_.size(); ++i) {
- EXPECT_EQ(backends_[i]->service().request_count(), 2UL);
- }
// The balancer got a single request.
EXPECT_EQ(1U, balancer_->service().request_count());
// and sent a single response.
diff --git a/test/cpp/end2end/port_sharing_end2end_test.cc b/test/cpp/end2end/port_sharing_end2end_test.cc
index 05c03c79a93..95f37870957 100644
--- a/test/cpp/end2end/port_sharing_end2end_test.cc
+++ b/test/cpp/end2end/port_sharing_end2end_test.cc
@@ -38,6 +38,7 @@
#include "src/core/lib/gprpp/crash.h"
#include "src/core/lib/gprpp/env.h"
+#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/pollset.h"
@@ -46,6 +47,7 @@
#include "src/core/lib/security/credentials/credentials.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/test_util/port.h"
+#include "test/core/test_util/resolve_localhost_ip46.h"
#include "test/core/test_util/test_config.h"
#include "test/core/test_util/test_tcp_server.h"
#include "test/cpp/end2end/test_service_impl.h"
@@ -96,9 +98,11 @@ class TestTcpServer {
: shutdown_(false),
queue_data_(false),
port_(grpc_pick_unused_port_or_die()) {
- std::ostringstream server_address;
- server_address << "localhost:" << port_;
- address_ = server_address.str();
+ grpc_init(); // needed by LocalIpAndPort()
+ // This test does not do well with multiple connection attempts at the same
+ // time to the same tcp server, so use the local IP address instead of
+ // "localhost" which can result in two connections (ipv4 and ipv6).
+ address_ = grpc_core::LocalIpAndPort(port_);
test_tcp_server_init(&tcp_server_, &TestTcpServer::OnConnect, this);
GRPC_CLOSURE_INIT(&on_fd_released_, &TestTcpServer::OnFdReleased, this,
grpc_schedule_on_exec_ctx);
@@ -108,6 +112,7 @@ class TestTcpServer {
running_thread_.join();
test_tcp_server_destroy(&tcp_server_);
grpc_recycle_unused_port(port_);
+ grpc_shutdown();
}
// Read some data before handing off the connection.
@@ -168,7 +173,7 @@ class TestTcpServer {
grpc_tcp_destroy_and_release_fd(tcp, &fd_, &on_fd_released_);
}
- void OnFdReleased(grpc_error_handle err) {
+ void OnFdReleased(const absl::Status& err) {
EXPECT_EQ(absl::OkStatus(), err);
experimental::ExternalConnectionAcceptor::NewConnectionParameters p;
p.listener_fd = listener_fd_;
diff --git a/test/cpp/end2end/rls_end2end_test.cc b/test/cpp/end2end/rls_end2end_test.cc
index 618b9213c01..348a700cfa7 100644
--- a/test/cpp/end2end/rls_end2end_test.cc
+++ b/test/cpp/end2end/rls_end2end_test.cc
@@ -234,7 +234,7 @@ class RlsEnd2endTest : public ::testing::Test {
}
struct RpcOptions {
- int timeout_ms = 2000;
+ int timeout_ms = 5000;
bool wait_for_ready = false;
std::vector> metadata;
@@ -922,14 +922,15 @@ TEST_F(RlsEnd2endTest, RlsRequestTimeout) {
.set_default_target(grpc_core::LocalIpUri(backends_[1]->port_))
.set_lookup_service_timeout(grpc_core::Duration::Seconds(2))
.Build());
- // RLS server will send a response, but it's longer than the timeout.
+ // RLS server will send a response, but it takes longer than the
+ // timeout set in the LB policy config.
rls_server_->service_.SetResponse(
BuildRlsRequest({{kTestKey, kTestValue}}),
BuildRlsResponse({grpc_core::LocalIpUri(backends_[0]->port_)}),
/*response_delay=*/grpc_core::Duration::Seconds(3));
// The data plane RPC should be sent to the default target.
- CheckRpcSendOk(DEBUG_LOCATION, RpcOptions().set_timeout_ms(4000).set_metadata(
- {{"key1", kTestValue}}));
+ CheckRpcSendOk(DEBUG_LOCATION,
+ RpcOptions().set_metadata({{"key1", kTestValue}}));
EXPECT_EQ(rls_server_->service_.request_count(), 1);
EXPECT_EQ(backends_[0]->service_.request_count(), 0);
EXPECT_EQ(backends_[1]->service_.request_count(), 1);
diff --git a/test/cpp/end2end/xds/BUILD b/test/cpp/end2end/xds/BUILD
index 07e486e6b62..f247f14425b 100644
--- a/test/cpp/end2end/xds/BUILD
+++ b/test/cpp/end2end/xds/BUILD
@@ -281,6 +281,7 @@ grpc_cc_test(
linkstatic = True, # Fixes dyld error on MacOS
shard_count = 5,
tags = [
+ "no_mac",
"no_test_ios",
"no_windows",
"xds_end2end_test",
diff --git a/test/cpp/end2end/xds/xds_cluster_end2end_test.cc b/test/cpp/end2end/xds/xds_cluster_end2end_test.cc
index 951639f2db5..24398adf7f3 100644
--- a/test/cpp/end2end/xds/xds_cluster_end2end_test.cc
+++ b/test/cpp/end2end/xds/xds_cluster_end2end_test.cc
@@ -108,7 +108,7 @@ TEST_P(CdsTest, InvalidClusterStillExistsIfPreviouslyCached) {
CheckRpcSendOk(DEBUG_LOCATION);
}
-// Tests round robin is not implacted by the endpoint weight, and that the
+// Tests round robin is not impacted by the endpoint weight, and that the
// localities in a locality map are picked according to their weights.
TEST_P(CdsTest, EndpointWeightDoesNotImpactWeightedRoundRobin) {
CreateAndStartBackends(2);
@@ -507,7 +507,7 @@ TEST_P(EdsTest, IgnoresUnhealthyEndpoints) {
CreateAndStartBackends(2);
const size_t kNumRpcsPerAddress = 100;
auto endpoints = CreateEndpointsForBackends();
- endpoints.push_back(MakeNonExistantEndpoint());
+ endpoints.push_back(MakeNonExistentEndpoint());
endpoints.back().health_status = HealthStatus::DRAINING;
EdsResourceArgs args({
{"locality0", std::move(endpoints), kDefaultLocalityWeight,
@@ -607,12 +607,12 @@ TEST_P(EdsTest, AllServersUnreachableFailFast) {
const size_t kNumUnreachableServers = 5;
std::vector endpoints;
for (size_t i = 0; i < kNumUnreachableServers; ++i) {
- endpoints.emplace_back(MakeNonExistantEndpoint());
+ endpoints.emplace_back(MakeNonExistentEndpoint());
}
EdsResourceArgs args({{"locality0", std::move(endpoints)}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
// The error shouldn't be DEADLINE_EXCEEDED because timeout is set to 5
- // seconds, and we should disocver in that time that the target backend is
+ // seconds, and we should discover in that time that the target backend is
// down.
CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
MakeConnectionFailureRegex(
@@ -677,7 +677,7 @@ TEST_P(EdsTest, IgnoresDuplicateUpdates) {
// of the invalid cases.
TEST_P(EdsTest, NacksInvalidResource) {
EdsResourceArgs args({
- {"locality0", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 1},
+ {"locality0", {MakeNonExistentEndpoint()}, kDefaultLocalityWeight, 1},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
const auto response_state = WaitForEdsNack(DEBUG_LOCATION);
@@ -1073,7 +1073,7 @@ TEST_P(EdsTest, DropPerTenThousand) {
// Tests that drop is working correctly after update.
TEST_P(EdsTest, DropConfigUpdate) {
- CreateAndStartBackends(1);
+ CreateAndStartBackends(2);
const uint32_t kDropPerMillionForLb = 100000;
const uint32_t kDropPerMillionForThrottle = 200000;
const double kErrorTolerance = 0.05;
@@ -1085,8 +1085,8 @@ TEST_P(EdsTest, DropConfigUpdate) {
ComputeIdealNumRpcs(kDropRateForLb, kErrorTolerance);
const size_t kNumRpcsBoth =
ComputeIdealNumRpcs(kDropRateForLbAndThrottle, kErrorTolerance);
- // The first ADS response contains one drop category.
- EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
+ // The first EDS response contains backend 0 and one drop category.
+ EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
args.drop_categories = {{kLbDropType, kDropPerMillionForLb}};
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
// Send kNumRpcsLbOnly RPCs and count the drops.
@@ -1100,32 +1100,20 @@ TEST_P(EdsTest, DropConfigUpdate) {
LOG(INFO) << "First batch drop rate " << seen_drop_rate;
EXPECT_THAT(seen_drop_rate,
::testing::DoubleNear(kDropRateForLb, kErrorTolerance));
- // The second ADS response contains two drop categories, send an update EDS
- // response.
+ // The second EDS response contains both backends and two drop categories.
+ args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends()}});
args.drop_categories = {{kLbDropType, kDropPerMillionForLb},
{kThrottleDropType, kDropPerMillionForThrottle}};
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
- // Wait until the drop rate increases to the middle of the two configs,
- // which implies that the update has been in effect.
- const double kDropRateThreshold =
- (kDropRateForLb + kDropRateForLbAndThrottle) / 2;
- size_t num_rpcs = kNumRpcsBoth;
- SendRpcsUntil(
- DEBUG_LOCATION,
- [&](const RpcResult& result) {
- ++num_rpcs;
- if (result.status.ok()) {
- EXPECT_EQ(result.response.message(), kRequestMessage);
- } else {
- EXPECT_EQ(result.status.error_code(), StatusCode::UNAVAILABLE);
- EXPECT_THAT(result.status.error_message(),
- ::testing::StartsWith(kStatusMessageDropPrefix));
- ++num_drops;
- }
- seen_drop_rate = static_cast(num_drops) / num_rpcs;
- return seen_drop_rate < kDropRateThreshold;
- },
- /*timeout_ms=*/40000);
+ // Wait until backend 1 sees traffic, so that we know the client has
+ // seen the update.
+ WaitForBackend(DEBUG_LOCATION, 1, [&](const RpcResult& result) {
+ if (!result.status.ok()) {
+ EXPECT_EQ(result.status.error_code(), StatusCode::UNAVAILABLE);
+ EXPECT_THAT(result.status.error_message(),
+ ::testing::StartsWith(kStatusMessageDropPrefix));
+ }
+ });
// Send kNumRpcsBoth RPCs and count the drops.
LOG(INFO) << "========= BEFORE SECOND BATCH ==========";
num_drops = SendRpcsAndCountFailuresWithMessage(DEBUG_LOCATION, kNumRpcsBoth,
@@ -1191,10 +1179,10 @@ TEST_P(EdsAuthorityRewriteTest, AutoAuthorityRewrite) {
{
CreateEndpoint(0),
CreateEndpoint(1, ::envoy::config::core::v3::HealthStatus::UNKNOWN,
- /*lb_weight=*/1, /*additional_backend_indxes=*/{},
+ /*lb_weight=*/1, /*additional_backend_indexes=*/{},
/*hostname=*/kAltAuthority1),
CreateEndpoint(2, ::envoy::config::core::v3::HealthStatus::UNKNOWN,
- /*lb_weight=*/1, /*additional_backend_indxes=*/{},
+ /*lb_weight=*/1, /*additional_backend_indexes=*/{},
/*hostname=*/kAltAuthority2),
}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
@@ -1231,7 +1219,7 @@ TEST_P(EdsAuthorityRewriteTest, NoRewriteWithoutEnvVar) {
EdsResourceArgs args(
{{"locality0",
{CreateEndpoint(0, ::envoy::config::core::v3::HealthStatus::UNKNOWN,
- /*lb_weight=*/1, /*additional_backend_indxes=*/{},
+ /*lb_weight=*/1, /*additional_backend_indexes=*/{},
/*hostname=*/kAltAuthority)}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
// Send an RPC and check the authority seen on the server side.
@@ -1261,7 +1249,7 @@ TEST_P(EdsAuthorityRewriteTest, NoRewriteIfServerNotTrustedInBootstrap) {
EdsResourceArgs args(
{{"locality0",
{CreateEndpoint(0, ::envoy::config::core::v3::HealthStatus::UNKNOWN,
- /*lb_weight=*/1, /*additional_backend_indxes=*/{},
+ /*lb_weight=*/1, /*additional_backend_indexes=*/{},
/*hostname=*/kAltAuthority)}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
// Send an RPC and check the authority seen on the server side.
@@ -1308,7 +1296,7 @@ TEST_P(EdsAuthorityRewriteTest, NoRewriteIfNotEnabledInRoute) {
EdsResourceArgs args(
{{"locality0",
{CreateEndpoint(0, ::envoy::config::core::v3::HealthStatus::UNKNOWN,
- /*lb_weight=*/1, /*additional_backend_indxes=*/{},
+ /*lb_weight=*/1, /*additional_backend_indexes=*/{},
/*hostname=*/kAltAuthority)}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
// Send an RPC and check the authority seen on the server side.
@@ -1395,12 +1383,12 @@ TEST_P(FailoverTest, DoesNotUseLocalityWithNoEndpoints) {
TEST_P(FailoverTest, Failover) {
CreateAndStartBackends(2);
EdsResourceArgs args({
- {"locality0", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 1},
+ {"locality0", {MakeNonExistentEndpoint()}, kDefaultLocalityWeight, 1},
{"locality1", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight,
2},
{"locality2", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
3},
- {"locality3", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 0},
+ {"locality3", {MakeNonExistentEndpoint()}, kDefaultLocalityWeight, 0},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
WaitForBackend(DEBUG_LOCATION, 0, /*check_status=*/nullptr,
@@ -1413,7 +1401,7 @@ TEST_P(FailoverTest, ReportsConnectingDuringFailover) {
CreateAndStartBackends(1);
// Priority 0 will be unreachable, so we'll use priority 1.
EdsResourceArgs args({
- {"locality0", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 0},
+ {"locality0", {MakeNonExistentEndpoint()}, kDefaultLocalityWeight, 0},
{"locality1", CreateEndpointsForBackends(), kDefaultLocalityWeight, 1},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
@@ -1470,8 +1458,8 @@ TEST_P(FailoverTest, SwitchBackToHigherPriority) {
TEST_P(FailoverTest, UpdateInitialUnavailable) {
CreateAndStartBackends(2);
EdsResourceArgs args({
- {"locality0", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 0},
- {"locality1", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 1},
+ {"locality0", {MakeNonExistentEndpoint()}, kDefaultLocalityWeight, 0},
+ {"locality1", {MakeNonExistentEndpoint()}, kDefaultLocalityWeight, 1},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
@@ -1534,12 +1522,12 @@ TEST_P(FailoverTest, UpdatePriority) {
// Moves all localities in the current priority to a higher priority.
TEST_P(FailoverTest, MoveAllLocalitiesInCurrentPriorityToHigherPriority) {
CreateAndStartBackends(3);
- auto non_existant_endpoint = MakeNonExistantEndpoint();
+ auto non_existent_endpoint = MakeNonExistentEndpoint();
// First update:
// - Priority 0 is locality 0, containing an unreachable backend.
// - Priority 1 is locality 1, containing backends 0 and 1.
EdsResourceArgs args({
- {"locality0", {non_existant_endpoint}, kDefaultLocalityWeight, 0},
+ {"locality0", {non_existent_endpoint}, kDefaultLocalityWeight, 0},
{"locality1", CreateEndpointsForBackends(0, 2), kDefaultLocalityWeight,
1},
});
@@ -1556,15 +1544,13 @@ TEST_P(FailoverTest, MoveAllLocalitiesInCurrentPriorityToHigherPriority) {
// - We add backend 2 to locality 1, just so we have a way to know
// when the update has been seen by the client.
args = EdsResourceArgs({
- {"locality0", {non_existant_endpoint}, kDefaultLocalityWeight, 0},
+ {"locality0", {non_existent_endpoint}, kDefaultLocalityWeight, 0},
{"locality1", CreateEndpointsForBackends(0, 3), kDefaultLocalityWeight,
0},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
// When backend 2 gets traffic, we know the second update has been seen.
WaitForBackend(DEBUG_LOCATION, 2);
- // The xDS server got at least 1 response.
- EXPECT_TRUE(balancer_->ads_service()->eds_response_state().has_value());
}
// This tests a bug triggered by the xds_cluster_resolver policy reusing
@@ -1572,13 +1558,13 @@ TEST_P(FailoverTest, MoveAllLocalitiesInCurrentPriorityToHigherPriority) {
// present but deactivated.
TEST_P(FailoverTest, PriorityChildNameChurn) {
CreateAndStartBackends(4);
- auto non_existant_endpoint = MakeNonExistantEndpoint();
+ auto non_existent_endpoint = MakeNonExistentEndpoint();
// Initial update:
// - P0:locality0, child number 0 (unreachable)
// - P1:locality1, child number 1
// - P2:locality2, child number 2
EdsResourceArgs args({
- {"locality0", {non_existant_endpoint}, kDefaultLocalityWeight, 0},
+ {"locality0", {non_existent_endpoint}, kDefaultLocalityWeight, 0},
{"locality1", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight,
1},
{"locality2", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
@@ -1592,7 +1578,7 @@ TEST_P(FailoverTest, PriorityChildNameChurn) {
// - P2:locality3, child number 3 (new child)
// Child number 1 will be deactivated.
args = EdsResourceArgs({
- {"locality0", {non_existant_endpoint}, kDefaultLocalityWeight, 0},
+ {"locality0", {non_existent_endpoint}, kDefaultLocalityWeight, 0},
{"locality2", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
1},
{"locality3", CreateEndpointsForBackends(2, 3), kDefaultLocalityWeight,
@@ -1606,7 +1592,7 @@ TEST_P(FailoverTest, PriorityChildNameChurn) {
// - P2:locality3, child number 3
// Child number 1 will be deactivated.
args = EdsResourceArgs({
- {"locality0", {non_existant_endpoint}, kDefaultLocalityWeight, 0},
+ {"locality0", {non_existent_endpoint}, kDefaultLocalityWeight, 0},
{"locality4", CreateEndpointsForBackends(3, 4), kDefaultLocalityWeight,
1},
{"locality3", CreateEndpointsForBackends(2, 3), kDefaultLocalityWeight,
diff --git a/test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc b/test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc
index b0af0178e8e..19ba50ecd8c 100644
--- a/test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc
+++ b/test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc
@@ -757,9 +757,9 @@ TEST_P(AggregateClusterTest, ReconfigEdsWhileLogicalDnsChildFails) {
// - Priority 0: locality0
// - Priority 1: locality1, locality2
EdsResourceArgs args1({
- {"locality0", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 0},
- {"locality1", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 1},
- {"locality2", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 1},
+ {"locality0", {MakeNonExistentEndpoint()}, kDefaultLocalityWeight, 0},
+ {"locality1", {MakeNonExistentEndpoint()}, kDefaultLocalityWeight, 1},
+ {"locality2", {MakeNonExistentEndpoint()}, kDefaultLocalityWeight, 1},
});
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsService1Name));
@@ -829,7 +829,7 @@ TEST_P(AggregateClusterTest, MultipleClustersWithSameLocalities) {
const char* kNewClusterName2 = "new_cluster_2";
const char* kNewEdsServiceName2 = "new_eds_service_name_2";
// Populate EDS resource for cluster 1 with unreachable endpoint.
- EdsResourceArgs args1({{"locality0", {MakeNonExistantEndpoint()}}});
+ EdsResourceArgs args1({{"locality0", {MakeNonExistentEndpoint()}}});
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsServiceName1));
// Populate CDS resource for cluster 1.
diff --git a/test/cpp/end2end/xds/xds_core_end2end_test.cc b/test/cpp/end2end/xds/xds_core_end2end_test.cc
index f3b6d78f901..e8d0ed404eb 100644
--- a/test/cpp/end2end/xds/xds_core_end2end_test.cc
+++ b/test/cpp/end2end/xds/xds_core_end2end_test.cc
@@ -540,7 +540,7 @@ TEST_P(TimeoutTest, EdsSecondResourceNotPresentInRequest) {
EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
CheckRpcSendOk(DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(4000));
- // New cluster that points to a non-existant EDS resource.
+ // New cluster that points to a non-existent EDS resource.
const char* kNewClusterName = "new_cluster_name";
Cluster cluster = default_cluster_;
cluster.set_name(kNewClusterName);
@@ -1060,7 +1060,7 @@ TEST_P(XdsFederationTest, FederationServer) {
"xdstp://xds.example.com/envoy.config.listener.v3.Listener"
"client/%s?client_listener_resource_name_template_not_in_use");
InitClient(builder);
- CreateAndStartBackends(2, /*xds_enabled=*/true);
+ CreateBackends(2, /*xds_enabled=*/true);
// Eds for new authority balancer.
EdsResourceArgs args =
EdsResourceArgs({{"locality0", CreateEndpointsForBackends()}});
@@ -1099,6 +1099,13 @@ TEST_P(XdsFederationTest, FederationServer) {
new_server_route_config,
ServerHcmAccessor());
}
+ // Start backends and wait for them to start serving.
+ StartAllBackends();
+ for (const auto& backend : backends_) {
+ ASSERT_TRUE(backend->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backend->port()), grpc::StatusCode::OK));
+ }
+ // Make sure everything works.
WaitForAllBackends(DEBUG_LOCATION);
}
@@ -1244,7 +1251,10 @@ TEST_P(XdsMetricsTest, MetricValues) {
EdsResourceArgs args =
EdsResourceArgs({{"locality0", CreateEndpointsForBackends()}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
- CheckRpcSendOk(DEBUG_LOCATION);
+ // Use wait_for_ready and increase timeout, in case the client takes a
+ // little while to get connected.
+ CheckRpcSendOk(DEBUG_LOCATION, /*times=*/1,
+ RpcOptions().set_wait_for_ready(true).set_timeout_ms(15000));
stats_plugin_->TriggerCallbacks();
// Check client metrics.
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
diff --git a/test/cpp/end2end/xds/xds_end2end_test.cc b/test/cpp/end2end/xds/xds_end2end_test.cc
index 0c6cfab5e84..451eae32dde 100644
--- a/test/cpp/end2end/xds/xds_end2end_test.cc
+++ b/test/cpp/end2end/xds/xds_end2end_test.cc
@@ -833,12 +833,16 @@ class XdsEnabledServerTest : public XdsEnd2endTest {
TEST_P(XdsEnabledServerTest, Basic) {
DoSetUp();
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
WaitForBackend(DEBUG_LOCATION, 0);
}
TEST_P(XdsEnabledServerTest, ListenerDeletionIgnored) {
DoSetUp(MakeBootstrapBuilder().SetIgnoreResourceDeletion());
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
WaitForBackend(DEBUG_LOCATION, 0);
// Check that we ACKed.
// TODO(roth): There may be multiple entries in the resource state response
@@ -906,9 +910,9 @@ TEST_P(XdsEnabledServerTest, NonTcpListener) {
ClientHcmAccessor().Pack(hcm, &listener);
balancer_->ads_service()->SetLdsResource(listener);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
grpc_core::LocalIpAndPort(backends_[0]->port()),
- grpc::StatusCode::FAILED_PRECONDITION);
+ grpc::StatusCode::FAILED_PRECONDITION));
}
// Verify that a mismatch of listening address results in "not serving"
@@ -923,9 +927,9 @@ TEST_P(XdsEnabledServerTest, ListenerAddressMismatch) {
backends_[0]->port(),
default_server_route_config_);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
grpc_core::LocalIpAndPort(backends_[0]->port()),
- grpc::StatusCode::FAILED_PRECONDITION);
+ grpc::StatusCode::FAILED_PRECONDITION));
}
class XdsServerSecurityTest : public XdsEnd2endTest {
@@ -944,7 +948,11 @@ class XdsServerSecurityTest : public XdsEnd2endTest {
builder.AddCertificateProviderPlugin("file_plugin", "file_watcher",
absl::StrJoin(fields, ",\n"));
InitClient(builder, /*lb_expected_authority=*/"",
- /*xds_resource_does_not_exist_timeout_ms=*/0,
+ /*xds_resource_does_not_exist_timeout_ms=*/
+ 500, // using a low timeout to quickly end negative tests.
+ // Prefer using WaitOnServingStatusChange() or a similar
+ // loop on the client side to wait on status changes
+ // instead of increasing this timeout.
/*balancer_authority_override=*/"", /*args=*/nullptr,
CreateXdsChannelCredentials());
CreateBackends(1, /*xds_enabled=*/true,
@@ -1071,23 +1079,25 @@ class XdsServerSecurityTest : public XdsEnd2endTest {
}
void SendRpc(
- std::function()> channel_creator,
- std::vector expected_server_identity,
- std::vector expected_client_identity,
+ absl::FunctionRef()> channel_creator,
+ const RpcOptions& rpc_options,
+ const std::vector& expected_server_identity,
+ const std::vector& expected_client_identity,
bool test_expects_failure = false,
- absl::optional expected_status = absl::nullopt) {
+ absl::optional expected_status = absl::nullopt,
+ absl::string_view expected_error_message_regex = "") {
LOG(INFO) << "Sending RPC";
int num_tries = 0;
constexpr int kRetryCount = 100;
- auto overall_deadline = absl::Now() + absl::Seconds(5);
+ auto overall_deadline =
+ absl::Now() + absl::Seconds(20) * grpc_test_slowdown_factor();
+ auto channel = channel_creator();
+ auto stub = grpc::testing::EchoTestService::NewStub(channel);
for (; num_tries < kRetryCount || absl::Now() < overall_deadline;
num_tries++) {
- auto channel = channel_creator();
- auto stub = grpc::testing::EchoTestService::NewStub(channel);
ClientContext context;
- context.set_wait_for_ready(true);
- context.set_deadline(grpc_timeout_milliseconds_to_deadline(2000));
EchoRequest request;
+ rpc_options.SetupRpc(&context, &request);
// TODO(yashykt): Skipping the cancelled check on the server since the
// server's graceful shutdown isn't as per spec and the check isn't
// necessary for what we want to test here anyway.
@@ -1108,6 +1118,8 @@ class XdsServerSecurityTest : public XdsEnd2endTest {
<< *expected_status << ")";
continue;
}
+ EXPECT_THAT(status.error_message(),
+ ::testing::MatchesRegex(expected_error_message_regex));
} else {
if (!status.ok()) {
LOG(ERROR) << "RPC failed. code=" << status.error_code()
@@ -1142,7 +1154,7 @@ class XdsServerSecurityTest : public XdsEnd2endTest {
}
break;
}
- EXPECT_LT(num_tries, kRetryCount);
+ EXPECT_TRUE(absl::Now() <= overall_deadline || num_tries < kRetryCount);
}
std::string root_cert_;
@@ -1173,23 +1185,34 @@ TEST_P(XdsServerSecurityTest,
backends_[0]->port(),
default_server_route_config_);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateTlsChannel(); },
- server_authenticated_identity_, {});
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ {});
}
TEST_P(XdsServerSecurityTest, CertificatesNotAvailable) {
g_fake1_cert_data_map->Set({});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
- SendRpc([this]() { return CreateMtlsChannel(); }, {}, {},
- true /* test_expects_failure */);
+ backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateMtlsChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
}
TEST_P(XdsServerSecurityTest, TestMtls) {
g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateMtlsChannel(); },
- server_authenticated_identity_, client_authenticated_identity_);
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ client_authenticated_identity_);
}
TEST_P(XdsServerSecurityTest, TestMtlsWithRootPluginUpdate) {
@@ -1197,11 +1220,16 @@ TEST_P(XdsServerSecurityTest, TestMtlsWithRootPluginUpdate) {
g_fake2_cert_data_map->Set({{"", {bad_root_cert_, bad_identity_pair_}}});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateMtlsChannel(); },
- server_authenticated_identity_, client_authenticated_identity_);
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ client_authenticated_identity_);
SetLdsUpdate("fake_plugin2", "", "fake_plugin1", "", true);
- SendRpc([this]() { return CreateMtlsChannel(); }, {}, {},
- true /* test_expects_failure */);
+ SendRpc([this]() { return CreateMtlsChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
}
TEST_P(XdsServerSecurityTest, TestMtlsWithIdentityPluginUpdate) {
@@ -1209,10 +1237,14 @@ TEST_P(XdsServerSecurityTest, TestMtlsWithIdentityPluginUpdate) {
g_fake2_cert_data_map->Set({{"", {root_cert_, identity_pair_2_}}});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateMtlsChannel(); },
- server_authenticated_identity_, client_authenticated_identity_);
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ client_authenticated_identity_);
SetLdsUpdate("fake_plugin1", "", "fake_plugin2", "", true);
SendRpc([this]() { return CreateMtlsChannel(); },
+ RpcOptions().set_wait_for_ready(true),
server_authenticated_identity_2_, client_authenticated_identity_);
}
@@ -1222,13 +1254,19 @@ TEST_P(XdsServerSecurityTest, TestMtlsWithBothPluginsUpdated) {
{"", {bad_root_cert_, bad_identity_pair_}}});
SetLdsUpdate("fake_plugin2", "", "fake_plugin2", "", true);
backends_[0]->Start();
- SendRpc([this]() { return CreateMtlsChannel(); }, {}, {},
- true /* test_expects_failure */);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateMtlsChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeTlsHandshakeFailureRegex(
+ "failed to connect to all addresses; last error: "));
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
SendRpc([this]() { return CreateMtlsChannel(); },
- server_authenticated_identity_, client_authenticated_identity_);
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ client_authenticated_identity_);
SetLdsUpdate("fake_plugin2", "good", "fake_plugin2", "good", true);
SendRpc([this]() { return CreateMtlsChannel(); },
+ RpcOptions().set_wait_for_ready(true),
server_authenticated_identity_2_, client_authenticated_identity_);
}
@@ -1237,11 +1275,16 @@ TEST_P(XdsServerSecurityTest, TestMtlsWithRootCertificateNameUpdate) {
{"bad", {bad_root_cert_, bad_identity_pair_}}});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateMtlsChannel(); },
- server_authenticated_identity_, client_authenticated_identity_);
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ client_authenticated_identity_);
SetLdsUpdate("fake_plugin1", "bad", "fake_plugin1", "", true);
- SendRpc([this]() { return CreateMtlsChannel(); }, {}, {},
- true /* test_expects_failure */);
+ SendRpc([this]() { return CreateMtlsChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
}
TEST_P(XdsServerSecurityTest, TestMtlsWithIdentityCertificateNameUpdate) {
@@ -1249,10 +1292,14 @@ TEST_P(XdsServerSecurityTest, TestMtlsWithIdentityCertificateNameUpdate) {
{"good", {root_cert_, identity_pair_2_}}});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateMtlsChannel(); },
- server_authenticated_identity_, client_authenticated_identity_);
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ client_authenticated_identity_);
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "good", true);
SendRpc([this]() { return CreateMtlsChannel(); },
+ RpcOptions().set_wait_for_ready(true),
server_authenticated_identity_2_, client_authenticated_identity_);
}
@@ -1261,10 +1308,14 @@ TEST_P(XdsServerSecurityTest, TestMtlsWithBothCertificateNamesUpdated) {
{"good", {root_cert_, identity_pair_2_}}});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateMtlsChannel(); },
- server_authenticated_identity_, client_authenticated_identity_);
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ client_authenticated_identity_);
SetLdsUpdate("fake_plugin1", "good", "fake_plugin1", "good", true);
SendRpc([this]() { return CreateMtlsChannel(); },
+ RpcOptions().set_wait_for_ready(true),
server_authenticated_identity_2_, client_authenticated_identity_);
}
@@ -1272,24 +1323,33 @@ TEST_P(XdsServerSecurityTest, TestMtlsNotRequiringButProvidingClientCerts) {
g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", false);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateMtlsChannel(); },
- server_authenticated_identity_, client_authenticated_identity_);
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ client_authenticated_identity_);
}
TEST_P(XdsServerSecurityTest, TestMtlsNotRequiringAndNotProvidingClientCerts) {
g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", false);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateTlsChannel(); },
- server_authenticated_identity_, {});
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ {});
}
TEST_P(XdsServerSecurityTest, TestTls) {
g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
SetLdsUpdate("", "", "fake_plugin1", "", false);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateTlsChannel(); },
- server_authenticated_identity_, {});
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ {});
}
TEST_P(XdsServerSecurityTest, TestTlsWithIdentityPluginUpdate) {
@@ -1297,10 +1357,14 @@ TEST_P(XdsServerSecurityTest, TestTlsWithIdentityPluginUpdate) {
g_fake2_cert_data_map->Set({{"", {root_cert_, identity_pair_2_}}});
SetLdsUpdate("", "", "fake_plugin1", "", false);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateTlsChannel(); },
- server_authenticated_identity_, {});
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ {});
SetLdsUpdate("", "", "fake_plugin2", "", false);
SendRpc([this]() { return CreateTlsChannel(); },
+ RpcOptions().set_wait_for_ready(true),
server_authenticated_identity_2_, {});
}
@@ -1309,10 +1373,14 @@ TEST_P(XdsServerSecurityTest, TestTlsWithIdentityCertificateNameUpdate) {
{"good", {root_cert_, identity_pair_2_}}});
SetLdsUpdate("", "", "fake_plugin1", "", false);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateTlsChannel(); },
- server_authenticated_identity_, {});
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ {});
SetLdsUpdate("", "", "fake_plugin1", "good", false);
SendRpc([this]() { return CreateTlsChannel(); },
+ RpcOptions().set_wait_for_ready(true),
server_authenticated_identity_2_, {});
}
@@ -1320,69 +1388,98 @@ TEST_P(XdsServerSecurityTest, TestFallback) {
g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
SetLdsUpdate("", "", "", "", false);
backends_[0]->Start();
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsServerSecurityTest, TestMtlsToTls) {
g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
backends_[0]->Start();
- SendRpc([this]() { return CreateTlsChannel(); }, {}, {},
- true /* test_expects_failure */);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateTlsChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
SetLdsUpdate("", "", "fake_plugin1", "", false);
SendRpc([this]() { return CreateTlsChannel(); },
- server_authenticated_identity_, {});
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ {});
}
TEST_P(XdsServerSecurityTest, TestTlsToMtls) {
g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
SetLdsUpdate("", "", "fake_plugin1", "", false);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateTlsChannel(); },
- server_authenticated_identity_, {});
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ {});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
- SendRpc([this]() { return CreateTlsChannel(); }, {}, {},
- true /* test_expects_failure */);
+ SendRpc([this]() { return CreateTlsChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
}
TEST_P(XdsServerSecurityTest, TestMtlsToFallback) {
g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", false);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateMtlsChannel(); },
- server_authenticated_identity_, client_authenticated_identity_);
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ client_authenticated_identity_);
SetLdsUpdate("", "", "", "", false);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsServerSecurityTest, TestFallbackToMtls) {
g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
SetLdsUpdate("", "", "", "", false);
backends_[0]->Start();
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
SendRpc([this]() { return CreateMtlsChannel(); },
- server_authenticated_identity_, client_authenticated_identity_);
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ client_authenticated_identity_);
}
TEST_P(XdsServerSecurityTest, TestTlsToFallback) {
g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
SetLdsUpdate("", "", "fake_plugin1", "", false);
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateTlsChannel(); },
- server_authenticated_identity_, {});
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ {});
SetLdsUpdate("", "", "", "", false);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsServerSecurityTest, TestFallbackToTls) {
g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
SetLdsUpdate("", "", "", "", false);
backends_[0]->Start();
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
SetLdsUpdate("", "", "fake_plugin1", "", false);
SendRpc([this]() { return CreateTlsChannel(); },
- server_authenticated_identity_, {});
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ {});
}
class XdsEnabledServerStatusNotificationTest : public XdsServerSecurityTest {
@@ -1409,51 +1506,60 @@ class XdsEnabledServerStatusNotificationTest : public XdsServerSecurityTest {
TEST_P(XdsEnabledServerStatusNotificationTest, ServingStatus) {
SetValidLdsUpdate();
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsEnabledServerStatusNotificationTest, NotServingStatus) {
SetInvalidLdsUpdate();
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
grpc_core::LocalIpAndPort(backends_[0]->port()),
- grpc::StatusCode::UNAVAILABLE);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
- true /* test_expects_failure */);
+ grpc::StatusCode::UNAVAILABLE));
+ SendRpc([this]() { return CreateInsecureChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
}
TEST_P(XdsEnabledServerStatusNotificationTest, ErrorUpdateWhenAlreadyServing) {
SetValidLdsUpdate();
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
// Invalid update does not lead to a change in the serving status.
SetInvalidLdsUpdate();
do {
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
} while (!balancer_->ads_service()->lds_response_state().has_value());
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsEnabledServerStatusNotificationTest,
NotServingStatusToServingStatusTransition) {
SetInvalidLdsUpdate();
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
grpc_core::LocalIpAndPort(backends_[0]->port()),
- grpc::StatusCode::UNAVAILABLE);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
- true /* test_expects_failure */);
+ grpc::StatusCode::UNAVAILABLE));
+ SendRpc([this]() { return CreateInsecureChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
// Send a valid LDS update to change to serving status
SetValidLdsUpdate();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
// This test verifies that the resource getting deleted when already serving
@@ -1462,16 +1568,19 @@ TEST_P(XdsEnabledServerStatusNotificationTest,
ServingStatusToNonServingStatusTransition) {
SetValidLdsUpdate();
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
// Deleting the resource should result in a non-serving status.
UnsetLdsUpdate();
- backends_[0]->notifier()->WaitOnServingStatusChange(
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
grpc_core::LocalIpAndPort(backends_[0]->port()),
- grpc::StatusCode::NOT_FOUND);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
- true /* test_expects_failure */);
+ grpc::StatusCode::NOT_FOUND));
+ SendRpc([this]() { return CreateInsecureChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
}
TEST_P(XdsEnabledServerStatusNotificationTest, RepeatedServingStatusChanges) {
@@ -1479,16 +1588,19 @@ TEST_P(XdsEnabledServerStatusNotificationTest, RepeatedServingStatusChanges) {
for (int i = 0; i < 5; i++) {
// Send a valid LDS update to get the server to start listening
SetValidLdsUpdate();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
// Deleting the resource will make the server start rejecting connections
UnsetLdsUpdate();
- backends_[0]->notifier()->WaitOnServingStatusChange(
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
grpc_core::LocalIpAndPort(backends_[0]->port()),
- grpc::StatusCode::NOT_FOUND);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
- true /* test_expects_failure */);
+ grpc::StatusCode::NOT_FOUND));
+ SendRpc([this]() { return CreateInsecureChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
}
}
@@ -1496,8 +1608,8 @@ TEST_P(XdsEnabledServerStatusNotificationTest, ExistingRpcsOnResourceDeletion) {
// Send a valid LDS update to get the server to start listening
SetValidLdsUpdate();
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
constexpr int kNumChannels = 10;
struct StreamingRpc {
std::shared_ptr channel;
@@ -1521,11 +1633,13 @@ TEST_P(XdsEnabledServerStatusNotificationTest, ExistingRpcsOnResourceDeletion) {
}
// Deleting the resource will make the server start rejecting connections
UnsetLdsUpdate();
- backends_[0]->notifier()->WaitOnServingStatusChange(
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
grpc_core::LocalIpAndPort(backends_[0]->port()),
- grpc::StatusCode::NOT_FOUND);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
- true /* test_expects_failure */);
+ grpc::StatusCode::NOT_FOUND));
+ SendRpc([this]() { return CreateInsecureChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
for (int i = 0; i < kNumChannels; i++) {
EXPECT_TRUE(streaming_rpcs[i].stream->Write(request));
streaming_rpcs[i].stream->Read(&response);
@@ -1551,8 +1665,8 @@ TEST_P(XdsEnabledServerStatusNotificationTest,
// Send a valid LDS update to get the server to start listening
SetValidLdsUpdate();
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
constexpr int kNumChannels = 10;
struct StreamingRpc {
std::shared_ptr channel;
@@ -1579,7 +1693,8 @@ TEST_P(XdsEnabledServerStatusNotificationTest,
SetLdsUpdate("", "", "fake_plugin1", "", false);
// Wait for the updated resource to take effect.
SendRpc([this]() { return CreateTlsChannel(); },
- server_authenticated_identity_, {});
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ {});
// After the drain grace time expires, the existing RPCs should all fail.
for (int i = 0; i < kNumChannels; i++) {
// Wait for the drain grace time to expire
@@ -1592,6 +1707,8 @@ TEST_P(XdsEnabledServerStatusNotificationTest,
<< status.error_code() << ", " << status.error_message() << ", "
<< status.error_details() << ", "
<< streaming_rpcs[i].context.debug_error_string();
+ EXPECT_EQ(status.error_message(),
+ "Drain grace time expired. Closing connection immediately.");
}
}
@@ -1609,7 +1726,10 @@ class XdsServerFilterChainMatchTest : public XdsServerSecurityTest {
TEST_P(XdsServerFilterChainMatchTest,
DefaultFilterChainUsedWhenNoFilterChainMentioned) {
backends_[0]->Start();
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsServerFilterChainMatchTest,
@@ -1626,7 +1746,10 @@ TEST_P(XdsServerFilterChainMatchTest,
backends_[0]->port(),
default_server_route_config_);
backends_[0]->Start();
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsServerFilterChainMatchTest,
@@ -1643,10 +1766,14 @@ TEST_P(XdsServerFilterChainMatchTest,
balancer_->ads_service()->SetLdsResource(
PopulateServerListenerNameAndPort(listener, backends_[0]->port()));
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// RPC should fail since no matching filter chain was found and no default
// filter chain is configured.
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
- true /* test_expects_failure */);
+ SendRpc([this]() { return CreateInsecureChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
}
TEST_P(XdsServerFilterChainMatchTest, FilterChainsWithServerNamesDontMatch) {
@@ -1660,10 +1787,14 @@ TEST_P(XdsServerFilterChainMatchTest, FilterChainsWithServerNamesDontMatch) {
balancer_->ads_service()->SetLdsResource(
PopulateServerListenerNameAndPort(listener, backends_[0]->port()));
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// RPC should fail since no matching filter chain was found and no default
// filter chain is configured.
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
- true /* test_expects_failure */);
+ SendRpc([this]() { return CreateInsecureChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
}
TEST_P(XdsServerFilterChainMatchTest,
@@ -1678,10 +1809,14 @@ TEST_P(XdsServerFilterChainMatchTest,
balancer_->ads_service()->SetLdsResource(
PopulateServerListenerNameAndPort(listener, backends_[0]->port()));
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// RPC should fail since no matching filter chain was found and no default
// filter chain is configured.
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
- true /* test_expects_failure */);
+ SendRpc([this]() { return CreateInsecureChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
}
TEST_P(XdsServerFilterChainMatchTest,
@@ -1696,10 +1831,14 @@ TEST_P(XdsServerFilterChainMatchTest,
balancer_->ads_service()->SetLdsResource(
PopulateServerListenerNameAndPort(listener, backends_[0]->port()));
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// RPC should fail since no matching filter chain was found and no default
// filter chain is configured.
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
- true /* test_expects_failure */);
+ SendRpc([this]() { return CreateInsecureChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ MakeConnectionFailureRegex(
+ "failed to connect to all addresses; last error: "));
}
TEST_P(XdsServerFilterChainMatchTest,
@@ -1721,9 +1860,12 @@ TEST_P(XdsServerFilterChainMatchTest,
balancer_->ads_service()->SetLdsResource(
PopulateServerListenerNameAndPort(listener, backends_[0]->port()));
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// A successful RPC proves that filter chains that mention "raw_buffer" as
// the transport protocol are chosen as the best match in the round.
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsServerFilterChainMatchTest,
@@ -1775,9 +1917,12 @@ TEST_P(XdsServerFilterChainMatchTest,
balancer_->ads_service()->SetLdsResource(
PopulateServerListenerNameAndPort(listener, backends_[0]->port()));
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// A successful RPC proves that the filter chain with the longest matching
// prefix range was the best match.
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsServerFilterChainMatchTest,
@@ -1809,9 +1954,12 @@ TEST_P(XdsServerFilterChainMatchTest,
balancer_->ads_service()->SetLdsResource(
PopulateServerListenerNameAndPort(listener, backends_[0]->port()));
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// A successful RPC proves that the filter chain with the longest matching
// prefix range was the best match.
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsServerFilterChainMatchTest,
@@ -1869,9 +2017,12 @@ TEST_P(XdsServerFilterChainMatchTest,
balancer_->ads_service()->SetLdsResource(
PopulateServerListenerNameAndPort(listener, backends_[0]->port()));
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// A successful RPC proves that the filter chain with the longest matching
// source prefix range was the best match.
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsServerFilterChainMatchTest,
@@ -1901,18 +2052,22 @@ TEST_P(XdsServerFilterChainMatchTest,
balancer_->ads_service()->SetLdsResource(
PopulateServerListenerNameAndPort(listener, backends_[0]->port()));
backends_[0]->Start();
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// A successful RPC proves that the filter chain with matching source port
// was chosen.
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
using XdsServerRdsTest = XdsEnabledServerStatusNotificationTest;
TEST_P(XdsServerRdsTest, Basic) {
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsServerRdsTest, FailsRouteMatchesOtherThanNonForwardingAction) {
@@ -1921,10 +2076,11 @@ TEST_P(XdsServerRdsTest, FailsRouteMatchesOtherThanNonForwardingAction) {
default_route_config_ /* inappropriate route config for servers */);
backends_[0]->Start();
// The server should be ready to serve but RPCs should fail.
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
- true /* test_expects_failure */);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
+ "UNAVAILABLE:matching route has unsupported action");
}
// Test that non-inline route configuration also works for non-default filter
@@ -1946,9 +2102,10 @@ TEST_P(XdsServerRdsTest, NonInlineRouteConfigurationNonDefaultFilterChain) {
backends_[0]->port(),
default_server_route_config_);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsServerRdsTest, NonInlineRouteConfigurationNotAvailable) {
@@ -1968,10 +2125,11 @@ TEST_P(XdsServerRdsTest, NonInlineRouteConfigurationNotAvailable) {
backends_[0]->port(),
default_server_route_config_);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
- true /* test_expects_failure */);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); }, RpcOptions(), {}, {},
+ true /* test_expects_failure */, grpc::StatusCode::NOT_FOUND,
+ "Requested route config does not exist");
}
// TODO(yashykt): Once https://github.com/grpc/grpc/issues/24035 is fixed, we
@@ -2020,9 +2178,10 @@ TEST_P(XdsServerRdsTest, MultipleRouteConfigurations) {
backends_[0]->port(),
default_server_route_config_);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
// Tests RBAC configurations on the server with RDS testing and route config
@@ -2086,10 +2245,11 @@ class XdsRbacTest : public XdsServerRdsTest {
TEST_P(XdsRbacTest, AbsentRbacPolicy) {
SetServerRbacPolicy(RBAC());
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// An absent RBAC policy leads to all RPCs being accepted.
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
TEST_P(XdsRbacTest, LogAction) {
@@ -2098,10 +2258,11 @@ TEST_P(XdsRbacTest, LogAction) {
rules->set_action(RBAC_Action_LOG);
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// A Log action is identical to no rbac policy being configured.
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
// Tests RBAC policies where a route override is always present. Action
@@ -2139,9 +2300,10 @@ TEST_P(XdsRbacTestWithRouteOverrideAlwaysPresent, EmptyRBACPerRouteOverride) {
SetServerListenerNameAndRouteConfiguration(
balancer_.get(), listener, backends_[0]->port(), route_config);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
// Test a non-empty top level RBAC with a non-empty RBACPerRouteOverride
@@ -2180,9 +2342,10 @@ TEST_P(XdsRbacTestWithRouteOverrideAlwaysPresent,
SetServerListenerNameAndRouteConfiguration(
balancer_.get(), listener, backends_[0]->port(), route_config);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {});
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {});
}
// Adds Action Permutations to XdsRbacTest
@@ -2193,13 +2356,14 @@ TEST_P(XdsRbacTestWithActionPermutations, EmptyRbacPolicy) {
rbac.mutable_rules()->set_action(GetParam().rbac_action());
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// An empty RBAC policy leads to all RPCs being rejected.
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionAnyPrincipal) {
@@ -2212,11 +2376,12 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionAnyPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, MultipleRbacPolicies) {
@@ -2234,11 +2399,12 @@ TEST_P(XdsRbacTestWithActionPermutations, MultipleRbacPolicies) {
SetServerRbacPolicies(default_server_listener_,
{always_allow, rbac, always_allow});
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, MethodPostPermissionAnyPrincipal) {
@@ -2254,17 +2420,18 @@ TEST_P(XdsRbacTestWithActionPermutations, MethodPostPermissionAnyPrincipal) {
SetServerRbacPolicy(rbac);
backends_[0]->set_allow_put_requests(true);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// All RPCs use POST method by default
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Test that an RPC with PUT method is handled properly.
SendRpc([this]() { return CreateInsecureChannel(/*use_put_requests=*/true); },
- {}, {},
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() != RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, MethodGetPermissionAnyPrincipal) {
@@ -2279,13 +2446,14 @@ TEST_P(XdsRbacTestWithActionPermutations, MethodGetPermissionAnyPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// Test that an RPC with a POST method gets rejected
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// TODO(yashykt): When we start supporting GET requests in the future, this
// should be modified to test that they are accepted with this rule.
}
@@ -2303,19 +2471,20 @@ TEST_P(XdsRbacTestWithActionPermutations, MethodPutPermissionAnyPrincipal) {
SetServerRbacPolicy(rbac);
backends_[0]->set_allow_put_requests(true);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// Test that an RPC with a POST method gets rejected
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Test that an RPC with a PUT method gets accepted
SendRpc(
- [this]() { return CreateInsecureChannel(/*use_put_requests=*/true); }, {},
- {},
+ [this]() { return CreateInsecureChannel(/*use_put_requests=*/true); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() != RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, UrlPathPermissionAnyPrincipal) {
@@ -2329,11 +2498,12 @@ TEST_P(XdsRbacTestWithActionPermutations, UrlPathPermissionAnyPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Test an RPC with a different URL path
auto stub = grpc::testing::EchoTestService::NewStub(CreateInsecureChannel());
ClientContext context;
@@ -2362,11 +2532,12 @@ TEST_P(XdsRbacTestWithActionPermutations, DestinationIpPermissionAnyPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Change the policy itself for a negative test where there is no match.
policy.clear_permissions();
range = policy.add_permissions()->mutable_destination_ip();
@@ -2377,9 +2548,10 @@ TEST_P(XdsRbacTestWithActionPermutations, DestinationIpPermissionAnyPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations,
@@ -2393,20 +2565,22 @@ TEST_P(XdsRbacTestWithActionPermutations,
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Change the policy itself for a negative test where there is no match.
policy.clear_permissions();
policy.add_permissions()->set_destination_port(1);
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, MetadataPermissionAnyPrincipal) {
@@ -2419,20 +2593,22 @@ TEST_P(XdsRbacTestWithActionPermutations, MetadataPermissionAnyPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Test metadata with inverted match
policy.clear_permissions();
policy.add_permissions()->mutable_metadata()->set_invert(true);
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, ReqServerNamePermissionAnyPrincipal) {
@@ -2446,19 +2622,21 @@ TEST_P(XdsRbacTestWithActionPermutations, ReqServerNamePermissionAnyPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
policy.clear_permissions();
policy.add_permissions()->mutable_requested_server_name()->set_exact("");
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, NotRulePermissionAnyPrincipal) {
@@ -2474,20 +2652,22 @@ TEST_P(XdsRbacTestWithActionPermutations, NotRulePermissionAnyPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Change the policy itself for a negative test where there is no match.
policy.clear_permissions();
policy.add_permissions()->mutable_not_rule()->set_any(true);
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, AndRulePermissionAnyPrincipal) {
@@ -2502,20 +2682,22 @@ TEST_P(XdsRbacTestWithActionPermutations, AndRulePermissionAnyPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Change the policy itself for a negative test where there is no match.
and_rules = (*policy.mutable_permissions())[0].mutable_and_rules();
(*and_rules->mutable_rules())[1].set_destination_port(1);
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, OrRulePermissionAnyPrincipal) {
@@ -2530,20 +2712,22 @@ TEST_P(XdsRbacTestWithActionPermutations, OrRulePermissionAnyPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Change the policy itself for a negative test where there is no match.
or_rules = (*policy.mutable_permissions())[0].mutable_or_rules();
(*or_rules->mutable_rules())[1].set_destination_port(1);
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionMethodPostPrincipal) {
@@ -2559,17 +2743,18 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionMethodPostPrincipal) {
SetServerRbacPolicy(rbac);
backends_[0]->set_allow_put_requests(true);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// All RPCs use POST method by default
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Test that an RPC with PUT method is handled properly.
SendRpc([this]() { return CreateInsecureChannel(/*use_put_requests=*/true); },
- {}, {},
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() != RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionMethodGetPrincipal) {
@@ -2584,13 +2769,14 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionMethodGetPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// Test that an RPC with a POST method gets rejected
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// TODO(yashykt): When we start supporting GET requests in the future, this
// should be modified to test that they are accepted with this rule.
}
@@ -2608,19 +2794,20 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionMethodPutPrincipal) {
SetServerRbacPolicy(rbac);
backends_[0]->set_allow_put_requests(true);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// Test that an RPC with a PUT method gets accepted
SendRpc(
- [this]() { return CreateInsecureChannel(/*use_put_requests=*/true); }, {},
- {},
+ [this]() { return CreateInsecureChannel(/*use_put_requests=*/true); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() != RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Test that an RPC with a POST method gets rejected
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionUrlPathPrincipal) {
@@ -2634,11 +2821,12 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionUrlPathPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Test an RPC with a different URL path
auto stub = grpc::testing::EchoTestService::NewStub(CreateInsecureChannel());
ClientContext context;
@@ -2668,11 +2856,12 @@ TEST_P(XdsRbacTestWithActionPermutations,
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Change the policy itself for a negative test where there is no match.
policy.clear_principals();
range = policy.add_principals()->mutable_direct_remote_ip();
@@ -2683,9 +2872,10 @@ TEST_P(XdsRbacTestWithActionPermutations,
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionRemoteIpPrincipal) {
@@ -2701,11 +2891,12 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionRemoteIpPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Change the policy itself for a negative test where there is no match.
policy.clear_principals();
range = policy.add_principals()->mutable_remote_ip();
@@ -2716,9 +2907,10 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionRemoteIpPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionAuthenticatedPrincipal) {
@@ -2749,12 +2941,13 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionAuthenticatedPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(listener, rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc([this]() { return CreateMtlsChannel(); },
- server_authenticated_identity_, client_authenticated_identity_,
+ RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
+ client_authenticated_identity_,
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionMetadataPrincipal) {
@@ -2767,20 +2960,22 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionMetadataPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Test metadata with inverted match
policy.clear_principals();
policy.add_principals()->mutable_metadata()->set_invert(true);
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionNotIdPrincipal) {
@@ -2797,20 +2992,22 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionNotIdPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Change the policy itself for a negative test where there is no match.
policy.clear_principals();
policy.add_principals()->mutable_not_id()->set_any(true);
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionAndIdPrincipal) {
@@ -2826,11 +3023,12 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionAndIdPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Change the policy itself for a negative test where there is no match.
and_ids = (*policy.mutable_principals())[0].mutable_and_ids();
(*and_ids->mutable_ids())[1].mutable_url_path()->mutable_path()->set_exact(
@@ -2838,9 +3036,10 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionAndIdPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionOrIdPrincipal) {
@@ -2856,11 +3055,12 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionOrIdPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Change the policy itself for a negative test where there is no match.
or_ids = (*policy.mutable_principals())[0].mutable_or_ids();
(*or_ids->mutable_ids())[1].mutable_url_path()->mutable_path()->set_exact(
@@ -2868,9 +3068,10 @@ TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionOrIdPrincipal) {
(*rules->mutable_policies())["policy"] = policy;
SetServerRbacPolicy(rbac);
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
}
TEST_P(XdsRbacTestWithActionPermutations,
@@ -2888,13 +3089,14 @@ TEST_P(XdsRbacTestWithActionPermutations,
audit_logger->mutable_typed_config()->PackFrom(typed_struct);
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
// An empty RBAC policy leads to all RPCs being rejected.
SendRpc(
- [this]() { return CreateInsecureChannel(); }, {}, {},
+ [this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
EXPECT_THAT(audit_logs_, ::testing::ElementsAre());
}
@@ -2930,11 +3132,12 @@ TEST_P(XdsRbacTestWithActionPermutations,
SetServerRbacPolicies(default_server_listener_,
{always_allow, rbac, always_allow});
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// If the second rbac denies the rpc, only one log from the first rbac.
// Otherwise, all three rbacs log.
std::vector expected(
@@ -2976,11 +3179,12 @@ TEST_P(XdsRbacTestWithActionPermutations, MultipleRbacPoliciesWithAuditOnDeny) {
SetServerRbacPolicies(default_server_listener_,
{always_allow, rbac, always_allow});
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// Only the second rbac logs if it denies the rpc.
std::vector expected;
if (GetParam().rbac_action() == RBAC_Action_DENY) {
@@ -3024,11 +3228,12 @@ TEST_P(XdsRbacTestWithActionPermutations,
SetServerRbacPolicies(default_server_listener_,
{always_allow, rbac, always_allow});
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
// If the second rbac denies the request, the last rbac won't log. Otherwise
// all rbacs log.
std::vector expected = {
@@ -3073,11 +3278,12 @@ TEST_P(XdsRbacTestWithActionAndAuditConditionPermutations,
audit_logger->mutable_typed_config()->PackFrom(typed_struct);
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
EXPECT_THAT(audit_logs_, ::testing::ElementsAre());
}
@@ -3105,12 +3311,13 @@ TEST_P(XdsRbacTestWithActionAndAuditConditionPermutations, MultipleLoggers) {
test_logger->mutable_typed_config()->PackFrom(typed_struct);
SetServerRbacPolicy(rbac);
backends_[0]->Start();
- backends_[0]->notifier()->WaitOnServingStatusChange(
- grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK);
+ ASSERT_TRUE(backends_[0]->notifier()->WaitOnServingStatusChange(
+ grpc_core::LocalIpAndPort(backends_[0]->port()), grpc::StatusCode::OK));
auto action = GetParam().rbac_action();
- SendRpc([this]() { return CreateInsecureChannel(); }, {}, {},
+ SendRpc([this]() { return CreateInsecureChannel(); },
+ RpcOptions().set_wait_for_ready(true), {}, {},
/*test_expects_failure=*/action == RBAC_Action_DENY,
- grpc::StatusCode::PERMISSION_DENIED);
+ grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
auto audit_condition = GetParam().rbac_audit_condition();
bool should_log =
(audit_condition ==
diff --git a/test/cpp/end2end/xds/xds_end2end_test_lib.cc b/test/cpp/end2end/xds/xds_end2end_test_lib.cc
index 88dd6af93c6..51812c21e12 100644
--- a/test/cpp/end2end/xds/xds_end2end_test_lib.cc
+++ b/test/cpp/end2end/xds/xds_end2end_test_lib.cc
@@ -72,15 +72,26 @@ void XdsEnd2endTest::ServerThread::XdsServingStatusNotifier::
cond_.Signal();
}
-void XdsEnd2endTest::ServerThread::XdsServingStatusNotifier::
- WaitOnServingStatusChange(std::string uri,
- grpc::StatusCode expected_status) {
+bool XdsEnd2endTest::ServerThread::XdsServingStatusNotifier::
+ WaitOnServingStatusChange(const std::string& uri,
+ grpc::StatusCode expected_status,
+ absl::Duration timeout) {
grpc_core::MutexLock lock(&mu_);
+ absl::Time deadline = absl::Now() + timeout * grpc_test_slowdown_factor();
std::map::iterator it;
while ((it = status_map.find(uri)) == status_map.end() ||
it->second.error_code() != expected_status) {
- cond_.Wait(&mu_);
+ if (cond_.WaitWithDeadline(&mu_, deadline)) {
+ LOG(ERROR) << "\nTimeout Elapsed waiting on serving status "
+ "change\nExpected status: "
+ << expected_status << "\nActual:"
+ << (it == status_map.end()
+ ? "Entry not found in map"
+ : absl::StrCat(it->second.error_code()));
+ return false;
+ }
}
+ return true;
}
//
@@ -714,33 +725,37 @@ Status XdsEnd2endTest::LongRunningRpc::GetStatus() {
return status_;
}
-std::vector XdsEnd2endTest::SendConcurrentRpcs(
+std::vector>
+XdsEnd2endTest::SendConcurrentRpcs(
const grpc_core::DebugLocation& debug_location,
grpc::testing::EchoTestService::Stub* stub, size_t num_rpcs,
const RpcOptions& rpc_options) {
// Variables for RPCs.
- std::vector rpcs(num_rpcs);
+ std::vector> rpcs;
+ rpcs.reserve(num_rpcs);
EchoRequest request;
// Variables for synchronization
grpc_core::Mutex mu;
grpc_core::CondVar cv;
size_t completed = 0;
// Set-off callback RPCs
- for (size_t i = 0; i < num_rpcs; i++) {
- ConcurrentRpc* rpc = &rpcs[i];
+ for (size_t i = 0; i < num_rpcs; ++i) {
+ auto rpc = std::make_unique();
rpc_options.SetupRpc(&rpc->context, &request);
grpc_core::Timestamp t0 = NowFromCycleCounter();
- stub->async()->Echo(&rpc->context, &request, &rpc->response,
- [rpc, &mu, &completed, &cv, num_rpcs, t0](Status s) {
- rpc->status = s;
- rpc->elapsed_time = NowFromCycleCounter() - t0;
- bool done;
- {
- grpc_core::MutexLock lock(&mu);
- done = (++completed) == num_rpcs;
- }
- if (done) cv.Signal();
- });
+ stub->async()->Echo(
+ &rpc->context, &request, &rpc->response,
+ [rpc = rpc.get(), &mu, &completed, &cv, num_rpcs, t0](Status s) {
+ rpc->status = s;
+ rpc->elapsed_time = NowFromCycleCounter() - t0;
+ bool done;
+ {
+ grpc_core::MutexLock lock(&mu);
+ done = (++completed) == num_rpcs;
+ }
+ if (done) cv.Signal();
+ });
+ rpcs.push_back(std::move(rpc));
}
{
grpc_core::MutexLock lock(&mu);
@@ -828,11 +843,26 @@ std::string XdsEnd2endTest::MakeConnectionFailureRegex(
"(Connection refused"
"|Connection reset by peer"
"|Socket closed"
+ "|Broken pipe"
"|FD shutdown)"
// errno value
"( \\([0-9]+\\))?");
}
+std::string XdsEnd2endTest::MakeTlsHandshakeFailureRegex(
+ absl::string_view prefix) {
+ return absl::StrCat(
+ prefix,
+ "(UNKNOWN|UNAVAILABLE): "
+ // IP address
+ "(ipv6:%5B::1%5D|ipv4:127.0.0.1):[0-9]+: "
+ // Prefixes added for context
+ "(Failed to connect to remote host: )?"
+ // Tls handshake failure
+ "Tls handshake failed \\(TSI_PROTOCOL_FAILURE\\): SSL_ERROR_SSL: "
+ "error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED");
+}
+
grpc_core::PemKeyCertPairList XdsEnd2endTest::ReadTlsIdentityPair(
const char* key_path, const char* cert_path) {
return grpc_core::PemKeyCertPairList{grpc_core::PemKeyCertPair(
diff --git a/test/cpp/end2end/xds/xds_end2end_test_lib.h b/test/cpp/end2end/xds/xds_end2end_test_lib.h
index 68991fc881c..5183e9cd562 100644
--- a/test/cpp/end2end/xds/xds_end2end_test_lib.h
+++ b/test/cpp/end2end/xds/xds_end2end_test_lib.h
@@ -217,8 +217,9 @@ class XdsEnd2endTest : public ::testing::TestWithParam,
void OnServingStatusUpdate(std::string uri,
ServingStatusUpdate update) override;
- void WaitOnServingStatusChange(std::string uri,
- grpc::StatusCode expected_status);
+ GRPC_MUST_USE_RESULT bool WaitOnServingStatusChange(
+ const std::string& uri, grpc::StatusCode expected_status,
+ absl::Duration timeout = absl::Seconds(10));
private:
grpc_core::Mutex mu_;
@@ -475,11 +476,11 @@ class XdsEnd2endTest : public ::testing::TestWithParam,
size_t backend_idx,
::envoy::config::core::v3::HealthStatus health_status =
::envoy::config::core::v3::HealthStatus::UNKNOWN,
- int lb_weight = 1, std::vector additional_backend_indxes = {},
+ int lb_weight = 1, std::vector additional_backend_indexes = {},
absl::string_view hostname = "") {
std::vector additional_ports;
- additional_ports.reserve(additional_backend_indxes.size());
- for (size_t idx : additional_backend_indxes) {
+ additional_ports.reserve(additional_backend_indexes.size());
+ for (size_t idx : additional_backend_indexes) {
additional_ports.push_back(backends_[idx]->port());
}
return EdsResourceArgs::Endpoint(backends_[backend_idx]->port(),
@@ -497,7 +498,7 @@ class XdsEnd2endTest : public ::testing::TestWithParam,
// Returns an endpoint for an unused port, for use in constructing an
// EDS resource.
- EdsResourceArgs::Endpoint MakeNonExistantEndpoint() {
+ EdsResourceArgs::Endpoint MakeNonExistentEndpoint() {
return EdsResourceArgs::Endpoint(grpc_pick_unused_port_or_die());
}
@@ -747,7 +748,7 @@ class XdsEnd2endTest : public ::testing::TestWithParam,
const RpcOptions& rpc_options = RpcOptions());
// Sends num_rpcs RPCs, counting how many of them fail with a message
- // matching the specfied expected_message_prefix.
+ // matching the specified expected_message_prefix.
// Any failure with a non-matching status or message is a test failure.
size_t SendRpcsAndCountFailuresWithMessage(
const grpc_core::DebugLocation& debug_location, size_t num_rpcs,
@@ -785,7 +786,7 @@ class XdsEnd2endTest : public ::testing::TestWithParam,
grpc_core::Duration elapsed_time;
EchoResponse response;
};
- std::vector SendConcurrentRpcs(
+ std::vector> SendConcurrentRpcs(
const grpc_core::DebugLocation& debug_location,
grpc::testing::EchoTestService::Stub* stub, size_t num_rpcs,
const RpcOptions& rpc_options);
@@ -943,7 +944,7 @@ class XdsEnd2endTest : public ::testing::TestWithParam,
// sigma (standard deviation) to cover the probability area of 99.99994%. In
// another word, for a sample with size "n" probability "p" error-tolerance
// "k", we want the error always land within 5.00 sigma. The sigma of
- // binominal distribution and be computed as sqrt(np(1-p)). Hence, we have
+ // binomial distribution and be computed as sqrt(np(1-p)). Hence, we have
// the equation:
//
// kn <= 5.00 * sqrt(np(1-p))
@@ -965,6 +966,10 @@ class XdsEnd2endTest : public ::testing::TestWithParam,
// message for a connection failure.
static std::string MakeConnectionFailureRegex(absl::string_view prefix);
+ // Returns a regex that can be matched against an RPC failure status
+ // message for a Tls handshake failure.
+ static std::string MakeTlsHandshakeFailureRegex(absl::string_view prefix);
+
// Returns a private key pair, read from local files.
static grpc_core::PemKeyCertPairList ReadTlsIdentityPair(
const char* key_path, const char* cert_path);
diff --git a/test/cpp/end2end/xds/xds_fault_injection_end2end_test.cc b/test/cpp/end2end/xds/xds_fault_injection_end2end_test.cc
index 35653fd8748..3c560fc5c5e 100644
--- a/test/cpp/end2end/xds/xds_fault_injection_end2end_test.cc
+++ b/test/cpp/end2end/xds/xds_fault_injection_end2end_test.cc
@@ -108,7 +108,7 @@ INSTANTIATE_TEST_SUITE_P(
TEST_P(FaultInjectionTest, XdsFaultInjectionAlwaysAbort) {
const uint32_t kAbortPercentagePerHundred = 100;
// Create an EDS resource
- EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
+ EdsResourceArgs args({{"locality0", {MakeNonExistentEndpoint()}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
// Construct the fault injection filter config
HTTPFault http_fault;
@@ -240,12 +240,12 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionPercentageDelay) {
// Send kNumRpcs RPCs and count the delays.
RpcOptions rpc_options =
RpcOptions().set_timeout(kRpcTimeout).set_skip_cancelled_check(true);
- std::vector rpcs =
+ std::vector> rpcs =
SendConcurrentRpcs(DEBUG_LOCATION, stub_.get(), kNumRpcs, rpc_options);
size_t num_delayed = 0;
for (auto& rpc : rpcs) {
- if (rpc.status.error_code() == StatusCode::OK) continue;
- EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, rpc.status.error_code());
+ if (rpc->status.error_code() == StatusCode::OK) continue;
+ EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, rpc->status.error_code());
++num_delayed;
}
// The delay rate should be roughly equal to the expectation.
@@ -295,12 +295,12 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionPercentageDelayViaHeaders) {
.set_metadata(metadata)
.set_timeout(kRpcTimeout)
.set_skip_cancelled_check(true);
- std::vector rpcs =
+ std::vector> rpcs =
SendConcurrentRpcs(DEBUG_LOCATION, stub_.get(), kNumRpcs, rpc_options);
size_t num_delayed = 0;
for (auto& rpc : rpcs) {
- if (rpc.status.error_code() == StatusCode::OK) continue;
- EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, rpc.status.error_code());
+ if (rpc->status.error_code() == StatusCode::OK) continue;
+ EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, rpc->status.error_code());
++num_delayed;
}
// The delay rate should be roughly equal to the expectation.
@@ -381,12 +381,12 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionAlwaysDelayPercentageAbort) {
// Send kNumRpcs RPCs and count the aborts.
int num_aborted = 0;
RpcOptions rpc_options = RpcOptions().set_timeout(kRpcTimeout);
- std::vector rpcs =
+ std::vector> rpcs =
SendConcurrentRpcs(DEBUG_LOCATION, stub_.get(), kNumRpcs, rpc_options);
for (auto& rpc : rpcs) {
- EXPECT_GE(rpc.elapsed_time, kFixedDelay * grpc_test_slowdown_factor());
- if (rpc.status.error_code() == StatusCode::OK) continue;
- EXPECT_EQ("Fault injected", rpc.status.error_message());
+ EXPECT_GE(rpc->elapsed_time, kFixedDelay * grpc_test_slowdown_factor());
+ if (rpc->status.error_code() == StatusCode::OK) continue;
+ EXPECT_EQ("Fault injected", rpc->status.error_message());
++num_aborted;
}
// The abort rate should be roughly equal to the expectation.
@@ -438,12 +438,12 @@ TEST_P(FaultInjectionTest,
// Send kNumRpcs RPCs and count the aborts.
int num_aborted = 0;
RpcOptions rpc_options = RpcOptions().set_timeout(kRpcTimeout);
- std::vector rpcs =
+ std::vector> rpcs =
SendConcurrentRpcs(DEBUG_LOCATION, stub_.get(), kNumRpcs, rpc_options);
for (auto& rpc : rpcs) {
- EXPECT_GE(rpc.elapsed_time, kFixedDelay * grpc_test_slowdown_factor());
- if (rpc.status.error_code() == StatusCode::OK) continue;
- EXPECT_EQ("Fault injected", rpc.status.error_message());
+ EXPECT_GE(rpc->elapsed_time, kFixedDelay * grpc_test_slowdown_factor());
+ if (rpc->status.error_code() == StatusCode::OK) continue;
+ EXPECT_EQ("Fault injected", rpc->status.error_message());
++num_aborted;
}
// The abort rate should be roughly equal to the expectation.
@@ -481,11 +481,11 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionMaxFault) {
// active faults quota.
int num_delayed = 0;
RpcOptions rpc_options = RpcOptions().set_timeout(kRpcTimeout);
- std::vector rpcs =
+ std::vector> rpcs =
SendConcurrentRpcs(DEBUG_LOCATION, stub_.get(), kNumRpcs, rpc_options);
for (auto& rpc : rpcs) {
- if (rpc.status.error_code() == StatusCode::OK) continue;
- EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, rpc.status.error_code());
+ if (rpc->status.error_code() == StatusCode::OK) continue;
+ EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, rpc->status.error_code());
++num_delayed;
}
// Only kMaxFault number of RPC should be fault injected.
@@ -495,8 +495,8 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionMaxFault) {
num_delayed = 0;
rpcs = SendConcurrentRpcs(DEBUG_LOCATION, stub_.get(), kNumRpcs, rpc_options);
for (auto& rpc : rpcs) {
- if (rpc.status.error_code() == StatusCode::OK) continue;
- EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, rpc.status.error_code());
+ if (rpc->status.error_code() == StatusCode::OK) continue;
+ EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, rpc->status.error_code());
++num_delayed;
}
// Only kMaxFault number of RPC should be fault injected. If the max fault
diff --git a/test/cpp/end2end/xds/xds_outlier_detection_end2end_test.cc b/test/cpp/end2end/xds/xds_outlier_detection_end2end_test.cc
index 99c5b38ded1..17df1d08cac 100644
--- a/test/cpp/end2end/xds/xds_outlier_detection_end2end_test.cc
+++ b/test/cpp/end2end/xds/xds_outlier_detection_end2end_test.cc
@@ -266,7 +266,7 @@ TEST_P(OutlierDetectionTest, SuccessRateStdevFactor) {
gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(
3000 * grpc_test_slowdown_factor()));
ResetBackendCounters();
- // 1 backend experenced failure, but since the stdev_factor is high, no
+ // 1 backend experienced failure, but since the stdev_factor is high, no
// backend will be noticed as an outlier so no ejection.
// Both backends are still getting the RPCs intended for them.
CheckRpcSendOk(DEBUG_LOCATION, 100, rpc_options);
@@ -326,9 +326,9 @@ TEST_P(OutlierDetectionTest, SuccessRateEnforcementPercentage) {
gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(
3000 * grpc_test_slowdown_factor()));
ResetBackendCounters();
- // 1 backend experenced failure, but since the enforcement percentage is 0, no
- // backend will be ejected.
- // Both backends are still getting the RPCs intended for them.
+ // 1 backend experienced failure, but since the enforcement percentage is 0,
+ // no backend will be ejected. Both backends are still getting the RPCs
+ // intended for them.
CheckRpcSendOk(DEBUG_LOCATION, 100, rpc_options);
CheckRpcSendOk(DEBUG_LOCATION, 100, rpc_options1);
EXPECT_EQ(100, backends_[0]->backend_service()->request_count());
@@ -677,7 +677,7 @@ TEST_P(OutlierDetectionTest, FailurePercentageThreshold) {
gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(
3000 * grpc_test_slowdown_factor()));
ResetBackendCounters();
- // 1 backend experenced 1 failure, but since the threshold is 50 % no
+ // 1 backend experienced 1 failure, but since the threshold is 50 % no
// backend will be noticed as an outlier so no ejection.
// Both backends are still getting the RPCs intended for them.
CheckRpcSendOk(DEBUG_LOCATION, 100, rpc_options);
@@ -738,9 +738,9 @@ TEST_P(OutlierDetectionTest, FailurePercentageEnforcementPercentage) {
gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(
3000 * grpc_test_slowdown_factor()));
ResetBackendCounters();
- // 1 backend experenced failure, but since the enforcement percentage is 0, no
- // backend will be ejected.
- // Both backends are still getting the RPCs intended for them.
+ // 1 backend experienced failure, but since the enforcement percentage is 0,
+ // no backend will be ejected. Both backends are still getting the RPCs
+ // intended for them.
CheckRpcSendOk(DEBUG_LOCATION, 100, rpc_options);
CheckRpcSendOk(DEBUG_LOCATION, 100, rpc_options1);
EXPECT_EQ(100, backends_[0]->backend_service()->request_count());
@@ -935,7 +935,7 @@ TEST_P(OutlierDetectionTest, SuccessRateAndFailurePercentage) {
// Cause 2 errors on 1 backend and 1 error on 2 backends and wait for 2
// backends to be ejected. The 2 errors to the 1 backend will make exactly 1
// outlier from the success rate algorithm; all 4 errors will make 3 outliers
- // from the failure pecentage algorithm because the threahold is set to 0. I
+ // from the failure percentage algorithm because the threshold is set to 0. I
// have verified through debug logs we eject 1 backend because of success
// rate, 1 backend because of failure percentage; but as we attempt to eject
// another backend because of failure percentage we will stop as we have
@@ -1037,7 +1037,7 @@ TEST_P(OutlierDetectionTest, SuccessRateAndFailurePercentageBothDisabled) {
gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(
3000 * grpc_test_slowdown_factor()));
ResetBackendCounters();
- // 1 backend experenced failure, but since there is no counting there is no
+ // 1 backend experienced failure, but since there is no counting there is no
// ejection. Both backends are still getting the RPCs intended for them.
CheckRpcSendOk(DEBUG_LOCATION, 100, rpc_options);
CheckRpcSendOk(DEBUG_LOCATION, 100, rpc_options1);
@@ -1136,7 +1136,7 @@ TEST_P(OutlierDetectionTest, EjectionRetainedAcrossPriorities) {
// Priority 0: backend 0 and a non-existent backend.
// Priority 1: backend 1.
EdsResourceArgs args({
- {"locality0", {CreateEndpoint(0), MakeNonExistantEndpoint()}},
+ {"locality0", {CreateEndpoint(0), MakeNonExistentEndpoint()}},
{"locality1", {CreateEndpoint(1)}, kDefaultLocalityWeight, 1},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
@@ -1156,7 +1156,7 @@ TEST_P(OutlierDetectionTest, EjectionRetainedAcrossPriorities) {
// Now send an EDS update that moves backend 0 to priority 1.
// We also add backend 2, so that we know when the client sees the update.
args = EdsResourceArgs({
- {"locality0", {MakeNonExistantEndpoint()}},
+ {"locality0", {MakeNonExistentEndpoint()}},
{"locality1", CreateEndpointsForBackends(), kDefaultLocalityWeight, 1},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
diff --git a/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc b/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc
index 70188884d2e..cfa4440d21d 100644
--- a/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc
+++ b/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc
@@ -105,7 +105,7 @@ TEST_P(RingHashTest, AggregateClusterFallBackFromRingHashAtStartup) {
const char* kNewEdsService2Name = "new_eds_service_name_2";
// Populate new EDS resources.
EdsResourceArgs args1({
- {"locality0", {MakeNonExistantEndpoint(), MakeNonExistantEndpoint()}},
+ {"locality0", {MakeNonExistentEndpoint(), MakeNonExistentEndpoint()}},
});
EdsResourceArgs args2({
{"locality0", CreateEndpointsForBackends()},
@@ -166,11 +166,11 @@ TEST_P(RingHashTest,
// Populate EDS resource.
EdsResourceArgs args({
{"locality0",
- {MakeNonExistantEndpoint(), MakeNonExistantEndpoint()},
+ {MakeNonExistentEndpoint(), MakeNonExistentEndpoint()},
kDefaultLocalityWeight,
0},
{"locality1",
- {MakeNonExistantEndpoint(), MakeNonExistantEndpoint()},
+ {MakeNonExistentEndpoint(), MakeNonExistentEndpoint()},
kDefaultLocalityWeight,
1},
});
@@ -234,11 +234,11 @@ TEST_P(RingHashTest,
// Populate EDS resource.
EdsResourceArgs args({
{"locality0",
- {MakeNonExistantEndpoint(), MakeNonExistantEndpoint()},
+ {MakeNonExistentEndpoint(), MakeNonExistentEndpoint()},
kDefaultLocalityWeight,
0},
{"locality1",
- {MakeNonExistantEndpoint(), MakeNonExistantEndpoint()},
+ {MakeNonExistentEndpoint(), MakeNonExistentEndpoint()},
kDefaultLocalityWeight,
1},
});
@@ -786,9 +786,9 @@ TEST_P(RingHashTest, IdleToReady) {
TEST_P(RingHashTest, ContinuesConnectingWithoutPicks) {
// Create EDS resource.
CreateAndStartBackends(1);
- auto non_existant_endpoint = MakeNonExistantEndpoint();
+ auto non_existent_endpoint = MakeNonExistentEndpoint();
EdsResourceArgs args(
- {{"locality0", {non_existant_endpoint, CreateEndpoint(0)}}});
+ {{"locality0", {non_existent_endpoint, CreateEndpoint(0)}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
// Change CDS resource to use RING_HASH.
auto cluster = default_cluster_;
@@ -804,12 +804,12 @@ TEST_P(RingHashTest, ContinuesConnectingWithoutPicks) {
// Start connection attempt injector and add a hold for the P0
// connection attempt.
ConnectionAttemptInjector injector;
- auto hold = injector.AddHold(non_existant_endpoint.port);
+ auto hold = injector.AddHold(non_existent_endpoint.port);
// A long-running RPC, just used to send the RPC in another thread.
LongRunningRpc rpc;
std::vector> metadata = {
{"address_hash",
- CreateMetadataValueThatHashesToBackendPort(non_existant_endpoint.port)}};
+ CreateMetadataValueThatHashesToBackendPort(non_existent_endpoint.port)}};
rpc.StartRpc(stub_.get(), RpcOptions().set_timeout_ms(0).set_metadata(
std::move(metadata)));
// Wait for the RPC to trigger the P0 connection attempt, then cancel it,
@@ -829,12 +829,12 @@ TEST_P(RingHashTest, ContinuesConnectingWithoutPicks) {
TEST_P(RingHashTest, ContinuesConnectingWithoutPicksOneSubchannelAtATime) {
// Create EDS resource.
CreateAndStartBackends(1);
- auto non_existant_endpoint0 = MakeNonExistantEndpoint();
- auto non_existant_endpoint1 = MakeNonExistantEndpoint();
- auto non_existant_endpoint2 = MakeNonExistantEndpoint();
+ auto non_existent_endpoint0 = MakeNonExistentEndpoint();
+ auto non_existent_endpoint1 = MakeNonExistentEndpoint();
+ auto non_existent_endpoint2 = MakeNonExistentEndpoint();
EdsResourceArgs args({{"locality0",
- {non_existant_endpoint0, non_existant_endpoint1,
- non_existant_endpoint2, CreateEndpoint(0)}}});
+ {non_existent_endpoint0, non_existent_endpoint1,
+ non_existent_endpoint2, CreateEndpoint(0)}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
// Change CDS resource to use RING_HASH.
auto cluster = default_cluster_;
@@ -849,59 +849,59 @@ TEST_P(RingHashTest, ContinuesConnectingWithoutPicksOneSubchannelAtATime) {
new_route_config);
// Start connection attempt injector.
ConnectionAttemptInjector injector;
- auto hold_non_existant0 = injector.AddHold(non_existant_endpoint0.port);
- auto hold_non_existant1 = injector.AddHold(non_existant_endpoint1.port);
- auto hold_non_existant2 = injector.AddHold(non_existant_endpoint2.port);
+ auto hold_non_existent0 = injector.AddHold(non_existent_endpoint0.port);
+ auto hold_non_existent1 = injector.AddHold(non_existent_endpoint1.port);
+ auto hold_non_existent2 = injector.AddHold(non_existent_endpoint2.port);
auto hold_good = injector.AddHold(backends_[0]->port());
// A long-running RPC, just used to send the RPC in another thread.
LongRunningRpc rpc;
std::vector> metadata = {
{"address_hash", CreateMetadataValueThatHashesToBackendPort(
- non_existant_endpoint0.port)}};
+ non_existent_endpoint0.port)}};
rpc.StartRpc(stub_.get(), RpcOptions().set_timeout_ms(0).set_metadata(
std::move(metadata)));
// Wait for the RPC to trigger a connection attempt to the first address,
// then cancel the RPC. No other connection attempts should be started yet.
- hold_non_existant0->Wait();
+ hold_non_existent0->Wait();
rpc.CancelRpc();
- EXPECT_FALSE(hold_non_existant1->IsStarted());
- EXPECT_FALSE(hold_non_existant2->IsStarted());
+ EXPECT_FALSE(hold_non_existent1->IsStarted());
+ EXPECT_FALSE(hold_non_existent2->IsStarted());
EXPECT_FALSE(hold_good->IsStarted());
// Allow the connection attempt to the first address to resume and wait
// for the attempt for the second address. No other connection
// attempts should be started yet.
- auto hold_non_existant0_again = injector.AddHold(non_existant_endpoint0.port);
- hold_non_existant0->Resume();
- hold_non_existant1->Wait();
- EXPECT_FALSE(hold_non_existant0_again->IsStarted());
- EXPECT_FALSE(hold_non_existant2->IsStarted());
+ auto hold_non_existent0_again = injector.AddHold(non_existent_endpoint0.port);
+ hold_non_existent0->Resume();
+ hold_non_existent1->Wait();
+ EXPECT_FALSE(hold_non_existent0_again->IsStarted());
+ EXPECT_FALSE(hold_non_existent2->IsStarted());
EXPECT_FALSE(hold_good->IsStarted());
// Allow the connection attempt to the second address to resume and wait
// for the attempt for the third address. No other connection
// attempts should be started yet.
- auto hold_non_existant1_again = injector.AddHold(non_existant_endpoint1.port);
- hold_non_existant1->Resume();
- hold_non_existant2->Wait();
- EXPECT_FALSE(hold_non_existant0_again->IsStarted());
- EXPECT_FALSE(hold_non_existant1_again->IsStarted());
+ auto hold_non_existent1_again = injector.AddHold(non_existent_endpoint1.port);
+ hold_non_existent1->Resume();
+ hold_non_existent2->Wait();
+ EXPECT_FALSE(hold_non_existent0_again->IsStarted());
+ EXPECT_FALSE(hold_non_existent1_again->IsStarted());
EXPECT_FALSE(hold_good->IsStarted());
// Allow the connection attempt to the third address to resume and wait
// for the attempt for the final address. No other connection
// attempts should be started yet.
- auto hold_non_existant2_again = injector.AddHold(non_existant_endpoint2.port);
- hold_non_existant2->Resume();
+ auto hold_non_existent2_again = injector.AddHold(non_existent_endpoint2.port);
+ hold_non_existent2->Resume();
hold_good->Wait();
- EXPECT_FALSE(hold_non_existant0_again->IsStarted());
- EXPECT_FALSE(hold_non_existant1_again->IsStarted());
- EXPECT_FALSE(hold_non_existant2_again->IsStarted());
+ EXPECT_FALSE(hold_non_existent0_again->IsStarted());
+ EXPECT_FALSE(hold_non_existent1_again->IsStarted());
+ EXPECT_FALSE(hold_non_existent2_again->IsStarted());
// Allow the final attempt to resume.
hold_good->Resume();
// Wait for channel to become connected without any pending RPC.
EXPECT_TRUE(channel_->WaitForConnected(grpc_timeout_seconds_to_deadline(10)));
// No other connection attempts should have been started.
- EXPECT_FALSE(hold_non_existant0_again->IsStarted());
- EXPECT_FALSE(hold_non_existant1_again->IsStarted());
- EXPECT_FALSE(hold_non_existant2_again->IsStarted());
+ EXPECT_FALSE(hold_non_existent0_again->IsStarted());
+ EXPECT_FALSE(hold_non_existent1_again->IsStarted());
+ EXPECT_FALSE(hold_non_existent2_again->IsStarted());
// RPC should have been cancelled.
EXPECT_EQ(StatusCode::CANCELLED, rpc.GetStatus().error_code());
// Make sure the backend did not get any requests.
@@ -940,7 +940,7 @@ TEST_P(RingHashTest, TransientFailureCheckNextOne) {
// Test that when a backend goes down, we will move on to the next subchannel
// (with a lower priority). When the backend comes back up, traffic will move
// back.
-TEST_P(RingHashTest, SwitchToLowerPrioirtyAndThenBack) {
+TEST_P(RingHashTest, SwitchToLowerPriorityAndThenBack) {
CreateAndStartBackends(2);
auto cluster = default_cluster_;
cluster.set_lb_policy(Cluster::RING_HASH);
@@ -990,7 +990,7 @@ TEST_P(RingHashTest, ReattemptWhenAllEndpointsUnreachable) {
SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
new_route_config);
EdsResourceArgs args(
- {{"locality0", {MakeNonExistantEndpoint(), CreateEndpoint(0)}}});
+ {{"locality0", {MakeNonExistentEndpoint(), CreateEndpoint(0)}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
std::vector> metadata = {
{"address_hash", CreateMetadataValueThatHashesToBackend(0)}};
@@ -1024,8 +1024,8 @@ TEST_P(RingHashTest, TransientFailureSkipToAvailableReady) {
// Make sure we include some unused ports to fill the ring.
EdsResourceArgs args({
{"locality0",
- {CreateEndpoint(0), CreateEndpoint(1), MakeNonExistantEndpoint(),
- MakeNonExistantEndpoint()}},
+ {CreateEndpoint(0), CreateEndpoint(1), MakeNonExistentEndpoint(),
+ MakeNonExistentEndpoint()}},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
std::vector> metadata = {
@@ -1124,7 +1124,7 @@ TEST_P(RingHashTest, ReattemptWhenGoingFromTransientFailureToIdle) {
EXPECT_EQ(GRPC_CHANNEL_READY, channel_->GetState(false));
}
-// Test unspported hash policy types are all ignored before a supported
+// Test unsupported hash policy types are all ignored before a supported
// policy.
TEST_P(RingHashTest, UnsupportedHashPolicyUntilChannelIdHashing) {
CreateAndStartBackends(2);
diff --git a/test/cpp/end2end/xds/xds_routing_end2end_test.cc b/test/cpp/end2end/xds/xds_routing_end2end_test.cc
index 1c6369f0cc3..7b7a2be9a52 100644
--- a/test/cpp/end2end/xds/xds_routing_end2end_test.cc
+++ b/test/cpp/end2end/xds/xds_routing_end2end_test.cc
@@ -472,7 +472,7 @@ TEST_P(LdsRdsTest, ChooseLastRoute) {
}
TEST_P(LdsRdsTest, NoMatchingRoute) {
- EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
+ EdsResourceArgs args({{"locality0", {MakeNonExistentEndpoint()}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
RouteConfiguration route_config = default_route_config_;
route_config.mutable_virtual_hosts(0)
@@ -531,7 +531,7 @@ TEST_P(LdsRdsTest, NacksInvalidRouteConfig) {
// Tests that LDS client should fail RPCs with UNAVAILABLE status code if the
// matching route has an action other than RouteAction.
TEST_P(LdsRdsTest, MatchingRouteHasNoRouteAction) {
- EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
+ EdsResourceArgs args({{"locality0", {MakeNonExistentEndpoint()}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
RouteConfiguration route_config = default_route_config_;
// Set a route with an inappropriate route action
@@ -1548,10 +1548,10 @@ TEST_P(LdsRdsTest, XdsRoutingApplyXdsTimeout) {
const char* kNewCluster3Name = "new_cluster_3";
const char* kNewEdsService3Name = "new_eds_service_name_3";
// Populate new EDS resources.
- EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
- EdsResourceArgs args1({{"locality0", {MakeNonExistantEndpoint()}}});
- EdsResourceArgs args2({{"locality0", {MakeNonExistantEndpoint()}}});
- EdsResourceArgs args3({{"locality0", {MakeNonExistantEndpoint()}}});
+ EdsResourceArgs args({{"locality0", {MakeNonExistentEndpoint()}}});
+ EdsResourceArgs args1({{"locality0", {MakeNonExistentEndpoint()}}});
+ EdsResourceArgs args2({{"locality0", {MakeNonExistentEndpoint()}}});
+ EdsResourceArgs args3({{"locality0", {MakeNonExistentEndpoint()}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsService1Name));
@@ -1661,9 +1661,9 @@ TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenXdsTimeoutExplicit) {
const char* kNewCluster2Name = "new_cluster_2";
const char* kNewEdsService2Name = "new_eds_service_name_2";
// Populate new EDS resources.
- EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
- EdsResourceArgs args1({{"locality0", {MakeNonExistantEndpoint()}}});
- EdsResourceArgs args2({{"locality0", {MakeNonExistantEndpoint()}}});
+ EdsResourceArgs args({{"locality0", {MakeNonExistentEndpoint()}}});
+ EdsResourceArgs args1({{"locality0", {MakeNonExistentEndpoint()}}});
+ EdsResourceArgs args2({{"locality0", {MakeNonExistentEndpoint()}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsService1Name));
@@ -1749,7 +1749,7 @@ TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenXdsTimeoutExplicit) {
TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenHttpTimeoutExplicit) {
const auto kTimeoutApplication = grpc_core::Duration::Milliseconds(4500);
// Populate new EDS resources.
- EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
+ EdsResourceArgs args({{"locality0", {MakeNonExistentEndpoint()}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
auto listener = default_listener_;
HttpConnectionManager http_connection_manager;
@@ -1784,7 +1784,7 @@ TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenHttpTimeoutExplicit) {
TEST_P(LdsRdsTest, XdsRoutingWithOnlyApplicationTimeout) {
const auto kTimeoutApplication = grpc_core::Duration::Milliseconds(4500);
// Populate new EDS resources.
- EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
+ EdsResourceArgs args({{"locality0", {MakeNonExistentEndpoint()}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
auto t0 = system_clock::now();
CheckRpcSendFailure(
diff --git a/test/cpp/util/channel_trace_proto_helper.cc b/test/cpp/util/channel_trace_proto_helper.cc
index 8acb762a889..e92f496e62a 100644
--- a/test/cpp/util/channel_trace_proto_helper.cc
+++ b/test/cpp/util/channel_trace_proto_helper.cc
@@ -40,7 +40,7 @@ namespace {
// then back to json. This ensures that the json string was correctly formatted
// according to https://developers.google.com/protocol-buffers/docs/proto3#json
template
-void VaidateProtoJsonTranslation(absl::string_view json_str) {
+void ValidateProtoJsonTranslation(absl::string_view json_str) {
Message msg;
grpc::protobuf::json::JsonParseOptions parse_options;
// If the following line is failing, then uncomment the last line of the
@@ -73,42 +73,42 @@ void VaidateProtoJsonTranslation(absl::string_view json_str) {
namespace testing {
void ValidateChannelTraceProtoJsonTranslation(absl::string_view json_string) {
- VaidateProtoJsonTranslation(json_string);
+ ValidateProtoJsonTranslation(json_string);
}
void ValidateChannelProtoJsonTranslation(absl::string_view json_string) {
- VaidateProtoJsonTranslation(json_string);
+ ValidateProtoJsonTranslation(json_string);
}
void ValidateGetTopChannelsResponseProtoJsonTranslation(
absl::string_view json_string) {
- VaidateProtoJsonTranslation(
+ ValidateProtoJsonTranslation(
json_string);
}
void ValidateGetChannelResponseProtoJsonTranslation(
absl::string_view json_string) {
- VaidateProtoJsonTranslation(
+ ValidateProtoJsonTranslation(
json_string);
}
void ValidateGetServerResponseProtoJsonTranslation(
absl::string_view json_string) {
- VaidateProtoJsonTranslation(
+ ValidateProtoJsonTranslation(
json_string);
}
void ValidateSubchannelProtoJsonTranslation(absl::string_view json_string) {
- VaidateProtoJsonTranslation(json_string);
+ ValidateProtoJsonTranslation(json_string);
}
void ValidateServerProtoJsonTranslation(absl::string_view json_string) {
- VaidateProtoJsonTranslation(json_string);
+ ValidateProtoJsonTranslation(json_string);
}
void ValidateGetServersResponseProtoJsonTranslation(
absl::string_view json_string) {
- VaidateProtoJsonTranslation(
+ ValidateProtoJsonTranslation(
json_string);
}
diff --git a/test/cpp/util/channelz_sampler.cc b/test/cpp/util/channelz_sampler.cc
index d689319f52c..043625afa4d 100644
--- a/test/cpp/util/channelz_sampler.cc
+++ b/test/cpp/util/channelz_sampler.cc
@@ -178,9 +178,9 @@ class ChannelzSampler final {
return get_socket_response.socket();
}
- // get the descedent channels/subchannels/sockets of a channel
- // push descedent channels/subchannels to queue for layer traverse
- // store descedent channels/subchannels/sockets for dumping data
+ // get the descendant channels/subchannels/sockets of a channel
+ // push descendant channels/subchannels to queue for layer traverse
+ // store descendant channels/subchannels/sockets for dumping data
void GetChannelDescedence(
const grpc::channelz::v1::Channel& channel,
std::queue& channel_queue,
@@ -232,9 +232,9 @@ class ChannelzSampler final {
std::cout << std::endl;
}
- // get the descedent channels/subchannels/sockets of a subchannel
- // push descedent channels/subchannels to queue for layer traverse
- // store descedent channels/subchannels/sockets for dumping data
+ // get the descendant channels/subchannels/sockets of a subchannel
+ // push descendant channels/subchannels to queue for layer traverse
+ // store descendant channels/subchannels/sockets for dumping data
void GetSubchannelDescedence(
grpc::channelz::v1::Subchannel& subchannel,
std::queue& channel_queue,
diff --git a/test/distrib/gcf/python/run_single.sh b/test/distrib/gcf/python/run_single.sh
index c2387555035..6d436e2510e 100755
--- a/test/distrib/gcf/python/run_single.sh
+++ b/test/distrib/gcf/python/run_single.sh
@@ -44,7 +44,8 @@ function cleanup() {
trap cleanup SIGINT SIGTERM EXIT
# Deploy
-DEPLOY_OUTPUT=$(gcloud functions deploy "${FUNCTION_NAME}" --entry-point test_publish --runtime "${RUNTIME}" --trigger-http --allow-unauthenticated)
+
+DEPLOY_OUTPUT=$(gcloud functions deploy "${FUNCTION_NAME}" --entry-point test_publish --runtime "${RUNTIME}" --trigger-http --allow-unauthenticated --no-gen2)
HTTP_URL=$(echo "${DEPLOY_OUTPUT}" | grep "url: " | awk '{print $2;}')
# Send Requests
diff --git a/third_party/boringssl-with-bazel b/third_party/boringssl-with-bazel
index 16c8d3db1af..b8b3e6e1116 160000
--- a/third_party/boringssl-with-bazel
+++ b/third_party/boringssl-with-bazel
@@ -1 +1 @@
-Subproject commit 16c8d3db1af20fcc04b5190b25242aadcb1fbb30
+Subproject commit b8b3e6e11166719a8ebfa43c0cde9ad7d57a84f6
diff --git a/tools/distrib/python/grpc_version.py b/tools/distrib/python/grpc_version.py
index 0a2b4c0a17c..2bc64495fe9 100644
--- a/tools/distrib/python/grpc_version.py
+++ b/tools/distrib/python/grpc_version.py
@@ -14,5 +14,5 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
PROTOBUF_VERSION = '3.27.2'
diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_tools/grpc_version.py
index 164aa76d02a..dc1b11d2874 100644
--- a/tools/distrib/python/grpcio_tools/grpc_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_tools/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_tools/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index 85cac2659c3..66dd7d524fd 100644
--- a/tools/distrib/python/grpcio_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_version.py
@@ -14,5 +14,5 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
PROTOBUF_VERSION = '3.27.2'
diff --git a/tools/distrib/python/xds_protos/grpc_version.py b/tools/distrib/python/xds_protos/grpc_version.py
index 978c2c572b6..ccf4716adfa 100644
--- a/tools/distrib/python/xds_protos/grpc_version.py
+++ b/tools/distrib/python/xds_protos/grpc_version.py
@@ -14,5 +14,5 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
-VERSION = '1.67.0.dev0'
+VERSION = '1.68.0.dev0'
PROTOBUF_VERSION = '3.27.2'
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 351040cc192..396a70209f2 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.67.0-dev
+PROJECT_NUMBER = 1.68.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 75cba764be5..0332a7ddb15 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.67.0-dev
+PROJECT_NUMBER = 1.68.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 9a92a5424c2..ac83d73e8aa 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 43.0.0
+PROJECT_NUMBER = 44.0.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 2c6b3e5be77..380ede52170 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 43.0.0
+PROJECT_NUMBER = 44.0.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.objc b/tools/doxygen/Doxyfile.objc
index b8ac808811b..d81be1bba3c 100644
--- a/tools/doxygen/Doxyfile.objc
+++ b/tools/doxygen/Doxyfile.objc
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Objective-C"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.67.0-dev
+PROJECT_NUMBER = 1.68.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.objc.internal b/tools/doxygen/Doxyfile.objc.internal
index 0a95c92d783..8da26876bcf 100644
--- a/tools/doxygen/Doxyfile.objc.internal
+++ b/tools/doxygen/Doxyfile.objc.internal
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Objective-C"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.67.0-dev
+PROJECT_NUMBER = 1.68.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.php b/tools/doxygen/Doxyfile.php
index 3c8936d9dc2..ac29fc41039 100644
--- a/tools/doxygen/Doxyfile.php
+++ b/tools/doxygen/Doxyfile.php
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC PHP"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.67.0-dev
+PROJECT_NUMBER = 1.68.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py
index a37749f1a02..bc4ea2d919e 100644
--- a/tools/interop_matrix/client_matrix.py
+++ b/tools/interop_matrix/client_matrix.py
@@ -305,7 +305,7 @@ LANG_RELEASE_MATRIX = {
("v1.63.3", ReleaseInfo()),
("v1.64.1", ReleaseInfo()),
("v1.65.0", ReleaseInfo()),
- ("v1.66.0", ReleaseInfo()),
+ ("v1.66.2", ReleaseInfo()),
]
),
"java": OrderedDict(
diff --git a/tools/run_tests/helper_scripts/build_ruby.sh b/tools/run_tests/helper_scripts/build_ruby.sh
index cbf7a3cb191..2d1c8b51925 100755
--- a/tools/run_tests/helper_scripts/build_ruby.sh
+++ b/tools/run_tests/helper_scripts/build_ruby.sh
@@ -36,6 +36,18 @@ if [ "$SYSTEM" == "Darwin" ]; then
fi
bundle exec rake compile
+# Log stuff and save a hash of the binary verify later at test runtime, in order
+# to detect corruption.
+if [ "$SYSTEM" == "Darwin" ]; then
+ ls -l src/ruby/lib/grpc/grpc_c.bundle
+ file src/ruby/lib/grpc/grpc_c.bundle
+ shasum -a 256 src/ruby/lib/grpc/grpc_c.bundle | awk '{print $1}' > src/ruby/lib/grpc/grpc_c_sha256
+else
+ ls -l src/ruby/lib/grpc/grpc_c.so
+ file src/ruby/lib/grpc/grpc_c.so
+ sha256sum src/ruby/lib/grpc/grpc_c.so | awk '{print $1}' > src/ruby/lib/grpc/grpc_c_sha256
+fi
+
# build grpc_ruby_plugin
mkdir -p cmake/build
pushd cmake/build
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 287431d617a..16f05533882 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -719,7 +719,7 @@ class PythonLanguage(object):
self.config.job_spec(
python_config.run
+ [self._TEST_COMMAND[io_platform]],
- timeout_seconds=8 * 60,
+ timeout_seconds=10 * 60,
environ=dict(
GRPC_PYTHON_TESTRUNNER_FILTER=str(test_case),
**environment,
@@ -926,6 +926,7 @@ class RubyLanguage(object):
# This crashes have been unreproducible outside of CI. Also see
# b/266212253.
# - src/ruby/end2end/grpc_class_init_test.rb
+ # - src/ruby/end2end/load_grpc_with_gc_stress_test.rb
for test in [
"src/ruby/end2end/fork_test.rb",
"src/ruby/end2end/simple_fork_test.rb",
@@ -938,7 +939,6 @@ class RubyLanguage(object):
"src/ruby/end2end/killed_client_thread_test.rb",
"src/ruby/end2end/forking_client_test.rb",
"src/ruby/end2end/multiple_killed_watching_threads_test.rb",
- "src/ruby/end2end/load_grpc_with_gc_stress_test.rb",
"src/ruby/end2end/client_memory_usage_test.rb",
"src/ruby/end2end/package_with_underscore_test.rb",
"src/ruby/end2end/graceful_sig_handling_test.rb",
@@ -1113,7 +1113,7 @@ class ObjCLanguage(object):
out.append(
self.config.job_spec(
["src/objective-c/tests/build_one_example.sh"],
- timeout_seconds=20 * 60,
+ timeout_seconds=60 * 60,
shortname="ios-buildtest-example-sample",
cpu_cost=1e6,
environ={
@@ -1126,7 +1126,7 @@ class ObjCLanguage(object):
out.append(
self.config.job_spec(
["src/objective-c/tests/build_one_example.sh"],
- timeout_seconds=20 * 60,
+ timeout_seconds=60 * 60,
shortname="ios-buildtest-example-switftsample",
cpu_cost=1e6,
environ={
@@ -1138,7 +1138,7 @@ class ObjCLanguage(object):
out.append(
self.config.job_spec(
["src/objective-c/tests/build_one_example.sh"],
- timeout_seconds=20 * 60,
+ timeout_seconds=60 * 60,
shortname="ios-buildtest-example-switft-use-frameworks",
cpu_cost=1e6,
environ={
@@ -1164,15 +1164,16 @@ class ObjCLanguage(object):
# TODO(jtattermusch): move the test out of the test/core/iomgr/CFStreamTests directory?
# How does one add the cfstream dependency in bazel?
- out.append(
- self.config.job_spec(
- ["test/core/iomgr/ios/CFStreamTests/build_and_run_tests.sh"],
- timeout_seconds=60 * 60,
- shortname="ios-test-cfstream-tests",
- cpu_cost=1e6,
- environ=_FORCE_ENVIRON_FOR_WRAPPERS,
- )
- )
+ # Disabled due to flakiness and being replaced with event engine
+ # out.append(
+ # self.config.job_spec(
+ # ["test/core/iomgr/ios/CFStreamTests/build_and_run_tests.sh"],
+ # timeout_seconds=60 * 60,
+ # shortname="ios-test-cfstream-tests",
+ # cpu_cost=1e6,
+ # environ=_FORCE_ENVIRON_FOR_WRAPPERS,
+ # )
+ # )
return sorted(out)
def pre_build_steps(self):
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index fc2cc2ee7d5..4058cc5261d 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -34,7 +34,7 @@ _DEFAULT_RUNTESTS_TIMEOUT = 1 * 60 * 60
_CPP_RUNTESTS_TIMEOUT = 4 * 60 * 60
# Set timeout high for ObjC for Cocoapods to install pods
-_OBJC_RUNTESTS_TIMEOUT = 2 * 60 * 60
+_OBJC_RUNTESTS_TIMEOUT = 4 * 60 * 60
# Number of jobs assigned to each run_tests.py instance
_DEFAULT_INNER_JOBS = 2
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index dbb6ee6c4f6..7e5245b963b 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -28,7 +28,7 @@ cat <"$want_submodules"
third_party/abseil-cpp 4a2c63365eff8823a5221db86ef490e828306f9d
third_party/benchmark 344117638c8ff7e239044fd0fa7085839fc03021
third_party/bloaty 60209eb1ccc34d5deefb002d1b7f37545204f7f2
-third_party/boringssl-with-bazel 16c8d3db1af20fcc04b5190b25242aadcb1fbb30
+third_party/boringssl-with-bazel b8b3e6e11166719a8ebfa43c0cde9ad7d57a84f6
third_party/cares/cares 6360e96b5cf8e5980c887ce58ef727e53d77243a
third_party/envoy-api f8b75d1efa92bbf534596a013d9ca5873f79dd30
third_party/googleapis fe8ba054ad4f7eca946c2d14a63c3f07c0b586a0