diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 9933dd7d9bb..e47065ce4a5 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -181,7 +181,7 @@ def grpc_deps(): ) native.bind( - name = "libuv", + name = "uv", actual = "@libuv//:libuv", ) diff --git a/src/objective-c/tests/ThirdPartyTests/Libuv/BUILD b/src/objective-c/tests/ThirdPartyTests/Libuv/BUILD new file mode 100644 index 00000000000..a5643abd0e7 --- /dev/null +++ b/src/objective-c/tests/ThirdPartyTests/Libuv/BUILD @@ -0,0 +1,48 @@ +# Copyright 2021 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. + +# +# This is for the gRPC build system. This isn't intended to be used outsite of +# the BUILD file for gRPC. It contains the mapping for the template system we +# use to generate other platform's build system files. +# +# Please consider that there should be a high bar for additions and changes to +# this file. +# Each rule listed must be re-written for Google's internal build system, and +# each change must be ported from one to the other. +# + +load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test") +load("@build_bazel_rules_apple//apple/testing/default_runner:ios_test_runner.bzl", "ios_test_runner") + +ios_test_runner( + name = "ios_x86_64_sim_runner", + device_type = "iPhone 8", +) + +objc_library( + name = "LibuvTestsLib", + testonly = True, + srcs = glob(["*.m"]), + deps = [ + "//external:uv", + ], +) + +ios_unit_test( + name = "LibuvTest", + minimum_os_version = "9.0", + runner = ":ios_x86_64_sim_runner", + deps = [":LibuvTestsLib"], +) diff --git a/src/objective-c/tests/ThirdPartyTests/Libuv/LibuvGetAddrInfoTests.m b/src/objective-c/tests/ThirdPartyTests/Libuv/LibuvGetAddrInfoTests.m new file mode 100644 index 00000000000..b28ff21f764 --- /dev/null +++ b/src/objective-c/tests/ThirdPartyTests/Libuv/LibuvGetAddrInfoTests.m @@ -0,0 +1,142 @@ +/* + * + * Copyright 2021 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 + +#import +#import + +#define ASSERT(x) XCTAssertTrue(x) +#define ASSERT_NULL(x) XCTAssertTrue(x == NULL) +#define ASSERT_NOT_NULL(x) XCTAssertFalse(x == NULL) +#define CONCURRENT_COUNT 10 + +static const char* name = "localhost"; + +static int getaddrinfo_cbs = 0; + +/* data used for running multiple calls concurrently */ +static uv_getaddrinfo_t* getaddrinfo_handle; +static uv_getaddrinfo_t getaddrinfo_handles[CONCURRENT_COUNT]; +static int callback_counts[CONCURRENT_COUNT]; +static int fail_cb_called; + +static void getaddrinfo_fail_cb(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { + ASSERT(fail_cb_called == 0); + ASSERT(status < 0); + ASSERT_NULL(res); + uv_freeaddrinfo(res); /* Should not crash. */ + fail_cb_called++; +} + +static void getaddrinfo_basic_cb(uv_getaddrinfo_t* handle, int status, struct addrinfo* res) { + ASSERT(handle == getaddrinfo_handle); + getaddrinfo_cbs++; + free(handle); + uv_freeaddrinfo(res); +} + +static void getaddrinfo_cuncurrent_cb(uv_getaddrinfo_t* handle, int status, struct addrinfo* res) { + int i; + int* data = (int*)handle->data; + + for (i = 0; i < CONCURRENT_COUNT; i++) { + if (&getaddrinfo_handles[i] == handle) { + ASSERT(i == *data); + callback_counts[i]++; + break; + } + } + ASSERT(i < CONCURRENT_COUNT); + free(data); + uv_freeaddrinfo(res); + getaddrinfo_cbs++; +} + +@interface LibuvGetAddrInfoTests : XCTestCase + +@end + +@implementation LibuvGetAddrInfoTests + +- (void)testGetAddrInfoFail { + uv_getaddrinfo_t req; + + ASSERT(UV_EINVAL == + uv_getaddrinfo(uv_default_loop(), &req, (uv_getaddrinfo_cb)abort, NULL, NULL, NULL)); + + /* Use a FQDN by ending in a period */ + ASSERT(0 == uv_getaddrinfo(uv_default_loop(), &req, getaddrinfo_fail_cb, "example.invalid.", NULL, + NULL)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(fail_cb_called == 1); +} + +- (void)testGetAddrInfoFailSync { + uv_getaddrinfo_t req; + + /* Use a FQDN by ending in a period */ + ASSERT(0 > uv_getaddrinfo(uv_default_loop(), &req, NULL, "example.invalid.", NULL, NULL)); + uv_freeaddrinfo(req.addrinfo); +} + +- (void)testGetAddrInfoBasic { + int r; + getaddrinfo_handle = (uv_getaddrinfo_t*)malloc(sizeof(uv_getaddrinfo_t)); + + r = uv_getaddrinfo(uv_default_loop(), getaddrinfo_handle, &getaddrinfo_basic_cb, name, NULL, + NULL); + ASSERT(r == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(getaddrinfo_cbs == 1); +} + +- (void)testGetAddrInfoBasicSync { + uv_getaddrinfo_t req; + + ASSERT(0 == uv_getaddrinfo(uv_default_loop(), &req, NULL, name, NULL, NULL)); + uv_freeaddrinfo(req.addrinfo); +} + +- (void)testGetAddrInfoConcurrent { + int i, r; + int* data; + + for (i = 0; i < CONCURRENT_COUNT; i++) { + callback_counts[i] = 0; + + data = (int*)malloc(sizeof(int)); + ASSERT_NOT_NULL(data); + *data = i; + getaddrinfo_handles[i].data = data; + + r = uv_getaddrinfo(uv_default_loop(), &getaddrinfo_handles[i], &getaddrinfo_cuncurrent_cb, name, + NULL, NULL); + ASSERT(r == 0); + } + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + for (i = 0; i < CONCURRENT_COUNT; i++) { + ASSERT(callback_counts[i] == 1); + } +} + +@end diff --git a/third_party/libuv.BUILD b/third_party/libuv.BUILD index 17446148d2a..84bfca89146 100644 --- a/third_party/libuv.BUILD +++ b/third_party/libuv.BUILD @@ -1,3 +1,132 @@ +# Copyright 2021 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. + +load("@bazel_skylib//lib:selects.bzl", "selects") + +config_setting( + name = "darwin", + values = {"cpu": "darwin"}, +) + +config_setting( + name = "darwin_x86_64", + values = {"cpu": "darwin_x86_64"}, +) + +config_setting( + name = "darwin_arm64", + values = {"cpu": "darwin_arm64"}, +) + +config_setting( + name = "darwin_arm64e", + values = {"cpu": "darwin_arm64e"}, +) + +config_setting( + name = "windows", + values = {"cpu": "x64_windows"}, +) + +config_setting( + name = "freebsd", + constraint_values = ["@platforms//os:freebsd"], +) + +# Android is not officially supported through C++. +# This just helps with the build for now. +config_setting( + name = "android", + values = { + "crosstool_top": "//external:android/crosstool", + }, +) + +# iOS is not officially supported through C++. +# This just helps with the build for now. +config_setting( + name = "ios_x86_64", + values = {"cpu": "ios_x86_64"}, +) + +config_setting( + name = "ios_armv7", + values = {"cpu": "ios_armv7"}, +) + +config_setting( + name = "ios_armv7s", + values = {"cpu": "ios_armv7s"}, +) + +config_setting( + name = "ios_arm64", + values = {"cpu": "ios_arm64"}, +) + +# The following architectures are found in +# https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/apple/ApplePlatform.java +config_setting( + name = "tvos_x86_64", + values = {"cpu": "tvos_x86_64"}, +) + +config_setting( + name = "tvos_arm64", + values = {"cpu": "tvos_arm64"}, +) + +config_setting( + name = "watchos_i386", + values = {"cpu": "watchos_i386"}, +) + +config_setting( + name = "watchos_x86_64", + values = {"cpu": "watchos_x86_64"}, +) + +config_setting( + name = "watchos_armv7k", + values = {"cpu": "watchos_armv7k"}, +) + +config_setting( + name = "watchos_arm64_32", + values = {"cpu": "watchos_arm64_32"}, +) + +selects.config_setting_group( + name = "apple", + match_any = [ + ":darwin", + ":darwin_x86_64", + ":darwin_arm64", + ":darwin_arm64e", + "ios_x86_64", + "ios_armv7", + "ios_armv7s", + "ios_arm64", + "tvos_x86_64", + "tvos_arm64", + "watchos_i386", + "watchos_x86_64", + "watchos_armv7k", + "watchos_arm64_32", + ], +) + COMMON_LIBUV_HEADERS = [ "include/uv.h", "include/uv/errno.h", @@ -139,17 +268,15 @@ WINDOWS_LIBUV_SOURCES = [ cc_library( name = "libuv", srcs = select({ - "//tools/cc_target_os:android": COMMON_LIBUV_SOURCES + UNIX_LIBUV_SOURCES + LINUX_LIBUV_SOURCES + ANDROID_LIBUV_SOURCES, - "//tools/cc_target_os:apple": COMMON_LIBUV_SOURCES + UNIX_LIBUV_SOURCES + DARWIN_LIBUV_SOURCES, - "//tools/cc_target_os:windows": COMMON_LIBUV_SOURCES + WINDOWS_LIBUV_SOURCES, + ":android": COMMON_LIBUV_SOURCES + UNIX_LIBUV_SOURCES + LINUX_LIBUV_SOURCES + ANDROID_LIBUV_SOURCES, + ":apple": COMMON_LIBUV_SOURCES + UNIX_LIBUV_SOURCES + DARWIN_LIBUV_SOURCES, + ":windows": COMMON_LIBUV_SOURCES + WINDOWS_LIBUV_SOURCES, "//conditions:default": COMMON_LIBUV_SOURCES + UNIX_LIBUV_SOURCES + LINUX_LIBUV_SOURCES, }), - hdrs = [ - "include/uv.h", - ] + select({ - "//tools/cc_target_os:android": COMMON_LIBUV_HEADERS + UNIX_LIBUV_HEADERS + LINUX_LIBUV_HEADERS + ANDROID_LIBUV_HEADERS, - "//tools/cc_target_os:apple": COMMON_LIBUV_HEADERS + UNIX_LIBUV_HEADERS + DARWIN_LIBUV_HEADERS, - "//tools/cc_target_os:windows": COMMON_LIBUV_HEADERS + WINDOWS_LIBUV_HEADERS, + hdrs = select({ + ":android": COMMON_LIBUV_HEADERS + UNIX_LIBUV_HEADERS + LINUX_LIBUV_HEADERS + ANDROID_LIBUV_HEADERS, + ":apple": COMMON_LIBUV_HEADERS + UNIX_LIBUV_HEADERS + DARWIN_LIBUV_HEADERS, + ":windows": COMMON_LIBUV_HEADERS + WINDOWS_LIBUV_HEADERS, "//conditions:default": COMMON_LIBUV_HEADERS + UNIX_LIBUV_HEADERS + LINUX_LIBUV_HEADERS, }), copts = [ @@ -167,8 +294,8 @@ cc_library( "-Wno-unused-function", "-Wno-unused-variable", ] + select({ - "//tools/cc_target_os:apple": [], - "//tools/cc_target_os:windows": [ + ":apple": [], + ":windows": [ "-DWIN32_LEAN_AND_MEAN", "-D_WIN32_WINNT=0x0600", ], @@ -184,7 +311,7 @@ cc_library( "src", ], linkopts = select({ - "//tools/cc_target_os:windows": [ + ":windows": [ "-Xcrosstool-compilation-mode=$(COMPILATION_MODE)", "-Wl,Iphlpapi.lib", "-Wl,Psapi.lib",