Merge branch 'master' into fix-time

pull/14894/head
Sree Kuchibhotla 7 years ago
commit 94d9034673
  1. 5
      .clang-format
  2. 1
      BUILD
  3. 2
      build.yaml
  4. 7
      grpc.def
  5. 70
      include/grpc/grpc_security.h
  6. 11
      include/grpc/impl/codegen/port_platform.h
  7. 4
      include/grpc/support/log.h
  8. 4
      include/grpcpp/impl/codegen/byte_buffer.h
  9. 6
      include/grpcpp/impl/codegen/proto_buffer_reader.h
  10. 13
      include/grpcpp/impl/codegen/proto_buffer_writer.h
  11. 7
      include/grpcpp/impl/codegen/proto_utils.h
  12. 16
      include/grpcpp/security/credentials.h
  13. 12
      include/grpcpp/security/server_credentials.h
  14. 3
      setup.py
  15. 9
      src/android/test/interop/.gitignore
  16. 37
      src/android/test/interop/README.md
  17. 1
      src/android/test/interop/app/.gitignore
  18. 119
      src/android/test/interop/app/CMakeLists.txt
  19. 56
      src/android/test/interop/app/build.gradle
  20. 21
      src/android/test/interop/app/proguard-rules.pro
  21. 93
      src/android/test/interop/app/src/androidTest/java/io/grpc/interop/cpp/InteropTest.java
  22. 22
      src/android/test/interop/app/src/main/AndroidManifest.xml
  23. 4475
      src/android/test/interop/app/src/main/assets/roots.pem
  24. 124
      src/android/test/interop/app/src/main/cpp/grpc-interop.cc
  25. 122
      src/android/test/interop/app/src/main/java/io/grpc/interop/cpp/InteropActivity.java
  26. 48
      src/android/test/interop/app/src/main/res/layout/activity_interop.xml
  27. BIN
      src/android/test/interop/app/src/main/res/mipmap-hdpi/ic_launcher.png
  28. BIN
      src/android/test/interop/app/src/main/res/mipmap-mdpi/ic_launcher.png
  29. BIN
      src/android/test/interop/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  30. BIN
      src/android/test/interop/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  31. 3
      src/android/test/interop/app/src/main/res/values/strings.xml
  32. 24
      src/android/test/interop/build.gradle
  33. 17
      src/android/test/interop/gradle.properties
  34. BIN
      src/android/test/interop/gradle/wrapper/gradle-wrapper.jar
  35. 6
      src/android/test/interop/gradle/wrapper/gradle-wrapper.properties
  36. 160
      src/android/test/interop/gradlew
  37. 90
      src/android/test/interop/gradlew.bat
  38. 1
      src/android/test/interop/settings.gradle
  39. 1
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  40. 30
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  41. 10
      src/core/lib/gpr/log.cc
  42. 4
      src/core/lib/gpr/log_android.cc
  43. 4
      src/core/lib/gpr/log_linux.cc
  44. 4
      src/core/lib/gpr/log_posix.cc
  45. 5
      src/core/lib/gpr/log_windows.cc
  46. 24
      src/core/lib/iomgr/socket_utils_common_posix.cc
  47. 3
      src/core/lib/iomgr/socket_utils_posix.h
  48. 27
      src/core/lib/iomgr/tcp_server_posix.cc
  49. 101
      src/core/lib/iomgr/udp_server.cc
  50. 10
      src/core/lib/iomgr/udp_server.h
  51. 20
      src/core/lib/security/credentials/alts/alts_credentials.h
  52. 14
      src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc
  53. 39
      src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h
  54. 21
      src/cpp/client/secure_credentials.cc
  55. 14
      src/cpp/server/secure_server_credentials.cc
  56. 6
      src/objective-c/GRPCClient/GRPCCall+ChannelArg.h
  57. 3
      src/objective-c/GRPCClient/GRPCCall+ChannelArg.m
  58. 3
      src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.m
  59. 2
      src/objective-c/GRPCClient/GRPCCall+GID.h
  60. 5
      src/objective-c/GRPCClient/GRPCCall+Tests.m
  61. 3
      src/objective-c/GRPCClient/GRPCCall.h
  62. 62
      src/objective-c/GRPCClient/GRPCCall.m
  63. 4
      src/objective-c/GRPCClient/private/GRPCChannel.h
  64. 46
      src/objective-c/GRPCClient/private/GRPCChannel.m
  65. 5
      src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
  66. 3
      src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h
  67. 11
      src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
  68. 1
      src/objective-c/GRPCClient/private/GRPCHost.h
  69. 42
      src/objective-c/GRPCClient/private/GRPCHost.m
  70. 1
      src/objective-c/GRPCClient/private/GRPCOpBatchLog.h
  71. 6
      src/objective-c/GRPCClient/private/GRPCReachabilityFlagNames.xmacro.h
  72. 12
      src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
  73. 3
      src/objective-c/GRPCClient/private/GRPCWrappedCall.h
  74. 35
      src/objective-c/GRPCClient/private/GRPCWrappedCall.m
  75. 10
      src/objective-c/GRPCClient/private/NSData+GRPC.m
  76. 3
      src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
  77. 1
      src/objective-c/GRPCClient/private/version.h
  78. 5
      src/objective-c/ProtoRPC/ProtoMethod.h
  79. 18
      src/objective-c/ProtoRPC/ProtoRPC.h
  80. 10
      src/objective-c/ProtoRPC/ProtoRPC.m
  81. 11
      src/objective-c/ProtoRPC/ProtoService.h
  82. 5
      src/objective-c/ProtoRPC/ProtoService.m
  83. 3
      src/objective-c/RxLibrary/GRXBufferedPipe.m
  84. 2
      src/objective-c/RxLibrary/GRXConcurrentWriteable.h
  85. 3
      src/objective-c/RxLibrary/GRXConcurrentWriteable.m
  86. 3
      src/objective-c/RxLibrary/GRXImmediateWriter.m
  87. 14
      src/objective-c/RxLibrary/GRXWriteable.m
  88. 2
      src/objective-c/RxLibrary/GRXWriter+Immediate.m
  89. 7
      src/objective-c/RxLibrary/transformations/GRXMappingWriter.h
  90. 12
      src/objective-c/examples/Sample/Sample/ViewController.m
  91. 28
      src/objective-c/tests/Connectivity/ConnectivityTestingApp/ViewController.m
  92. 34
      src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm
  93. 49
      src/objective-c/tests/CronetUnitTests/CronetUnitTests.m
  94. 175
      src/objective-c/tests/GRPCClientTests.m
  95. 119
      src/objective-c/tests/InteropTests.m
  96. 4
      src/objective-c/tests/InteropTestsLocalSSL.m
  97. 1
      src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m
  98. 13
      src/objective-c/tests/RxLibraryUnitTests.m
  99. 1
      src/objective-c/tests/version.h
  100. 2
      src/php/bin/run_tests.sh
  101. Some files were not shown because too many files have changed in this diff Show More

@ -3,5 +3,10 @@ Language: Cpp
BasedOnStyle: Google
DerivePointerAlignment: false
PointerAlignment: Left
---
Language: ObjC
BasedOnStyle: Google
ColumnLimit: 100
ObjCBlockIndentWidth: 2
...

@ -1708,6 +1708,7 @@ grpc_cc_library(
"src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h",
"src/core/tsi/alts/handshaker/transport_security_common_api.h",
],
public_hdrs = GRPC_SECURE_PUBLIC_HDRS,
external_deps = [
"nanopb",
],

@ -70,6 +70,8 @@ filegroups:
- tsi_interface
- tsi
- name: alts_util
public_headers:
- include/grpc/grpc_security.h
headers:
- src/core/lib/security/credentials/alts/check_gcp_environment.h
- src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h

@ -115,6 +115,12 @@ EXPORTS
grpc_server_add_secure_http2_port
grpc_call_set_credentials
grpc_server_credentials_set_auth_metadata_processor
grpc_alts_credentials_client_options_create
grpc_alts_credentials_server_options_create
grpc_alts_credentials_client_options_add_target_service_account
grpc_alts_credentials_options_destroy
grpc_alts_credentials_create
grpc_alts_server_credentials_create
grpc_raw_byte_buffer_create
grpc_raw_compressed_byte_buffer_create
grpc_byte_buffer_copy
@ -185,6 +191,7 @@ EXPORTS
gpr_cpu_current_cpu
gpr_log_severity_string
gpr_log
gpr_should_log
gpr_log_message
gpr_set_log_verbosity
gpr_log_verbosity_init

@ -488,6 +488,76 @@ typedef struct {
GRPCAPI void grpc_server_credentials_set_auth_metadata_processor(
grpc_server_credentials* creds, grpc_auth_metadata_processor processor);
/** --- ALTS channel/server credentials --- **/
/**
* Main interface for ALTS credentials options. The options will contain
* information that will be passed from grpc to TSI layer such as RPC protocol
* versions. ALTS client (channel) and server credentials will have their own
* implementation of this interface. The APIs listed in this header are
* thread-compatible. It is used for experimental purpose for now and subject
* to change.
*/
typedef struct grpc_alts_credentials_options grpc_alts_credentials_options;
/**
* This method creates a grpc ALTS credentials client options instance.
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI grpc_alts_credentials_options*
grpc_alts_credentials_client_options_create();
/**
* This method creates a grpc ALTS credentials server options instance.
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI grpc_alts_credentials_options*
grpc_alts_credentials_server_options_create();
/**
* This method adds a target service account to grpc client's ALTS credentials
* options instance. It is used for experimental purpose for now and subject
* to change.
*
* - options: grpc ALTS credentials options instance.
* - service_account: service account of target endpoint.
*/
GRPCAPI void grpc_alts_credentials_client_options_add_target_service_account(
grpc_alts_credentials_options* options, const char* service_account);
/**
* This method destroys a grpc_alts_credentials_options instance by
* de-allocating all of its occupied memory. It is used for experimental purpose
* for now and subject to change.
*
* - options: a grpc_alts_credentials_options instance that needs to be
* destroyed.
*/
GRPCAPI void grpc_alts_credentials_options_destroy(
grpc_alts_credentials_options* options);
/**
* This method creates an ALTS channel credential object. It is used for
* experimental purpose for now and subject to change.
*
* - options: grpc ALTS credentials options instance for client.
*
* It returns the created ALTS channel credential object.
*/
GRPCAPI grpc_channel_credentials* grpc_alts_credentials_create(
const grpc_alts_credentials_options* options);
/**
* This method creates an ALTS server credential object. It is used for
* experimental purpose for now and subject to change.
*
* - options: grpc ALTS credentials options instance for server.
*
* It returns the created ALTS server credential object.
*/
GRPCAPI grpc_server_credentials* grpc_alts_server_credentials_create(
const grpc_alts_credentials_options* options);
#ifdef __cplusplus
}
#endif

@ -500,6 +500,17 @@ typedef unsigned __int64 uint64_t;
#endif /* __GPR_WINDOWS */
#endif /* GRPC_ALLOW_EXCEPTIONS */
/* Use GPR_LIKELY only in cases where you are sure that a certain outcome is the
* most likely. Ideally, also collect performance numbers to justify the claim.
*/
#ifdef __GNUC__
#define GPR_LIKELY(x) __builtin_expect((x), 1)
#define GPR_UNLIKELY(x) __builtin_expect((x), 0)
#else /* __GNUC__ */
#define GPR_LIKELY(x) (x)
#define GPR_UNLIKELY(x) (x)
#endif /* __GNUC__ */
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

@ -61,6 +61,8 @@ GPRAPI const char* gpr_log_severity_string(gpr_log_severity severity);
GPRAPI void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) GPR_PRINT_FORMAT_CHECK(4, 5);
GPRAPI int gpr_should_log(gpr_log_severity severity);
GPRAPI void gpr_log_message(const char* file, int line,
gpr_log_severity severity, const char* message);
@ -91,7 +93,7 @@ GPRAPI void gpr_set_log_function(gpr_log_func func);
an exception in a higher-level language, consider returning error code. */
#define GPR_ASSERT(x) \
do { \
if (!(x)) { \
if (GPR_UNLIKELY(!(x))) { \
gpr_log(GPR_ERROR, "assertion failed: %s", #x); \
abort(); \
} \

@ -146,8 +146,8 @@ class ByteBuffer final {
friend class internal::ServerStreamingHandler;
template <class R>
friend class internal::DeserializeFuncType;
friend class GrpcProtoBufferReader;
friend class GrpcProtoBufferWriter;
friend class ProtoBufferReader;
friend class ProtoBufferWriter;
friend class internal::GrpcByteBufferPeer;
grpc_byte_buffer* buffer_;

@ -43,11 +43,11 @@ extern CoreCodegenInterface* g_core_codegen_interface;
///
/// Read more about ZeroCopyInputStream interface here:
/// https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.io.zero_copy_stream#ZeroCopyInputStream
class GrpcProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
public:
/// Constructs buffer reader from \a buffer. Will set \a status() to non ok
/// if \a buffer is invalid (the internal buffer has not been initialized).
explicit GrpcProtoBufferReader(ByteBuffer* buffer)
explicit ProtoBufferReader(ByteBuffer* buffer)
: byte_count_(0), backup_count_(0), status_() {
/// Implemented through a grpc_byte_buffer_reader which iterates
/// over the slices that make up a byte buffer
@ -59,7 +59,7 @@ class GrpcProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
}
}
~GrpcProtoBufferReader() {
~ProtoBufferReader() {
if (status_.ok()) {
g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader_);
}

@ -38,10 +38,10 @@ extern CoreCodegenInterface* g_core_codegen_interface;
// Forward declaration for testing use only
namespace internal {
class GrpcProtoBufferWriterPeer;
class ProtoBufferWriterPeer;
} // namespace internal
const int kGrpcProtoBufferWriterMaxBufferLength = 1024 * 1024;
const int kProtoBufferWriterMaxBufferLength = 1024 * 1024;
/// This is a specialization of the protobuf class ZeroCopyOutputStream.
/// The principle is to give the proto layer one buffer of bytes at a time
@ -50,15 +50,14 @@ const int kGrpcProtoBufferWriterMaxBufferLength = 1024 * 1024;
///
/// Read more about ZeroCopyOutputStream interface here:
/// https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.io.zero_copy_stream#ZeroCopyOutputStream
class GrpcProtoBufferWriter
: public ::grpc::protobuf::io::ZeroCopyOutputStream {
class ProtoBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream {
public:
/// Constructor for this derived class
///
/// \param[out] byte_buffer A pointer to the grpc::ByteBuffer created
/// \param block_size How big are the chunks to allocate at a time
/// \param total_size How many total bytes are required for this proto
GrpcProtoBufferWriter(ByteBuffer* byte_buffer, int block_size, int total_size)
ProtoBufferWriter(ByteBuffer* byte_buffer, int block_size, int total_size)
: block_size_(block_size),
total_size_(total_size),
byte_count_(0),
@ -71,7 +70,7 @@ class GrpcProtoBufferWriter
slice_buffer_ = &bp->data.raw.slice_buffer;
}
~GrpcProtoBufferWriter() {
~ProtoBufferWriter() {
if (have_backup_) {
g_core_codegen_interface->grpc_slice_unref(backup_slice_);
}
@ -151,7 +150,7 @@ class GrpcProtoBufferWriter
private:
// friend for testing purposes only
friend class internal::GrpcProtoBufferWriterPeer;
friend class internal::ProtoBufferWriterPeer;
const int block_size_; ///< size to alloc for each new \a grpc_slice needed
const int total_size_; ///< byte size of proto being serialized
int64_t byte_count_; ///< bytes written since this object was created

@ -60,8 +60,7 @@ Status GenericSerialize(const grpc::protobuf::Message& msg, ByteBuffer* bb,
return g_core_codegen_interface->ok();
}
ProtoBufferWriter writer(bb, kGrpcProtoBufferWriterMaxBufferLength,
byte_size);
ProtoBufferWriter writer(bb, kProtoBufferWriterMaxBufferLength, byte_size);
return msg.SerializeToZeroCopyStream(&writer)
? g_core_codegen_interface->ok()
: Status(StatusCode::INTERNAL, "Failed to serialize message");
@ -108,11 +107,11 @@ class SerializationTraits<T, typename std::enable_if<std::is_base_of<
public:
static Status Serialize(const grpc::protobuf::Message& msg, ByteBuffer* bb,
bool* own_buffer) {
return GenericSerialize<GrpcProtoBufferWriter, T>(msg, bb, own_buffer);
return GenericSerialize<ProtoBufferWriter, T>(msg, bb, own_buffer);
}
static Status Deserialize(ByteBuffer* buffer, grpc::protobuf::Message* msg) {
return GenericDeserialize<GrpcProtoBufferReader, T>(buffer, msg);
return GenericDeserialize<ProtoBufferReader, T>(buffer, msg);
}
};
#endif

@ -21,6 +21,7 @@
#include <map>
#include <memory>
#include <vector>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/security/auth_context.h>
@ -219,6 +220,21 @@ class MetadataCredentialsPlugin {
std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
std::unique_ptr<MetadataCredentialsPlugin> plugin);
namespace experimental {
/// Options used to build AltsCredentials.
struct AltsCredentialsOptions {
/// service accounts of target endpoint that will be acceptable
/// by the client. If service accounts are provided and none of them matches
/// that of the server, authentication will fail.
std::vector<grpc::string> target_service_accounts;
};
/// Builds ALTS Credentials given ALTS specific options
std::shared_ptr<ChannelCredentials> AltsCredentials(
const AltsCredentialsOptions& options);
} // namespace experimental
} // namespace grpc
#endif // GRPCPP_SECURITY_CREDENTIALS_H

@ -86,6 +86,18 @@ std::shared_ptr<ServerCredentials> SslServerCredentials(
/// Builds insecure server credentials.
std::shared_ptr<ServerCredentials> InsecureServerCredentials();
namespace experimental {
/// Options to create ServerCredentials with ALTS
struct AltsServerCredentialsOptions {
/// Add fields if needed.
};
/// Builds ALTS ServerCredentials given ALTS specific options
std::shared_ptr<ServerCredentials> AltsServerCredentials(
const AltsServerCredentialsOptions& options);
} // namespace experimental
} // namespace grpc
#endif // GRPCPP_SECURITY_SERVER_CREDENTIALS_H

@ -239,9 +239,6 @@ PACKAGE_DIRECTORIES = {
INSTALL_REQUIRES = (
'six>=1.5.2',
# TODO(atash): eventually split the grpcio package into a metapackage
# depending on protobuf and the runtime component (independent of protobuf)
'protobuf>=3.5.0.post1',
)
if not PY3:

@ -0,0 +1,9 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild

@ -0,0 +1,37 @@
gRPC on Android
==============
Note: Building the protobuf dependency for Android requires
https://github.com/google/protobuf/pull/3878. This fix will be in the next
protobuf release, but until then must be manually patched in to
`third_party/protobuf` to build gRPC for Android.
PREREQUISITES
-------------
- Android SDK
- Android NDK
- `protoc` and `grpc_cpp_plugin` binaries on the host system
INSTALL
-------
The example application can be built via Android Studio or on the command line
using `gradle`:
```sh
$ ./gradlew installDebug
```
INSTRUMENTATION TESTS
---------------------
The instrumentation tests can be run via the following `gradle` command. This
requires an emulator already running on your computer.
```
$ ./gradlew connectedAndroidTest \
-Pandroid.testInstrumentationRunnerArguments.server_host=grpc-test.sandbox.googleapis.com \
-Pandroid.testInstrumentationRunnerArguments.server_port=443 \
-Pandroid.testInstrumentationRunnerArguments.use_tls=true
```

@ -0,0 +1,119 @@
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(PROTOBUF_PROTOC_EXECUTABLE "/usr/local/bin/protoc" CACHE STRING "Protoc binary on host")
set(gRPC_CPP_PLUGIN_EXECUTABLE "/usr/local/bin/grpc_cpp_plugin" CACHE STRING "gRPC CPP plugin binary on host")
set(GRPC_SRC_DIR ../../../../../)
set(GRPC_BUILD_DIR ../grpc/outputs/${ANDROID_ABI})
file(MAKE_DIRECTORY ${GRPC_BUILD_DIR})
add_subdirectory(${GRPC_SRC_DIR} ${GRPC_BUILD_DIR})
#include_directories(${GRPC_SRC_DIR}/include)
include_directories(${GRPC_SRC_DIR})
set(GRPC_PROTO_GENS_DIR ${CMAKE_BINARY_DIR}/gens)
file(MAKE_DIRECTORY ${GRPC_PROTO_GENS_DIR})
include_directories(${GRPC_PROTO_GENS_DIR})
function(android_protobuf_grpc_generate_cpp SRC_FILES HDR_FILES INCLUDE_ROOT)
if(NOT ARGN)
message(SEND_ERROR "Error: android_protobuf_grpc_generate_cpp() called without any proto files")
return()
endif()
set(${SRC_FILES})
set(${HDR_FILES})
set(PROTOBUF_INCLUDE_PATH -I ${INCLUDE_ROOT})
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)
file(RELATIVE_PATH REL_FIL ${CMAKE_CURRENT_SOURCE_DIR}/${INCLUDE_ROOT} ${ABS_FIL})
get_filename_component(REL_DIR ${REL_FIL} DIRECTORY)
set(RELFIL_WE "${REL_DIR}/${FIL_WE}")
list(APPEND ${SRC_FILES} "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc")
list(APPEND ${HDR_FILES} "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h")
list(APPEND ${SRC_FILES} "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc")
list(APPEND ${HDR_FILES} "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h")
add_custom_command(
OUTPUT "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc"
"${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h"
"${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc"
"${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h"
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --grpc_out=${GRPC_PROTO_GENS_DIR}
--cpp_out=${GRPC_PROTO_GENS_DIR}
--plugin=protoc-gen-grpc=${gRPC_CPP_PLUGIN_EXECUTABLE}
${PROTOBUF_INCLUDE_PATH}
${REL_FIL}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${PROTOBUF_PROTOC_EXECUTABLE} ${gRPC_CPP_PLUGIN_EXECUTABLE} ${ABS_FIL} )
endforeach()
set_source_files_properties(${${SRC_FILES}} ${${HDR_FILES}} PROPERTIES GENERATED TRUE)
set(${SRC_FILES} ${${SRC_FILES}} PARENT_SCOPE)
set(${HDR_FILES} ${${HDR_FILES}} PARENT_SCOPE)
endfunction()
set(PROTO_BASE_DIR ${GRPC_SRC_DIR}/examples/protos)
android_protobuf_grpc_generate_cpp(
MESSAGES_PROTO_SRCS MESSAGES_PROTO_HDRS
${GRPC_SRC_DIR} ${GRPC_SRC_DIR}/src/proto/grpc/testing/messages.proto)
add_library(messages_proto_lib
SHARED ${MESSAGES_PROTO_SRCS} ${MESSAGES_PROTO_HDRS})
target_link_libraries(messages_proto_lib
libprotobuf
grpc++
android
log)
android_protobuf_grpc_generate_cpp(
EMPTY_PROTO_SRCS EMPTY_PROTO_HDRS
${GRPC_SRC_DIR} ${GRPC_SRC_DIR}/src/proto/grpc/testing/empty.proto)
add_library(empty_proto_lib
SHARED ${EMPTY_PROTO_SRCS} ${EMPTY_PROTO_HDRS})
target_link_libraries(empty_proto_lib
libprotobuf
grpc++
android
log)
android_protobuf_grpc_generate_cpp(
TEST_PROTO_SRCS TEST_PROTO_HDRS ${GRPC_SRC_DIR} ${GRPC_SRC_DIR}/src/proto/grpc/testing/test.proto)
add_library(test_proto_lib
SHARED ${TEST_PROTO_SRCS} ${TEST_PROTO_HDRS})
target_link_libraries(test_proto_lib
libprotobuf
grpc++
empty_proto_lib
messages_proto_lib
android
log)
find_library(log-lib
log)
add_library(grpc-interop
SHARED
src/main/cpp/grpc-interop.cc
${GRPC_SRC_DIR}/test/cpp/interop/interop_client.h
${GRPC_SRC_DIR}/test/cpp/interop/interop_client.cc)
target_link_libraries(grpc-interop
messages_proto_lib
empty_proto_lib
test_proto_lib
android
${log-lib})

@ -0,0 +1,56 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "io.grpc.android.interop.cpp"
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
// The paths to the protoc and grpc_cpp_plugin binaries on the host system (codegen
// is not cross-compiled to Android)
def protoc = project.hasProperty('protoc') ?
project.property('protoc') : '/usr/local/bin/protoc'
def grpc_cpp_plugin = project.hasProperty('grpc_cpp_plugin') ?
project.property('grpc_cpp_plugin') : '/usr/local/bin/grpc_cpp_plugin'
cppFlags "-std=c++14 -frtti -fexceptions"
arguments '-DANDROID_STL=c++_shared'
arguments '-DRUN_HAVE_POSIX_REGEX=0'
arguments '-DRUN_HAVE_STD_REGEX=0'
arguments '-DRUN_HAVE_STEADY_CLOCK=0'
arguments '-Dprotobuf_BUILD_PROTOC_BINARIES=off'
arguments '-DgRPC_BUILD_CODEGEN=off'
arguments '-DPROTOBUF_PROTOC_EXECUTABLE=' + protoc
arguments '-DgRPC_CPP_PLUGIN_EXECUTABLE=' + grpc_cpp_plugin
}
}
ndk.abiFilters 'x86'
}
buildTypes {
debug {
minifyEnabled false
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -0,0 +1,93 @@
/*
* Copyright 2018, gRPC Authors All rights reserved.
*
* 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.
*/
package io.grpc.interop.cpp;
import static junit.framework.Assert.assertTrue;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class InteropTest {
private String host;
private int port;
private boolean useTls;
@Before
public void setUp() throws Exception {
host =
InstrumentationRegistry.getArguments()
.getString("server_host", "grpc-test.sandbox.googleapis.com");
port = Integer.parseInt(InstrumentationRegistry.getArguments().getString("server_port", "443"));
useTls =
Boolean.parseBoolean(InstrumentationRegistry.getArguments().getString("use_tls", "true"));
if (useTls) {
Context ctx = InstrumentationRegistry.getTargetContext();
String sslRootsFile = "roots.pem";
InputStream in = ctx.getAssets().open(sslRootsFile);
File outFile = new File(ctx.getExternalFilesDir(null), sslRootsFile);
OutputStream out = new FileOutputStream(outFile);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
in.close();
out.close();
InteropActivity.configureSslRoots(outFile.getCanonicalPath());
}
}
@Test
public void emptyUnary() {
assertTrue(InteropActivity.doEmpty(host, port, useTls));
}
@Test
public void largeUnary() {
assertTrue(InteropActivity.doLargeUnary(host, port, useTls));
}
@Test
public void emptyStream() {
assertTrue(InteropActivity.doEmptyStream(host, port, useTls));
}
@Test
public void requestStreaming() {
assertTrue(InteropActivity.doRequestStreaming(host, port, useTls));
}
@Test
public void responseStreaming() {
assertTrue(InteropActivity.doResponseStreaming(host, port, useTls));
}
@Test
public void pingPong() {
assertTrue(InteropActivity.doPingPong(host, port, useTls));
}
}

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.grpc.interop.cpp" >
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Base.V7.Theme.AppCompat.Light" >
<activity
android:name=".InteropActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,124 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpcpp/grpcpp.h>
#include <jni.h>
#include <src/core/lib/gpr/env.h>
#include "test/cpp/interop/interop_client.h"
extern "C" JNIEXPORT void JNICALL
Java_io_grpc_interop_cpp_InteropActivity_configureSslRoots(JNIEnv* env,
jobject obj_this,
jstring path_raw) {
const char* path = env->GetStringUTFChars(path_raw, (jboolean*)0);
gpr_setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", path);
}
std::shared_ptr<grpc::testing::InteropClient> GetClient(const char* host,
int port,
bool use_tls) {
const int host_port_buf_size = 1024;
char host_port[host_port_buf_size];
snprintf(host_port, host_port_buf_size, "%s:%d", host, port);
std::shared_ptr<grpc::ChannelCredentials> credentials;
if (use_tls) {
credentials = grpc::SslCredentials(grpc::SslCredentialsOptions());
} else {
credentials = grpc::InsecureChannelCredentials();
}
return std::shared_ptr<grpc::testing::InteropClient>(
new grpc::testing::InteropClient(
grpc::CreateChannel(host_port, credentials), true, false));
}
extern "C" JNIEXPORT jboolean JNICALL
Java_io_grpc_interop_cpp_InteropActivity_doEmpty(JNIEnv* env, jobject obj_this,
jstring host_raw,
jint port_raw,
jboolean use_tls_raw) {
const char* host = env->GetStringUTFChars(host_raw, (jboolean*)0);
int port = static_cast<int>(port_raw);
bool use_tls = static_cast<bool>(use_tls_raw);
return GetClient(host, port, use_tls)->DoEmpty();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_io_grpc_interop_cpp_InteropActivity_doLargeUnary(JNIEnv* env,
jobject obj_this,
jstring host_raw,
jint port_raw,
jboolean use_tls_raw) {
const char* host = env->GetStringUTFChars(host_raw, (jboolean*)0);
int port = static_cast<int>(port_raw);
bool use_tls = static_cast<bool>(use_tls_raw);
return GetClient(host, port, use_tls)->DoLargeUnary();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_io_grpc_interop_cpp_InteropActivity_doEmptyStream(JNIEnv* env,
jobject obj_this,
jstring host_raw,
jint port_raw,
jboolean use_tls_raw) {
const char* host = env->GetStringUTFChars(host_raw, (jboolean*)0);
int port = static_cast<int>(port_raw);
bool use_tls = static_cast<bool>(use_tls_raw);
return GetClient(host, port, use_tls)->DoEmptyStream();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_io_grpc_interop_cpp_InteropActivity_doRequestStreaming(
JNIEnv* env, jobject obj_this, jstring host_raw, jint port_raw,
jboolean use_tls_raw) {
const char* host = env->GetStringUTFChars(host_raw, (jboolean*)0);
int port = static_cast<int>(port_raw);
bool use_tls = static_cast<bool>(use_tls_raw);
return GetClient(host, port, use_tls)->DoRequestStreaming();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_io_grpc_interop_cpp_InteropActivity_doResponseStreaming(
JNIEnv* env, jobject obj_this, jstring host_raw, jint port_raw,
jboolean use_tls_raw) {
const char* host = env->GetStringUTFChars(host_raw, (jboolean*)0);
int port = static_cast<int>(port_raw);
bool use_tls = static_cast<bool>(use_tls_raw);
return GetClient(host, port, use_tls)->DoResponseStreaming();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_io_grpc_interop_cpp_InteropActivity_doPingPong(JNIEnv* env,
jobject obj_this,
jstring host_raw,
jint port_raw,
jboolean use_tls_raw) {
const char* host = env->GetStringUTFChars(host_raw, (jboolean*)0);
int port = static_cast<int>(port_raw);
bool use_tls = static_cast<bool>(use_tls_raw);
return GetClient(host, port, use_tls)->DoPingPong();
}

@ -0,0 +1,122 @@
/*
* Copyright 2018, gRPC Authors All rights reserved.
*
* 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.
*/
package io.grpc.interop.cpp;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.lang.ref.WeakReference;
public class InteropActivity extends AppCompatActivity {
static {
System.loadLibrary("grpc-interop");
}
private Button sendButton;
private EditText hostEdit;
private EditText portEdit;
private TextView resultText;
private GrpcTask grpcTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_interop);
sendButton = (Button) findViewById(R.id.ping_pong_button);
hostEdit = (EditText) findViewById(R.id.host_edit_text);
portEdit = (EditText) findViewById(R.id.port_edit_text);
resultText = (TextView) findViewById(R.id.grpc_result_text);
resultText.setMovementMethod(new ScrollingMovementMethod());
}
@Override
protected void onPause() {
super.onPause();
if (grpcTask != null) {
grpcTask.cancel(true);
grpcTask = null;
}
}
public void doPingPong(View view) {
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(hostEdit.getWindowToken(), 0);
sendButton.setEnabled(false);
resultText.setText("");
grpcTask = new GrpcTask(this);
grpcTask.executeOnExecutor(
AsyncTask.THREAD_POOL_EXECUTOR,
hostEdit.getText().toString(),
portEdit.getText().toString());
}
private static class GrpcTask extends AsyncTask<String, Void, String> {
private final WeakReference<InteropActivity> activityReference;
private GrpcTask(InteropActivity activity) {
this.activityReference = new WeakReference<InteropActivity>(activity);
}
@Override
protected String doInBackground(String... params) {
String host = params[0];
String portStr = params[1];
int port = TextUtils.isEmpty(portStr) ? 50051 : Integer.valueOf(portStr);
// TODO(ericgribkoff) Support other test cases in the app UI
if (doPingPong(host, port, false)) {
return "Success";
} else {
return "Failure";
}
}
@Override
protected void onPostExecute(String result) {
InteropActivity activity = activityReference.get();
if (activity == null || isCancelled()) {
return;
}
TextView resultText = (TextView) activity.findViewById(R.id.grpc_result_text);
Button sendButton = (Button) activity.findViewById(R.id.ping_pong_button);
resultText.setText(result);
sendButton.setEnabled(true);
}
}
public static native void configureSslRoots(String path);
public static native boolean doEmpty(String host, int port, boolean useTls);
public static native boolean doLargeUnary(String host, int port, boolean useTls);
public static native boolean doEmptyStream(String host, int port, boolean useTls);
public static native boolean doRequestStreaming(String host, int port, boolean useTls);
public static native boolean doResponseStreaming(String host, int port, boolean useTls);
public static native boolean doPingPong(String host, int port, boolean useTls);
}

@ -0,0 +1,48 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".InteropActivity"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/host_edit_text"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Enter Host" />
<EditText
android:id="@+id/port_edit_text"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:hint="Enter Port" />
</LinearLayout>
<Button
android:id="@+id/ping_pong_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doPingPong"
android:text="Ping Pong" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:textSize="16sp"
android:text="Result:" />
<TextView
android:id="@+id/grpc_result_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars = "vertical"
android:textSize="16sp" />
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

@ -0,0 +1,3 @@
<resources>
<string name="app_name">gRPC C++ Interop App</string>
</resources>

@ -0,0 +1,24 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

@ -0,0 +1,17 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

@ -0,0 +1,6 @@
#Thu Jan 25 11:45:30 PST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip

@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

@ -135,6 +135,7 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args)
if (path[0] == '/') ++path;
name_to_resolve_ = gpr_strdup(path);
// Get DNS server from URI authority.
dns_server_ = nullptr;
if (0 != strcmp(args.uri->authority, "")) {
dns_server_ = gpr_strdup(args.uri->authority);
}

@ -1676,6 +1676,33 @@ static void send_ping_locked(grpc_chttp2_transport* t,
GRPC_ERROR_NONE);
}
/*
* Specialized form of send_ping_locked for keepalive ping. If there is already
* a ping in progress, the keepalive ping would piggyback onto that ping,
* instead of waiting for that ping to complete and then starting a new ping.
*/
static void send_keepalive_ping_locked(grpc_chttp2_transport* t) {
if (t->closed_with_error != GRPC_ERROR_NONE) {
GRPC_CLOSURE_SCHED(&t->start_keepalive_ping_locked,
GRPC_ERROR_REF(t->closed_with_error));
GRPC_CLOSURE_SCHED(&t->finish_keepalive_ping_locked,
GRPC_ERROR_REF(t->closed_with_error));
return;
}
grpc_chttp2_ping_queue* pq = &t->ping_queue;
if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_INFLIGHT])) {
/* There is a ping in flight. Add yourself to the inflight closure list. */
GRPC_CLOSURE_SCHED(&t->start_keepalive_ping_locked, GRPC_ERROR_NONE);
grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_INFLIGHT],
&t->finish_keepalive_ping_locked, GRPC_ERROR_NONE);
return;
}
grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_INITIATE],
&t->start_keepalive_ping_locked, GRPC_ERROR_NONE);
grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_NEXT],
&t->finish_keepalive_ping_locked, GRPC_ERROR_NONE);
}
static void retry_initiate_ping_locked(void* tp, grpc_error* error) {
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp);
t->ping_state.is_delayed_ping_timer_set = false;
@ -2619,8 +2646,7 @@ static void init_keepalive_ping_locked(void* arg, grpc_error* error) {
grpc_chttp2_stream_map_size(&t->stream_map) > 0) {
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_PINGING;
GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive ping end");
send_ping_locked(t, &t->start_keepalive_ping_locked,
&t->finish_keepalive_ping_locked);
send_keepalive_ping_locked(t);
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_KEEPALIVE_PING);
} else {
GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping");

@ -44,10 +44,16 @@ const char* gpr_log_severity_string(gpr_log_severity severity) {
GPR_UNREACHABLE_CODE(return "UNKNOWN");
}
int gpr_should_log(gpr_log_severity severity) {
return static_cast<gpr_atm>(severity) >=
gpr_atm_no_barrier_load(&g_min_severity_to_print)
? 1
: 0;
}
void gpr_log_message(const char* file, int line, gpr_log_severity severity,
const char* message) {
if (static_cast<gpr_atm>(severity) <
gpr_atm_no_barrier_load(&g_min_severity_to_print)) {
if (gpr_should_log(severity) == 0) {
return;
}

@ -41,6 +41,10 @@ static android_LogPriority severity_to_log_priority(gpr_log_severity severity) {
void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) {
/* Avoid message construction if gpr_log_message won't log */
if (gpr_should_log(severity) == 0) {
return;
}
char* message = NULL;
va_list args;
va_start(args, format);

@ -44,6 +44,10 @@ static long gettid(void) { return syscall(__NR_gettid); }
void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) {
/* Avoid message construction if gpr_log_message won't log */
if (gpr_should_log(severity) == 0) {
return;
}
char* message = nullptr;
va_list args;
va_start(args, format);

@ -34,6 +34,10 @@ static intptr_t gettid(void) { return (intptr_t)pthread_self(); }
void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) {
/* Avoid message construction if gpr_log_message won't log */
if (gpr_should_log(severity) == 0) {
return;
}
char buf[64];
char* allocated = nullptr;
char* message = nullptr;

@ -34,6 +34,11 @@
void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) {
/* Avoid message construction if gpr_log_message won't log */
if (gpr_should_log(severity) == 0) {
return;
}
char* message = NULL;
va_list args;
int ret;

@ -181,6 +181,30 @@ grpc_error* grpc_set_socket_reuse_port(int fd, int reuse) {
#endif
}
static gpr_once g_probe_so_reuesport_once = GPR_ONCE_INIT;
static int g_support_so_reuseport = false;
void probe_so_reuseport_once(void) {
#ifndef GPR_MANYLINUX1
int s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
/* This might be an ipv6-only environment in which case 'socket(AF_INET,..)'
call would fail. Try creating IPv6 socket in that case */
s = socket(AF_INET6, SOCK_STREAM, 0);
}
if (s >= 0) {
g_support_so_reuseport = GRPC_LOG_IF_ERROR(
"check for SO_REUSEPORT", grpc_set_socket_reuse_port(s, 1));
close(s);
}
#endif
}
bool grpc_is_socket_reuse_port_supported() {
gpr_once_init(&g_probe_so_reuesport_once, probe_so_reuseport_once);
return g_support_so_reuseport;
}
/* disable nagle */
grpc_error* grpc_set_socket_low_latency(int fd, int low_latency) {
int val = (low_latency != 0);

@ -44,6 +44,9 @@ grpc_error* grpc_set_socket_cloexec(int fd, int close_on_exec);
/* set a socket to reuse old addresses */
grpc_error* grpc_set_socket_reuse_addr(int fd, int reuse);
/* return true if SO_REUSEPORT is supported */
bool grpc_is_socket_reuse_port_supported();
/* disable nagle */
grpc_error* grpc_set_socket_low_latency(int fd, int low_latency);

@ -55,39 +55,18 @@
#include "src/core/lib/iomgr/tcp_server_utils_posix.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
static gpr_once check_init = GPR_ONCE_INIT;
static bool has_so_reuseport = false;
static void init(void) {
#ifndef GPR_MANYLINUX1
int s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
/* This might be an ipv6-only environment in which case 'socket(AF_INET,..)'
call would fail. Try creating IPv6 socket in that case */
s = socket(AF_INET6, SOCK_STREAM, 0);
}
if (s >= 0) {
has_so_reuseport = GRPC_LOG_IF_ERROR("check for SO_REUSEPORT",
grpc_set_socket_reuse_port(s, 1));
close(s);
}
#endif
}
static grpc_error* tcp_server_create(grpc_closure* shutdown_complete,
const grpc_channel_args* args,
grpc_tcp_server** server) {
gpr_once_init(&check_init, init);
grpc_tcp_server* s =
static_cast<grpc_tcp_server*>(gpr_zalloc(sizeof(grpc_tcp_server)));
s->so_reuseport = has_so_reuseport;
s->so_reuseport = grpc_is_socket_reuse_port_supported();
s->expand_wildcard_addrs = false;
for (size_t i = 0; i < (args == nullptr ? 0 : args->num_args); i++) {
if (0 == strcmp(GRPC_ARG_ALLOW_REUSEPORT, args->args[i].key)) {
if (args->args[i].type == GRPC_ARG_INTEGER) {
s->so_reuseport =
has_so_reuseport && (args->args[i].value.integer != 0);
s->so_reuseport = grpc_is_socket_reuse_port_supported() &&
(args->args[i].value.integer != 0);
} else {
gpr_free(s);
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(GRPC_ARG_ALLOW_REUSEPORT

@ -191,6 +191,9 @@ struct grpc_udp_server {
size_t pollset_count;
/* opaque object to pass to callbacks */
void* user_data;
/* latch has_so_reuseport during server creation */
bool so_reuseport;
};
static grpc_socket_factory* get_socket_factory(const grpc_channel_args* args) {
@ -214,6 +217,7 @@ grpc_udp_server* grpc_udp_server_create(const grpc_channel_args* args) {
s->active_ports = 0;
s->destroyed_ports = 0;
s->shutdown = 0;
s->so_reuseport = grpc_is_socket_reuse_port_supported();
return s;
}
@ -353,7 +357,7 @@ static int bind_socket(grpc_socket_factory* socket_factory, int sockfd,
/* Prepare a recently-created socket for listening. */
static int prepare_socket(grpc_socket_factory* socket_factory, int fd,
const grpc_resolved_address* addr, int rcv_buf_size,
int snd_buf_size) {
int snd_buf_size, bool so_reuseport) {
grpc_resolved_address sockname_temp;
grpc_sockaddr* addr_ptr =
reinterpret_cast<grpc_sockaddr*>(const_cast<char*>(addr->addr));
@ -381,21 +385,6 @@ static int prepare_socket(grpc_socket_factory* socket_factory, int fd,
}
}
if (bind_socket(socket_factory, fd, addr) < 0) {
char* addr_str;
grpc_sockaddr_to_string(&addr_str, addr, 0);
gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
gpr_free(addr_str);
goto error;
}
sockname_temp.len = static_cast<socklen_t>(sizeof(struct sockaddr_storage));
if (getsockname(fd, reinterpret_cast<grpc_sockaddr*>(sockname_temp.addr),
&sockname_temp.len) < 0) {
goto error;
}
if (grpc_set_socket_sndbuf(fd, snd_buf_size) != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR, "Failed to set send buffer size to %d bytes",
snd_buf_size);
@ -415,6 +404,30 @@ static int prepare_socket(grpc_socket_factory* socket_factory, int fd,
gpr_log(GPR_INFO, "Failed to set socket overflow support");
}
}
if (so_reuseport && !grpc_is_unix_socket(addr) &&
grpc_set_socket_reuse_port(fd, 1) != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR, "Failed to set SO_REUSEPORT for fd %d", fd);
goto error;
}
if (bind_socket(socket_factory, fd, addr) < 0) {
char* addr_str;
grpc_sockaddr_to_string(&addr_str, addr, 0);
gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
gpr_free(addr_str);
goto error;
}
sockname_temp.len = static_cast<socklen_t>(sizeof(struct sockaddr_storage));
if (getsockname(fd, reinterpret_cast<grpc_sockaddr*>(sockname_temp.addr),
&sockname_temp.len) < 0) {
gpr_log(GPR_ERROR, "Unable to get the address socket %d is bound to: %s",
fd, strerror(errno));
goto error;
}
return grpc_sockaddr_get_port(&sockname_temp);
error:
@ -541,8 +554,8 @@ static int add_socket_to_server(grpc_udp_server* s, int fd,
int rcv_buf_size, int snd_buf_size) {
gpr_log(GPR_DEBUG, "add socket %d to server", fd);
int port =
prepare_socket(s->socket_factory, fd, addr, rcv_buf_size, snd_buf_size);
int port = prepare_socket(s->socket_factory, fd, addr, rcv_buf_size,
snd_buf_size, s->so_reuseport);
if (port >= 0) {
gpr_mu_lock(&s->mu);
s->listeners.emplace_back(s, fd, addr);
@ -557,7 +570,18 @@ static int add_socket_to_server(grpc_udp_server* s, int fd,
int grpc_udp_server_add_port(grpc_udp_server* s,
const grpc_resolved_address* addr,
int rcv_buf_size, int snd_buf_size,
GrpcUdpHandlerFactory* handler_factory) {
GrpcUdpHandlerFactory* handler_factory,
size_t num_listeners) {
if (num_listeners > 1 && !s->so_reuseport) {
gpr_log(GPR_ERROR,
"Try to have multiple listeners on same port, but SO_REUSEPORT is "
"not supported. Only create 1 listener.");
}
char* addr_str;
grpc_sockaddr_to_string(&addr_str, addr, 1);
gpr_log(GPR_DEBUG, "add address: %s to server", addr_str);
gpr_free(addr_str);
int allocated_port1 = -1;
int allocated_port2 = -1;
int fd;
@ -568,11 +592,12 @@ int grpc_udp_server_add_port(grpc_udp_server* s,
grpc_resolved_address addr4_copy;
grpc_resolved_address* allocated_addr = nullptr;
grpc_resolved_address sockname_temp;
int port;
int port = 0;
/* Check if this is a wildcard port, and if so, try to keep the port the same
as some previously created listener. */
if (grpc_sockaddr_get_port(addr) == 0) {
/* Loop through existing listeners to find the port in use. */
for (size_t i = 0; i < s->listeners.size(); ++i) {
sockname_temp.len =
static_cast<socklen_t>(sizeof(struct sockaddr_storage));
@ -581,6 +606,7 @@ int grpc_udp_server_add_port(grpc_udp_server* s,
&sockname_temp.len)) {
port = grpc_sockaddr_get_port(&sockname_temp);
if (port > 0) {
/* Found such a port, update |addr| to reflects this port. */
allocated_addr = static_cast<grpc_resolved_address*>(
gpr_malloc(sizeof(grpc_resolved_address)));
memcpy(allocated_addr, addr, sizeof(grpc_resolved_address));
@ -597,6 +623,7 @@ int grpc_udp_server_add_port(grpc_udp_server* s,
}
s->handler_factory = handler_factory;
for (size_t i = 0; i < num_listeners; ++i) {
/* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
if (grpc_sockaddr_is_wildcard(addr, &port)) {
grpc_sockaddr_make_wildcards(port, &wild4, &wild6);
@ -609,13 +636,33 @@ int grpc_udp_server_add_port(grpc_udp_server* s,
allocated_port1 =
add_socket_to_server(s, fd, addr, rcv_buf_size, snd_buf_size);
if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
goto done;
if (port == 0) {
/* This is the first time to bind to |addr|. If its port is still
* wildcard port, update |addr| with the ephermeral port returned by
* kernel. Thus |addr| can have a specific port in following
* iterations. */
grpc_sockaddr_set_port(addr, allocated_port1);
port = allocated_port1;
} else if (allocated_port1 >= 0) {
/* The following sucessfully created socket should have same port as
* the first one. */
GPR_ASSERT(port == allocated_port1);
}
/* A dualstack socket is created, no need to create corresponding IPV4
* socket. */
continue;
}
/* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
if (port == 0 && allocated_port1 > 0) {
/* |port| hasn't been assigned to an emphemeral port yet, |wild4| must
* have a wildcard port. Update it with the emphemeral port created
* during binding.*/
grpc_sockaddr_set_port(&wild4, allocated_port1);
port = allocated_port1;
}
/* |wild4| should have been updated with an emphemeral port by now. Use
* this IPV4 address to create a IPV4 socket. */
addr = &wild4;
}
@ -631,10 +678,18 @@ int grpc_udp_server_add_port(grpc_udp_server* s,
}
allocated_port2 =
add_socket_to_server(s, fd, addr, rcv_buf_size, snd_buf_size);
if (port == 0) {
/* Update |addr| with the ephermeral port returned by kernel. So |addr|
* can have a specific port in following iterations. */
grpc_sockaddr_set_port(addr, allocated_port2);
port = allocated_port2;
} else if (allocated_port2 >= 0) {
GPR_ASSERT(port == allocated_port2);
}
}
done:
gpr_free(allocated_addr);
return allocated_port1 >= 0 ? allocated_port1 : allocated_port2;
return port;
}
int grpc_udp_server_get_fd(grpc_udp_server* s, unsigned port_index) {

@ -86,17 +86,21 @@ int grpc_udp_server_get_fd(grpc_udp_server* s, unsigned port_index);
/* Add a port to the server, returning port number on success, or negative
on failure.
Create |num_listeners| sockets for given address to listen on using
SO_REUSEPORT if supported.
The :: and 0.0.0.0 wildcard addresses are treated identically, accepting
both IPv4 and IPv6 connections, but :: is the preferred style. This usually
creates one socket, but possibly two on systems which support IPv6,
but not dualstack sockets. */
creates |num_listeners| sockets, but possibly 2 * |num_listeners| on systems
which support IPv6, but not dualstack sockets. */
/* TODO(ctiller): deprecate this, and make grpc_udp_server_add_ports to handle
all of the multiple socket port matching logic in one place */
int grpc_udp_server_add_port(grpc_udp_server* s,
const grpc_resolved_address* addr,
int rcv_buf_size, int snd_buf_size,
GrpcUdpHandlerFactory* handler_factory);
GrpcUdpHandlerFactory* handler_factory,
size_t num_listeners);
void grpc_udp_server_destroy(grpc_udp_server* server, grpc_closure* on_done);

@ -40,26 +40,6 @@ typedef struct grpc_alts_server_credentials {
char* handshaker_service_url;
} grpc_alts_server_credentials;
/**
* This method creates an ALTS channel credential object.
*
* - options: grpc ALTS credentials options instance for client.
*
* It returns the created ALTS channel credential object.
*/
grpc_channel_credentials* grpc_alts_credentials_create(
const grpc_alts_credentials_options* options);
/**
* This method creates an ALTS server credential object.
*
* - options: grpc ALTS credentials options instance for server.
*
* It returns the created ALTS server credential object.
*/
grpc_server_credentials* grpc_alts_server_credentials_create(
const grpc_alts_credentials_options* options);
/**
* This method creates an ALTS channel credential object with customized
* information provided by caller.

@ -44,20 +44,20 @@ static target_service_account* target_service_account_create(
return sa;
}
bool grpc_alts_credentials_client_options_add_target_service_account(
grpc_alts_credentials_client_options* options,
const char* service_account) {
void grpc_alts_credentials_client_options_add_target_service_account(
grpc_alts_credentials_options* options, const char* service_account) {
if (options == nullptr || service_account == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid nullptr arguments to "
"grpc_alts_credentials_client_options_add_target_service_account()");
return false;
return;
}
auto client_options =
reinterpret_cast<grpc_alts_credentials_client_options*>(options);
target_service_account* node = target_service_account_create(service_account);
node->next = options->target_account_list_head;
options->target_account_list_head = node;
return true;
node->next = client_options->target_account_list_head;
client_options->target_account_list_head = node;
}
static void target_service_account_destroy(

@ -21,19 +21,10 @@
#include <grpc/support/port_platform.h>
#include <stdbool.h>
#include <grpc/grpc_security.h>
#include "src/core/tsi/alts/handshaker/transport_security_common_api.h"
/**
* Main interface for ALTS credentials options. The options will contain
* information that will be passed from grpc to TSI layer such as RPC protocol
* versions. ALTS client (channel) and server credentials will have their own
* implementation of this interface. The APIs listed in this header are
* thread-compatible.
*/
typedef struct grpc_alts_credentials_options grpc_alts_credentials_options;
/* V-table for grpc_alts_credentials_options */
typedef struct grpc_alts_credentials_options_vtable {
grpc_alts_credentials_options* (*copy)(
@ -80,33 +71,5 @@ typedef struct grpc_alts_credentials_server_options {
grpc_alts_credentials_options* grpc_alts_credentials_options_copy(
const grpc_alts_credentials_options* options);
/**
* This method destroys a grpc_alts_credentials_options instance by
* de-allocating all of its occupied memory.
*
* - options: a grpc_alts_credentials_options instance that needs to be
* destroyed.
*/
void grpc_alts_credentials_options_destroy(
grpc_alts_credentials_options* options);
/* This method creates a grpc ALTS credentials client options instance. */
grpc_alts_credentials_options* grpc_alts_credentials_client_options_create();
/* This method creates a grpc ALTS credentials server options instance. */
grpc_alts_credentials_options* grpc_alts_credentials_server_options_create();
/**
* This method adds a target service account to grpc ALTS credentials client
* options instance.
*
* - options: grpc ALTS credentials client options instance.
* - service_account: service account of target endpoint.
*
* It returns true on success and false on failure.
*/
bool grpc_alts_credentials_client_options_add_target_service_account(
grpc_alts_credentials_client_options* options, const char* service_account);
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_GRPC_ALTS_CREDENTIALS_OPTIONS_H \
*/

@ -87,6 +87,27 @@ std::shared_ptr<ChannelCredentials> SslCredentials(
return WrapChannelCredentials(c_creds);
}
namespace experimental {
// Builds ALTS Credentials given ALTS specific options
std::shared_ptr<ChannelCredentials> AltsCredentials(
const AltsCredentialsOptions& options) {
GrpcLibraryCodegen init; // To call grpc_init().
grpc_alts_credentials_options* c_options =
grpc_alts_credentials_client_options_create();
for (auto service_account = options.target_service_accounts.begin();
service_account != options.target_service_accounts.end();
service_account++) {
grpc_alts_credentials_client_options_add_target_service_account(
c_options, service_account->c_str());
}
grpc_channel_credentials* c_creds = grpc_alts_credentials_create(c_options);
grpc_alts_credentials_options_destroy(c_options);
return WrapChannelCredentials(c_creds);
}
} // namespace experimental
// Builds credentials for use when running in GCE
std::shared_ptr<CallCredentials> GoogleComputeEngineCredentials() {
GrpcLibraryCodegen init; // To call grpc_init().

@ -126,4 +126,18 @@ std::shared_ptr<ServerCredentials> SslServerCredentials(
new SecureServerCredentials(c_creds));
}
namespace experimental {
std::shared_ptr<ServerCredentials> AltsServerCredentials(
const AltsServerCredentialsOptions& options) {
grpc_alts_credentials_options* c_options =
grpc_alts_credentials_server_options_create();
grpc_server_credentials* c_creds =
grpc_alts_server_credentials_create(c_options);
grpc_alts_credentials_options_destroy(c_options);
return std::shared_ptr<ServerCredentials>(
new SecureServerCredentials(c_creds));
}
} // namespace experimental
} // namespace grpc

@ -39,12 +39,12 @@ typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) {
/** The default response size limit is 4MB. Set this to override that default. */
+ (void)setResponseSizeLimit:(NSUInteger)limit forHost:(nonnull NSString *)host;
+ (void)closeOpenConnections DEPRECATED_MSG_ATTRIBUTE("The API for this feature is experimental, "
+ (void)closeOpenConnections DEPRECATED_MSG_ATTRIBUTE(
"The API for this feature is experimental, "
"and might be removed or modified at any "
"time.");
+ (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm
forhost:(nonnull NSString *)host;
+ (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host;
/** Enable keepalive and configure keepalive parameters. A user should call this function once to
* enable keepalive for a particular host. gRPC client sends a ping after every \a interval ms to

@ -38,8 +38,7 @@
[GRPCHost flushChannelCache];
}
+ (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm
forhost:(nonnull NSString *)host {
+ (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host {
GRPCHost *hostConfig = [GRPCHost hostWithAddress:host];
switch (algorithm) {
case GRPCCompressNone:

@ -28,8 +28,7 @@
forHost:(nonnull NSString *)host
error:(NSError **)errorPtr {
if (!host) {
[NSException raise:NSInvalidArgumentException
format:@"host must be provided."];
[NSException raise:NSInvalidArgumentException format:@"host must be provided."];
}
GRPCHost *hostConfig = [GRPCHost hostWithAddress:host];
return [hostConfig setTLSPEMRootCerts:pemRootCerts

@ -16,8 +16,8 @@
*
*/
#import "GRPCCall.h"
#import "GRPCCall+OAuth2.h"
#import "GRPCCall.h"
#import <Google/SignIn.h>

@ -29,9 +29,8 @@
[NSException raise:NSInvalidArgumentException format:@"host, path and name must be provided."];
}
NSError *error = nil;
NSString *certs = [NSString stringWithContentsOfFile:certsPath
encoding:NSUTF8StringEncoding
error:&error];
NSString *certs =
[NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error];
if (error != nil) {
[NSException raise:[error localizedDescription] format:@"failed to load certs"];
}

@ -147,7 +147,8 @@ typedef NS_ENUM(NSUInteger, GRPCCallSafety) {
GRPCCallSafetyDefault = 0,
/** Signal that the call is idempotent. gRPC is free to use PUT verb. */
GRPCCallSafetyIdempotentRequest = 1,
/** Signal that the call is cacheable and will not affect server state. gRPC is free to use GET verb. */
/** Signal that the call is cacheable and will not affect server state. gRPC is free to use GET
verb. */
GRPCCallSafetyCacheableRequest = 2,
};

@ -20,10 +20,10 @@
#import "GRPCCall+OAuth2.h"
#include <grpc/grpc.h>
#include <grpc/support/time.h>
#import <RxLibrary/GRXConcurrentWriteable.h>
#import <RxLibrary/GRXImmediateSingleWriter.h>
#include <grpc/grpc.h>
#include <grpc/support/time.h>
#import "private/GRPCConnectivityMonitor.h"
#import "private/GRPCHost.h"
@ -219,7 +219,9 @@ static NSString * const kBearerPrefix = @"Bearer ";
}
- (void)cancel {
[self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
[self
maybeFinishWithError:[NSError
errorWithDomain:kGRPCErrorDomain
code:GRPCErrorCodeCancelled
userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]];
@ -287,13 +289,19 @@ static NSString * const kBearerPrefix = @"Bearer ";
// don't want to throw, because the app shouldn't crash for a behavior
// that's on the hands of any server to have. Instead we finish and ask
// the server to cancel.
[strongSelf maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
[strongSelf
maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
code:GRPCErrorCodeResourceExhausted
userInfo:@{NSLocalizedDescriptionKey: @"Client does not have enough memory to hold the server response."}]];
userInfo:@{
NSLocalizedDescriptionKey :
@"Client does not have enough memory to "
@"hold the server response."
}]];
[strongSelf cancelCall];
return;
}
[strongWriteable enqueueValue:data completionHandler:^{
[strongWriteable enqueueValue:data
completionHandler:^{
[strongSelf startNextRead];
}];
}];
@ -304,7 +312,8 @@ static NSString * const kBearerPrefix = @"Bearer ";
- (void)sendHeaders:(NSDictionary *)headers {
// TODO(jcanizales): Add error handlers for async failures
GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] initWithMetadata:headers
GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc]
initWithMetadata:headers
flags:[GRPCCall callFlagsForHost:_host path:_path]
handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA
if (!_unaryCall) {
@ -321,7 +330,6 @@ static NSString * const kBearerPrefix = @"Bearer ";
// If the call is a unary call, parameter \a errorHandler will be ignored and
// the error handler of GRPCOpSendClose will be executed in case of error.
- (void)writeMessage:(NSData *)message withErrorHandler:(void (^)(void))errorHandler {
__weak GRPCCall *weakSelf = self;
void (^resumingHandler)(void) = ^{
// Resume the request writer.
@ -333,11 +341,10 @@ static NSString * const kBearerPrefix = @"Bearer ";
}
};
GRPCOpSendMessage *op = [[GRPCOpSendMessage alloc] initWithMessage:message
handler:resumingHandler];
GRPCOpSendMessage *op =
[[GRPCOpSendMessage alloc] initWithMessage:message handler:resumingHandler];
if (!_unaryCall) {
[_wrappedCall startBatchWithOperations:@[op]
errorHandler:errorHandler];
[_wrappedCall startBatchWithOperations:@[ op ] errorHandler:errorHandler];
} else {
// Ignored errorHandler since it is the same as the one for GRPCOpSendClose.
// TODO (mxyan): unify the error handlers of all Ops into a single closure.
@ -368,8 +375,7 @@ static NSString * const kBearerPrefix = @"Bearer ";
errorHandler:errorHandler];
} else {
[_unaryOpBatch addObject:[[GRPCOpSendClose alloc] init]];
[_wrappedCall startBatchWithOperations:_unaryOpBatch
errorHandler:errorHandler];
[_wrappedCall startBatchWithOperations:_unaryOpBatch errorHandler:errorHandler];
}
}
@ -393,10 +399,10 @@ static NSString * const kBearerPrefix = @"Bearer ";
- (void)invokeCallWithHeadersHandler:(void (^)(NSDictionary *))headersHandler
completionHandler:(void (^)(NSError *, NSDictionary *))completionHandler {
// TODO(jcanizales): Add error handlers for async failures
[_wrappedCall startBatchWithOperations:@[[[GRPCOpRecvMetadata alloc]
initWithHandler:headersHandler]]];
[_wrappedCall startBatchWithOperations:@[[[GRPCOpRecvStatus alloc]
initWithHandler:completionHandler]]];
[_wrappedCall
startBatchWithOperations:@[ [[GRPCOpRecvMetadata alloc] initWithHandler:headersHandler] ]];
[_wrappedCall
startBatchWithOperations:@[ [[GRPCOpRecvStatus alloc] initWithHandler:completionHandler] ]];
}
- (void)invokeCall {
@ -408,7 +414,8 @@ static NSString * const kBearerPrefix = @"Bearer ";
strongSelf.responseHeaders = headers;
[strongSelf startNextRead];
}
} completionHandler:^(NSError *error, NSDictionary *trailers) {
}
completionHandler:^(NSError *error, NSDictionary *trailers) {
__strong GRPCCall *strongSelf = weakSelf;
if (strongSelf) {
strongSelf.responseTrailers = trailers;
@ -421,9 +428,9 @@ static NSString * const kBearerPrefix = @"Bearer ";
userInfo[kGRPCTrailersKey] = strongSelf.responseTrailers;
// TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be
// called before this one, so an error might end up with trailers but no headers. We
// shouldn't call finishWithError until ater both blocks are called. It is also when this is
// done that we can provide a merged view of response headers and trailers in a thread-safe
// way.
// shouldn't call finishWithError until ater both blocks are called. It is also when
// this is done that we can provide a merged view of response headers and trailers in a
// thread-safe way.
if (strongSelf.responseHeaders) {
userInfo[kGRPCHeadersKey] = strongSelf.responseHeaders;
}
@ -441,8 +448,8 @@ static NSString * const kBearerPrefix = @"Bearer ";
#pragma mark GRXWriter implementation
- (void)startCallWithWriteable:(id<GRXWriteable>)writeable {
_responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable
dispatchQueue:_responseQueue];
_responseWriteable =
[[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue];
_wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host
serverName:_serverName
@ -453,8 +460,7 @@ static NSString * const kBearerPrefix = @"Bearer ";
[self sendHeaders:_requestHeaders];
[self invokeCall];
[GRPCConnectivityMonitor registerObserver:self
selector:@selector(connectivityChanged:)];
[GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)];
}
- (void)startWithWriteable:(id<GRXWriteable>)writeable {
@ -521,7 +527,9 @@ static NSString * const kBearerPrefix = @"Bearer ";
- (void)connectivityChanged:(NSNotification *)note {
[self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
code:GRPCErrorCodeUnavailable
userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]];
userInfo:@{
NSLocalizedDescriptionKey : @"Connectivity lost."
}]];
// Cancel underlying call upon this notification
[self cancelCall];
}

@ -23,7 +23,6 @@
@class GRPCCompletionQueue;
struct grpc_channel_credentials;
/**
* Each separate instance of this class represents at least one TCP connection to the provided host.
*/
@ -52,7 +51,8 @@ struct grpc_channel_credentials;
* @c channelArgs. Only in tests should @c GRPC_SSL_TARGET_NAME_OVERRIDE_ARG channel arg be set.
*/
+ (nonnull GRPCChannel *)secureChannelWithHost:(nonnull NSString *)host
credentials:(nonnull struct grpc_channel_credentials *)credentials
credentials:
(nonnull struct grpc_channel_credentials *)credentials
channelArgs:(nullable NSDictionary *)channelArgs;
/**

@ -43,12 +43,10 @@ static void destroy_pointer_arg(void *p) {
CFRelease((CFTreeRef)p);
}
static int cmp_pointer_arg(void *p, void *q) {
return p == q;
}
static int cmp_pointer_arg(void *p, void *q) { return p == q; }
static const grpc_arg_pointer_vtable objc_arg_vtable = {
copy_pointer_arg, destroy_pointer_arg, cmp_pointer_arg};
static const grpc_arg_pointer_vtable objc_arg_vtable = {copy_pointer_arg, destroy_pointer_arg,
cmp_pointer_arg};
static void FreeChannelArgs(grpc_channel_args *channel_args) {
for (size_t i = 0; i < channel_args->num_args; ++i) {
@ -124,10 +122,8 @@ static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) {
if (self = [super init]) {
_channelArgs = BuildChannelArgs(channelArgs);
_host = [host copy];
_unmanagedChannel = grpc_cronet_secure_channel_create(cronetEngine,
_host.UTF8String,
_channelArgs,
NULL);
_unmanagedChannel =
grpc_cronet_secure_channel_create(cronetEngine, _host.UTF8String, _channelArgs, NULL);
}
return self;
@ -150,8 +146,8 @@ static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) {
_channelArgs = BuildChannelArgs(channelArgs);
_host = [host copy];
if (secure) {
_unmanagedChannel = grpc_secure_channel_create(credentials, _host.UTF8String, _channelArgs,
NULL);
_unmanagedChannel =
grpc_secure_channel_create(credentials, _host.UTF8String, _channelArgs, NULL);
} else {
_unmanagedChannel = grpc_insecure_channel_create(_host.UTF8String, _channelArgs, NULL);
}
@ -172,8 +168,7 @@ static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) {
channelArgs:(NSDictionary *)channelArgs {
stream_engine *engine = [GRPCCall cronetEngine];
if (!engine) {
[NSException raise:NSInvalidArgumentException
format:@"cronet_engine is NULL. Set it first."];
[NSException raise:NSInvalidArgumentException format:@"cronet_engine is NULL. Set it first."];
return nil;
}
return [[GRPCChannel alloc] initWithHost:host cronetEngine:engine channelArgs:channelArgs];
@ -191,15 +186,10 @@ static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) {
secure:YES
credentials:credentials
channelArgs:channelArgs];
}
+ (GRPCChannel *)insecureChannelWithHost:(NSString *)host
channelArgs:(NSDictionary *)channelArgs {
return [[GRPCChannel alloc] initWithHost:host
secure:NO
credentials:NULL
channelArgs:channelArgs];
+ (GRPCChannel *)insecureChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)channelArgs {
return [[GRPCChannel alloc] initWithHost:host secure:NO credentials:NULL channelArgs:channelArgs];
}
- (grpc_call *)unmanagedCallWithPath:(NSString *)path
@ -215,17 +205,13 @@ static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) {
host_slice = grpc_slice_from_copied_string(serverName.UTF8String);
}
grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String);
gpr_timespec deadline_ms = timeout == 0 ?
gpr_inf_future(GPR_CLOCK_REALTIME) :
gpr_time_add(
gpr_now(GPR_CLOCK_MONOTONIC),
gpr_timespec deadline_ms =
timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME)
: gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN));
grpc_call *call = grpc_channel_create_call(_unmanagedChannel,
NULL, GRPC_PROPAGATE_DEFAULTS,
queue.unmanagedQueue,
path_slice,
serverName ? &host_slice : NULL,
deadline_ms, NULL);
grpc_call *call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS,
queue.unmanagedQueue, path_slice,
serverName ? &host_slice : NULL, deadline_ms, NULL);
if (serverName) {
grpc_slice_unref(host_slice);
}

@ -53,9 +53,8 @@
dispatch_async(gDefaultConcurrentQueue, ^{
while (YES) {
// The following call blocks until an event is available.
grpc_event event = grpc_completion_queue_next(unmanagedQueue,
gpr_inf_future(GPR_CLOCK_REALTIME),
NULL);
grpc_event event =
grpc_completion_queue_next(unmanagedQueue, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
GRPCQueueCompletionHandler handler;
switch (event.type) {
case GRPC_OP_COMPLETE:

@ -39,8 +39,7 @@ extern NSString * _Nonnull kGRPCConnectivityNotification;
// must have a notification method with one parameter of type
// (NSNotification *) and should pass it to parameter \a selector. The
// parameter of this notification method is not used for now.
+ (void)registerObserver:(_Nonnull id)observer
selector:(_Nonnull SEL)selector;
+ (void)registerObserver:(_Nonnull id)observer selector:(_Nonnull SEL)selector;
// Ungegister an object from observers of network status change.
+ (void)unregisterObserver:(_Nonnull id)observer;

@ -41,8 +41,8 @@ GRPCConnectivityStatus CalculateConnectivityStatus(SCNetworkReachabilityFlags fl
return result;
}
static void ReachabilityCallback(
SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) {
static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags,
void *info) {
GRPCConnectivityStatus newStatus = CalculateConnectivityStatus(flags);
if (newStatus != currentStatus) {
@ -69,15 +69,14 @@ static void ReachabilityCallback(
SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
if (!SCNetworkReachabilitySetCallback(reachability, ReachabilityCallback, &context) ||
!SCNetworkReachabilityScheduleWithRunLoop(
reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes)) {
!SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(),
kCFRunLoopCommonModes)) {
NSLog(@"gRPC connectivity monitor fail to set");
}
}
}
+ (void)registerObserver:(_Nonnull id)observer
selector:(SEL)selector {
+ (void)registerObserver:(_Nonnull id)observer selector:(SEL)selector {
[[NSNotificationCenter defaultCenter] addObserver:observer
selector:selector
name:kGRPCConnectivityNotification

@ -47,7 +47,6 @@ struct grpc_channel_credentials;
/** The default response size limit is 4MB. Set this to override that default. */
@property(nonatomic, strong, nullable) NSNumber *responseSizeLimitOverride;
- (nullable instancetype)init NS_UNAVAILABLE;
/** Host objects initialized with the same address are the same. */
+ (nullable instancetype)hostWithAddress:(NSString *)address;

@ -18,10 +18,10 @@
#import "GRPCHost.h"
#import <GRPCClient/GRPCCall+MobileLog.h>
#import <GRPCClient/GRPCCall.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#import <GRPCClient/GRPCCall.h>
#import <GRPCClient/GRPCCall+MobileLog.h>
#ifdef GRPC_COMPILE_WITH_CRONET
#import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+Cronet.h>
@ -91,8 +91,7 @@ static NSMutableDictionary *kHostCache;
+ (void)flushChannelCache {
@synchronized(kHostCache) {
[kHostCache enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key,
GRPCHost * _Nonnull host,
[kHostCache enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, GRPCHost *_Nonnull host,
BOOL *_Nonnull stop) {
[host disconnect];
}];
@ -138,27 +137,27 @@ static NSMutableDictionary *kHostCache;
NSError *error;
// Files in PEM format can have non-ASCII characters in their comments (e.g. for the name of the
// issuer). Load them as UTF8 and produce an ASCII equivalent.
NSString *contentInUTF8 = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:&error];
NSString *contentInUTF8 =
[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if (contentInUTF8 == nil) {
kDefaultRootsError = error;
return;
}
kDefaultRootsASCII = [contentInUTF8 dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
kDefaultRootsASCII =
[contentInUTF8 dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
});
NSData *rootsASCII;
if (pemRootCerts != nil) {
rootsASCII = [pemRootCerts dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
rootsASCII = [pemRootCerts dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
} else {
if (kDefaultRootsASCII == nil) {
if (errorPtr) {
*errorPtr = kDefaultRootsError;
}
NSAssert(kDefaultRootsASCII, @"Could not read gRPCCertificates.bundle/roots.pem. This file, "
NSAssert(
kDefaultRootsASCII,
@"Could not read gRPCCertificates.bundle/roots.pem. This file, "
"with the root certificates, is needed to establish secure (TLS) connections. "
"Because the file is distributed with the gRPC library, this error is usually a sign "
"that the library wasn't configured correctly for your project. Error: %@",
@ -173,10 +172,10 @@ static NSMutableDictionary *kHostCache;
creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL);
} else {
grpc_ssl_pem_key_cert_pair key_cert_pair;
NSData *privateKeyASCII = [pemPrivateKey dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
NSData *certChainASCII = [pemCertChain dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
NSData *privateKeyASCII =
[pemPrivateKey dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSData *certChainASCII =
[pemCertChain dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
key_cert_pair.private_key = privateKeyASCII.bytes;
key_cert_pair.cert_chain = certChainASCII.bytes;
creds = grpc_ssl_credentials_create(rootsASCII.bytes, &key_cert_pair, NULL);
@ -212,8 +211,7 @@ static NSMutableDictionary *kHostCache;
}
if (_compressAlgorithm != GRPC_COMPRESS_NONE) {
args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] =
[NSNumber numberWithInt:_compressAlgorithm];
args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = [NSNumber numberWithInt:_compressAlgorithm];
}
if (_keepaliveInterval != 0) {
@ -247,14 +245,12 @@ static NSMutableDictionary *kHostCache;
}
#ifdef GRPC_COMPILE_WITH_CRONET
if (useCronet) {
channel = [GRPCChannel secureCronetChannelWithHost:_address
channelArgs:args];
channel = [GRPCChannel secureCronetChannelWithHost:_address channelArgs:args];
} else
#endif
{
channel = [GRPCChannel secureChannelWithHost:_address
credentials:_channelCreds
channelArgs:args];
channel =
[GRPCChannel secureChannelWithHost:_address credentials:_channelCreds channelArgs:args];
}
}
return channel;

@ -16,7 +16,6 @@
*
*/
#ifdef GRPC_TEST_OBJC
/**

@ -17,7 +17,8 @@
*/
/**
* "X-macro" file that lists the flags names of Apple's Network Reachability API, along with a nice
* "X-macro" file that lists the flags names of Apple's Network Reachability
API, along with a nice
* Objective-C method name used to query each of them.
*
* Example usage: To generate a dictionary from flag value to name, one can do:
@ -29,7 +30,8 @@
#undef GRPC_XMACRO_ITEM
};
XCTAssertEqualObjects(flagNames[@(kSCNetworkReachabilityFlagsIsWWAN)], @"isCell");
XCTAssertEqualObjects(flagNames[@(kSCNetworkReachabilityFlagsIsWWAN)],
@"isCell");
*/

@ -38,14 +38,18 @@ static void CheckKeyValuePairIsValid(NSString *key, id value) {
if ([key hasSuffix:@"-bin"]) {
if (![value isKindOfClass:NSData.class]) {
[NSException raise:NSInvalidArgumentException
format:@"Expected NSData value for header %@ ending in \"-bin\", "
@"instead got %@", key, value];
format:
@"Expected NSData value for header %@ ending in \"-bin\", "
@"instead got %@",
key, value];
}
} else {
if (![value isKindOfClass:NSString.class]) {
[NSException raise:NSInvalidArgumentException
format:@"Expected NSString value for header %@ not ending in \"-bin\", "
@"instead got %@", key, value];
format:
@"Expected NSString value for header %@ not ending in \"-bin\", "
@"instead got %@",
key, value];
}
CheckIsNonNilASCII(@"Text header value", (NSString *)value);
}

@ -29,8 +29,7 @@
@interface GRPCOpSendMetadata : GRPCOperation
- (instancetype)initWithMetadata:(NSDictionary *)metadata
handler:(void(^)(void))handler;
- (instancetype)initWithMetadata:(NSDictionary *)metadata handler:(void (^)(void))handler;
- (instancetype)initWithMetadata:(NSDictionary *)metadata
flags:(uint32_t)flags

@ -19,14 +19,14 @@
#import "GRPCWrappedCall.h"
#import <Foundation/Foundation.h>
#include <grpc/grpc.h>
#include <grpc/byte_buffer.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#import "GRPCCompletionQueue.h"
#import "GRPCHost.h"
#import "NSDictionary+GRPC.h"
#import "NSData+GRPC.h"
#import "NSDictionary+GRPC.h"
#import "NSError+GRPC.h"
#import "GRPCOpBatchLog.h"
@ -54,8 +54,7 @@
return [self initWithMetadata:nil flags:0 handler:nil];
}
- (instancetype)initWithMetadata:(NSDictionary *)metadata
handler:(void (^)(void))handler {
- (instancetype)initWithMetadata:(NSDictionary *)metadata handler:(void (^)(void))handler {
return [self initWithMetadata:metadata flags:0 handler:handler];
}
@ -142,8 +141,8 @@
__weak typeof(self) weakSelf = self;
_handler = ^{
__strong typeof(self) strongSelf = weakSelf;
NSDictionary *metadata = [NSDictionary
grpc_dictionaryFromMetadataArray:strongSelf->_headers];
NSDictionary *metadata =
[NSDictionary grpc_dictionaryFromMetadataArray:strongSelf->_headers];
handler(metadata);
};
}
@ -208,10 +207,10 @@
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
char *details = grpc_slice_to_c_string(strongSelf->_details);
NSError *error = [NSError grpc_errorFromStatusCode:strongSelf->_statusCode
details:details];
NSDictionary *trailers = [NSDictionary
grpc_dictionaryFromMetadataArray:strongSelf->_trailers];
NSError *error =
[NSError grpc_errorFromStatusCode:strongSelf->_statusCode details:details];
NSDictionary *trailers =
[NSDictionary grpc_dictionaryFromMetadataArray:strongSelf->_trailers];
handler(error, trailers);
gpr_free(details);
}
@ -244,8 +243,7 @@
path:(NSString *)path
timeout:(NSTimeInterval)timeout {
if (!path || !host) {
[NSException raise:NSInvalidArgumentException
format:@"path and host cannot be nil."];
[NSException raise:NSInvalidArgumentException format:@"path and host cannot be nil."];
}
if (self = [super init]) {
@ -282,8 +280,8 @@
for (GRPCOperation *operation in operations) {
ops_array[i++] = operation.op;
}
grpc_call_error error = grpc_call_start_batch(_call, ops_array, nops,
(__bridge_retained void *)(^(bool success){
grpc_call_error error =
grpc_call_start_batch(_call, ops_array, nops, (__bridge_retained void *)(^(bool success) {
if (!success) {
if (errorHandler) {
errorHandler();
@ -294,13 +292,14 @@
for (GRPCOperation *operation in operations) {
[operation finish];
}
}), NULL);
}),
NULL);
gpr_free(ops_array);
if (error != GRPC_CALL_OK) {
[NSException raise:NSInternalInconsistencyException
format:@"A precondition for calling grpc_call_start_batch wasn't met. Error %i",
error];
[NSException
raise:NSInternalInconsistencyException
format:@"A precondition for calling grpc_call_start_batch wasn't met. Error %i", error];
}
}

@ -24,8 +24,8 @@
// TODO(jcanizales): Move these two incantations to the C library.
static void MallocAndCopyByteBufferToCharArray(grpc_byte_buffer *buffer,
size_t *length, char **array) {
static void MallocAndCopyByteBufferToCharArray(grpc_byte_buffer *buffer, size_t *length,
char **array) {
grpc_byte_buffer_reader reader;
if (!grpc_byte_buffer_reader_init(&reader, buffer)) {
// grpc_byte_buffer_reader_init can fail if the data sent by the server
@ -51,8 +51,7 @@ static void MallocAndCopyByteBufferToCharArray(grpc_byte_buffer *buffer,
grpc_byte_buffer_reader_destroy(&reader);
}
static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array,
size_t length) {
static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array, size_t length) {
grpc_slice slice = grpc_slice_from_copied_buffer(array, length);
grpc_byte_buffer *buffer = grpc_raw_byte_buffer_create(&slice, 1);
grpc_slice_unref(slice);
@ -89,7 +88,6 @@ static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array,
// to create an array of grpc_slice objects to pass to
// grpc_raw_byte_buffer_create.
// That would make it do exactly one copy, always.
return CopyCharArrayToNewByteBuffer((const char *)self.bytes,
(size_t)self.length);
return CopyCharArrayToNewByteBuffer((const char *)self.bytes, (size_t)self.length);
}
@end

@ -74,8 +74,7 @@
NSMutableDictionary *metadata = [NSMutableDictionary dictionaryWithCapacity:count];
for (grpc_metadata *entry = entries; entry < entries + count; entry++) {
char *key = grpc_slice_to_c_string(entry->key);
NSString *name = [NSString stringWithCString:key
encoding:NSASCIIStringEncoding];
NSString *name = [NSString stringWithCString:key encoding:NSASCIIStringEncoding];
gpr_free(key);
if (!name || metadata[name]) {
// Log if name is nil?

@ -22,5 +22,4 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
#define GRPC_OBJC_VERSION_STRING @"1.12.0-dev"

@ -22,9 +22,8 @@
* A fully-qualified proto service method name. Full qualification is needed because a gRPC endpoint
* can implement multiple services.
*/
__attribute__((deprecated("Please use GRPCProtoMethod.")))
@interface ProtoMethod : NSObject
@property(nonatomic, readonly) NSString *package;
__attribute__((deprecated("Please use GRPCProtoMethod."))) @interface ProtoMethod
: NSObject @property(nonatomic, readonly) NSString *package;
@property(nonatomic, readonly) NSString *service;
@property(nonatomic, readonly) NSString *method;

@ -21,18 +21,18 @@
#import "ProtoMethod.h"
__attribute__((deprecated("Please use GRPCProtoCall.")))
@interface ProtoRPC : GRPCCall
__attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC
: GRPCCall
/**
* host parameter should not contain the scheme (http:// or https://), only the name or IP addr
* and the port number, for example @"localhost:5050".
* host parameter should not contain the scheme (http:// or https://), only the name or IP
* addr and the port number, for example @"localhost:5050".
*/
- (instancetype)initWithHost:(NSString *)host
method:(GRPCProtoMethod *)method
requestsWriter:(GRXWriter *)requestsWriter
responseClass:(Class)responseClass
responsesWriteable:(id<GRXWriteable>)responsesWriteable NS_DESIGNATED_INITIALIZER;
-
(instancetype)initWithHost : (NSString *)host method
: (GRPCProtoMethod *)method requestsWriter : (GRXWriter *)requestsWriter responseClass
: (Class)responseClass responsesWriteable
: (id<GRXWriteable>)responsesWriteable NS_DESIGNATED_INITIALIZER;
- (void)start;
@end

@ -29,7 +29,8 @@
static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsingError) {
NSDictionary *info = @{
NSLocalizedDescriptionKey : @"Unable to parse response from the server",
NSLocalizedRecoverySuggestionErrorKey: @"If this RPC is idempotent, retry "
NSLocalizedRecoverySuggestionErrorKey :
@"If this RPC is idempotent, retry "
@"with exponential backoff. Otherwise, query the server status before "
@"retrying.",
NSUnderlyingErrorKey : parsingError,
@ -37,9 +38,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing
@"Received value" : proto,
};
// TODO(jcanizales): Use kGRPCErrorDomain and GRPCErrorCodeInternal when they're public.
return [NSError errorWithDomain:@"io.grpc"
code:13
userInfo:info];
return [NSError errorWithDomain:@"io.grpc" code:13 userInfo:info];
}
#pragma clang diagnostic push
@ -92,7 +91,8 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing
} else {
[weakSelf finishWithError:ErrorForBadProto(value, responseClass, error)];
}
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil) {
[responsesWriteable writesFinishedWithError:errorOrNil];
}];
}

@ -22,12 +22,10 @@
@protocol GRXWriteable;
@class GRXWriter;
__attribute__((deprecated("Please use GRPCProtoService.")))
@interface ProtoService : NSObject
- (instancetype)initWithHost:(NSString *)host
packageName:(NSString *)packageName
serviceName:(NSString *)serviceName NS_DESIGNATED_INITIALIZER;
__attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService
: NSObject -
(instancetype)initWithHost : (NSString *)host packageName
: (NSString *)packageName serviceName : (NSString *)serviceName NS_DESIGNATED_INITIALIZER;
- (GRPCProtoCall *)RPCToMethod:(NSString *)method
requestsWriter:(GRXWriter *)requestsWriter
@ -35,7 +33,6 @@ __attribute__((deprecated("Please use GRPCProtoService.")))
responsesWriteable:(id<GRXWriteable>)responsesWriteable;
@end
/**
* This subclass is empty now. Eventually we'll remove ProtoService class
* to avoid potential naming conflict

@ -57,9 +57,8 @@
requestsWriter:(GRXWriter *)requestsWriter
responseClass:(Class)responseClass
responsesWriteable:(id<GRXWriteable>)responsesWriteable {
GRPCProtoMethod *methodName = [[GRPCProtoMethod alloc] initWithPackage:_packageName
service:_serviceName
method:method];
GRPCProtoMethod *methodName =
[[GRPCProtoMethod alloc] initWithPackage:_packageName service:_serviceName method:method];
return [[GRPCProtoCall alloc] initWithHost:_host
method:methodName
requestsWriter:requestsWriter

@ -112,8 +112,7 @@
- (void)dealloc {
GRXWriterState state = self.state;
if (state == GRXWriterStateNotStarted ||
state == GRXWriterStatePaused) {
if (state == GRXWriterStateNotStarted || state == GRXWriterStatePaused) {
dispatch_resume(_writeQueue);
}
}

@ -18,8 +18,8 @@
#import <Foundation/Foundation.h>
#import "GRXWriter.h"
#import "GRXWriteable.h"
#import "GRXWriter.h"
/**
* This is a thread-safe wrapper over a GRXWriteable instance. It lets one enqueue calls to a

@ -46,8 +46,7 @@
}
- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable {
return [self initWithWriteable:writeable
dispatchQueue:dispatch_get_main_queue()];
return [self initWithWriteable:writeable dispatchQueue:dispatch_get_main_queue()];
}
- (void)enqueueValue:(id)value completionHandler:(void (^)(void))handler {

@ -57,7 +57,8 @@
}
+ (GRXWriter *)writerWithContainer:(id<NSFastEnumeration>)container {
return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithContainer:container]];;
return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithContainer:container]];
;
}
+ (GRXWriter *)writerWithValue:(id)value {

@ -42,9 +42,8 @@
} else if (error) {
singleHandler(nil, error);
} else {
NSDictionary *userInfo = @{
NSLocalizedDescriptionKey: @"The writer finished without producing any value."
};
NSDictionary *userInfo =
@{NSLocalizedDescriptionKey : @"The writer finished without producing any value."};
// Even though RxLibrary is independent of gRPC, the domain and code here are, for the moment,
// set to the values of kGRPCErrorDomain and GRPCErrorCodeInternal. This way, the error formed
// is the one user of gRPC would expect if the server failed to produce a response.
@ -55,9 +54,9 @@
// the two domains.
static NSString *kGRPCErrorDomain = @"io.grpc";
static NSUInteger kGRPCErrorCodeInternal = 13;
singleHandler(nil, [NSError errorWithDomain:kGRPCErrorDomain
code:kGRPCErrorCodeInternal
userInfo:userInfo]);
singleHandler(
nil,
[NSError errorWithDomain:kGRPCErrorDomain code:kGRPCErrorCodeInternal userInfo:userInfo]);
}
};
return [self writeableWithEventHandler:^(BOOL done, id value, NSError *error) {
@ -73,7 +72,8 @@
}
return [[self alloc] initWithValueHandler:^(id value) {
handler(NO, value, nil);
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil) {
handler(YES, nil, errorOrNil);
}];
}

@ -18,8 +18,8 @@
#import "GRXWriter+Immediate.h"
#import "GRXImmediateWriter.h"
#import "GRXImmediateSingleWriter.h"
#import "GRXImmediateWriter.h"
@implementation GRXWriter (Immediate)

@ -18,8 +18,9 @@
#import "RxLibrary/GRXForwardingWriter.h"
/** A "proxy" writer that transforms all the values of its input writer by using a mapping function. */
/** A "proxy" writer that transforms all the values of its input writer by using a mapping function.
*/
@interface GRXMappingWriter : GRXForwardingWriter
- (instancetype)initWithWriter:(GRXWriter *)writer map:(id (^)(id value))map
NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithWriter:(GRXWriter *)writer
map:(id (^)(id value))map NS_DESIGNATED_INITIALIZER;
@end

@ -22,8 +22,8 @@
#import <ProtoRPC/ProtoMethod.h>
#import <RemoteTest/Messages.pbobjc.h>
#import <RemoteTest/Test.pbrpc.h>
#import <RxLibrary/GRXWriter+Immediate.h>
#import <RxLibrary/GRXWriteable.h>
#import <RxLibrary/GRXWriter+Immediate.h>
@implementation ViewController
@ -40,7 +40,8 @@
// Example gRPC call using a generated proto client library:
RMTTestService *service = [[RMTTestService alloc] initWithHost:kRemoteHost];
[service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
[service unaryCallWithRequest:request
handler:^(RMTSimpleResponse *response, NSError *error) {
if (response) {
NSLog(@"Finished successfully with response:\n%@", response);
} else if (error) {
@ -48,7 +49,6 @@
}
}];
// Same example call using the generic gRPC client library:
GRPCProtoMethod *method = [[GRPCProtoMethod alloc] initWithPackage:@"grpc.testing"
@ -61,10 +61,12 @@
path:method.HTTPPath
requestsWriter:requestsWriter];
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
id<GRXWriteable> responsesWriteable =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value error:NULL];
NSLog(@"Received response:\n%@", response);
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil) {
if (errorOrNil) {
NSLog(@"Finished with error: %@", errorOrNil);
} else {

@ -20,9 +20,9 @@
#import <GRPCClient/GRPCCall.h>
#import <ProtoRPC/ProtoMethod.h>
#import <RxLibrary/GRXBufferedPipe.h>
#import <RxLibrary/GRXWriter+Immediate.h>
#import <RxLibrary/GRXWriter+Transformations.h>
#import <RxLibrary/GRXBufferedPipe.h>
#import "src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h"
@ -35,8 +35,7 @@ NSString *host = @"grpc-test.sandbox.googleapis.com";
- (void)viewDidLoad {
[super viewDidLoad];
[GRPCConnectivityMonitor registerObserver:self
selector:@selector(reachabilityChanged:)];
[GRPCConnectivityMonitor registerObserver:self selector:@selector(reachabilityChanged:)];
}
- (void)reachabilityChanged:(NSNotification *)note {
@ -52,18 +51,16 @@ NSString *host = @"grpc-test.sandbox.googleapis.com";
GRPCProtoMethod *method = [[GRPCProtoMethod alloc] initWithPackage:@"grpc.testing"
service:@"TestService"
method:@"UnaryCall"];
GRXWriter *loggingRequestWriter =
[[GRXWriter writerWithValue:[NSData dataWithBytes:bytes length:sizeof(bytes)]]
map:^id(id value) {
GRXWriter *loggingRequestWriter = [[GRXWriter
writerWithValue:[NSData dataWithBytes:bytes length:sizeof(bytes)]] map:^id(id value) {
NSLog(@"Sending request.");
return value;
}];
GRPCCall *call = [[GRPCCall alloc] initWithHost:host
path:method.HTTPPath
requestsWriter:loggingRequestWriter];
GRPCCall *call =
[[GRPCCall alloc] initWithHost:host path:method.HTTPPath requestsWriter:loggingRequestWriter];
[call startWithWriteable:[GRXWriteable writeableWithEventHandler:^(BOOL done, id value,
NSError *error) {
[call startWithWriteable:[GRXWriteable
writeableWithEventHandler:^(BOOL done, id value, NSError *error) {
if (!done) {
return;
}
@ -85,12 +82,11 @@ NSString *host = @"grpc-test.sandbox.googleapis.com";
[requestsBuffer writeValue:[NSData dataWithBytes:bytes length:sizeof(bytes)]];
GRPCCall *call = [[GRPCCall alloc] initWithHost:host
path:method.HTTPPath
requestsWriter:requestsBuffer];
GRPCCall *call =
[[GRPCCall alloc] initWithHost:host path:method.HTTPPath requestsWriter:requestsBuffer];
[call startWithWriteable:[GRXWriteable writeableWithEventHandler:^(BOOL done, id value,
NSError *error) {
[call startWithWriteable:[GRXWriteable
writeableWithEventHandler:^(BOOL done, id value, NSError *error) {
if (!done) {
return;
}

@ -37,11 +37,11 @@
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/tmpfile.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@ -70,9 +70,8 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
return f;
}
static void process_auth_failure(void *state, grpc_auth_context *ctx,
const grpc_metadata *md, size_t md_count,
grpc_process_auth_metadata_done_cb cb,
static void process_auth_failure(void *state, grpc_auth_context *ctx, const grpc_metadata *md,
size_t md_count, grpc_process_auth_metadata_done_cb cb,
void *user_data) {
GPR_ASSERT(state == NULL);
cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL);
@ -87,14 +86,13 @@ static void cronet_init_client_secure_fullstack(grpc_end2end_test_fixture *f,
arg.type = GRPC_ARG_INTEGER;
arg.value.integer = 1;
client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1);
f->client = grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr,
client_args, NULL);
f->client = grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL);
grpc_channel_args_destroy(client_args);
GPR_ASSERT(f->client != NULL);
}
static void chttp2_init_server_secure_fullstack(
grpc_end2end_test_fixture *f, grpc_channel_args *server_args,
static void chttp2_init_server_secure_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *server_args,
grpc_server_credentials *server_creds) {
fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data;
if (f->server) {
@ -102,8 +100,7 @@ static void chttp2_init_server_secure_fullstack(
}
f->server = grpc_server_create(server_args, NULL);
grpc_server_register_completion_queue(f->server, f->cq, NULL);
GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr,
server_creds));
GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds));
grpc_server_credentials_release(server_creds);
grpc_server_start(f->server);
}
@ -114,8 +111,8 @@ static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) {
gpr_free(ffd);
}
static void cronet_init_client_simple_ssl_secure_fullstack(
grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
static void cronet_init_client_simple_ssl_secure_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *client_args) {
grpc_core::ExecCtx exec_ctx;
stream_engine *cronetEngine = [Cronet getGlobalEngine];
@ -128,18 +125,16 @@ static int fail_server_auth_check(grpc_channel_args *server_args) {
size_t i;
if (server_args == NULL) return 0;
for (i = 0; i < server_args->num_args; i++) {
if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) ==
0) {
if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) == 0) {
return 1;
}
}
return 0;
}
static void chttp2_init_server_simple_ssl_secure_fullstack(
grpc_end2end_test_fixture *f, grpc_channel_args *server_args) {
grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
test_server1_cert};
static void chttp2_init_server_simple_ssl_secure_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *server_args) {
grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, test_server1_cert};
grpc_server_credentials *ssl_creds =
grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL);
if (fail_server_auth_check(server_args)) {
@ -189,8 +184,7 @@ static char *roots_filename;
[Cronet setHttp2Enabled:YES];
[Cronet enableTestCertVerifierForTesting];
NSURL *url = [[[NSFileManager defaultManager]
URLsForDirectory:NSDocumentDirectory
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
NSLog(@"Documents directory: %@", url);
[Cronet start];

@ -42,8 +42,7 @@
static void drain_cq(grpc_completion_queue *cq) {
grpc_event ev;
do {
ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5),
NULL);
ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5), NULL);
} while (ev.type != GRPC_QUEUE_SHUTDOWN);
}
@ -64,8 +63,7 @@ static void drain_cq(grpc_completion_queue *cq) {
[Cronet setHttp2Enabled:YES];
[Cronet setSslKeyLogFileName:@"Documents/key"];
[Cronet enableTestCertVerifierForTesting];
NSURL *url = [[[NSFileManager defaultManager]
URLsForDirectory:NSDocumentDirectory
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
NSLog(@"Documents directory: %@", url);
[Cronet start];
@ -88,8 +86,8 @@ void init_ssl(void) {
void cleanup_ssl(void) { EVP_cleanup(); }
int alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
const unsigned char *in, unsigned int inlen, void *arg) {
int alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg) {
// Always select "h2" as the ALPN protocol to be used
*out = (const unsigned char *)"h2";
*outlen = 2;
@ -98,16 +96,14 @@ int alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
void init_ctx(SSL_CTX *ctx) {
// Install server certificate
BIO *pem = BIO_new_mem_buf((void *)test_server1_cert,
(int)strlen(test_server1_cert));
BIO *pem = BIO_new_mem_buf((void *)test_server1_cert, (int)strlen(test_server1_cert));
X509 *cert = PEM_read_bio_X509_AUX(pem, NULL, NULL, (char *)"");
SSL_CTX_use_certificate(ctx, cert);
X509_free(cert);
BIO_free(pem);
// Install server private key
pem =
BIO_new_mem_buf((void *)test_server1_key, (int)strlen(test_server1_key));
pem = BIO_new_mem_buf((void *)test_server1_key, (int)strlen(test_server1_key));
EVP_PKEY *key = PEM_read_bio_PrivateKey(pem, NULL, NULL, (char *)"");
SSL_CTX_use_PrivateKey(ctx, key);
EVP_PKEY_free(key);
@ -136,10 +132,8 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a
- (void)testInternalError {
grpc_call *c;
grpc_slice request_payload_slice =
grpc_slice_from_copied_string("hello world");
grpc_byte_buffer *request_payload =
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_slice request_payload_slice = grpc_slice_from_copied_string("hello world");
grpc_byte_buffer *request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
grpc_slice_from_static_string("val1"),
@ -156,8 +150,7 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a
grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
stream_engine *cronetEngine = [Cronet getGlobalEngine];
grpc_channel_args *client_args = add_disable_client_authority_filter_args(NULL);
grpc_channel *client =
grpc_cronet_secure_channel_create(cronetEngine, addr, client_args, NULL);
grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, client_args, NULL);
grpc_channel_args_destroy(client_args);
cq_verifier *cqv = cq_verifier_create(cq);
@ -173,8 +166,7 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a
grpc_slice details;
c = grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
grpc_slice_from_static_string("/foo"), NULL,
deadline, NULL);
grpc_slice_from_static_string("/foo"), NULL, deadline, NULL);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@ -231,8 +223,7 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a
error = grpc_call_start_batch(c, ops, (size_t)(op - ops), (void *)1, NULL);
GPR_ASSERT(GRPC_CALL_OK == error);
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
int s = accept(sl, NULL, NULL);
GPR_ASSERT(s >= 0);
@ -275,10 +266,8 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a
args = add_disable_client_authority_filter_args(args);
grpc_call *c;
grpc_slice request_payload_slice =
grpc_slice_from_copied_string("hello world");
grpc_byte_buffer *request_payload =
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_slice request_payload_slice = grpc_slice_from_copied_string("hello world");
grpc_byte_buffer *request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5);
grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
grpc_slice_from_static_string("val1"),
@ -294,8 +283,7 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a
gpr_join_host_port(&addr, "127.0.0.1", port);
grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
stream_engine *cronetEngine = [Cronet getGlobalEngine];
grpc_channel *client =
grpc_cronet_secure_channel_create(cronetEngine, addr, args, NULL);
grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, args, NULL);
cq_verifier *cqv = cq_verifier_create(cq);
grpc_op ops[6];
@ -310,8 +298,7 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a
grpc_slice details;
c = grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
grpc_slice_from_static_string("/foo"), NULL,
deadline, NULL);
grpc_slice_from_static_string("/foo"), NULL, deadline, NULL);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@ -319,8 +306,7 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
__weak XCTestExpectation *expectation =
[self expectationWithDescription:@"Coalescing"];
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"Coalescing"];
int sl = socket(AF_INET, SOCK_STREAM, 0);
GPR_ASSERT(sl >= 0);
@ -332,8 +318,7 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a
GPR_ASSERT(0 == bind(sl, (struct sockaddr *)&s_addr, sizeof(s_addr)));
GPR_ASSERT(0 == listen(sl, 5));
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
int s = accept(sl, NULL, NULL);
GPR_ASSERT(s >= 0);
struct timeval tv;

@ -20,16 +20,16 @@
#import <XCTest/XCTest.h>
#import <grpc/grpc.h>
#import <GRPCClient/GRPCCall.h>
#import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+OAuth2.h>
#import <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCCall.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import <ProtoRPC/ProtoMethod.h>
#import <RemoteTest/Messages.pbobjc.h>
#import <RxLibrary/GRXBufferedPipe.h>
#import <RxLibrary/GRXWriteable.h>
#import <RxLibrary/GRXWriter+Immediate.h>
#import <RxLibrary/GRXBufferedPipe.h>
#include <netinet/in.h>
@ -52,7 +52,9 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
- (instancetype)initWithCallback:(void (^)(NSString *, id, NSDictionary *))callback
NS_DESIGNATED_INITIALIZER;
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context;
@end
@ -108,18 +110,14 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
[GRPCCall useInsecureConnectionsForHost:kHostAddress];
// This method isn't implemented by the remote server.
kInexistentMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage
service:kService
method:@"Inexistent"];
kEmptyCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage
service:kService
method:@"EmptyCall"];
kUnaryCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage
service:kService
method:@"UnaryCall"];
kFullDuplexCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage
service:kService
method:@"FullDuplexCall"];
kInexistentMethod =
[[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"Inexistent"];
kEmptyCallMethod =
[[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"EmptyCall"];
kUnaryCallMethod =
[[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"UnaryCall"];
kFullDuplexCallMethod =
[[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"];
}
- (void)testConnectionToRemoteServer {
@ -129,9 +127,11 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
path:kInexistentMethod.HTTPPath
requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
id<GRXWriteable> responsesWriteable =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
XCTFail(@"Received unexpected response: %@", value);
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil) {
XCTAssertNotNil(errorOrNil, @"Finished without error!");
XCTAssertEqual(errorOrNil.code, 12, @"Finished with unexpected error: %@", errorOrNil);
[expectation fulfill];
@ -143,18 +143,21 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
}
- (void)testEmptyRPC {
__weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
__weak XCTestExpectation *response =
[self expectationWithDescription:@"Empty response received."];
__weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
path:kEmptyCallMethod.HTTPPath
requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
id<GRXWriteable> responsesWriteable =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
XCTAssertNotNil(value, @"nil value received as response.");
XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
[response fulfill];
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil) {
XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
[completion fulfill];
}];
@ -178,7 +181,8 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
path:kUnaryCallMethod.HTTPPath
requestsWriter:requestsWriter];
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
id<GRXWriteable> responsesWriteable =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
XCTAssertNotNil(value, @"nil value received as response.");
XCTAssertGreaterThan(value.length, 0, @"Empty response received.");
RMTSimpleResponse *responseProto = [RMTSimpleResponse parseFromData:value error:NULL];
@ -186,7 +190,8 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
XCTAssertNotNil(responseProto.username, @"Response's username is nil.");
XCTAssertNotNil(responseProto.oauthScope, @"Response's OAuth scope is nil.");
[response fulfill];
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil) {
XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
[completion fulfill];
}];
@ -210,9 +215,11 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
call.oauth2AccessToken = @"bogusToken";
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
id<GRXWriteable> responsesWriteable =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
XCTFail(@"Received unexpected response: %@", value);
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil) {
XCTAssertNotNil(errorOrNil, @"Finished without error!");
XCTAssertEqual(errorOrNil.code, 16, @"Finished with unexpected error: %@", errorOrNil);
XCTAssertEqualObjects(call.responseHeaders, errorOrNil.userInfo[kGRPCHeadersKey],
@ -220,8 +227,8 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
XCTAssertEqualObjects(call.responseTrailers, errorOrNil.userInfo[kGRPCTrailersKey],
@"Trailers in the NSError object and call object differ.");
NSString *challengeHeader = call.oauth2ChallengeHeader;
XCTAssertGreaterThan(challengeHeader.length, 0,
@"No challenge in response headers %@", call.responseHeaders);
XCTAssertGreaterThan(challengeHeader.length, 0, @"No challenge in response headers %@",
call.responseHeaders);
[expectation fulfill];
}];
@ -231,7 +238,8 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
}
- (void)testResponseMetadataKVO {
__weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
__weak XCTestExpectation *response =
[self expectationWithDescription:@"Empty response received."];
__weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
__weak XCTestExpectation *metadata = [self expectationWithDescription:@"Metadata changed."];
@ -239,7 +247,8 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
path:kEmptyCallMethod.HTTPPath
requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
PassthroughObserver *observer = [[PassthroughObserver alloc] initWithCallback:^(NSString *keypath, id object, NSDictionary * change) {
PassthroughObserver *observer = [[PassthroughObserver alloc]
initWithCallback:^(NSString *keypath, id object, NSDictionary *change) {
if ([keypath isEqual:@"responseHeaders"]) {
[metadata fulfill];
}
@ -247,11 +256,13 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
[call addObserver:observer forKeyPath:@"responseHeaders" options:0 context:NULL];
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
id<GRXWriteable> responsesWriteable =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
XCTAssertNotNil(value, @"nil value received as response.");
XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
[response fulfill];
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil) {
XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
[completion fulfill];
}];
@ -262,7 +273,8 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
}
- (void)testUserAgentPrefix {
__weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
__weak XCTestExpectation *response =
[self expectationWithDescription:@"Empty response received."];
__weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
@ -272,7 +284,8 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
// user-agent value, which we confirm.
call.requestHeaders[@"x-grpc-test-echo-useragent"] = @"";
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
id<GRXWriteable> responsesWriteable =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
XCTAssertNotNil(value, @"nil value received as response.");
XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
@ -281,23 +294,20 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
// Test the regex is correct
NSString *expectedUserAgent = @"Foo grpc-objc/";
expectedUserAgent =
[expectedUserAgent stringByAppendingString:GRPC_OBJC_VERSION_STRING];
expectedUserAgent =
[expectedUserAgent stringByAppendingString:@" grpc-c/"];
expectedUserAgent =
[expectedUserAgent stringByAppendingString:GRPC_C_VERSION_STRING];
expectedUserAgent =
[expectedUserAgent stringByAppendingString:@" (ios; chttp2; "];
expectedUserAgent =
[expectedUserAgent stringByAppendingString:[NSString stringWithUTF8String:grpc_g_stands_for()]];
expectedUserAgent = [expectedUserAgent stringByAppendingString:GRPC_OBJC_VERSION_STRING];
expectedUserAgent = [expectedUserAgent stringByAppendingString:@" grpc-c/"];
expectedUserAgent = [expectedUserAgent stringByAppendingString:GRPC_C_VERSION_STRING];
expectedUserAgent = [expectedUserAgent stringByAppendingString:@" (ios; chttp2; "];
expectedUserAgent = [expectedUserAgent
stringByAppendingString:[NSString stringWithUTF8String:grpc_g_stands_for()]];
expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"];
XCTAssertEqualObjects(userAgent, expectedUserAgent);
// Change in format of user-agent field in a direction that does not match the regex will likely
// cause problem for certain gRPC users. For details, refer to internal doc https://goo.gl/c2diBc
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:@" grpc-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/[^ ,]+( \\([^)]*\\))?"
// Change in format of user-agent field in a direction that does not match the regex will
// likely cause problem for certain gRPC users. For details, refer to internal doc
// https://goo.gl/c2diBc
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:@" grpc-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/[^ ,]+( \\([^)]*\\))?"
options:0
error:&error];
NSString *customUserAgent =
@ -308,7 +318,8 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
XCTAssertEqualObjects(customUserAgent, @"Foo");
[response fulfill];
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil) {
XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
[completion fulfill];
}];
@ -319,7 +330,8 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
}
- (void)testTrailers {
__weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
__weak XCTestExpectation *response =
[self expectationWithDescription:@"Empty response received."];
__weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
@ -331,15 +343,16 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
NSData *trailer_data = [NSData dataWithBytes:raw_bytes length:sizeof(raw_bytes)];
call.requestHeaders[@"x-grpc-test-echo-trailing-bin"] = trailer_data;
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
id<GRXWriteable> responsesWriteable =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
XCTAssertNotNil(value, @"nil value received as response.");
XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
[response fulfill];
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil) {
XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
XCTAssertEqualObjects((NSData *)call.responseTrailers[@"x-grpc-test-echo-trailing-bin"],
trailer_data,
@"Did not receive expected trailer");
trailer_data, @"Did not receive expected trailer");
[completion fulfill];
}];
@ -351,15 +364,12 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
- (void)testExceptions {
// Try to set parameters to nil for GRPCCall. This should cause an exception
@try {
(void)[[GRPCCall alloc] initWithHost:nil
path:nil
requestsWriter:nil];
(void)[[GRPCCall alloc] initWithHost:nil path:nil requestsWriter:nil];
XCTFail(@"Did not receive an exception when parameters are nil");
} @catch (NSException *theException) {
NSLog(@"Received exception as expected: %@", theException.name);
}
// Set state to Finished by force
GRXWriter *requestsWriter = [GRXWriter emptyWriter];
[requestsWriter finishWithError:nil];
@ -371,7 +381,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
} @catch (NSException *theException) {
NSLog(@"Received exception as expected: %@", theException.name);
}
}
- (void)testIdempotentProtoRPC {
@ -387,9 +396,12 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
path:kUnaryCallMethod.HTTPPath
requestsWriter:requestsWriter];
[GRPCCall setCallSafety:GRPCCallSafetyIdempotentRequest host:kHostAddress path:kUnaryCallMethod.HTTPPath];
[GRPCCall setCallSafety:GRPCCallSafetyIdempotentRequest
host:kHostAddress
path:kUnaryCallMethod.HTTPPath];
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
id<GRXWriteable> responsesWriteable =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
XCTAssertNotNil(value, @"nil value received as response.");
XCTAssertGreaterThan(value.length, 0, @"Empty response received.");
RMTSimpleResponse *responseProto = [RMTSimpleResponse parseFromData:value error:NULL];
@ -397,7 +409,8 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
XCTAssertNotNil(responseProto.username, @"Response's username is nil.");
XCTAssertNotNil(responseProto.oauthScope, @"Response's OAuth scope is nil.");
[response fulfill];
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil) {
XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
[completion fulfill];
}];
@ -412,10 +425,12 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
RMTSimpleRequest *request = [RMTSimpleRequest message];
request.responseSize = kPayloadSize;
__weak XCTestExpectation *expectation1 = [self expectationWithDescription:@"AlternateDispatchQueue1"];
__weak XCTestExpectation *expectation1 =
[self expectationWithDescription:@"AlternateDispatchQueue1"];
// Use default (main) dispatch queue
NSString *main_queue_label = [NSString stringWithUTF8String:dispatch_queue_get_label(dispatch_get_main_queue())];
NSString *main_queue_label =
[NSString stringWithUTF8String:dispatch_queue_get_label(dispatch_get_main_queue())];
GRXWriter *requestsWriter1 = [GRXWriter writerWithValue:[request data]];
@ -423,12 +438,15 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
path:kUnaryCallMethod.HTTPPath
requestsWriter:requestsWriter1];
id<GRXWriteable> responsesWriteable1 = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
NSString *label = [NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
id<GRXWriteable> responsesWriteable1 =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
NSString *label =
[NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
XCTAssert([label isEqualToString:main_queue_label]);
[expectation1 fulfill];
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil){
}];
[call1 startWithWriteable:responsesWriteable1];
@ -436,7 +454,8 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
// Use a custom queue
__weak XCTestExpectation *expectation2 = [self expectationWithDescription:@"AlternateDispatchQueue2"];
__weak XCTestExpectation *expectation2 =
[self expectationWithDescription:@"AlternateDispatchQueue2"];
NSString *queue_label = @"test.queue1";
dispatch_queue_t queue = dispatch_queue_create([queue_label UTF8String], DISPATCH_QUEUE_SERIAL);
@ -449,12 +468,15 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
[call2 setResponseDispatchQueue:queue];
id<GRXWriteable> responsesWriteable2 = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
NSString *label = [NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
id<GRXWriteable> responsesWriteable2 =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
NSString *label =
[NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
XCTAssert([label isEqualToString:queue_label]);
[expectation2 fulfill];
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil){
}];
[call2 startWithWriteable:responsesWriteable2];
@ -470,10 +492,13 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
path:kFullDuplexCallMethod.HTTPPath
requestsWriter:pipe];
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
id<GRXWriteable> responsesWriteable =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
XCTAssert(0, @"Failure: response received; Expect: no response received.");
} completionHandler:^(NSError *errorOrNil) {
XCTAssertNotNil(errorOrNil, @"Failure: no error received; Expect: receive deadline exceeded.");
}
completionHandler:^(NSError *errorOrNil) {
XCTAssertNotNil(errorOrNil,
@"Failure: no error received; Expect: receive deadline exceeded.");
XCTAssertEqual(errorOrNil.code, GRPCErrorCodeDeadlineExceeded);
[completion fulfill];
}];
@ -506,10 +531,12 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
path:kEmptyCallMethod.HTTPPath
requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
id<GRXWriteable> responsesWriteable =
[[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
// Should not reach here
XCTAssert(NO);
} completionHandler:^(NSError *errorOrNil) {
}
completionHandler:^(NSError *errorOrNil) {
XCTAssertNotNil(errorOrNil, @"Finished with no error");
XCTAssertEqual(errorOrNil.code, GRPC_STATUS_UNAVAILABLE);
[completion fulfill];

@ -22,17 +22,17 @@
#import <Cronet/Cronet.h>
#import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+Cronet.h>
#import <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import <GRPCClient/GRPCCall+Cronet.h>
#import <ProtoRPC/ProtoRPC.h>
#import <RemoteTest/Messages.pbobjc.h>
#import <RemoteTest/Test.pbobjc.h>
#import <RemoteTest/Test.pbrpc.h>
#import <RxLibrary/GRXBufferedPipe.h>
#import <RxLibrary/GRXWriter+Immediate.h>
#import <grpc/support/log.h>
#import <grpc/grpc.h>
#import <grpc/support/log.h>
#define TEST_TIMEOUT 32
@ -113,7 +113,8 @@ BOOL isRemoteInteropTest(NSString *host) {
GPBEmpty *request = [GPBEmpty message];
[_service emptyCallWithRequest:request handler:^(GPBEmpty *response, NSError *error) {
[_service emptyCallWithRequest:request
handler:^(GPBEmpty *response, NSError *error) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
id expectedResponse = [GPBEmpty message];
@ -134,7 +135,8 @@ BOOL isRemoteInteropTest(NSString *host) {
request.responseSize = 314159;
request.payload.body = [NSMutableData dataWithLength:271828];
[_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
[_service unaryCallWithRequest:request
handler:^(RMTSimpleResponse *response, NSError *error) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
@ -158,7 +160,8 @@ BOOL isRemoteInteropTest(NSString *host) {
request.payload.body = [NSMutableData dataWithLength:10];
[GRPCCall enableOpBatchLog:YES];
[_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
[_service unaryCallWithRequest:request
handler:^(RMTSimpleResponse *response, NSError *error) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
@ -166,9 +169,9 @@ BOOL isRemoteInteropTest(NSString *host) {
expectedResponse.payload.body = [NSMutableData dataWithLength:10];
XCTAssertEqualObjects(response, expectedResponse);
// The test is a success if there is a batch of exactly 3 ops (SEND_INITIAL_METADATA,
// SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT). Without packet coalescing each batch of ops contains
// only one op.
// The test is a success if there is a batch of exactly 3 ops
// (SEND_INITIAL_METADATA, SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT). Without
// packet coalescing each batch of ops contains only one op.
NSArray *opBatches = [GRPCCall obtainAndCleanOpBatchLog];
const NSInteger kExpectedOpBatchSize = 3;
for (NSObject *o in opBatches) {
@ -194,7 +197,8 @@ BOOL isRemoteInteropTest(NSString *host) {
const int32_t kPayloadSize = 4 * 1024 * 1024 - self.encodingOverhead; // 4MB - encoding overhead
request.responseSize = kPayloadSize;
[_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
[_service unaryCallWithRequest:request
handler:^(RMTSimpleResponse *response, NSError *error) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
XCTAssertEqual(response.payload.body.length, kPayloadSize);
[expectation fulfill];
@ -211,13 +215,18 @@ BOOL isRemoteInteropTest(NSString *host) {
const int32_t kPayloadSize = 4 * 1024 * 1024 - self.encodingOverhead + 1; // 1B over max size
request.responseSize = kPayloadSize;
[_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
// TODO(jcanizales): Catch the error and rethrow it with an actionable message:
[_service unaryCallWithRequest:request
handler:^(RMTSimpleResponse *response, NSError *error) {
// TODO(jcanizales): Catch the error and rethrow it with an actionable
// message:
// - Use +[GRPCCall setResponseSizeLimit:forHost:] to set a higher limit.
// - If you're developing the server, consider using response streaming, or let clients filter
// - If you're developing the server, consider using response streaming,
// or let clients filter
// responses by setting a google.protobuf.FieldMask in the request:
// https://github.com/google/protobuf/blob/master/src/google/protobuf/field_mask.proto
XCTAssertEqualObjects(error.localizedDescription, @"Received message larger than max (4194305 vs. 4194304)");
XCTAssertEqualObjects(
error.localizedDescription,
@"Received message larger than max (4194305 vs. 4194304)");
[expectation fulfill];
}];
@ -235,7 +244,8 @@ BOOL isRemoteInteropTest(NSString *host) {
[GRPCCall setResponseSizeLimit:6 * 1024 * 1024 forHost:self.class.host];
[_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
[_service unaryCallWithRequest:request
handler:^(RMTSimpleResponse *response, NSError *error) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
XCTAssertEqual(response.payload.body.length, kPayloadSize);
[expectation fulfill];
@ -265,9 +275,11 @@ BOOL isRemoteInteropTest(NSString *host) {
[_service streamingInputCallWithRequestsWriter:writer
handler:^(RMTStreamingInputCallResponse *response,
NSError *error) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
XCTAssertNil(
error, @"Finished with unexpected error: %@", error);
RMTStreamingInputCallResponse *expectedResponse = [RMTStreamingInputCallResponse message];
RMTStreamingInputCallResponse *expectedResponse =
[RMTStreamingInputCallResponse message];
expectedResponse.aggregatedPayloadSize = 74922;
XCTAssertEqualObjects(response, expectedResponse);
@ -291,16 +303,18 @@ BOOL isRemoteInteropTest(NSString *host) {
}
__block int index = 0;
[_service streamingOutputCallWithRequest:request
eventHandler:^(BOOL done,
RMTStreamingOutputCallResponse *response,
[_service
streamingOutputCallWithRequest:request
eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
NSError *error) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
XCTAssertTrue(done || response, @"Event handler called without an event.");
XCTAssertTrue(done || response,
@"Event handler called without an event.");
if (response) {
XCTAssertLessThan(index, 4, @"More than 4 responses received.");
id expected = [RMTStreamingOutputCallResponse messageWithPayloadSize:expectedSizes[index]];
id expected = [RMTStreamingOutputCallResponse
messageWithPayloadSize:expectedSizes[index]];
XCTAssertEqualObjects(response, expected);
index += 1;
}
@ -330,19 +344,21 @@ BOOL isRemoteInteropTest(NSString *host) {
[requestsBuffer writeValue:request];
[_service fullDuplexCallWithRequestsWriter:requestsBuffer
eventHandler:^(BOOL done,
RMTStreamingOutputCallResponse *response,
eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
NSError *error) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
XCTAssertTrue(done || response, @"Event handler called without an event.");
XCTAssertTrue(done || response,
@"Event handler called without an event.");
if (response) {
XCTAssertLessThan(index, 4, @"More than 4 responses received.");
id expected = [RMTStreamingOutputCallResponse messageWithPayloadSize:responses[index]];
id expected = [RMTStreamingOutputCallResponse
messageWithPayloadSize:responses[index]];
XCTAssertEqualObjects(response, expected);
index += 1;
if (index < 4) {
id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index]
id request = [RMTStreamingOutputCallRequest
messageWithPayloadSize:requests[index]
requestedResponseSize:responses[index]];
[requestsBuffer writeValue:request];
} else {
@ -351,7 +367,8 @@ BOOL isRemoteInteropTest(NSString *host) {
}
if (done) {
XCTAssertEqual(index, 4, @"Received %i responses instead of 4.", index);
XCTAssertEqual(index, 4, @"Received %i responses instead of 4.",
index);
[expectation fulfill];
}
}];
@ -362,8 +379,7 @@ BOOL isRemoteInteropTest(NSString *host) {
XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"];
[_service fullDuplexCallWithRequestsWriter:[GRXWriter emptyWriter]
eventHandler:^(BOOL done,
RMTStreamingOutputCallResponse *response,
eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
NSError *error) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
XCTAssert(done, @"Unexpected response: %@", response);
@ -379,8 +395,8 @@ BOOL isRemoteInteropTest(NSString *host) {
// A buffered pipe to which we never write any value acts as a writer that just hangs.
GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
GRPCProtoCall *call =
[_service RPCToStreamingInputCallWithRequestsWriter:requestsBuffer
GRPCProtoCall *call = [_service
RPCToStreamingInputCallWithRequestsWriter:requestsBuffer
handler:^(RMTStreamingInputCallResponse *response,
NSError *error) {
XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
@ -399,29 +415,30 @@ BOOL isRemoteInteropTest(NSString *host) {
- (void)testCancelAfterFirstResponseRPC {
XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterFirstResponse"];
__weak XCTestExpectation *expectation =
[self expectationWithDescription:@"CancelAfterFirstResponse"];
// A buffered pipe to which we write a single value but never close
GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
__block BOOL receivedResponse = NO;
id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782
requestedResponseSize:@31415];
id request =
[RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415];
[requestsBuffer writeValue:request];
__block GRPCProtoCall *call =
[_service RPCToFullDuplexCallWithRequestsWriter:requestsBuffer
eventHandler:^(BOOL done,
RMTStreamingOutputCallResponse *response,
__block GRPCProtoCall *call = [_service
RPCToFullDuplexCallWithRequestsWriter:requestsBuffer
eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
NSError *error) {
if (receivedResponse) {
XCTAssert(done, @"Unexpected extra response %@", response);
XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
[expectation fulfill];
} else {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
XCTAssertNil(error, @"Finished with unexpected error: %@",
error);
XCTAssertFalse(done, @"Finished without response");
XCTAssertNotNil(response);
receivedResponse = YES;
@ -439,7 +456,9 @@ BOOL isRemoteInteropTest(NSString *host) {
GPBEmpty *request = [GPBEmpty message];
[_service emptyCallWithRequest:request handler:^(GPBEmpty *response, NSError *error) {
[_service
emptyCallWithRequest:request
handler:^(GPBEmpty *response, NSError *error) {
XCTAssertNil(error, @"First RPC finished with unexpected error: %@", error);
#pragma clang diagnostic push
@ -447,8 +466,12 @@ BOOL isRemoteInteropTest(NSString *host) {
[GRPCCall closeOpenConnections];
#pragma clang diagnostic pop
[_service emptyCallWithRequest:request handler:^(GPBEmpty *response, NSError *error) {
XCTAssertNil(error, @"Second RPC finished with unexpected error: %@", error);
[_service
emptyCallWithRequest:request
handler:^(GPBEmpty *response, NSError *error) {
XCTAssertNil(
error, @"Second RPC finished with unexpected error: %@",
error);
[expectation fulfill];
}];
}];
@ -472,7 +495,8 @@ BOOL isRemoteInteropTest(NSString *host) {
request.expectCompressed.value = YES;
[GRPCCall setDefaultCompressMethod:GRPCCompressGzip forhost:self.class.host];
[_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
[_service unaryCallWithRequest:request
handler:^(RMTSimpleResponse *response, NSError *error) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
@ -504,9 +528,9 @@ BOOL isRemoteInteropTest(NSString *host) {
requestedResponseSize:responses[index]];
[requestsBuffer writeValue:request];
[_service fullDuplexCallWithRequestsWriter:requestsBuffer
eventHandler:^(BOOL done,
RMTStreamingOutputCallResponse *response,
[_service
fullDuplexCallWithRequestsWriter:requestsBuffer
eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
NSError *error) {
if (index == 0) {
XCTAssertNil(error, @"Finished with unexpected error: %@", error);
@ -517,7 +541,8 @@ BOOL isRemoteInteropTest(NSString *host) {
// Keepalive should kick after 1s elapsed and fails the call.
XCTAssertNotNil(error);
XCTAssertEqual(error.code, GRPC_STATUS_INTERNAL);
XCTAssertEqualObjects(error.localizedDescription, @"keepalive watchdog timeout",
XCTAssertEqualObjects(
error.localizedDescription, @"keepalive watchdog timeout",
@"Unexpected failure that is not keepalive watchdog timeout.");
XCTAssertTrue(done);
[expectation fulfill];

@ -49,8 +49,8 @@ static int32_t kLocalInteropServerOverhead = 10;
// Register test server certificates and name.
NSBundle *bundle = [NSBundle bundleForClass:self.class];
NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates"
ofType:@"pem"];
NSString *certsPath =
[bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"];
[GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:kLocalSSLHost];
}

@ -30,7 +30,6 @@
#define NSStringize(x) @NSStringize_helper(x)
static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE);
// The Protocol Buffers encoding overhead of remote interop server. Acquired
// by experiment. Adjust this when server's proto file changes.
static int32_t kRemoteInteropServerOverhead = 12;

@ -149,7 +149,8 @@
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
// Given:
CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
id<GRXWriteable> writeable =
[GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
handler.block(value, errorOrNil);
[expectation fulfill];
}];
@ -167,14 +168,14 @@
XCTAssertEqual(handler.timesCalled, 1);
XCTAssertEqualObjects(handler.value, anyValue);
XCTAssertEqualObjects(handler.errorOrNil, nil);
}
- (void)testBufferedPipePropagatesError {
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
// Given:
CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
id<GRXWriteable> writeable =
[GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
handler.block(value, errorOrNil);
[expectation fulfill];
}];
@ -196,7 +197,8 @@
__weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
// Given:
CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
id<GRXWriteable> writeable =
[GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
handler.block(value, errorOrNil);
[expectation fulfill];
}];
@ -220,7 +222,8 @@
#define WRITE_ROUNDS (1000)
- (void)testBufferedPipeResumeWhenDealloc {
id anyValue = @7;
id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
id<GRXWriteable> writeable =
[GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil){
}];
// Release after alloc;

@ -22,6 +22,5 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
#define GRPC_OBJC_VERSION_STRING @"1.12.0-dev"
#define GRPC_C_VERSION_STRING @"6.0.0-dev"

@ -21,6 +21,6 @@ root=$(pwd)
cd src/php/bin
source ./determine_extension_dir.sh
# in some jenkins macos machine, somehow the PHP build script can't find libgrpc.dylib
export DYLD_LIBRARY_PATH=$root/libs/$config
export DYLD_LIBRARY_PATH=$root/libs/$CONFIG
php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \
../tests/unit_tests

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save