[ObjC] dns service resolver for cf event engine (#33971)

re-submit of #33233 with refactored tests

1. split ios event engine tests to client tests (require oracle engine)
and unit test
2. disable dns server setup in
[dns_test.cc](https://github.com/grpc/grpc/blob/master/test/core/event_engine/test_suite/tests/dns_test.cc#L127)
for ios test, this is what's caused the revert.
3. disable dns_test in cf_event_engine_test for MacOS
pull/33994/merge
Hannah Shi 1 year ago committed by GitHub
parent c9fe64c409
commit 239a5fce2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      CMakeLists.txt
  2. 2
      Makefile
  3. 2
      Package.swift
  4. 8
      build_autogenerated.yaml
  5. 1
      config.m4
  6. 1
      config.w32
  7. 2
      gRPC-C++.podspec
  8. 3
      gRPC-Core.podspec
  9. 2
      grpc.gemspec
  10. 3
      grpc.gyp
  11. 2
      package.xml
  12. 8
      src/core/BUILD
  13. 12
      src/core/lib/event_engine/cf_engine/cf_engine.cc
  14. 229
      src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
  15. 117
      src/core/lib/event_engine/cf_engine/dns_service_resolver.h
  16. 24
      src/objective-c/tests/BUILD
  17. 2
      src/objective-c/tests/EventEngineTests/CFEventEngineClientTests.mm
  18. 61
      src/objective-c/tests/EventEngineTests/CFEventEngineUnitTests.mm
  19. 1
      src/python/grpcio/grpc_core_dependencies.py
  20. 24
      test/core/event_engine/cf/BUILD
  21. 211
      test/core/event_engine/cf/cf_engine_test.cc
  22. 1
      test/core/event_engine/test_suite/BUILD
  23. 2
      test/core/event_engine/test_suite/cf_event_engine_test.cc
  24. 8
      test/core/event_engine/test_suite/tests/dns_test.cc
  25. 2
      tools/doxygen/Doxyfile.c++.internal
  26. 2
      tools/doxygen/Doxyfile.core.internal
  27. 4
      tools/internal_ci/macos/grpc_objc_bazel_test.sh

4
CMakeLists.txt generated

@ -2159,6 +2159,7 @@ add_library(grpc
src/core/lib/event_engine/ares_resolver.cc
src/core/lib/event_engine/cf_engine/cf_engine.cc
src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc
src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
src/core/lib/event_engine/channel_args_endpoint_config.cc
src/core/lib/event_engine/default_event_engine.cc
src/core/lib/event_engine/default_event_engine_factory.cc
@ -2868,6 +2869,7 @@ add_library(grpc_unsecure
src/core/lib/event_engine/ares_resolver.cc
src/core/lib/event_engine/cf_engine/cf_engine.cc
src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc
src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
src/core/lib/event_engine/channel_args_endpoint_config.cc
src/core/lib/event_engine/default_event_engine.cc
src/core/lib/event_engine/default_event_engine_factory.cc
@ -4406,6 +4408,7 @@ add_library(grpc_authorization_provider
src/core/lib/event_engine/ares_resolver.cc
src/core/lib/event_engine/cf_engine/cf_engine.cc
src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc
src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
src/core/lib/event_engine/channel_args_endpoint_config.cc
src/core/lib/event_engine/default_event_engine.cc
src/core/lib/event_engine/default_event_engine_factory.cc
@ -12485,6 +12488,7 @@ add_executable(frame_test
src/core/lib/event_engine/ares_resolver.cc
src/core/lib/event_engine/cf_engine/cf_engine.cc
src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc
src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
src/core/lib/event_engine/channel_args_endpoint_config.cc
src/core/lib/event_engine/default_event_engine.cc
src/core/lib/event_engine/default_event_engine_factory.cc

2
Makefile generated

@ -1440,6 +1440,7 @@ LIBGRPC_SRC = \
src/core/lib/event_engine/ares_resolver.cc \
src/core/lib/event_engine/cf_engine/cf_engine.cc \
src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc \
src/core/lib/event_engine/cf_engine/dns_service_resolver.cc \
src/core/lib/event_engine/channel_args_endpoint_config.cc \
src/core/lib/event_engine/default_event_engine.cc \
src/core/lib/event_engine/default_event_engine_factory.cc \
@ -2002,6 +2003,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/event_engine/ares_resolver.cc \
src/core/lib/event_engine/cf_engine/cf_engine.cc \
src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc \
src/core/lib/event_engine/cf_engine/dns_service_resolver.cc \
src/core/lib/event_engine/channel_args_endpoint_config.cc \
src/core/lib/event_engine/default_event_engine.cc \
src/core/lib/event_engine/default_event_engine_factory.cc \

2
Package.swift generated

@ -1069,6 +1069,8 @@ let package = Package(
"src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc",
"src/core/lib/event_engine/cf_engine/cfstream_endpoint.h",
"src/core/lib/event_engine/cf_engine/cftype_unique_ref.h",
"src/core/lib/event_engine/cf_engine/dns_service_resolver.cc",
"src/core/lib/event_engine/cf_engine/dns_service_resolver.h",
"src/core/lib/event_engine/channel_args_endpoint_config.cc",
"src/core/lib/event_engine/channel_args_endpoint_config.h",
"src/core/lib/event_engine/common_closures.h",

@ -687,6 +687,7 @@ libs:
- src/core/lib/event_engine/cf_engine/cf_engine.h
- src/core/lib/event_engine/cf_engine/cfstream_endpoint.h
- src/core/lib/event_engine/cf_engine/cftype_unique_ref.h
- src/core/lib/event_engine/cf_engine/dns_service_resolver.h
- src/core/lib/event_engine/channel_args_endpoint_config.h
- src/core/lib/event_engine/common_closures.h
- src/core/lib/event_engine/default_event_engine.h
@ -1501,6 +1502,7 @@ libs:
- src/core/lib/event_engine/ares_resolver.cc
- src/core/lib/event_engine/cf_engine/cf_engine.cc
- src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc
- src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
- src/core/lib/event_engine/channel_args_endpoint_config.cc
- src/core/lib/event_engine/default_event_engine.cc
- src/core/lib/event_engine/default_event_engine_factory.cc
@ -2084,6 +2086,7 @@ libs:
- src/core/lib/event_engine/cf_engine/cf_engine.h
- src/core/lib/event_engine/cf_engine/cfstream_endpoint.h
- src/core/lib/event_engine/cf_engine/cftype_unique_ref.h
- src/core/lib/event_engine/cf_engine/dns_service_resolver.h
- src/core/lib/event_engine/channel_args_endpoint_config.h
- src/core/lib/event_engine/common_closures.h
- src/core/lib/event_engine/default_event_engine.h
@ -2505,6 +2508,7 @@ libs:
- src/core/lib/event_engine/ares_resolver.cc
- src/core/lib/event_engine/cf_engine/cf_engine.cc
- src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc
- src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
- src/core/lib/event_engine/channel_args_endpoint_config.cc
- src/core/lib/event_engine/default_event_engine.cc
- src/core/lib/event_engine/default_event_engine_factory.cc
@ -3592,6 +3596,7 @@ libs:
- src/core/lib/event_engine/cf_engine/cf_engine.h
- src/core/lib/event_engine/cf_engine/cfstream_endpoint.h
- src/core/lib/event_engine/cf_engine/cftype_unique_ref.h
- src/core/lib/event_engine/cf_engine/dns_service_resolver.h
- src/core/lib/event_engine/channel_args_endpoint_config.h
- src/core/lib/event_engine/common_closures.h
- src/core/lib/event_engine/default_event_engine.h
@ -3892,6 +3897,7 @@ libs:
- src/core/lib/event_engine/ares_resolver.cc
- src/core/lib/event_engine/cf_engine/cf_engine.cc
- src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc
- src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
- src/core/lib/event_engine/channel_args_endpoint_config.cc
- src/core/lib/event_engine/default_event_engine.cc
- src/core/lib/event_engine/default_event_engine_factory.cc
@ -8127,6 +8133,7 @@ targets:
- src/core/lib/event_engine/cf_engine/cf_engine.h
- src/core/lib/event_engine/cf_engine/cfstream_endpoint.h
- src/core/lib/event_engine/cf_engine/cftype_unique_ref.h
- src/core/lib/event_engine/cf_engine/dns_service_resolver.h
- src/core/lib/event_engine/channel_args_endpoint_config.h
- src/core/lib/event_engine/common_closures.h
- src/core/lib/event_engine/default_event_engine.h
@ -8409,6 +8416,7 @@ targets:
- src/core/lib/event_engine/ares_resolver.cc
- src/core/lib/event_engine/cf_engine/cf_engine.cc
- src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc
- src/core/lib/event_engine/cf_engine/dns_service_resolver.cc
- src/core/lib/event_engine/channel_args_endpoint_config.cc
- src/core/lib/event_engine/default_event_engine.cc
- src/core/lib/event_engine/default_event_engine_factory.cc

1
config.m4 generated

@ -522,6 +522,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/event_engine/ares_resolver.cc \
src/core/lib/event_engine/cf_engine/cf_engine.cc \
src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc \
src/core/lib/event_engine/cf_engine/dns_service_resolver.cc \
src/core/lib/event_engine/channel_args_endpoint_config.cc \
src/core/lib/event_engine/default_event_engine.cc \
src/core/lib/event_engine/default_event_engine_factory.cc \

1
config.w32 generated

@ -487,6 +487,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\event_engine\\ares_resolver.cc " +
"src\\core\\lib\\event_engine\\cf_engine\\cf_engine.cc " +
"src\\core\\lib\\event_engine\\cf_engine\\cfstream_endpoint.cc " +
"src\\core\\lib\\event_engine\\cf_engine\\dns_service_resolver.cc " +
"src\\core\\lib\\event_engine\\channel_args_endpoint_config.cc " +
"src\\core\\lib\\event_engine\\default_event_engine.cc " +
"src\\core\\lib\\event_engine\\default_event_engine_factory.cc " +

2
gRPC-C++.podspec generated

@ -758,6 +758,7 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/cf_engine/cf_engine.h',
'src/core/lib/event_engine/cf_engine/cfstream_endpoint.h',
'src/core/lib/event_engine/cf_engine/cftype_unique_ref.h',
'src/core/lib/event_engine/cf_engine/dns_service_resolver.h',
'src/core/lib/event_engine/channel_args_endpoint_config.h',
'src/core/lib/event_engine/common_closures.h',
'src/core/lib/event_engine/default_event_engine.h',
@ -1807,6 +1808,7 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/cf_engine/cf_engine.h',
'src/core/lib/event_engine/cf_engine/cfstream_endpoint.h',
'src/core/lib/event_engine/cf_engine/cftype_unique_ref.h',
'src/core/lib/event_engine/cf_engine/dns_service_resolver.h',
'src/core/lib/event_engine/channel_args_endpoint_config.h',
'src/core/lib/event_engine/common_closures.h',
'src/core/lib/event_engine/default_event_engine.h',

3
gRPC-Core.podspec generated

@ -1170,6 +1170,8 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc',
'src/core/lib/event_engine/cf_engine/cfstream_endpoint.h',
'src/core/lib/event_engine/cf_engine/cftype_unique_ref.h',
'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc',
'src/core/lib/event_engine/cf_engine/dns_service_resolver.h',
'src/core/lib/event_engine/channel_args_endpoint_config.cc',
'src/core/lib/event_engine/channel_args_endpoint_config.h',
'src/core/lib/event_engine/common_closures.h',
@ -2542,6 +2544,7 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/cf_engine/cf_engine.h',
'src/core/lib/event_engine/cf_engine/cfstream_endpoint.h',
'src/core/lib/event_engine/cf_engine/cftype_unique_ref.h',
'src/core/lib/event_engine/cf_engine/dns_service_resolver.h',
'src/core/lib/event_engine/channel_args_endpoint_config.h',
'src/core/lib/event_engine/common_closures.h',
'src/core/lib/event_engine/default_event_engine.h',

2
grpc.gemspec generated

@ -1075,6 +1075,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc )
s.files += %w( src/core/lib/event_engine/cf_engine/cfstream_endpoint.h )
s.files += %w( src/core/lib/event_engine/cf_engine/cftype_unique_ref.h )
s.files += %w( src/core/lib/event_engine/cf_engine/dns_service_resolver.cc )
s.files += %w( src/core/lib/event_engine/cf_engine/dns_service_resolver.h )
s.files += %w( src/core/lib/event_engine/channel_args_endpoint_config.cc )
s.files += %w( src/core/lib/event_engine/channel_args_endpoint_config.h )
s.files += %w( src/core/lib/event_engine/common_closures.h )

3
grpc.gyp generated

@ -744,6 +744,7 @@
'src/core/lib/event_engine/ares_resolver.cc',
'src/core/lib/event_engine/cf_engine/cf_engine.cc',
'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc',
'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc',
'src/core/lib/event_engine/channel_args_endpoint_config.cc',
'src/core/lib/event_engine/default_event_engine.cc',
'src/core/lib/event_engine/default_event_engine_factory.cc',
@ -1245,6 +1246,7 @@
'src/core/lib/event_engine/ares_resolver.cc',
'src/core/lib/event_engine/cf_engine/cf_engine.cc',
'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc',
'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc',
'src/core/lib/event_engine/channel_args_endpoint_config.cc',
'src/core/lib/event_engine/default_event_engine.cc',
'src/core/lib/event_engine/default_event_engine_factory.cc',
@ -1766,6 +1768,7 @@
'src/core/lib/event_engine/ares_resolver.cc',
'src/core/lib/event_engine/cf_engine/cf_engine.cc',
'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc',
'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc',
'src/core/lib/event_engine/channel_args_endpoint_config.cc',
'src/core/lib/event_engine/default_event_engine.cc',
'src/core/lib/event_engine/default_event_engine_factory.cc',

2
package.xml generated

@ -1057,6 +1057,8 @@
<file baseinstalldir="/" name="src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/cf_engine/cfstream_endpoint.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/cf_engine/cftype_unique_ref.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/cf_engine/dns_service_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/cf_engine/dns_service_resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/channel_args_endpoint_config.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/channel_args_endpoint_config.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/common_closures.h" role="src" />

@ -2123,13 +2123,18 @@ grpc_cc_library(
srcs = [
"lib/event_engine/cf_engine/cf_engine.cc",
"lib/event_engine/cf_engine/cfstream_endpoint.cc",
"lib/event_engine/cf_engine/dns_service_resolver.cc",
],
hdrs = [
"lib/event_engine/cf_engine/cf_engine.h",
"lib/event_engine/cf_engine/cfstream_endpoint.h",
"lib/event_engine/cf_engine/cftype_unique_ref.h",
"lib/event_engine/cf_engine/dns_service_resolver.h",
],
external_deps = [
"absl/container:flat_hash_map",
"absl/strings:str_format",
],
external_deps = ["absl/strings:str_format"],
deps = [
"event_engine_common",
"event_engine_tcp_socket_utils",
@ -2145,6 +2150,7 @@ grpc_cc_library(
"strerror",
"//:event_engine_base_hdrs",
"//:gpr",
"//:parse_address",
"//:ref_counted_ptr",
"//:sockaddr_utils",
],

@ -22,6 +22,7 @@
#include "src/core/lib/event_engine/cf_engine/cf_engine.h"
#include "src/core/lib/event_engine/cf_engine/cfstream_endpoint.h"
#include "src/core/lib/event_engine/cf_engine/dns_service_resolver.h"
#include "src/core/lib/event_engine/posix_engine/timer_manager.h"
#include "src/core/lib/event_engine/tcp_socket_utils.h"
#include "src/core/lib/event_engine/thread_pool/thread_pool.h"
@ -156,9 +157,14 @@ bool CFEventEngine::CancelConnectInternal(ConnectionHandle handle,
bool CFEventEngine::IsWorkerThread() { grpc_core::Crash("unimplemented"); }
absl::StatusOr<std::unique_ptr<EventEngine::DNSResolver>>
CFEventEngine::GetDNSResolver(
const DNSResolver::ResolverOptions& /* options */) {
grpc_core::Crash("unimplemented");
CFEventEngine::GetDNSResolver(const DNSResolver::ResolverOptions& options) {
if (!options.dns_server.empty()) {
return absl::InvalidArgumentError(
"CFEventEngine does not support custom DNS servers");
}
return std::make_unique<DNSServiceResolver>(
std::static_pointer_cast<CFEventEngine>(shared_from_this()));
}
void CFEventEngine::Run(EventEngine::Closure* closure) {

@ -0,0 +1,229 @@
// Copyright 2023 The 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 <grpc/support/port_platform.h>
#ifdef GPR_APPLE
#include "absl/strings/str_format.h"
#include "src/core/lib/address_utils/parse_address.h"
#include "src/core/lib/event_engine/cf_engine/dns_service_resolver.h"
#include "src/core/lib/event_engine/posix_engine/lockfree_event.h"
#include "src/core/lib/event_engine/tcp_socket_utils.h"
#include "src/core/lib/event_engine/trace.h"
#include "src/core/lib/gprpp/host_port.h"
namespace grpc_event_engine {
namespace experimental {
void DNSServiceResolverImpl::LookupHostname(
EventEngine::DNSResolver::LookupHostnameCallback on_resolve,
absl::string_view name, absl::string_view default_port) {
GRPC_EVENT_ENGINE_DNS_TRACE(
"DNSServiceResolverImpl::LookupHostname: name: %.*s, default_port: %.*s, "
"this: %p",
static_cast<int>(name.length()), name.data(),
static_cast<int>(default_port.length()), default_port.data(), this);
absl::string_view host;
absl::string_view port_string;
if (!grpc_core::SplitHostPort(name, &host, &port_string)) {
engine_->Run([on_resolve = std::move(on_resolve),
status = absl::InvalidArgumentError(
absl::StrCat("Unparseable name: ", name))]() mutable {
on_resolve(status);
});
return;
}
GPR_ASSERT(!host.empty());
if (port_string.empty()) {
if (default_port.empty()) {
engine_->Run([on_resolve = std::move(on_resolve),
status = absl::InvalidArgumentError(absl::StrFormat(
"No port in name %s or default_port argument",
name))]() mutable { on_resolve(std::move(status)); });
return;
}
port_string = default_port;
}
int port = 0;
if (port_string == "http") {
port = 80;
} else if (port_string == "https") {
port = 443;
} else if (!absl::SimpleAtoi(port_string, &port)) {
engine_->Run([on_resolve = std::move(on_resolve),
status = absl::InvalidArgumentError(absl::StrCat(
"Failed to parse port in name: ", name))]() mutable {
on_resolve(std::move(status));
});
return;
}
// TODO(yijiem): Change this when refactoring code in
// src/core/lib/address_utils to use EventEngine::ResolvedAddress.
grpc_resolved_address addr;
const std::string hostport = grpc_core::JoinHostPort(host, port);
if (grpc_parse_ipv4_hostport(hostport.c_str(), &addr,
/*log_errors=*/false) ||
grpc_parse_ipv6_hostport(hostport.c_str(), &addr,
/*log_errors=*/false)) {
// Early out if the target is an ipv4 or ipv6 literal, otherwise dns service
// responses with kDNSServiceErr_NoSuchRecord
std::vector<EventEngine::ResolvedAddress> result;
result.emplace_back(reinterpret_cast<sockaddr*>(addr.addr), addr.len);
engine_->Run([on_resolve = std::move(on_resolve),
result = std::move(result)]() mutable {
on_resolve(std::move(result));
});
return;
}
DNSServiceRef sdRef;
auto host_string = std::string{host};
auto error = DNSServiceGetAddrInfo(
&sdRef, kDNSServiceFlagsTimeout | kDNSServiceFlagsReturnIntermediates, 0,
kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6, host_string.c_str(),
&DNSServiceResolverImpl::ResolveCallback, this /* do not Ref */);
if (error != kDNSServiceErr_NoError) {
engine_->Run([on_resolve = std::move(on_resolve),
status = absl::UnknownError(absl::StrFormat(
"DNSServiceGetAddrInfo failed with error:%d",
error))]() mutable { on_resolve(std::move(status)); });
return;
}
grpc_core::ReleasableMutexLock lock(&request_mu_);
error = DNSServiceSetDispatchQueue(sdRef, queue_);
if (error != kDNSServiceErr_NoError) {
engine_->Run([on_resolve = std::move(on_resolve),
status = absl::UnknownError(absl::StrFormat(
"DNSServiceSetDispatchQueue failed with error:%d",
error))]() mutable { on_resolve(std::move(status)); });
return;
}
requests_.try_emplace(
sdRef, DNSServiceRequest{
std::move(on_resolve), static_cast<uint16_t>(port), {}});
}
/* static */
void DNSServiceResolverImpl::ResolveCallback(
DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
DNSServiceErrorType errorCode, const char* hostname,
const struct sockaddr* address, uint32_t ttl, void* context) {
GRPC_EVENT_ENGINE_DNS_TRACE(
"DNSServiceResolverImpl::ResolveCallback: sdRef: %p, flags: %x, "
"interface: %d, errorCode: %d, hostname: %s, addressFamily: %d, ttl: "
"%d, "
"this: %p",
sdRef, flags, interfaceIndex, errorCode, hostname, address->sa_family,
ttl, context);
// no need to increase refcount here, since ResolveCallback and Shutdown is
// called from the serial queue and it is guarenteed that it won't be called
// after the sdRef is deallocated
auto that = static_cast<DNSServiceResolverImpl*>(context);
grpc_core::ReleasableMutexLock lock(&that->request_mu_);
auto request_it = that->requests_.find(sdRef);
GPR_ASSERT(request_it != that->requests_.end());
auto& request = request_it->second;
if (errorCode != kDNSServiceErr_NoError &&
errorCode != kDNSServiceErr_NoSuchRecord) {
request.on_resolve(absl::UnknownError(absl::StrFormat(
"address lookup failed for %s: errorCode: %d", hostname, errorCode)));
that->requests_.erase(request_it);
DNSServiceRefDeallocate(sdRef);
return;
}
// set received ipv4 or ipv6 response, even for kDNSServiceErr_NoSuchRecord to
// mark that the response for the stack is received, it is possible that the
// one stack receives some results and the other stack gets
// kDNSServiceErr_NoSuchRecord error.
if (address->sa_family == AF_INET) {
request.has_ipv4_response = true;
} else if (address->sa_family == AF_INET6) {
request.has_ipv6_response = true;
}
// collect results if there is no error (not kDNSServiceErr_NoSuchRecord)
if (errorCode == kDNSServiceErr_NoError) {
request.result.emplace_back(address, address->sa_len);
auto& resolved_address = request.result.back();
if (address->sa_family == AF_INET) {
(const_cast<sockaddr_in*>(
reinterpret_cast<const sockaddr_in*>(resolved_address.address())))
->sin_port = htons(request.port);
} else if (address->sa_family == AF_INET6) {
(const_cast<sockaddr_in6*>(
reinterpret_cast<const sockaddr_in6*>(resolved_address.address())))
->sin6_port = htons(request.port);
}
GRPC_EVENT_ENGINE_DNS_TRACE(
"DNSServiceResolverImpl::ResolveCallback: "
"sdRef: %p, hostname: %s, addressPort: %s, this: %p",
sdRef, hostname,
ResolvedAddressToString(resolved_address).value_or("ERROR").c_str(),
context);
}
// received both ipv4 and ipv6 responses, and no more responses (e.g. multiple
// IP addresses for a domain name) are coming, finish `LookupHostname` resolve
// with the collected results.
if (!(flags & kDNSServiceFlagsMoreComing) && request.has_ipv4_response &&
request.has_ipv6_response) {
if (request.result.empty()) {
request.on_resolve(absl::NotFoundError(absl::StrFormat(
"address lookup failed for %s: Domain name not found", hostname)));
} else {
request.on_resolve(std::move(request.result));
}
that->requests_.erase(request_it);
DNSServiceRefDeallocate(sdRef);
}
}
void DNSServiceResolverImpl::Shutdown() {
dispatch_async_f(queue_, Ref().release(), [](void* thatPtr) {
grpc_core::RefCountedPtr<DNSServiceResolverImpl> that{
static_cast<DNSServiceResolverImpl*>(thatPtr)};
grpc_core::MutexLock lock(&that->request_mu_);
for (auto& kv : that->requests_) {
auto& sdRef = kv.first;
auto& request = kv.second;
GRPC_EVENT_ENGINE_DNS_TRACE(
"DNSServiceResolverImpl::Shutdown sdRef: %p, this: %p", sdRef,
thatPtr);
request.on_resolve(
absl::CancelledError("DNSServiceResolverImpl::Shutdown"));
DNSServiceRefDeallocate(static_cast<DNSServiceRef>(sdRef));
}
that->requests_.clear();
});
}
} // namespace experimental
} // namespace grpc_event_engine
#endif // GPR_APPLE

@ -0,0 +1,117 @@
// Copyright 2023 The gRPC Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_CF_ENGINE_DNS_SERVICE_RESOLVER_H
#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_CF_ENGINE_DNS_SERVICE_RESOLVER_H
#include <grpc/support/port_platform.h>
#ifdef GPR_APPLE
#include <CoreFoundation/CoreFoundation.h>
#include <dns_sd.h>
#include "absl/container/flat_hash_map.h"
#include <grpc/event_engine/event_engine.h>
#include "src/core/lib/event_engine/cf_engine/cf_engine.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
namespace grpc_event_engine {
namespace experimental {
class DNSServiceResolverImpl
: public grpc_core::RefCounted<DNSServiceResolverImpl> {
struct DNSServiceRequest {
EventEngine::DNSResolver::LookupHostnameCallback on_resolve;
uint16_t port;
std::vector<EventEngine::ResolvedAddress> result;
bool has_ipv4_response = false;
bool has_ipv6_response = false;
};
public:
explicit DNSServiceResolverImpl(std::shared_ptr<CFEventEngine> engine)
: engine_(std::move((engine))) {}
~DNSServiceResolverImpl() override {
GPR_ASSERT(requests_.empty());
dispatch_release(queue_);
}
void Shutdown();
void LookupHostname(
EventEngine::DNSResolver::LookupHostnameCallback on_resolve,
absl::string_view name, absl::string_view default_port);
private:
static void ResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
const char* hostname,
const struct sockaddr* address, uint32_t ttl,
void* context);
private:
std::shared_ptr<CFEventEngine> engine_;
// DNSServiceSetDispatchQueue requires a serial dispatch queue
dispatch_queue_t queue_ =
dispatch_queue_create("dns_service_resolver", nullptr);
grpc_core::Mutex request_mu_;
absl::flat_hash_map<DNSServiceRef, DNSServiceRequest> requests_
ABSL_GUARDED_BY(request_mu_);
};
class DNSServiceResolver : public EventEngine::DNSResolver {
public:
explicit DNSServiceResolver(std::shared_ptr<CFEventEngine> engine)
: engine_(std::move(engine)),
impl_(grpc_core::MakeRefCounted<DNSServiceResolverImpl>(
std::move((engine_)))) {}
~DNSServiceResolver() override { impl_->Shutdown(); }
void LookupHostname(
EventEngine::DNSResolver::LookupHostnameCallback on_resolve,
absl::string_view name, absl::string_view default_port) override {
impl_->LookupHostname(std::move(on_resolve), name, default_port);
};
void LookupSRV(EventEngine::DNSResolver::LookupSRVCallback on_resolve,
absl::string_view /* name */) override {
engine_->Run([on_resolve = std::move(on_resolve)]() mutable {
on_resolve(absl::UnimplementedError(
"The DNS Service resolver does not support looking up SRV records"));
});
}
void LookupTXT(EventEngine::DNSResolver::LookupTXTCallback on_resolve,
absl::string_view /* name */) override {
engine_->Run([on_resolve = std::move(on_resolve)]() mutable {
on_resolve(absl::UnimplementedError(
"The DNS Service resolver does not support looking up TXT records"));
});
}
private:
std::shared_ptr<CFEventEngine> engine_;
grpc_core::RefCountedPtr<DNSServiceResolverImpl> impl_;
};
} // namespace experimental
} // namespace grpc_event_engine
#endif // GPR_APPLE
#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_CF_ENGINE_DNS_SERVICE_RESOLVER_H

@ -334,20 +334,36 @@ grpc_objc_ios_unit_test(
)
grpc_objc_testing_library(
name = "EventEngineTests-lib",
srcs = glob(["EventEngineTests/*.mm"]),
name = "EventEngineClientTests-lib",
srcs = ["EventEngineTests/CFEventEngineClientTests.mm"],
# defines = ["GRPC_IOS_EVENT_ENGINE_CLIENT=1"],
deps = [
"//src/core:cf_event_engine",
"//test/core/event_engine/test_suite/posix:oracle_event_engine_posix",
"//test/core/event_engine/test_suite/tests:client",
],
)
grpc_objc_testing_library(
name = "EventEngineUnitTests-lib",
srcs = ["EventEngineTests/CFEventEngineUnitTests.mm"],
defines = ["GRPC_IOS_EVENT_ENGINE_CLIENT=1"],
deps = [
"//src/core:cf_event_engine",
"//test/core/event_engine/cf:cf_engine_unit_test_lib",
"//test/core/event_engine/test_suite/tests:dns",
"//test/core/event_engine/test_suite/tests:timer",
],
)
grpc_objc_ios_unit_test(
name = "EventEngineTests",
deps = [":EventEngineTests-lib"],
name = "EventEngineClientTests",
deps = [":EventEngineClientTests-lib"],
)
grpc_objc_ios_unit_test(
name = "EventEngineUnitTests",
deps = [":EventEngineUnitTests-lib"],
)
# Note that bazel currently doesn't support running tvos_unit_test

@ -24,7 +24,6 @@
#include "test/core/event_engine/test_suite/event_engine_test_framework.h"
#include "test/core/event_engine/test_suite/posix/oracle_event_engine_posix.h"
#include "test/core/event_engine/test_suite/tests/client_test.h"
#include "test/core/event_engine/test_suite/tests/timer_test.h"
#include "test/core/util/test_config.h"
@interface EventEngineTimerTests : XCTestCase
@ -51,7 +50,6 @@
return std::make_unique<grpc_event_engine::experimental::PosixOracleEventEngine>();
};
SetEventEngineFactories(factory, oracle_factory);
grpc_event_engine::experimental::InitTimerTests();
grpc_event_engine::experimental::InitClientTests();
// TODO(ctiller): EventEngine temporarily needs grpc to be initialized first
// until we clear out the iomgr shutdown code.

@ -0,0 +1,61 @@
/*
*
* Copyright 2023 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.
*
*/
#import <XCTest/XCTest.h>
#include <grpc/grpc.h>
#include "src/core/lib/event_engine/cf_engine/cf_engine.h"
#include "test/core/event_engine/test_suite/event_engine_test_framework.h"
#include "test/core/event_engine/test_suite/tests/dns_test.h"
#include "test/core/event_engine/test_suite/tests/timer_test.h"
#include "test/core/util/test_config.h"
@interface EventEngineTimerTests : XCTestCase
@end
@implementation EventEngineTimerTests
- (void)testAll {
NSArray *arguments = [NSProcessInfo processInfo].arguments;
int argc = (int)arguments.count;
char **argv = static_cast<char **>(alloca((sizeof(char *) * (argc + 1))));
for (int index = 0; index < argc; index++) {
argv[index] = const_cast<char *>([arguments[index] UTF8String]);
}
argv[argc] = NULL;
testing::InitGoogleTest(&argc, (char **)argv);
grpc::testing::TestEnvironment env(&argc, (char **)argv);
auto factory = []() {
return std::make_unique<grpc_event_engine::experimental::CFEventEngine>();
};
SetEventEngineFactories(factory, nullptr);
grpc_event_engine::experimental::InitTimerTests();
grpc_event_engine::experimental::InitDNSTests();
// TODO(ctiller): EventEngine temporarily needs grpc to be initialized first
// until we clear out the iomgr shutdown code.
grpc_init();
int r = RUN_ALL_TESTS();
grpc_shutdown();
XCTAssertEqual(r, 0);
}
@end

@ -496,6 +496,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/event_engine/ares_resolver.cc',
'src/core/lib/event_engine/cf_engine/cf_engine.cc',
'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc',
'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc',
'src/core/lib/event_engine/channel_args_endpoint_config.cc',
'src/core/lib/event_engine/default_event_engine.cc',
'src/core/lib/event_engine/default_event_engine_factory.cc',

@ -12,10 +12,32 @@
# See the License for the specific language governing permissions and
# limitations under the License.
load("//bazel:grpc_build_system.bzl", "grpc_cc_test")
load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test")
licenses(["notice"])
grpc_cc_library(
name = "cf_engine_unit_test_lib",
testonly = True,
srcs = ["cf_engine_test.cc"],
external_deps = ["gtest"],
language = "C++",
tags = [
"no_linux",
"no_windows",
],
visibility = [
"//src/objective-c/tests:__subpackages__",
"//test:__subpackages__",
],
deps = [
"//:gpr_platform",
"//src/core:cf_event_engine",
"//test/core/util:grpc_test_util",
],
alwayslink = 1,
)
grpc_cc_test(
name = "cf_engine_test",
timeout = "short",

@ -19,6 +19,8 @@
#include <thread>
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <grpc/event_engine/event_engine.h>
@ -80,6 +82,215 @@ TEST(CFEventEngineTest, TestConnectionCancelled) {
client_signal.WaitForNotification();
}
namespace {
std::vector<std::string> ResolvedAddressesToStrings(
const std::vector<EventEngine::ResolvedAddress> addresses) {
std::vector<std::string> ip_strings;
std::transform(addresses.cbegin(), addresses.cend(),
std::back_inserter(ip_strings), [](auto const& address) {
return ResolvedAddressToString(address).value_or("ERROR");
});
return ip_strings;
}
} // namespace
TEST(CFEventEngineTest, TestCreateDNSResolver) {
grpc_core::MemoryQuota memory_quota("cf_engine_test");
auto cf_engine = std::make_shared<CFEventEngine>();
EXPECT_TRUE(cf_engine->GetDNSResolver({}).status().ok());
EXPECT_TRUE(cf_engine->GetDNSResolver({.dns_server = ""}).status().ok());
EXPECT_EQ(
cf_engine->GetDNSResolver({.dns_server = "8.8.8.8"}).status().code(),
absl::StatusCode::kInvalidArgument);
EXPECT_EQ(
cf_engine->GetDNSResolver({.dns_server = "8.8.8.8:53"}).status().code(),
absl::StatusCode::kInvalidArgument);
EXPECT_EQ(
cf_engine->GetDNSResolver({.dns_server = "invalid"}).status().code(),
absl::StatusCode::kInvalidArgument);
}
TEST(CFEventEngineTest, TestResolveLocalhost) {
grpc_core::Notification resolve_signal;
auto cf_engine = std::make_shared<CFEventEngine>();
auto dns_resolver = cf_engine->GetDNSResolver({});
dns_resolver.value()->LookupHostname(
[&resolve_signal](auto result) {
EXPECT_TRUE(result.status().ok());
EXPECT_THAT(ResolvedAddressesToStrings(result.value()),
testing::UnorderedElementsAre("127.0.0.1:80", "[::1]:80"));
resolve_signal.Notify();
},
"localhost", "80");
resolve_signal.WaitForNotification();
}
TEST(CFEventEngineTest, TestResolveRemote) {
grpc_core::Notification resolve_signal;
auto cf_engine = std::make_shared<CFEventEngine>();
auto dns_resolver = cf_engine->GetDNSResolver({});
dns_resolver.value()->LookupHostname(
[&resolve_signal](auto result) {
EXPECT_TRUE(result.status().ok());
EXPECT_THAT(ResolvedAddressesToStrings(result.value()),
testing::UnorderedElementsAre("127.0.0.1:80", "[::1]:80"));
resolve_signal.Notify();
},
"localtest.me:80", "443");
resolve_signal.WaitForNotification();
}
TEST(CFEventEngineTest, TestResolveIPv4Remote) {
grpc_core::Notification resolve_signal;
auto cf_engine = std::make_shared<CFEventEngine>();
auto dns_resolver = cf_engine->GetDNSResolver({});
dns_resolver.value()->LookupHostname(
[&resolve_signal](auto result) {
EXPECT_TRUE(result.status().ok());
EXPECT_THAT(ResolvedAddressesToStrings(result.value()),
testing::IsSubsetOf(
{"1.2.3.4:80", "[64:ff9b::102:304]:80" /*NAT64*/}));
resolve_signal.Notify();
},
"1.2.3.4.nip.io:80", "");
resolve_signal.WaitForNotification();
}
TEST(CFEventEngineTest, TestResolveIPv6Remote) {
grpc_core::Notification resolve_signal;
auto cf_engine = std::make_shared<CFEventEngine>();
auto dns_resolver = cf_engine->GetDNSResolver({});
dns_resolver.value()->LookupHostname(
[&resolve_signal](auto result) {
EXPECT_TRUE(result.status().ok());
EXPECT_THAT(
ResolvedAddressesToStrings(result.value()),
testing::UnorderedElementsAre("[2607:f8b0:400a:801::1002]:80"));
resolve_signal.Notify();
},
"2607-f8b0-400a-801--1002.sslip.io.", "80");
resolve_signal.WaitForNotification();
}
TEST(CFEventEngineTest, TestResolveIPv4Literal) {
grpc_core::Notification resolve_signal;
auto cf_engine = std::make_shared<CFEventEngine>();
auto dns_resolver = cf_engine->GetDNSResolver({});
dns_resolver.value()->LookupHostname(
[&resolve_signal](auto result) {
EXPECT_TRUE(result.status().ok());
EXPECT_THAT(ResolvedAddressesToStrings(result.value()),
testing::UnorderedElementsAre("1.2.3.4:443"));
resolve_signal.Notify();
},
"1.2.3.4", "https");
resolve_signal.WaitForNotification();
}
TEST(CFEventEngineTest, TestResolveIPv6Literal) {
grpc_core::Notification resolve_signal;
auto cf_engine = std::make_shared<CFEventEngine>();
auto dns_resolver = cf_engine->GetDNSResolver({});
dns_resolver.value()->LookupHostname(
[&resolve_signal](auto result) {
EXPECT_TRUE(result.status().ok());
EXPECT_THAT(
ResolvedAddressesToStrings(result.value()),
testing::UnorderedElementsAre("[2607:f8b0:400a:801::1002]:443"));
resolve_signal.Notify();
},
"[2607:f8b0:400a:801::1002]", "443");
resolve_signal.WaitForNotification();
}
TEST(CFEventEngineTest, TestResolveNoRecord) {
grpc_core::Notification resolve_signal;
auto cf_engine = std::make_shared<CFEventEngine>();
auto dns_resolver = std::move(cf_engine->GetDNSResolver({})).value();
dns_resolver->LookupHostname(
[&resolve_signal](auto result) {
EXPECT_EQ(result.status().code(), absl::StatusCode::kNotFound);
resolve_signal.Notify();
},
"nonexisting-target.dns-test.event-engine.", "443");
resolve_signal.WaitForNotification();
}
TEST(CFEventEngineTest, TestResolveCanceled) {
grpc_core::Notification resolve_signal;
auto cf_engine = std::make_shared<CFEventEngine>();
auto dns_resolver = std::move(cf_engine->GetDNSResolver({})).value();
dns_resolver->LookupHostname(
[&resolve_signal](auto result) {
// query may have already finished before canceling, only verity the
// code if status is not ok
if (!result.status().ok()) {
EXPECT_EQ(result.status().code(), absl::StatusCode::kCancelled);
}
resolve_signal.Notify();
},
"dont-care-since-wont-be-resolved.localtest.me", "443");
dns_resolver.reset();
resolve_signal.WaitForNotification();
}
TEST(CFEventEngineTest, TestResolveMany) {
std::atomic<int> times{10};
grpc_core::Notification resolve_signal;
auto cf_engine = std::make_shared<CFEventEngine>();
auto dns_resolver = std::move(cf_engine->GetDNSResolver({})).value();
for (int i = times; i >= 1; --i) {
dns_resolver->LookupHostname(
[&resolve_signal, &times, i](auto result) {
EXPECT_TRUE(result.status().ok());
EXPECT_THAT(
ResolvedAddressesToStrings(result.value()),
testing::IsSubsetOf(
{absl::StrFormat("100.0.0.%d:443", i),
absl::StrFormat("[64:ff9b::6400:%x]:443", i) /*NAT64*/}));
if (--times == 0) {
resolve_signal.Notify();
}
},
absl::StrFormat("100.0.0.%d.nip.io", i), "443");
}
resolve_signal.WaitForNotification();
}
} // namespace experimental
} // namespace grpc_event_engine

@ -96,6 +96,7 @@ grpc_cc_test(
grpc_cc_test(
name = "cf_event_engine_test",
srcs = ["cf_event_engine_test.cc"],
copts = ["-DGRPC_IOS_EVENT_ENGINE_CLIENT=1"],
tags = [
"no_linux",
"no_windows",

@ -37,8 +37,6 @@ int main(int argc, char** argv) {
SetEventEngineFactories(factory, oracle_factory);
grpc_event_engine::experimental::InitTimerTests();
grpc_event_engine::experimental::InitClientTests();
// TODO(vigneshbabu): remove when the experiment is over
grpc_core::ForceEnableExperiment("event_engine_client", true);
// TODO(ctiller): EventEngine temporarily needs grpc to be initialized first
// until we clear out the iomgr shutdown code.
grpc_init();

@ -102,6 +102,7 @@ MATCHER(StatusCodeEq, "") {
class EventEngineDNSTest : public EventEngineTest {
protected:
static void SetUpTestSuite() {
#ifndef GRPC_IOS_EVENT_ENGINE_CLIENT
std::string test_records_path = kDNSTestRecordGroupsYamlPath;
std::string dns_server_path = kDNSServerRelPath;
std::string dns_resolver_path = kDNSResolverRelPath;
@ -143,12 +144,15 @@ class EventEngineDNSTest : public EventEngineTest {
int status = health_check.Join();
// TODO(yijiem): make this portable for Windows
ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
#endif // GRPC_IOS_EVENT_ENGINE_CLIENT
}
static void TearDownTestSuite() {
#ifndef GRPC_IOS_EVENT_ENGINE_CLIENT
dns_server_.server_process->Interrupt();
dns_server_.server_process->Join();
delete dns_server_.server_process;
#endif // GRPC_IOS_EVENT_ENGINE_CLIENT
}
std::unique_ptr<EventEngine::DNSResolver> CreateDefaultDNSResolver() {
@ -194,6 +198,9 @@ class EventEngineDNSTest : public EventEngineTest {
EventEngineDNSTest::DNSServer EventEngineDNSTest::dns_server_;
// TODO(hork): implement XFAIL for resolvers that don't support TXT or SRV
#ifndef GRPC_IOS_EVENT_ENGINE_CLIENT
TEST_F(EventEngineDNSTest, QueryNXHostname) {
auto dns_resolver = CreateDefaultDNSResolver();
dns_resolver->LookupHostname(
@ -365,6 +372,7 @@ TEST_F(EventEngineDNSTest, TestCancelActiveDNSQuery) {
dns_resolver.reset();
dns_resolver_signal_.WaitForNotification();
}
#endif // GRPC_IOS_EVENT_ENGINE_CLIENT
#define EXPECT_SUCCESS() \
do { \

@ -2072,6 +2072,8 @@ src/core/lib/event_engine/cf_engine/cf_engine.h \
src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc \
src/core/lib/event_engine/cf_engine/cfstream_endpoint.h \
src/core/lib/event_engine/cf_engine/cftype_unique_ref.h \
src/core/lib/event_engine/cf_engine/dns_service_resolver.cc \
src/core/lib/event_engine/cf_engine/dns_service_resolver.h \
src/core/lib/event_engine/channel_args_endpoint_config.cc \
src/core/lib/event_engine/channel_args_endpoint_config.h \
src/core/lib/event_engine/common_closures.h \

@ -1850,6 +1850,8 @@ src/core/lib/event_engine/cf_engine/cf_engine.h \
src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc \
src/core/lib/event_engine/cf_engine/cfstream_endpoint.h \
src/core/lib/event_engine/cf_engine/cftype_unique_ref.h \
src/core/lib/event_engine/cf_engine/dns_service_resolver.cc \
src/core/lib/event_engine/cf_engine/dns_service_resolver.h \
src/core/lib/event_engine/channel_args_endpoint_config.cc \
src/core/lib/event_engine/channel_args_endpoint_config.h \
src/core/lib/event_engine/common_closures.h \

@ -61,7 +61,8 @@ TEST_TARGETS=(
#//src/objective-c/tests:CronetTests
#//src/objective-c/tests:PerfTests
//src/objective-c/tests:CFStreamTests
//src/objective-c/tests:EventEngineTests
# Needs oracle engine, which doesn't work with GRPC_IOS_EVENT_ENGINE_CLIENT=1
//src/objective-c/tests:EventEngineClientTests
//src/objective-c/tests:tvtests_build_test
# codegen plugin tests
//src/objective-c/tests:objc_codegen_plugin_test
@ -128,6 +129,7 @@ EVENT_ENGINE_TEST_TARGETS=(
//src/objective-c/tests:InteropTestsRemote
//src/objective-c/tests:MacTests
//src/objective-c/tests:UnitTests
//src/objective-c/tests:EventEngineUnitTests
//src/objective-c/tests:tvtests_build_test
)

Loading…
Cancel
Save