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