From 9fbc9105a62e5ca309d5152407dea0db86cc1709 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 8 Oct 2018 15:47:22 -0700 Subject: [PATCH 001/534] Update tests --- .../tests/ChannelTests/ChannelPoolTest.m | 164 ++++ .../tests/ChannelTests/ChannelTests.m | 93 ++ src/objective-c/tests/ChannelTests/Info.plist | 22 + src/objective-c/tests/GRPCClientTests.m | 291 +++++- src/objective-c/tests/InteropTests.h | 21 + src/objective-c/tests/InteropTests.m | 201 +++++ .../tests/InteropTestsCallOptions/Info.plist | 22 + .../InteropTestsCallOptions.m | 116 +++ .../tests/InteropTestsLocalCleartext.m | 12 + src/objective-c/tests/InteropTestsLocalSSL.m | 16 + .../InteropTestsMultipleChannels/Info.plist | 22 + .../InteropTestsMultipleChannels.m | 259 ++++++ src/objective-c/tests/InteropTestsRemote.m | 18 + src/objective-c/tests/Podfile | 10 +- .../tests/Tests.xcodeproj/project.pbxproj | 832 +++++++++++++++++- .../xcschemes/ChannelTests.xcscheme | 92 ++ .../InteropTestsCallOptions.xcscheme | 56 ++ .../InteropTestsLocalCleartext.xcscheme | 8 - .../InteropTestsMultipleChannels.xcscheme | 56 ++ .../xcschemes/InteropTestsRemote.xcscheme | 2 - src/objective-c/tests/run_tests.sh | 10 + 21 files changed, 2305 insertions(+), 18 deletions(-) create mode 100644 src/objective-c/tests/ChannelTests/ChannelPoolTest.m create mode 100644 src/objective-c/tests/ChannelTests/ChannelTests.m create mode 100644 src/objective-c/tests/ChannelTests/Info.plist create mode 100644 src/objective-c/tests/InteropTestsCallOptions/Info.plist create mode 100644 src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m create mode 100644 src/objective-c/tests/InteropTestsMultipleChannels/Info.plist create mode 100644 src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m create mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme create mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsCallOptions.xcscheme create mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m new file mode 100644 index 00000000000..3b6b10b1a5f --- /dev/null +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -0,0 +1,164 @@ +/* + * + * 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. + * + */ + +#import + +#import "../../GRPCClient/private/GRPCChannel.h" +#import "../../GRPCClient/private/GRPCChannelPool.h" + +#define TEST_TIMEOUT 32 + +NSString *kDummyHost = @"dummy.host"; + +@interface ChannelPoolTest : XCTestCase + +@end + +@implementation ChannelPoolTest + ++ (void)setUp { + grpc_init(); +} + +- (void)testCreateChannel { + NSString *kDummyHost = @"dummy.host"; + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; + options1.transportType = GRPCTransportTypeInsecure; + GRPCCallOptions *options2 = [options1 copy]; + GRPCChannelConfiguration *config1 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; + GRPCChannelConfiguration *config2 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initWithChannelDestroyDelay:1]; + + __weak XCTestExpectation *expectCreateChannel = + [self expectationWithDescription:@"Create first channel"]; + GRPCChannel *channel1 = + [pool channelWithConfiguration:config1 + createChannel:^{ + [expectCreateChannel fulfill]; + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; + GRPCChannel *channel2 = [pool channelWithConfiguration:config2 + createChannel:^{ + XCTFail(@"Should not create a second channel."); + return (GRPCChannel *)nil; + }]; + XCTAssertEqual(channel1, channel2); +} + +- (void)testChannelTimeout { + NSTimeInterval kChannelDestroyDelay = 1.0; + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; + options1.transportType = GRPCTransportTypeInsecure; + GRPCChannelConfiguration *config1 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; + GRPCChannelPool *pool = + [[GRPCChannelPool alloc] initWithChannelDestroyDelay:kChannelDestroyDelay]; + GRPCChannel *channel1 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + [pool unrefChannelWithConfiguration:config1]; + __weak XCTestExpectation *expectTimerDone = [self expectationWithDescription:@"Timer elapse."]; + NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:kChannelDestroyDelay + 1 + repeats:NO + block:^(NSTimer *_Nonnull timer) { + [expectTimerDone fulfill]; + }]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; + timer = nil; + GRPCChannel *channel2 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + XCTAssertNotEqual(channel1, channel2); +} + +- (void)testChannelTimeoutCancel { + NSTimeInterval kChannelDestroyDelay = 3.0; + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; + options1.transportType = GRPCTransportTypeInsecure; + GRPCChannelConfiguration *config1 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; + GRPCChannelPool *pool = + [[GRPCChannelPool alloc] initWithChannelDestroyDelay:kChannelDestroyDelay]; + GRPCChannel *channel1 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + [channel1 unmanagedCallUnref]; + sleep(1); + GRPCChannel *channel2 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + XCTAssertEqual(channel1, channel2); + sleep((int)kChannelDestroyDelay + 2); + GRPCChannel *channel3 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + XCTAssertEqual(channel1, channel3); +} + +- (void)testClearChannels { + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; + options1.transportType = GRPCTransportTypeInsecure; + GRPCMutableCallOptions *options2 = [[GRPCMutableCallOptions alloc] init]; + options2.transportType = GRPCTransportTypeDefault; + GRPCChannelConfiguration *config1 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; + GRPCChannelConfiguration *config2 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initWithChannelDestroyDelay:1]; + + GRPCChannel *channel1 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + GRPCChannel *channel2 = + [pool channelWithConfiguration:config2 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config2]; + }]; + XCTAssertNotEqual(channel1, channel2); + + [pool clear]; + GRPCChannel *channel3 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + GRPCChannel *channel4 = + [pool channelWithConfiguration:config2 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config2]; + }]; + XCTAssertNotEqual(channel1, channel3); + XCTAssertNotEqual(channel2, channel4); +} + +@end diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m new file mode 100644 index 00000000000..0a8b7ae6ee6 --- /dev/null +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -0,0 +1,93 @@ +/* + * + * 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. + * + */ + +#import + +#import "../../GRPCClient/GRPCCallOptions.h" +#import "../../GRPCClient/private/GRPCChannel.h" + +@interface ChannelTests : XCTestCase + +@end + +@implementation ChannelTests + ++ (void)setUp { + grpc_init(); +} + +- (void)testSameConfiguration { + NSString *host = @"grpc-test.sandbox.googleapis.com"; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.userAgentPrefix = @"TestUAPrefix"; + NSMutableDictionary *args = [NSMutableDictionary new]; + args[@"abc"] = @"xyz"; + options.additionalChannelArgs = [args copy]; + GRPCChannel *channel1 = [GRPCChannel channelWithHost:host callOptions:options]; + GRPCChannel *channel2 = [GRPCChannel channelWithHost:host callOptions:options]; + XCTAssertEqual(channel1, channel2); + GRPCMutableCallOptions *options2 = [options mutableCopy]; + options2.additionalChannelArgs = [args copy]; + GRPCChannel *channel3 = [GRPCChannel channelWithHost:host callOptions:options2]; + XCTAssertEqual(channel1, channel3); +} + +- (void)testDifferentHost { + NSString *host1 = @"grpc-test.sandbox.googleapis.com"; + NSString *host2 = @"grpc-test2.sandbox.googleapis.com"; + NSString *host3 = @"http://grpc-test.sandbox.googleapis.com"; + NSString *host4 = @"dns://grpc-test.sandbox.googleapis.com"; + NSString *host5 = @"grpc-test.sandbox.googleapis.com:80"; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.userAgentPrefix = @"TestUAPrefix"; + NSMutableDictionary *args = [NSMutableDictionary new]; + args[@"abc"] = @"xyz"; + options.additionalChannelArgs = [args copy]; + GRPCChannel *channel1 = [GRPCChannel channelWithHost:host1 callOptions:options]; + GRPCChannel *channel2 = [GRPCChannel channelWithHost:host2 callOptions:options]; + GRPCChannel *channel3 = [GRPCChannel channelWithHost:host3 callOptions:options]; + GRPCChannel *channel4 = [GRPCChannel channelWithHost:host4 callOptions:options]; + GRPCChannel *channel5 = [GRPCChannel channelWithHost:host5 callOptions:options]; + XCTAssertNotEqual(channel1, channel2); + XCTAssertNotEqual(channel1, channel3); + XCTAssertNotEqual(channel1, channel4); + XCTAssertNotEqual(channel1, channel5); +} + +- (void)testDifferentChannelParameters { + NSString *host = @"grpc-test.sandbox.googleapis.com"; + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; + options1.transportType = GRPCTransportTypeDefault; + NSMutableDictionary *args = [NSMutableDictionary new]; + args[@"abc"] = @"xyz"; + options1.additionalChannelArgs = [args copy]; + GRPCMutableCallOptions *options2 = [[GRPCMutableCallOptions alloc] init]; + options2.transportType = GRPCTransportTypeInsecure; + options2.additionalChannelArgs = [args copy]; + GRPCMutableCallOptions *options3 = [[GRPCMutableCallOptions alloc] init]; + options3.transportType = GRPCTransportTypeDefault; + args[@"def"] = @"uvw"; + options3.additionalChannelArgs = [args copy]; + GRPCChannel *channel1 = [GRPCChannel channelWithHost:host callOptions:options1]; + GRPCChannel *channel2 = [GRPCChannel channelWithHost:host callOptions:options2]; + GRPCChannel *channel3 = [GRPCChannel channelWithHost:host callOptions:options3]; + XCTAssertNotEqual(channel1, channel2); + XCTAssertNotEqual(channel1, channel3); +} + +@end diff --git a/src/objective-c/tests/ChannelTests/Info.plist b/src/objective-c/tests/ChannelTests/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/ChannelTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index a0de8ba8990..bad22d30cbb 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -86,6 +86,58 @@ static GRPCProtoMethod *kFullDuplexCallMethod; @end +// Convenience class to use blocks as callbacks +@interface ClientTestsBlockCallbacks : NSObject + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; + +@end + +@implementation ClientTestsBlockCallbacks { + void (^_initialMetadataCallback)(NSDictionary *); + void (^_messageCallback)(id); + void (^_closeCallback)(NSDictionary *, NSError *); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + if ((self = [super init])) { + _initialMetadataCallback = initialMetadataCallback; + _messageCallback = messageCallback; + _closeCallback = closeCallback; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } +} + +- (void)receivedMessage:(id)message { + if (_messageCallback) { + _messageCallback(message); + } +} + +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + #pragma mark Tests /** @@ -237,6 +289,55 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testMetadataWithV2API { + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.fillUsername = YES; + request.fillOauthScope = YES; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kRemoteSSLHost + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + __block NSDictionary *init_md; + __block NSDictionary *trailing_md; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.oauth2AccessToken = @"bogusToken"; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + handler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + init_md = initialMetadata; + } + messageCallback:^(id message) { + XCTFail(@"Received unexpected response."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + trailing_md = trailingMetadata; + if (error) { + XCTAssertEqual(error.code, 16, + @"Finished with unexpected error: %@", error); + XCTAssertEqualObjects(init_md, + error.userInfo[kGRPCHeadersKey]); + XCTAssertEqualObjects(trailing_md, + error.userInfo[kGRPCTrailersKey]); + NSString *challengeHeader = init_md[@"www-authenticate"]; + XCTAssertGreaterThan(challengeHeader.length, 0, + @"No challenge in response headers %@", + init_md); + [expectation fulfill]; + } + }] + callOptions:options]; + + [call start]; + [call writeWithData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testResponseMetadataKVO { __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."]; @@ -329,6 +430,77 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testUserAgentPrefixWithV2API { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."]; + __weak XCTestExpectation *recvInitialMd = + [self expectationWithDescription:@"Did not receive initial md."]; + + GRPCRequestOptions *request = [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kEmptyCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + NSDictionary *headers = + [NSDictionary dictionaryWithObjectsAndKeys:@"", @"x-grpc-test-echo-useragent", nil]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.userAgentPrefix = @"Foo"; + options.initialMetadata = headers; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:request + handler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( + NSDictionary *initialMetadata) { + NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; + // 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:@")"]; + XCTAssertEqualObjects(userAgent, expectedUserAgent); + + NSError *error = nil; + // 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 = [regex + stringByReplacingMatchesInString:userAgent + options:0 + range:NSMakeRange(0, [userAgent length]) + withTemplate:@""]; + XCTAssertEqualObjects(customUserAgent, @"Foo"); + [recvInitialMd fulfill]; + } + messageCallback:^(id message) { + XCTAssertNotNil(message); + XCTAssertEqual([message length], 0, + @"Non-empty response received: %@", message); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + if (error) { + XCTFail(@"Finished with unexpected error: %@", error); + } else { + [completion fulfill]; + } + }] + callOptions:options]; + [call writeWithData:[NSData data]]; + [call start]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testTrailers { __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."]; @@ -420,6 +592,52 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testIdempotentProtoRPCWithV2API { + __weak XCTestExpectation *response = [self expectationWithDescription:@"Expected response."]; + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = 100; + request.fillUsername = YES; + request.fillOauthScope = YES; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyIdempotentRequest]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + handler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + NSData *data = (NSData *)message; + XCTAssertNotNil(data, @"nil value received as response."); + XCTAssertGreaterThan(data.length, 0, + @"Empty response received."); + RMTSimpleResponse *responseProto = + [RMTSimpleResponse parseFromData:data error:NULL]; + // We expect empty strings, not nil: + XCTAssertNotNil(responseProto.username, + @"Response's username is nil."); + XCTAssertNotNil(responseProto.oauthScope, + @"Response's OAuth scope is nil."); + [response fulfill]; + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", + error); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + [call writeWithData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testAlternateDispatchQueue { const int32_t kPayloadSize = 100; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -509,6 +727,38 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testTimeoutWithV2API { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.timeout = 0.001; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + handler: + [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id data) { + XCTFail( + @"Failure: response received; Expect: no response received."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Failure: no error received; Expect: receive " + @"deadline exceeded."); + XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (int)findFreePort { struct sockaddr_in addr; unsigned int addr_len = sizeof(addr); @@ -580,15 +830,52 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testTimeoutBackoffWithOptionsWithTimeout:(double)timeout Backoff:(double)backoff { + const double maxConnectTime = timeout > backoff ? timeout : backoff; + const double kMargin = 0.1; + + __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; + NSString *const kDummyAddress = [NSString stringWithFormat:@"8.8.8.8:1"]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kDummyAddress path:@"" safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.connectMinTimeout = timeout; + options.connectInitialBackoff = backoff; + options.connectMaxBackoff = 0; + + NSDate *startTime = [NSDate date]; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + handler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id data) { + XCTFail(@"Received message. Should not reach here."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Finished with no error; expecting error"); + XCTAssertLessThan( + [[NSDate date] timeIntervalSinceDate:startTime], + maxConnectTime + kMargin); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + // The numbers of the following three tests are selected to be smaller than the default values of // initial backoff (1s) and min_connect_timeout (20s), so that if they fail we know the default // values fail to be overridden by the channel args. -- (void)testTimeoutBackoff2 { +- (void)testTimeoutBackoff1 { [self testTimeoutBackoffWithTimeout:0.7 Backoff:0.3]; + [self testTimeoutBackoffWithOptionsWithTimeout:0.7 Backoff:0.4]; } -- (void)testTimeoutBackoff3 { +- (void)testTimeoutBackoff2 { [self testTimeoutBackoffWithTimeout:0.3 Backoff:0.7]; + [self testTimeoutBackoffWithOptionsWithTimeout:0.3 Backoff:0.8]; } - (void)testErrorDebugInformation { diff --git a/src/objective-c/tests/InteropTests.h b/src/objective-c/tests/InteropTests.h index 039d92a8d35..e223839d3ac 100644 --- a/src/objective-c/tests/InteropTests.h +++ b/src/objective-c/tests/InteropTests.h @@ -18,6 +18,8 @@ #import +#import + /** * Implements tests as described here: * https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md @@ -38,4 +40,23 @@ * remote servers enconde responses with different overhead (?), so this is defined per-subclass. */ - (int32_t)encodingOverhead; + +/** + * The type of transport to be used. The base implementation returns default. Subclasses should + * override to appropriate settings. + */ ++ (GRPCTransportType)transportType; + +/** + * The root certificates to be used. The base implementation returns nil. Subclasses should override + * to appropriate settings. + */ ++ (NSString *)pemRootCert; + +/** + * The root certificates to be used. The base implementation returns nil. Subclasses should override + * to appropriate settings. + */ ++ (NSString *)hostNameOverride; + @end diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 9d796068818..54af7036c35 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -74,6 +74,58 @@ BOOL isRemoteInteropTest(NSString *host) { return [host isEqualToString:@"grpc-test.sandbox.googleapis.com"]; } +// Convenience class to use blocks as callbacks +@interface InteropTestsBlockCallbacks : NSObject + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; + +@end + +@implementation InteropTestsBlockCallbacks { + void (^_initialMetadataCallback)(NSDictionary *); + void (^_messageCallback)(id); + void (^_closeCallback)(NSDictionary *, NSError *); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + if ((self = [super init])) { + _initialMetadataCallback = initialMetadataCallback; + _messageCallback = messageCallback; + _closeCallback = closeCallback; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } +} + +- (void)receivedMessage:(id)message { + if (_messageCallback) { + _messageCallback(message); + } +} + +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + #pragma mark Tests @implementation InteropTests { @@ -91,6 +143,18 @@ BOOL isRemoteInteropTest(NSString *host) { return 0; } ++ (GRPCTransportType)transportType { + return GRPCTransportTypeDefault; +} + ++ (NSString *)pemRootCert { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + + (void)setUp { NSLog(@"InteropTest Started, class: %@", [[self class] description]); #ifdef GRPC_COMPILE_WITH_CRONET @@ -131,6 +195,33 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testEmptyUnaryRPCWithV2API { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnary"]; + + GPBEmpty *request = [GPBEmpty message]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = self.class.transportType; + options.pemRootCert = self.class.pemRootCert; + options.hostNameOverride = self.class.hostNameOverride; + + [_service + emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + if (message) { + id expectedResponse = [GPBEmpty message]; + XCTAssertEqualObjects(message, expectedResponse); + [expectation fulfill]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + }] + callOptions:options]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testLargeUnaryRPC { XCTAssertNotNil(self.class.host); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; @@ -380,6 +471,57 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testPingPongRPCWithV2API { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"]; + + NSArray *requests = @[ @27182, @8, @1828, @45904 ]; + NSArray *responses = @[ @31415, @9, @2653, @58979 ]; + + __block int index = 0; + + id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = self.class.transportType; + options.pemRootCert = self.class.pemRootCert; + options.hostNameOverride = self.class.hostNameOverride; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + id expected = [RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]]; + XCTAssertEqualObjects(message, expected); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + [call writeWithMessage:request]; + } else { + [call finish]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + XCTAssertEqual(index, 4, + @"Received %i responses instead of 4.", + index); + [expectation fulfill]; + }] + callOptions:options]; + [call writeWithMessage:request]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testEmptyStreamRPC { XCTAssertNotNil(self.class.host); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"]; @@ -418,6 +560,28 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testCancelAfterBeginRPCWithV2API { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBegin"]; + + // A buffered pipe to which we never write any value acts as a writer that just hangs. + __block GRPCStreamingProtoCall *call = [_service + streamingInputCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTFail(@"Not expected to receive message"); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + [expectation fulfill]; + }] + callOptions:nil]; + [call cancel]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testCancelAfterFirstResponseRPC { XCTAssertNotNil(self.class.host); __weak XCTestExpectation *expectation = @@ -454,6 +618,43 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testCancelAfterFirstResponseRPCWithV2API { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *completionExpectation = + [self expectationWithDescription:@"Call completed."]; + __weak XCTestExpectation *responseExpectation = + [self expectationWithDescription:@"Received response."]; + + __block BOOL receivedResponse = NO; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = self.class.transportType; + options.pemRootCert = self.class.pemRootCert; + options.hostNameOverride = self.class.hostNameOverride; + + id request = + [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertFalse(receivedResponse); + receivedResponse = YES; + [call cancel]; + [responseExpectation fulfill]; + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + [completionExpectation fulfill]; + }] + callOptions:options]; + + [call writeWithMessage:request]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testRPCAfterClosingOpenConnections { XCTAssertNotNil(self.class.host); __weak XCTestExpectation *expectation = diff --git a/src/objective-c/tests/InteropTestsCallOptions/Info.plist b/src/objective-c/tests/InteropTestsCallOptions/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/InteropTestsCallOptions/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m b/src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m new file mode 100644 index 00000000000..db51cb1cfbb --- /dev/null +++ b/src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m @@ -0,0 +1,116 @@ +/* + * + * 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. + * + */ + +#import + +#import +#import +#import +#import +#import +#import + +#define NSStringize_helper(x) #x +#define NSStringize(x) @NSStringize_helper(x) +static NSString *kRemoteHost = NSStringize(HOST_PORT_REMOTE); +const int32_t kRemoteInteropServerOverhead = 12; + +static const NSTimeInterval TEST_TIMEOUT = 16000; + +@interface InteropTestsCallOptions : XCTestCase + +@end + +@implementation InteropTestsCallOptions { + RMTTestService *_service; +} + +- (void)setUp { + self.continueAfterFailure = NO; + _service = [RMTTestService serviceWithHost:kRemoteHost]; + _service.options = [[GRPCCallOptions alloc] init]; +} + +- (void)test4MBResponsesAreAccepted { + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"MaxResponseSize"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const int32_t kPayloadSize = + 4 * 1024 * 1024 - kRemoteInteropServerOverhead; // 4MB - encoding overhead + request.responseSize = kPayloadSize; + + [_service unaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + XCTAssertEqual(response.payload.body.length, kPayloadSize); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testResponsesOverMaxSizeFailWithActionableMessage { + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const int32_t kPayloadSize = + 4 * 1024 * 1024 - kRemoteInteropServerOverhead + 1; // 1B over max size + request.responseSize = kPayloadSize; + + [_service unaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertEqualObjects( + error.localizedDescription, + @"Received message larger than max (4194305 vs. 4194304)"); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testResponsesOver4MBAreAcceptedIfOptedIn { + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"HigherResponseSizeLimit"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const size_t kPayloadSize = 5 * 1024 * 1024; // 5MB + request.responseSize = kPayloadSize; + + GRPCProtoCall *rpc = [_service + RPCToUnaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + XCTAssertEqual(response.payload.body.length, kPayloadSize); + [expectation fulfill]; + }]; + GRPCCallOptions *options = rpc.options; + options.responseSizeLimit = 6 * 1024 * 1024; + + [rpc start]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTestsLocalCleartext.m index d49e875bd02..42e327a3303 100644 --- a/src/objective-c/tests/InteropTestsLocalCleartext.m +++ b/src/objective-c/tests/InteropTestsLocalCleartext.m @@ -41,6 +41,14 @@ static int32_t kLocalInteropServerOverhead = 10; return kLocalCleartextHost; } ++ (NSString *)pemRootCert { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + - (int32_t)encodingOverhead { return kLocalInteropServerOverhead; // bytes } @@ -52,4 +60,8 @@ static int32_t kLocalInteropServerOverhead = 10; [GRPCCall useInsecureConnectionsForHost:kLocalCleartextHost]; } ++ (GRPCTransportType)transportType { + return GRPCTransportTypeInsecure; +} + @end diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m index a8c4dc7dfd1..eb72dd1d311 100644 --- a/src/objective-c/tests/InteropTestsLocalSSL.m +++ b/src/objective-c/tests/InteropTestsLocalSSL.m @@ -40,10 +40,26 @@ static int32_t kLocalInteropServerOverhead = 10; return kLocalSSLHost; } ++ (NSString *)pemRootCert { + NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSString *certsPath = + [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; + NSError *error; + return [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error]; +} + ++ (NSString *)hostNameOverride { + return @"foo.test.google.fr"; +} + - (int32_t)encodingOverhead { return kLocalInteropServerOverhead; // bytes } ++ (GRPCTransportType)transportType { + return GRPCTransportTypeDefault; +} + - (void)setUp { [super setUp]; diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/Info.plist b/src/objective-c/tests/InteropTestsMultipleChannels/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/InteropTestsMultipleChannels/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m new file mode 100644 index 00000000000..eb0ba7f34b3 --- /dev/null +++ b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m @@ -0,0 +1,259 @@ +/* + * + * 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. + * + */ + +#import + +#import +#import +#import +#import +#import + +#define NSStringize_helper(x) #x +#define NSStringize(x) @NSStringize_helper(x) +static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); +static NSString *const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL); +static NSString *const kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL); + +static const NSTimeInterval TEST_TIMEOUT = 8000; + +@interface RMTStreamingOutputCallRequest (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize + requestedResponseSize:(NSNumber *)responseSize; +@end + +@implementation RMTStreamingOutputCallRequest (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize + requestedResponseSize:(NSNumber *)responseSize { + RMTStreamingOutputCallRequest *request = [self message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = responseSize.intValue; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; + return request; +} +@end + +@interface RMTStreamingOutputCallResponse (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize; +@end + +@implementation RMTStreamingOutputCallResponse (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize { + RMTStreamingOutputCallResponse *response = [self message]; + response.payload.type = RMTPayloadType_Compressable; + response.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; + return response; +} +@end + +@interface InteropTestsMultipleChannels : XCTestCase + +@end + +dispatch_once_t initCronet; + +@implementation InteropTestsMultipleChannels { + RMTTestService *_remoteService; + RMTTestService *_remoteCronetService; + RMTTestService *_localCleartextService; + RMTTestService *_localSSLService; +} + +- (void)setUp { + [super setUp]; + + self.continueAfterFailure = NO; + + // Default stack with remote host + _remoteService = [RMTTestService serviceWithHost:kRemoteSSLHost]; + + // Cronet stack with remote host + _remoteCronetService = [RMTTestService serviceWithHost:kRemoteSSLHost]; + + dispatch_once(&initCronet, ^{ + [Cronet setHttp2Enabled:YES]; + [Cronet start]; + }); + + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + options.transportType = GRPCTransportTypeCronet; + options.cronetEngine = [Cronet getGlobalEngine]; + _remoteCronetService.options = options; + + // Local stack with no SSL + _localCleartextService = [RMTTestService serviceWithHost:kLocalCleartextHost]; + options = [[GRPCCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + _localCleartextService.options = options; + + // Local stack with SSL + _localSSLService = [RMTTestService serviceWithHost:kLocalSSLHost]; + + NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSString *certsPath = + [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; + NSError *error = nil; + NSString *certs = + [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error]; + XCTAssertNil(error); + + options = [[GRPCCallOptions alloc] init]; + options.transportType = GRPCTransportTypeDefault; + options.pemRootCert = certs; + options.hostNameOverride = @"foo.test.google.fr"; + _localSSLService.options = options; +} + +- (void)testEmptyUnaryRPC { + __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCronetRemote = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCleartext = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; + + GPBEmpty *request = [GPBEmpty message]; + + void (^handler)(GPBEmpty *response, NSError *error) = ^(GPBEmpty *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + + id expectedResponse = [GPBEmpty message]; + XCTAssertEqualObjects(response, expectedResponse); + }; + + [_remoteService emptyCallWithRequest:request + handler:^(GPBEmpty *response, NSError *error) { + handler(response, error); + [expectRemote fulfill]; + }]; + [_remoteCronetService emptyCallWithRequest:request + handler:^(GPBEmpty *response, NSError *error) { + handler(response, error); + [expectCronetRemote fulfill]; + }]; + [_localCleartextService emptyCallWithRequest:request + handler:^(GPBEmpty *response, NSError *error) { + handler(response, error); + [expectCleartext fulfill]; + }]; + [_localSSLService emptyCallWithRequest:request + handler:^(GPBEmpty *response, NSError *error) { + handler(response, error); + [expectSSL fulfill]; + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testFullDuplexRPC { + __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCronetRemote = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCleartext = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; + + NSArray *requestSizes = @[ @100, @101, @102, @103 ]; + NSArray *responseSizes = @[ @104, @105, @106, @107 ]; + XCTAssertEqual([requestSizes count], [responseSizes count]); + NSUInteger kRounds = [requestSizes count]; + + NSMutableArray *requests = [NSMutableArray arrayWithCapacity:kRounds]; + NSMutableArray *responses = [NSMutableArray arrayWithCapacity:kRounds]; + for (int i = 0; i < kRounds; i++) { + requests[i] = [RMTStreamingOutputCallRequest messageWithPayloadSize:requestSizes[i] + requestedResponseSize:responseSizes[i]]; + responses[i] = [RMTStreamingOutputCallResponse messageWithPayloadSize:responseSizes[i]]; + } + + __block NSMutableArray *steps = [NSMutableArray arrayWithCapacity:4]; + __block NSMutableArray *requestsBuffers = [NSMutableArray arrayWithCapacity:4]; + for (int i = 0; i < 4; i++) { + steps[i] = [NSNumber numberWithUnsignedInteger:0]; + requestsBuffers[i] = [[GRXBufferedPipe alloc] init]; + [requestsBuffers[i] writeValue:requests[0]]; + } + + BOOL (^handler)(int, BOOL, RMTStreamingOutputCallResponse *, NSError *) = + ^(int index, BOOL done, RMTStreamingOutputCallResponse *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + XCTAssertTrue(done || response, @"Event handler called without an event."); + if (response) { + NSUInteger step = [steps[index] unsignedIntegerValue]; + XCTAssertLessThan(step, kRounds, @"More than %lu responses received.", + (unsigned long)kRounds); + XCTAssertEqualObjects(response, responses[step]); + step++; + steps[index] = [NSNumber numberWithUnsignedInteger:step]; + GRXBufferedPipe *pipe = requestsBuffers[index]; + if (step < kRounds) { + [pipe writeValue:requests[step]]; + } else { + [pipe writesFinishedWithError:nil]; + } + } + if (done) { + NSUInteger step = [steps[index] unsignedIntegerValue]; + XCTAssertEqual(step, kRounds, @"Received %lu responses instead of %lu.", step, kRounds); + return YES; + } + return NO; + }; + + [_remoteService + fullDuplexCallWithRequestsWriter:requestsBuffers[0] + eventHandler:^(BOOL done, + RMTStreamingOutputCallResponse *_Nullable response, + NSError *_Nullable error) { + if (handler(0, done, response, error)) { + [expectRemote fulfill]; + } + }]; + [_remoteCronetService + fullDuplexCallWithRequestsWriter:requestsBuffers[1] + eventHandler:^(BOOL done, + RMTStreamingOutputCallResponse *_Nullable response, + NSError *_Nullable error) { + if (handler(1, done, response, error)) { + [expectCronetRemote fulfill]; + } + }]; + [_localCleartextService + fullDuplexCallWithRequestsWriter:requestsBuffers[2] + eventHandler:^(BOOL done, + RMTStreamingOutputCallResponse *_Nullable response, + NSError *_Nullable error) { + if (handler(2, done, response, error)) { + [expectCleartext fulfill]; + } + }]; + [_localSSLService + fullDuplexCallWithRequestsWriter:requestsBuffers[3] + eventHandler:^(BOOL done, + RMTStreamingOutputCallResponse *_Nullable response, + NSError *_Nullable error) { + if (handler(3, done, response, error)) { + [expectSSL fulfill]; + } + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +@end diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m index e5738aac73b..516a1f432a5 100644 --- a/src/objective-c/tests/InteropTestsRemote.m +++ b/src/objective-c/tests/InteropTestsRemote.m @@ -41,8 +41,26 @@ static int32_t kRemoteInteropServerOverhead = 12; return kRemoteSSLHost; } ++ (NSString *)pemRootCert { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + - (int32_t)encodingOverhead { return kRemoteInteropServerOverhead; // bytes } +#ifdef GRPC_COMPILE_WITH_CRONET ++ (GRPCTransportType)transportType { + return GRPCTransportTypeCronet; +} +#else ++ (GRPCTransportType)transportType { + return GRPCTransportTypeDefault; +} +#endif + @end diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 5d2f1340daa..e87aba235ad 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -14,6 +14,8 @@ GRPC_LOCAL_SRC = '../../..' InteropTestsLocalSSL InteropTestsLocalCleartext InteropTestsRemoteWithCronet + InteropTestsMultipleChannels + InteropTestsCallOptions UnitTests ).each do |target_name| target target_name do @@ -30,7 +32,7 @@ GRPC_LOCAL_SRC = '../../..' pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true - if target_name == 'InteropTestsRemoteWithCronet' + if target_name == 'InteropTestsRemoteWithCronet' or target_name == 'InteropTestsMultipleChannels' pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" end @@ -72,6 +74,12 @@ end end end +target 'ChannelTests' do + pod 'gRPC', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core', :path => GRPC_LOCAL_SRC + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true +end + # gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's # pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded # and before they are installed in the user project. diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index f0d81232635..104fd0a4ea0 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -11,14 +11,23 @@ 09B76D9585ACE7403804D9DC /* libPods-InteropTestsRemoteWithCronet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */; }; 0F9232F984C08643FD40C34F /* libPods-InteropTestsRemote.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */; }; 16A9E77B6E336B3C0B9BA6E0 /* libPods-InteropTestsLocalSSL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */; }; + 1A0FB7F8C95A2F82538BC950 /* libPods-ChannelTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 48F1841C9A920626995DC28C /* libPods-ChannelTests.a */; }; 20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; }; 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 5E0282E9215AA697007AC99D /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; 5E0282EB215AA697007AC99D /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; + 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */; }; + 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */; }; 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; 5EAD6D271E27047400002378 /* CronetUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EAD6D261E27047400002378 /* CronetUnitTests.m */; }; 5EAD6D291E27047400002378 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5EB2A2E72107DED300EB4B69 /* ChannelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB2A2E62107DED300EB4B69 /* ChannelTests.m */; }; + 5EB2A2E92107DED300EB4B69 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5EB2A2F82109284500EB4B69 /* InteropTestsMultipleChannels.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB2A2F72109284500EB4B69 /* InteropTestsMultipleChannels.m */; }; + 5EB2A2FA2109284500EB4B69 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5EB5C3AA21656CEA00ADC300 /* ChannelPoolTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB5C3A921656CEA00ADC300 /* ChannelPoolTest.m */; }; 5EC5E42B2081782C000EF4AD /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; }; 5EC5E42C20817832000EF4AD /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; 5EC5E43B208185A7000EF4AD /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; }; @@ -53,6 +62,8 @@ 63DC84501BE153AA000708E8 /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; }; 63E240CE1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; }; 63E240D01B6C63DC005F3B0E /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; + 6C1A3F81CCF7C998B4813EFD /* libPods-InteropTestsCallOptions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */; }; + 886717A79EFF774F356798E6 /* libPods-InteropTestsMultipleChannels.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */; }; 91D4B3C85B6D8562F409CB48 /* libPods-InteropTestsLocalSSLCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */; }; BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */; }; C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */; }; @@ -68,6 +79,13 @@ remoteGlobalIDString = 635697C61B14FC11007A7283; remoteInfo = Tests; }; + 5E7D71B8210B9EC9001EA6BA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; 5E8A5DAA1D3840B4000F8BC4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 635697BF1B14FC11007A7283 /* Project object */; @@ -82,6 +100,20 @@ remoteGlobalIDString = 635697C61B14FC11007A7283; remoteInfo = Tests; }; + 5EB2A2EA2107DED300EB4B69 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; + 5EB2A2FB2109284500EB4B69 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; 5EE84BF71D4717E40050C6CC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 635697BF1B14FC11007A7283 /* Project object */; @@ -144,20 +176,26 @@ 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartextCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.debug.xcconfig"; sourceTree = ""; }; + 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.cronet.xcconfig"; sourceTree = ""; }; 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.cronet.xcconfig"; sourceTree = ""; }; 1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.test.xcconfig"; sourceTree = ""; }; 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; sourceTree = ""; }; 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-UnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2650FEF00956E7924772F9D9 /* Pods-InteropTestsMultipleChannels.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.release.xcconfig"; sourceTree = ""; }; 2B89F3037963E6EDDD48D8C3 /* Pods-InteropTestsRemoteWithCronet.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.test.xcconfig"; sourceTree = ""; }; 303F4A17EB1650FC44603D17 /* Pods-InteropTestsRemoteCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.release.xcconfig"; sourceTree = ""; }; 32748C4078AEB05F8F954361 /* Pods-InteropTestsRemoteCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.debug.xcconfig"; sourceTree = ""; }; + 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsMultipleChannels.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 386712AEACF7C2190C4B8B3F /* Pods-CronetUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.cronet.xcconfig"; sourceTree = ""; }; + 3A98DF08852F60AF1D96481D /* Pods-InteropTestsCallOptions.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.debug.xcconfig"; sourceTree = ""; }; 3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.release.xcconfig"; sourceTree = ""; }; + 3CADF86203B9D03EA96C359D /* Pods-InteropTestsMultipleChannels.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.debug.xcconfig"; sourceTree = ""; }; 3EB55EF291706E3DDE23C3B7 /* Pods-InteropTestsLocalSSLCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.debug.xcconfig"; sourceTree = ""; }; 3F27B2E744482771EB93C394 /* Pods-InteropTestsRemoteWithCronet.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.cronet.xcconfig"; sourceTree = ""; }; 41AA59529240A6BBBD3DB904 /* Pods-InteropTestsLocalSSLCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.test.xcconfig"; sourceTree = ""; }; + 48F1841C9A920626995DC28C /* libPods-ChannelTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ChannelTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 4A1A42B2E941CCD453489E5B /* Pods-InteropTestsRemoteCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.cronet.xcconfig"; sourceTree = ""; }; 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.release.xcconfig"; sourceTree = ""; }; 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.cronet.xcconfig"; sourceTree = ""; }; @@ -169,6 +207,9 @@ 5E0282E6215AA697007AC99D /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E0282E8215AA697007AC99D /* UnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnitTests.m; sourceTree = ""; }; 5E0282EA215AA697007AC99D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsCallOptions.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsCallOptions.m; sourceTree = ""; }; + 5E7D71B6210B9EC9001EA6BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CoreCronetEnd2EndTests.mm; sourceTree = ""; }; 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.release.xcconfig"; sourceTree = ""; }; @@ -176,6 +217,13 @@ 5EAD6D261E27047400002378 /* CronetUnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CronetUnitTests.m; sourceTree = ""; }; 5EAD6D281E27047400002378 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5EAFE8271F8EFB87007F2189 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = ""; }; + 5EB2A2E42107DED300EB4B69 /* ChannelTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ChannelTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EB2A2E62107DED300EB4B69 /* ChannelTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChannelTests.m; sourceTree = ""; }; + 5EB2A2E82107DED300EB4B69 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsMultipleChannels.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EB2A2F72109284500EB4B69 /* InteropTestsMultipleChannels.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsMultipleChannels.m; sourceTree = ""; }; + 5EB2A2F92109284500EB4B69 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5EB5C3A921656CEA00ADC300 /* ChannelPoolTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChannelPoolTest.m; sourceTree = ""; }; 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsRemoteCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalCleartextCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalSSLCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -200,25 +248,32 @@ 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = TestCertificates.bundle; sourceTree = ""; }; 64F68A9A6A63CC930DD30A6E /* Pods-CronetUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.debug.xcconfig"; sourceTree = ""; }; 6793C9D019CB268C5BB491A2 /* Pods-CoreCronetEnd2EndTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.test.xcconfig"; sourceTree = ""; }; + 73D2DF07027835BA0FB0B1C0 /* Pods-InteropTestsCallOptions.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.cronet.xcconfig"; sourceTree = ""; }; 781089FAE980F51F88A3BE0B /* Pods-RxLibraryUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.test.xcconfig"; sourceTree = ""; }; 79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.cronet.xcconfig"; sourceTree = ""; }; 7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.release.xcconfig"; sourceTree = ""; }; 7BA53C6D224288D5870FE6F3 /* Pods-InteropTestsLocalCleartextCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; sourceTree = ""; }; 8B498B05C6DA0818B2FA91D4 /* Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; sourceTree = ""; }; + 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.cronet.xcconfig"; sourceTree = ""; }; 943138072A9605B5B8DC1FC0 /* Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; sourceTree = ""; }; 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.test.xcconfig"; sourceTree = ""; }; 9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteWithCronet.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + A25967A0D40ED14B3287AD81 /* Pods-InteropTestsCallOptions.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.test.xcconfig"; sourceTree = ""; }; A2DCF2570BE515B62CB924CA /* Pods-UnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.debug.xcconfig"; sourceTree = ""; }; A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RxLibraryUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A6F832FCEFA6F6881E620F12 /* Pods-InteropTestsRemote.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.test.xcconfig"; sourceTree = ""; }; AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.cronet.xcconfig"; sourceTree = ""; }; AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.release.xcconfig"; sourceTree = ""; }; + AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsCallOptions.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.test.xcconfig"; sourceTree = ""; }; B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = ""; }; + BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.test.xcconfig"; sourceTree = ""; }; C17F57E5BCB989AB1C2F1F25 /* Pods-InteropTestsRemoteCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.test.xcconfig"; sourceTree = ""; }; C6134277D2EB8B380862A03F /* libPods-CronetUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CronetUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + C9172F9020E8C97A470D7250 /* Pods-InteropTestsCallOptions.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.release.xcconfig"; sourceTree = ""; }; CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AllTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; D13BEC8181B8E678A1B52F54 /* Pods-InteropTestsLocalSSL.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.test.xcconfig"; sourceTree = ""; }; + D52B92A7108602F170DA8091 /* Pods-ChannelTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.release.xcconfig"; sourceTree = ""; }; DB1F4391AF69D20D38D74B67 /* Pods-AllTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.test.xcconfig"; sourceTree = ""; }; DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemote.a"; sourceTree = BUILT_PRODUCTS_DIR; }; DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalSSL.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -228,9 +283,11 @@ E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.release.xcconfig"; sourceTree = ""; }; E4FD4606D4AB8D5A314D72F0 /* Pods-InteropTestsLocalCleartextCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.test.xcconfig"; sourceTree = ""; }; E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.cronet.xcconfig"; sourceTree = ""; }; + EA8B122ACDE73E3AAA0E4A19 /* Pods-InteropTestsMultipleChannels.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.test.xcconfig"; sourceTree = ""; }; EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.release.xcconfig"; sourceTree = ""; }; F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalSSLCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + F9E48EF5ACB1F38825171C5F /* Pods-ChannelTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.debug.xcconfig"; sourceTree = ""; }; FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CoreCronetEnd2EndTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartext.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; @@ -246,6 +303,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E7D71AF210B9EC8001EA6BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */, + 6C1A3F81CCF7C998B4813EFD /* libPods-InteropTestsCallOptions.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E8A5DA11D3840B4000F8BC4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -264,6 +330,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5EB2A2E12107DED300EB4B69 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EB2A2E92107DED300EB4B69 /* libTests.a in Frameworks */, + 1A0FB7F8C95A2F82538BC950 /* libPods-ChannelTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EB2A2F22109284500EB4B69 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EB2A2FA2109284500EB4B69 /* libTests.a in Frameworks */, + 886717A79EFF774F356798E6 /* libPods-InteropTestsMultipleChannels.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5EC5E41E208177CC000EF4AD /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -368,6 +452,9 @@ F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */, 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */, F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */, + 48F1841C9A920626995DC28C /* libPods-ChannelTests.a */, + 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */, + AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */, 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */, ); name = Frameworks; @@ -422,6 +509,18 @@ 41AA59529240A6BBBD3DB904 /* Pods-InteropTestsLocalSSLCFStream.test.xcconfig */, 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */, 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */, + F9E48EF5ACB1F38825171C5F /* Pods-ChannelTests.debug.xcconfig */, + BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */, + 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */, + D52B92A7108602F170DA8091 /* Pods-ChannelTests.release.xcconfig */, + 3CADF86203B9D03EA96C359D /* Pods-InteropTestsMultipleChannels.debug.xcconfig */, + EA8B122ACDE73E3AAA0E4A19 /* Pods-InteropTestsMultipleChannels.test.xcconfig */, + 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */, + 2650FEF00956E7924772F9D9 /* Pods-InteropTestsMultipleChannels.release.xcconfig */, + 3A98DF08852F60AF1D96481D /* Pods-InteropTestsCallOptions.debug.xcconfig */, + A25967A0D40ED14B3287AD81 /* Pods-InteropTestsCallOptions.test.xcconfig */, + 73D2DF07027835BA0FB0B1C0 /* Pods-InteropTestsCallOptions.cronet.xcconfig */, + C9172F9020E8C97A470D7250 /* Pods-InteropTestsCallOptions.release.xcconfig */, A2DCF2570BE515B62CB924CA /* Pods-UnitTests.debug.xcconfig */, 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */, E1E7660656D902104F728892 /* Pods-UnitTests.cronet.xcconfig */, @@ -439,6 +538,15 @@ path = UnitTests; sourceTree = ""; }; + 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */ = { + isa = PBXGroup; + children = ( + 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */, + 5E7D71B6210B9EC9001EA6BA /* Info.plist */, + ); + path = InteropTestsCallOptions; + sourceTree = ""; + }; 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { isa = PBXGroup; children = ( @@ -456,6 +564,25 @@ path = CronetUnitTests; sourceTree = ""; }; + 5EB2A2E52107DED300EB4B69 /* ChannelTests */ = { + isa = PBXGroup; + children = ( + 5EB5C3A921656CEA00ADC300 /* ChannelPoolTest.m */, + 5EB2A2E62107DED300EB4B69 /* ChannelTests.m */, + 5EB2A2E82107DED300EB4B69 /* Info.plist */, + ); + path = ChannelTests; + sourceTree = ""; + }; + 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */ = { + isa = PBXGroup; + children = ( + 5EB2A2F72109284500EB4B69 /* InteropTestsMultipleChannels.m */, + 5EB2A2F92109284500EB4B69 /* Info.plist */, + ); + path = InteropTestsMultipleChannels; + sourceTree = ""; + }; 5EE84BF21D4717E40050C6CC /* InteropTestsRemoteWithCronet */ = { isa = PBXGroup; children = ( @@ -473,6 +600,9 @@ 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */, 5EE84BF21D4717E40050C6CC /* InteropTestsRemoteWithCronet */, 5EAD6D251E27047400002378 /* CronetUnitTests */, + 5EB2A2E52107DED300EB4B69 /* ChannelTests */, + 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */, + 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */, 5E0282E7215AA697007AC99D /* UnitTests */, 635697C81B14FC11007A7283 /* Products */, 51E4650F34F854F41FF053B3 /* Pods */, @@ -495,6 +625,9 @@ 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */, 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */, 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */, + 5EB2A2E42107DED300EB4B69 /* ChannelTests.xctest */, + 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */, + 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */, 5E0282E6215AA697007AC99D /* UnitTests.xctest */, ); name = Products; @@ -548,6 +681,26 @@ productReference = 5E0282E6215AA697007AC99D /* UnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */; + buildPhases = ( + 2865C6386D677998F861E183 /* [CP] Check Pods Manifest.lock */, + 5E7D71AE210B9EC8001EA6BA /* Sources */, + 5E7D71AF210B9EC8001EA6BA /* Frameworks */, + 5E7D71B0210B9EC8001EA6BA /* Resources */, + 6BA6D00B1816306453BF82D4 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5E7D71B9210B9EC9001EA6BA /* PBXTargetDependency */, + ); + name = InteropTestsCallOptions; + productName = InteropTestsCallOptions; + productReference = 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { isa = PBXNativeTarget; buildConfigurationList = 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */; @@ -588,6 +741,47 @@ productReference = 5EAD6D241E27047400002378 /* CronetUnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 5EB2A2E32107DED300EB4B69 /* ChannelTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5EB2A2F02107DED300EB4B69 /* Build configuration list for PBXNativeTarget "ChannelTests" */; + buildPhases = ( + 021B3B1F545989843EBC9A4B /* [CP] Check Pods Manifest.lock */, + 5EB2A2E02107DED300EB4B69 /* Sources */, + 5EB2A2E12107DED300EB4B69 /* Frameworks */, + 5EB2A2E22107DED300EB4B69 /* Resources */, + 1EAF0CBDBFAB18D4DA64535D /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5EB2A2EB2107DED300EB4B69 /* PBXTargetDependency */, + ); + name = ChannelTests; + productName = ChannelTests; + productReference = 5EB2A2E42107DED300EB4B69 /* ChannelTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5EB2A3012109284500EB4B69 /* Build configuration list for PBXNativeTarget "InteropTestsMultipleChannels" */; + buildPhases = ( + 8C1ED025E07C4D457C355336 /* [CP] Check Pods Manifest.lock */, + 5EB2A2F12109284500EB4B69 /* Sources */, + 5EB2A2F22109284500EB4B69 /* Frameworks */, + 5EB2A2F32109284500EB4B69 /* Resources */, + 8D685CB612835DB3F7A6F14A /* [CP] Embed Pods Frameworks */, + 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5EB2A2FC2109284500EB4B69 /* PBXTargetDependency */, + ); + name = InteropTestsMultipleChannels; + productName = InteropTestsMultipleChannels; + productReference = 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5EC5E420208177CC000EF4AD /* InteropTestsRemoteCFStream */ = { isa = PBXNativeTarget; buildConfigurationList = 5EC5E42A208177CD000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsRemoteCFStream" */; @@ -796,12 +990,24 @@ CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; }; + 5E7D71B1210B9EC8001EA6BA = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; 5E8A5DA31D3840B4000F8BC4 = { CreatedOnToolsVersion = 7.3.1; }; 5EAD6D231E27047400002378 = { CreatedOnToolsVersion = 7.3.1; }; + 5EB2A2E32107DED300EB4B69 = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; + 5EB2A2F42109284500EB4B69 = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; 5EC5E420208177CC000EF4AD = { CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; @@ -861,6 +1067,9 @@ 5EC5E420208177CC000EF4AD /* InteropTestsRemoteCFStream */, 5EC5E4302081856B000EF4AD /* InteropTestsLocalCleartextCFStream */, 5EC5E441208185CE000EF4AD /* InteropTestsLocalSSLCFStream */, + 5EB2A2E32107DED300EB4B69 /* ChannelTests */, + 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */, + 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */, 5E0282E5215AA697007AC99D /* UnitTests */, ); }; @@ -874,6 +1083,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E7D71B0210B9EC8001EA6BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E8A5DA21D3840B4000F8BC4 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -888,6 +1104,21 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5EB2A2E22107DED300EB4B69 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EB2A2F32109284500EB4B69 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5EC5E41F208177CC000EF4AD /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -957,6 +1188,60 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 021B3B1F545989843EBC9A4B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ChannelTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 1EAF0CBDBFAB18D4DA64535D /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 252A376345E38FD452A89C3D /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -975,6 +1260,24 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + 2865C6386D677998F861E183 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-InteropTestsCallOptions-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 31F8D1C407195CBF0C02929B /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1083,6 +1386,24 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 6BA6D00B1816306453BF82D4 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1137,6 +1458,42 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 8C1ED025E07C4D457C355336 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-InteropTestsMultipleChannels-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 8D685CB612835DB3F7A6F14A /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-frameworks.sh", + "${PODS_ROOT}/CronetFramework/Cronet.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 914ADDD7106BA9BB8A7E569F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1418,6 +1775,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E7D71AE210B9EC8001EA6BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E8A5DA01D3840B4000F8BC4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1434,6 +1799,23 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5EB2A2E02107DED300EB4B69 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EB2A2E72107DED300EB4B69 /* ChannelTests.m in Sources */, + 5EB5C3AA21656CEA00ADC300 /* ChannelPoolTest.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EB2A2F12109284500EB4B69 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EB2A2F82109284500EB4B69 /* InteropTestsMultipleChannels.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5EC5E41D208177CC000EF4AD /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1536,6 +1918,11 @@ target = 635697C61B14FC11007A7283 /* Tests */; targetProxy = 5E0282EC215AA697007AC99D /* PBXContainerItemProxy */; }; + 5E7D71B9210B9EC9001EA6BA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5E7D71B8210B9EC9001EA6BA /* PBXContainerItemProxy */; + }; 5E8A5DAB1D3840B4000F8BC4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 635697C61B14FC11007A7283 /* Tests */; @@ -1546,6 +1933,16 @@ target = 635697C61B14FC11007A7283 /* Tests */; targetProxy = 5EAD6D2A1E27047400002378 /* PBXContainerItemProxy */; }; + 5EB2A2EB2107DED300EB4B69 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5EB2A2EA2107DED300EB4B69 /* PBXContainerItemProxy */; + }; + 5EB2A2FC2109284500EB4B69 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5EB2A2FB2109284500EB4B69 /* PBXContainerItemProxy */; + }; 5EE84BF81D4717E40050C6CC /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 635697C61B14FC11007A7283 /* Tests */; @@ -1909,16 +2306,146 @@ }; name = Test; }; - 5E8A5DAC1D3840B4000F8BC4 /* Debug */ = { + 5E7D71BB210B9EC9001EA6BA /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */; + baseConfigurationReference = 3A98DF08852F60AF1D96481D /* Pods-InteropTestsCallOptions.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5E7D71BC210B9EC9001EA6BA /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A25967A0D40ED14B3287AD81 /* Pods-InteropTestsCallOptions.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5E7D71BD210B9EC9001EA6BA /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 73D2DF07027835BA0FB0B1C0 /* Pods-InteropTestsCallOptions.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5E7D71BE210B9EC9001EA6BA /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C9172F9020E8C97A470D7250 /* Pods-InteropTestsCallOptions.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 5E8A5DAC1D3840B4000F8BC4 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -2011,6 +2538,266 @@ }; name = Release; }; + 5EB2A2EC2107DED300EB4B69 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F9E48EF5ACB1F38825171C5F /* Pods-ChannelTests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ChannelTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5EB2A2ED2107DED300EB4B69 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ChannelTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5EB2A2EE2107DED300EB4B69 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ChannelTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5EB2A2EF2107DED300EB4B69 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D52B92A7108602F170DA8091 /* Pods-ChannelTests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ChannelTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 5EB2A2FD2109284500EB4B69 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3CADF86203B9D03EA96C359D /* Pods-InteropTestsMultipleChannels.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5EB2A2FE2109284500EB4B69 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EA8B122ACDE73E3AAA0E4A19 /* Pods-InteropTestsMultipleChannels.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5EB2A2FF2109284500EB4B69 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5EB2A3002109284500EB4B69 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2650FEF00956E7924772F9D9 /* Pods-InteropTestsMultipleChannels.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 5EC3C7A01D4FC18C000330E2 /* Cronet */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2039,6 +2826,8 @@ "DEBUG=1", "$(inherited)", "HOST_PORT_REMOTE=$(HOST_PORT_REMOTE)", + "HOST_PORT_LOCALSSL=$(HOST_PORT_LOCALSSL)", + "HOST_PORT_LOCAL=$(HOST_PORT_LOCAL)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_TREAT_WARNINGS_AS_ERRORS = YES; @@ -2859,6 +3648,17 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E7D71BB210B9EC9001EA6BA /* Debug */, + 5E7D71BC210B9EC9001EA6BA /* Test */, + 5E7D71BD210B9EC9001EA6BA /* Cronet */, + 5E7D71BE210B9EC9001EA6BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -2881,6 +3681,28 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 5EB2A2F02107DED300EB4B69 /* Build configuration list for PBXNativeTarget "ChannelTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EB2A2EC2107DED300EB4B69 /* Debug */, + 5EB2A2ED2107DED300EB4B69 /* Test */, + 5EB2A2EE2107DED300EB4B69 /* Cronet */, + 5EB2A2EF2107DED300EB4B69 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5EB2A3012109284500EB4B69 /* Build configuration list for PBXNativeTarget "InteropTestsMultipleChannels" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EB2A2FD2109284500EB4B69 /* Debug */, + 5EB2A2FE2109284500EB4B69 /* Test */, + 5EB2A2FF2109284500EB4B69 /* Cronet */, + 5EB2A3002109284500EB4B69 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5EC5E42A208177CD000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsRemoteCFStream" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme new file mode 100644 index 00000000000..16ae481123b --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsCallOptions.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsCallOptions.xcscheme new file mode 100644 index 00000000000..dd83282190f --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsCallOptions.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme index 510115fc757..11b41c92140 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme @@ -26,7 +26,6 @@ buildConfiguration = "Test" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - @@ -58,7 +51,6 @@ buildConfiguration = "Test" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme new file mode 100644 index 00000000000..1b4c1f5e51c --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme index 48837e57f9a..412bf6a0143 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme @@ -26,7 +26,6 @@ buildConfiguration = "Test" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> Date: Mon, 8 Oct 2018 15:49:17 -0700 Subject: [PATCH 002/534] Proto-related changes --- src/compiler/objective_c_generator.cc | 103 +++++++++++++++- src/compiler/objective_c_generator.h | 7 +- src/compiler/objective_c_plugin.cc | 21 +++- src/objective-c/ProtoRPC/ProtoRPC.h | 49 ++++++++ src/objective-c/ProtoRPC/ProtoRPC.m | 157 ++++++++++++++++++++++++ src/objective-c/ProtoRPC/ProtoService.h | 28 ++++- src/objective-c/ProtoRPC/ProtoService.m | 47 ++++++- 7 files changed, 399 insertions(+), 13 deletions(-) diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc index 39f68cb9565..eb67e9bb88f 100644 --- a/src/compiler/objective_c_generator.cc +++ b/src/compiler/objective_c_generator.cc @@ -113,6 +113,29 @@ void PrintAdvancedSignature(Printer* printer, const MethodDescriptor* method, PrintMethodSignature(printer, method, vars); } +void PrintV2Signature(Printer* printer, const MethodDescriptor* method, + map< ::grpc::string, ::grpc::string> vars) { + if (method->client_streaming()) { + vars["return_type"] = "GRPCStreamingProtoCall *"; + } else { + vars["return_type"] = "GRPCUnaryProtoCall *"; + } + vars["method_name"] = + grpc_generator::LowercaseFirstLetter(vars["method_name"]); + + PrintAllComments(method, printer); + + printer->Print(vars, "- ($return_type$)$method_name$With"); + if (method->client_streaming()) { + printer->Print("ResponseHandler:(id)handler"); + } else { + printer->Print(vars, + "Message:($request_class$ *)message " + "responseHandler:(id)handler"); + } + printer->Print(" callOptions:(GRPCCallOptions *_Nullable)callOptions"); +} + inline map< ::grpc::string, ::grpc::string> GetMethodVars( const MethodDescriptor* method) { map< ::grpc::string, ::grpc::string> res; @@ -135,6 +158,16 @@ void PrintMethodDeclarations(Printer* printer, const MethodDescriptor* method) { printer->Print(";\n\n\n"); } +void PrintV2MethodDeclarations(Printer* printer, + const MethodDescriptor* method) { + map< ::grpc::string, ::grpc::string> vars = GetMethodVars(method); + + PrintProtoRpcDeclarationAsPragma(printer, method, vars); + + PrintV2Signature(printer, method, vars); + printer->Print(";\n\n"); +} + void PrintSimpleImplementation(Printer* printer, const MethodDescriptor* method, map< ::grpc::string, ::grpc::string> vars) { printer->Print("{\n"); @@ -177,6 +210,25 @@ void PrintAdvancedImplementation(Printer* printer, printer->Print("}\n"); } +void PrintV2Implementation(Printer* printer, const MethodDescriptor* method, + map< ::grpc::string, ::grpc::string> vars) { + printer->Print(" {\n"); + if (method->client_streaming()) { + printer->Print(vars, " return [self RPCToMethod:@\"$method_name$\"\n"); + printer->Print(" responseHandler:handler\n"); + printer->Print(" callOptions:callOptions\n"); + printer->Print( + vars, " responseClass:[$response_class$ class]];\n}\n\n"); + } else { + printer->Print(vars, " return [self RPCToMethod:@\"$method_name$\"\n"); + printer->Print(" message:message\n"); + printer->Print(" responseHandler:handler\n"); + printer->Print(" callOptions:callOptions\n"); + printer->Print( + vars, " responseClass:[$response_class$ class]];\n}\n\n"); + } +} + void PrintMethodImplementations(Printer* printer, const MethodDescriptor* method) { map< ::grpc::string, ::grpc::string> vars = GetMethodVars(method); @@ -184,12 +236,16 @@ void PrintMethodImplementations(Printer* printer, PrintProtoRpcDeclarationAsPragma(printer, method, vars); // TODO(jcanizales): Print documentation from the method. + printer->Print("// Deprecated methods.\n"); PrintSimpleSignature(printer, method, vars); PrintSimpleImplementation(printer, method, vars); printer->Print("// Returns a not-yet-started RPC object.\n"); PrintAdvancedSignature(printer, method, vars); PrintAdvancedImplementation(printer, method, vars); + + PrintV2Signature(printer, method, vars); + PrintV2Implementation(printer, method, vars); } } // namespace @@ -231,6 +287,25 @@ void PrintMethodImplementations(Printer* printer, return output; } +::grpc::string GetV2Protocol(const ServiceDescriptor* service) { + ::grpc::string output; + + // Scope the output stream so it closes and finalizes output to the string. + grpc::protobuf::io::StringOutputStream output_stream(&output); + Printer printer(&output_stream, '$'); + + map< ::grpc::string, ::grpc::string> vars = { + {"service_class", ServiceClassName(service) + "2"}}; + + printer.Print(vars, "@protocol $service_class$ \n\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintV2MethodDeclarations(&printer, service->method(i)); + } + printer.Print("@end\n\n"); + + return output; +} + ::grpc::string GetInterface(const ServiceDescriptor* service) { ::grpc::string output; @@ -248,10 +323,16 @@ void PrintMethodImplementations(Printer* printer, " */\n"); printer.Print(vars, "@interface $service_class$ :" - " GRPCProtoService<$service_class$>\n"); + " GRPCProtoService<$service_class$, $service_class$2>\n"); printer.Print( - "- (instancetype)initWithHost:(NSString *)host" + "- (instancetype)initWithHost:(NSString *)host " + "callOptions:(GRPCCallOptions " + "*_Nullable)callOptions" " NS_DESIGNATED_INITIALIZER;\n"); + printer.Print("- (instancetype)initWithHost:(NSString *)host;\n"); + printer.Print( + "+ (instancetype)serviceWithHost:(NSString *)host " + "callOptions:(GRPCCallOptions *_Nullable)callOptions;\n"); printer.Print("+ (instancetype)serviceWithHost:(NSString *)host;\n"); printer.Print("@end\n"); @@ -273,11 +354,19 @@ void PrintMethodImplementations(Printer* printer, printer.Print(vars, "@implementation $service_class$\n\n" "// Designated initializer\n" - "- (instancetype)initWithHost:(NSString *)host {\n" + "- (instancetype)initWithHost:(NSString *)host " + "callOptions:(GRPCCallOptions *_Nullable)callOptions{\n" " self = [super initWithHost:host\n" " packageName:@\"$package$\"\n" - " serviceName:@\"$service_name$\"];\n" + " serviceName:@\"$service_name$\"\n" + " callOptions:callOptions];\n" " return self;\n" + "}\n\n" + "- (instancetype)initWithHost:(NSString *)host {\n" + " return [self initWithHost:host\n" + " packageName:@\"$package$\"\n" + " serviceName:@\"$service_name$\"\n" + " callOptions:nil];\n" "}\n\n"); printer.Print( @@ -292,7 +381,11 @@ void PrintMethodImplementations(Printer* printer, printer.Print( "#pragma mark - Class Methods\n\n" "+ (instancetype)serviceWithHost:(NSString *)host {\n" - " return [[self alloc] initWithHost:host];\n" + " return [self serviceWithHost:host callOptions:nil];\n" + "}\n\n" + "+ (instancetype)serviceWithHost:(NSString *)host " + "callOptions:(GRPCCallOptions *_Nullable)callOptions {\n" + " return [[self alloc] initWithHost:host callOptions:callOptions];\n" "}\n\n"); printer.Print("#pragma mark - Method Implementations\n\n"); diff --git a/src/compiler/objective_c_generator.h b/src/compiler/objective_c_generator.h index eb1c7ff005a..c171e5bf772 100644 --- a/src/compiler/objective_c_generator.h +++ b/src/compiler/objective_c_generator.h @@ -32,9 +32,14 @@ using ::grpc::string; string GetAllMessageClasses(const FileDescriptor* file); // Returns the content to be included defining the @protocol segment at the -// insertion point of the generated implementation file. +// insertion point of the generated implementation file. This interface is +// legacy and for backwards compatibility. string GetProtocol(const ServiceDescriptor* service); +// Returns the content to be included defining the @protocol segment at the +// insertion point of the generated implementation file. +string GetV2Protocol(const ServiceDescriptor* service); + // Returns the content to be included defining the @interface segment at the // insertion point of the generated implementation file. string GetInterface(const ServiceDescriptor* service); diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc index f0fe3688cca..d0ef9ed0d62 100644 --- a/src/compiler/objective_c_plugin.cc +++ b/src/compiler/objective_c_plugin.cc @@ -93,7 +93,13 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { SystemImport("RxLibrary/GRXWriteable.h") + SystemImport("RxLibrary/GRXWriter.h"); - ::grpc::string forward_declarations = "@class GRPCProtoCall;\n\n"; + ::grpc::string forward_declarations = + "@class GRPCProtoCall;\n" + "@class GRPCUnaryProtoCall;\n" + "@class GRPCStreamingProtoCall;\n" + "@class GRPCCallOptions;\n" + "@protocol GRPCResponseHandler;\n" + "\n"; ::grpc::string class_declarations = grpc_objective_c_generator::GetAllMessageClasses(file); @@ -103,6 +109,12 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { class_imports += ImportProtoHeaders(file->dependency(i), " "); } + ::grpc::string ng_protocols; + for (int i = 0; i < file->service_count(); i++) { + const grpc::protobuf::ServiceDescriptor* service = file->service(i); + ng_protocols += grpc_objective_c_generator::GetV2Protocol(service); + } + ::grpc::string protocols; for (int i = 0; i < file->service_count(); i++) { const grpc::protobuf::ServiceDescriptor* service = file->service(i); @@ -120,9 +132,10 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { PreprocIfNot(kProtocolOnly, system_imports) + "\n" + class_declarations + "\n" + PreprocIfNot(kForwardDeclare, class_imports) + "\n" + - forward_declarations + "\n" + kNonNullBegin + "\n" + protocols + - "\n" + PreprocIfNot(kProtocolOnly, interfaces) + "\n" + - kNonNullEnd + "\n"); + forward_declarations + "\n" + kNonNullBegin + "\n" + + ng_protocols + protocols + "\n" + + PreprocIfNot(kProtocolOnly, interfaces) + "\n" + kNonNullEnd + + "\n"); } { diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 45d35260921..1a27cac2a32 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -21,6 +21,55 @@ #import "ProtoMethod.h" +@class GPBMessage; + +/** A unary-request RPC call with Protobuf. */ +@interface GRPCUnaryProtoCall : NSObject + +/** + * Users should not use this initializer directly. Call objects will be created, initialized, and + * returned to users by methods of the generated service. + */ +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + message:(GPBMessage *)message + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass; + +/** Cancel the call at best effort. */ +- (void)cancel; + +@end + +/** A client-streaming RPC call with Protobuf. */ +@interface GRPCStreamingProtoCall : NSObject + +/** + * Users should not use this initializer directly. Call objects will be created, initialized, and + * returned to users by methods of the generated service. + */ +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass; + +/** Cancel the call at best effort. */ +- (void)cancel; + +/** + * Send a message to the server. The message should be a Protobuf message which will be serialized + * internally. + */ +- (void)writeWithMessage:(GPBMessage *)message; + +/** + * Finish the RPC request and half-close the call. The server may still send messages and/or + * trailers to the client. + */ +- (void)finish; + +@end + __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC : GRPCCall diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 5dca971b08a..f89c1606507 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -23,9 +23,166 @@ #else #import #endif +#import #import #import +@implementation GRPCUnaryProtoCall { + GRPCStreamingProtoCall *_call; +} + +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + message:(GPBMessage *)message + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass { + if ((self = [super init])) { + _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions + responseHandler:handler + callOptions:callOptions + responseClass:responseClass]; + [_call writeWithMessage:message]; + [_call finish]; + } + return self; +} + +- (void)cancel { + [_call cancel]; + _call = nil; +} + +@end + +@interface GRPCStreamingProtoCall () + +@end + +@implementation GRPCStreamingProtoCall { + GRPCRequestOptions *_requestOptions; + id _handler; + GRPCCallOptions *_callOptions; + Class _responseClass; + + GRPCCall2 *_call; + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass { + if ((self = [super init])) { + _requestOptions = [requestOptions copy]; + _handler = handler; + _callOptions = [callOptions copy]; + _responseClass = responseClass; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + + [self start]; + } + return self; +} + +- (void)start { + _call = [[GRPCCall2 alloc] initWithRequestOptions:_requestOptions + handler:self + callOptions:_callOptions]; + [_call start]; +} + +- (void)cancel { + dispatch_async(_dispatchQueue, ^{ + if (_call) { + [_call cancel]; + _call = nil; + } + if (_handler) { + id handler = _handler; + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); + _handler = nil; + } + }); +} + +- (void)writeWithMessage:(GPBMessage *)message { + if (![message isKindOfClass:[GPBMessage class]]) { + [NSException raise:NSInvalidArgumentException format:@"Data must be a valid protobuf type."]; + } + + dispatch_async(_dispatchQueue, ^{ + if (_call) { + [_call writeWithData:[message data]]; + } + }); +} + +- (void)finish { + dispatch_async(_dispatchQueue, ^{ + if (_call) { + [_call finish]; + _call = nil; + } + }); +} + +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { + if (_handler) { + id handler = _handler; + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedInitialMetadata:initialMetadata]; + }); + } +} + +- (void)receivedMessage:(NSData *)message { + if (_handler) { + id handler = _handler; + NSError *error = nil; + id parsed = [_responseClass parseFromData:message error:&error]; + if (parsed) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedMessage:parsed]; + }); + } else { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:nil error:error]; + }); + handler = nil; + [_call cancel]; + _call = nil; + } + } +} + +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (_handler) { + id handler = _handler; + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:trailingMetadata error:error]; + }); + _handler = nil; + } + if (_call) { + [_call cancel]; + _call = nil; + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsingError) { NSDictionary *info = @{ NSLocalizedDescriptionKey : @"Unable to parse response from the server", diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 29c4e9be360..2105de78a38 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -21,16 +21,40 @@ @class GRPCProtoCall; @protocol GRXWriteable; @class GRXWriter; +@class GRPCCallOptions; +@class GRPCProtoCall; +@class GRPCUnaryProtoCall; +@class GRPCStreamingProtoCall; +@protocol GRPCProtoResponseCallbacks; __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService - : NSObject - + : NSObject + + - (instancetype)initWithHost : (NSString *)host packageName - : (NSString *)packageName serviceName : (NSString *)serviceName NS_DESIGNATED_INITIALIZER; + : (NSString *)packageName serviceName : (NSString *)serviceName callOptions + : (GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithHost:(NSString *)host + packageName:(NSString *)packageName + serviceName:(NSString *)serviceName; - (GRPCProtoCall *)RPCToMethod:(NSString *)method requestsWriter:(GRXWriter *)requestsWriter responseClass:(Class)responseClass responsesWriteable:(id)responsesWriteable; + +- (GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method + message:(id)message + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass; + +- (GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass; + @end /** diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m index 3e9cc5c0b2d..6df502fb0c0 100644 --- a/src/objective-c/ProtoRPC/ProtoService.m +++ b/src/objective-c/ProtoRPC/ProtoService.m @@ -18,6 +18,7 @@ #import "ProtoService.h" +#import #import #import @@ -31,6 +32,7 @@ NSString *_host; NSString *_packageName; NSString *_serviceName; + GRPCCallOptions *_callOptions; } - (instancetype)init { @@ -40,7 +42,8 @@ // Designated initializer - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName - serviceName:(NSString *)serviceName { + serviceName:(NSString *)serviceName + callOptions:(GRPCCallOptions *)callOptions { if (!host || !serviceName) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor serviceName can be nil."]; @@ -49,10 +52,17 @@ _host = [host copy]; _packageName = [packageName copy]; _serviceName = [serviceName copy]; + _callOptions = [callOptions copy]; } return self; } +- (instancetype)initWithHost:(NSString *)host + packageName:(NSString *)packageName + serviceName:(NSString *)serviceName { + return [self initWithHost:host packageName:packageName serviceName:serviceName callOptions:nil]; +} + - (GRPCProtoCall *)RPCToMethod:(NSString *)method requestsWriter:(GRXWriter *)requestsWriter responseClass:(Class)responseClass @@ -65,6 +75,41 @@ responseClass:responseClass responsesWriteable:responsesWriteable]; } + +- (GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method + message:(id)message + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass { + GRPCProtoMethod *methodName = + [[GRPCProtoMethod alloc] initWithPackage:_packageName service:_serviceName method:method]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:_host + path:methodName.HTTPPath + safety:GRPCCallSafetyDefault]; + return [[GRPCUnaryProtoCall alloc] initWithRequestOptions:requestOptions + message:message + responseHandler:handler + callOptions:callOptions ?: _callOptions + responseClass:responseClass]; +} + +- (GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass { + GRPCProtoMethod *methodName = + [[GRPCProtoMethod alloc] initWithPackage:_packageName service:_serviceName method:method]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:_host + path:methodName.HTTPPath + safety:GRPCCallSafetyDefault]; + return [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions + responseHandler:handler + callOptions:callOptions ?: _callOptions + responseClass:responseClass]; +} + @end @implementation GRPCProtoService From e2e5c8189310841f7edd5ae8a51a616c9d93b309 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 8 Oct 2018 15:50:55 -0700 Subject: [PATCH 003/534] New API for GRPCCall --- include/grpc/impl/codegen/grpc_types.h | 4 + src/objective-c/GRPCClient/GRPCCall.h | 145 +++++-- src/objective-c/GRPCClient/GRPCCall.m | 253 ++++++++++- src/objective-c/GRPCClient/GRPCCallOptions.h | 317 ++++++++++++++ src/objective-c/GRPCClient/GRPCCallOptions.m | 431 +++++++++++++++++++ 5 files changed, 1105 insertions(+), 45 deletions(-) create mode 100644 src/objective-c/GRPCClient/GRPCCallOptions.h create mode 100644 src/objective-c/GRPCClient/GRPCCallOptions.m diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 3ce88a82645..4cf13edca93 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -347,6 +347,10 @@ typedef struct { /** If set to non zero, surfaces the user agent string to the server. User agent is surfaced by default. */ #define GRPC_ARG_SURFACE_USER_AGENT "grpc.surface_user_agent" +/** gRPC Objective-C channel pooling domain string. */ +#define GRPC_ARG_CHANNEL_POOL_DOMAIN "grpc.channel_pooling_domain" +/** gRPC Objective-C channel pooling id. */ +#define GRPC_ARG_CHANNEL_ID "grpc.channel_id" /** \} */ /** Result of a grpc call. If the caller satisfies the prerequisites of a diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index e0ef8b1391f..3f6ec75c04e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -37,6 +37,10 @@ #include +#include "GRPCCallOptions.h" + +@class GRPCCallOptions; + #pragma mark gRPC errors /** Domain of NSError objects produced by gRPC. */ @@ -139,19 +143,6 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { GRPCErrorCodeDataLoss = 15, }; -/** - * Safety remark of a gRPC method as defined in RFC 2616 Section 9.1 - */ -typedef NS_ENUM(NSUInteger, GRPCCallSafety) { - /** Signal that there is no guarantees on how the call affects the server state. */ - 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. */ - GRPCCallSafetyCacheableRequest = 2, -}; - /** * Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by * the server. @@ -159,23 +150,117 @@ typedef NS_ENUM(NSUInteger, GRPCCallSafety) { extern id const kGRPCHeadersKey; extern id const kGRPCTrailersKey; +/** An object can implement this protocol to receive responses from server from a call. */ +@protocol GRPCResponseHandler +@optional +/** Issued when initial metadata is received from the server. */ +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; +/** + * Issued when a message is received from the server. The message may be raw data from the server + * (when using \a GRPCCall2 directly) or deserialized proto object (when using \a ProtoRPC). + */ +- (void)receivedMessage:(id)message; +/** + * Issued when a call finished. If the call finished successfully, \a error is nil and \a + * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error + * is non-nil and contains the corresponding error information, including gRPC error codes and + * error descriptions. + */ +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error; + +/** + * All the responses must be issued to a user-provided dispatch queue. This property specifies the + * dispatch queue to be used for issuing the notifications. + */ +@property(atomic, readonly) dispatch_queue_t dispatchQueue; + +@end + +/** + * Call related parameters. These parameters are automatically specified by Protobuf. If directly + * using the \a GRPCCall2 class, users should specify these parameters manually. + */ +@interface GRPCRequestOptions : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/** Initialize with all properties. */ +- (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety; + +/** The host serving the RPC service. */ +@property(copy, readonly) NSString *host; +/** The path to the RPC call. */ +@property(copy, readonly) NSString *path; +/** + * Specify whether the call is idempotent or cachable. gRPC may select different HTTP verbs for the + * call based on this information. + */ +@property(readonly) GRPCCallSafety safety; + +@end + #pragma mark GRPCCall -/** Represents a single gRPC remote call. */ -@interface GRPCCall : GRXWriter +/** + * A \a GRPCCall2 object represents an RPC call. + */ +@interface GRPCCall2 : NSObject + +- (instancetype)init NS_UNAVAILABLE; /** - * The authority for the RPC. If nil, the default authority will be used. This property must be nil - * when Cronet transport is enabled. + * Designated initializer for a call. + * \param requestOptions Protobuf generated parameters for the call. + * \param handler The object to which responses should be issed. + * \param callOptions Options for the call. */ -@property(atomic, copy, readwrite) NSString *serverName; +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + handler:(id)handler + callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; +/** + * Convevience initializer for a call that uses default call options. + */ +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + handler:(id)handler; /** - * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to - * positive, the gRPC call returns with status GRPCErrorCodeDeadlineExceeded if it is not completed - * within \a timeout seconds. A negative value is not allowed. + * Starts the call. Can only be called once. */ -@property NSTimeInterval timeout; +- (void)start; + +/** + * Cancel the request of this call at best effort; notifies the server that the RPC should be + * cancelled, and issue callback to the user with an error code CANCELED if the call is not + * finished. + */ +- (void)cancel; + +/** + * Send a message to the server. Data are sent as raw bytes in gRPC message frames. + */ +- (void)writeWithData:(NSData *)data; + +/** + * Finish the RPC request and half-close the call. The server may still send messages and/or + * trailers to the client. + */ -(void)finish; + +/** + * Get a copy of the original call options. + */ +@property(readonly, copy) GRPCCallOptions *callOptions; + +/** Get a copy of the original request options. */ +@property(readonly, copy) GRPCRequestOptions *requestOptions; + +@end + +/** + * This interface is deprecated. Please use \a GRPCcall2. + * + * Represents a single gRPC remote call. + */ +@interface GRPCCall : GRXWriter /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of @@ -236,7 +321,7 @@ extern id const kGRPCTrailersKey; */ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path - requestsWriter:(GRXWriter *)requestsWriter NS_DESIGNATED_INITIALIZER; + requestsWriter:(GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -245,21 +330,13 @@ extern id const kGRPCTrailersKey; - (void)cancel; /** - * Set the call flag for a specific host path. - * - * Host parameter should not contain the scheme (http:// or https://), only the name or IP addr - * and the port number, for example @"localhost:5050". + * The following methods are deprecated. */ + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path; - -/** - * Set the dispatch queue to be used for callbacks. - * - * This configuration is only effective before the call starts. - */ +@property(atomic, copy, readwrite) NSString *serverName; +@property NSTimeInterval timeout; - (void)setResponseDispatchQueue:(dispatch_queue_t)queue; -// TODO(jcanizales): Let specify a deadline. As a category of GRXWriter? @end #pragma mark Backwards compatibiity diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 084fbdeb491..519f91e5229 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -20,13 +20,16 @@ #import "GRPCCall+OAuth2.h" +#import #import #import +#import #include #include -#import "private/GRPCConnectivityMonitor.h" +#import "GRPCCallOptions.h" #import "private/GRPCHost.h" +#import "private/GRPCConnectivityMonitor.h" #import "private/GRPCRequestHeaders.h" #import "private/GRPCWrappedCall.h" #import "private/NSData+GRPC.h" @@ -52,6 +55,165 @@ const char *kCFStreamVarName = "grpc_cfstream"; @property(atomic, strong) NSDictionary *responseHeaders; @property(atomic, strong) NSDictionary *responseTrailers; @property(atomic) BOOL isWaitingForToken; + +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestsWriter + callOptions:(GRPCCallOptions *)callOptions; + +@end + +@implementation GRPCRequestOptions + +- (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { + if ((self = [super init])) { + _host = host; + _path = path; + _safety = safety; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + GRPCRequestOptions *request = + [[GRPCRequestOptions alloc] initWithHost:[_host copy] path:[_path copy] safety:_safety]; + + return request; +} + +@end + +@implementation GRPCCall2 { + GRPCCallOptions *_callOptions; + id _handler; + + GRPCCall *_call; + BOOL _initialMetadataPublished; + GRXBufferedPipe *_pipe; + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + handler:(id)handler + callOptions:(GRPCCallOptions *)callOptions { + if (!requestOptions || !requestOptions.host || !requestOptions.path) { + [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; + } + + if ((self = [super init])) { + _requestOptions = [requestOptions copy]; + _callOptions = [callOptions copy]; + _handler = handler; + _initialMetadataPublished = NO; + _pipe = [GRXBufferedPipe pipe]; + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + + return self; +} + +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + handler:(id)handler { + return [self initWithRequestOptions:requestOptions handler:handler callOptions:nil]; +} + +- (void)start { + dispatch_async(_dispatchQueue, ^{ + if (!self->_callOptions) { + self->_callOptions = [[GRPCCallOptions alloc] init]; + } + + self->_call = [[GRPCCall alloc] initWithHost:self->_requestOptions.host + path:self->_requestOptions.path + callSafety:self->_requestOptions.safety + requestsWriter:self->_pipe + callOptions:self->_callOptions]; + if (self->_callOptions.initialMetadata) { + [self->_call.requestHeaders addEntriesFromDictionary:self->_callOptions.initialMetadata]; + } + id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) { + dispatch_async(self->_dispatchQueue, ^{ + if (self->_handler) { + id handler = self->_handler; + NSDictionary *headers = nil; + if (!self->_initialMetadataPublished) { + headers = self->_call.responseHeaders; + self->_initialMetadataPublished = YES; + } + if (headers) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedInitialMetadata:headers]; + }); + } + if (value) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedMessage:value]; + }); + } + } + }); + } + completionHandler:^(NSError *errorOrNil) { + dispatch_async(self->_dispatchQueue, ^{ + if (self->_handler) { + id handler = self->_handler; + NSDictionary *headers = nil; + if (!self->_initialMetadataPublished) { + headers = self->_call.responseHeaders; + self->_initialMetadataPublished = YES; + } + if (headers) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedInitialMetadata:headers]; + }); + } + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + }); + } + }); + }]; + [self->_call startWithWriteable:responseWriteable]; + }); +} + +- (void)cancel { + dispatch_async(_dispatchQueue, ^{ + if (self->_call) { + [self->_call cancel]; + self->_call = nil; + } + if (self->_handler) { + id handler = self->_handler; + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); + self->_handler = nil; + } + }); +} + +- (void)writeWithData:(NSData *)data { + dispatch_async(_dispatchQueue, ^{ + [self->_pipe writeValue:data]; + }); +} + +- (void)finish { + dispatch_async(_dispatchQueue, ^{ + if (self->_call) { + [self->_pipe writesFinishedWithError:nil]; + } + }); +} + @end // The following methods of a C gRPC call object aren't reentrant, and thus @@ -75,6 +237,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; NSString *_host; NSString *_path; + GRPCCallSafety _callSafety; + GRPCCallOptions *_callOptions; GRPCWrappedCall *_wrappedCall; GRPCConnectivityMonitor *_connectivityMonitor; @@ -113,6 +277,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Whether the call is finished. If it is, should not call finishWithError again. BOOL _finished; + + // The OAuth2 token fetched from a token provider. + NSString *_fetchedOauth2AccessToken; } @synthesize state = _state; @@ -156,6 +323,18 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithHost:(NSString *)host path:(NSString *)path requestsWriter:(GRXWriter *)requestWriter { + return [self initWithHost:host + path:path + callSafety:GRPCCallSafetyDefault + requestsWriter:requestWriter + callOptions:nil]; +} + +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestWriter + callOptions:(GRPCCallOptions *)callOptions { if (!host || !path) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; } @@ -166,6 +345,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; if ((self = [super init])) { _host = [host copy]; _path = [path copy]; + _callSafety = safety; + _callOptions = [callOptions copy]; // Serial queue to invoke the non-reentrant methods of the grpc_call object. _callQueue = dispatch_queue_create("io.grpc.call", NULL); @@ -317,11 +498,36 @@ const char *kCFStreamVarName = "grpc_cfstream"; #pragma mark Send headers -- (void)sendHeaders:(NSDictionary *)headers { +- (void)sendHeaders { + // TODO (mxyan): Remove after deprecated methods are removed + uint32_t callSafetyFlags; + switch (_callSafety) { + case GRPCCallSafetyDefault: + callSafetyFlags = 0; + break; + case GRPCCallSafetyIdempotentRequest: + callSafetyFlags = GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; + break; + case GRPCCallSafetyCacheableRequest: + callSafetyFlags = GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; + break; + default: + [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; + } + uint32_t callFlag = callSafetyFlags; + + NSMutableDictionary *headers = _requestHeaders; + if (_fetchedOauth2AccessToken != nil) { + headers[@"authorization"] = [kBearerPrefix stringByAppendingString:_fetchedOauth2AccessToken]; + } else if (_callOptions.oauth2AccessToken != nil) { + headers[@"authorization"] = + [kBearerPrefix stringByAppendingString:_callOptions.oauth2AccessToken]; + } + // TODO(jcanizales): Add error handlers for async failures GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] initWithMetadata:headers - flags:[GRPCCall callFlagsForHost:_host path:_path] + flags:callFlag handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA if (!_unaryCall) { [_wrappedCall startBatchWithOperations:@[ op ]]; @@ -458,13 +664,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host - serverName:_serverName - path:_path - timeout:_timeout]; + _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?"); - [self sendHeaders:_requestHeaders]; + [self sendHeaders]; [self invokeCall]; // Connectivity monitor is not required for CFStream @@ -486,15 +689,43 @@ const char *kCFStreamVarName = "grpc_cfstream"; // that the life of the instance is determined by this retain cycle. _retainSelf = self; - if (self.tokenProvider != nil) { + if (_callOptions == nil) { + GRPCMutableCallOptions *callOptions; + if ([GRPCHost isHostConfigured:_host]) { + GRPCHost *hostConfig = [GRPCHost hostWithAddress:_host]; + callOptions = hostConfig.callOptions; + } else { + callOptions = [[GRPCMutableCallOptions alloc] init]; + } + if (_serverName != nil) { + callOptions.serverAuthority = _serverName; + } + if (_timeout != 0) { + callOptions.timeout = _timeout; + } + uint32_t callFlags = [GRPCCall callFlagsForHost:_host path:_path]; + if (callFlags != 0) { + if (callFlags == GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) { + _callSafety = GRPCCallSafetyIdempotentRequest; + } else if (callFlags == GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) { + _callSafety = GRPCCallSafetyCacheableRequest; + } + } + + id tokenProvider = self.tokenProvider; + if (tokenProvider != nil) { + callOptions.authTokenProvider = tokenProvider; + } + _callOptions = callOptions; + } + if (_callOptions.authTokenProvider != nil) { self.isWaitingForToken = YES; __weak typeof(self) weakSelf = self; [self.tokenProvider getTokenWithHandler:^(NSString *token) { typeof(self) strongSelf = weakSelf; if (strongSelf && strongSelf.isWaitingForToken) { if (token) { - NSString *t = [kBearerPrefix stringByAppendingString:token]; - strongSelf.requestHeaders[kAuthorizationHeader] = t; + strongSelf->_fetchedOauth2AccessToken = token; } [strongSelf startCallWithWriteable:writeable]; strongSelf.isWaitingForToken = NO; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h new file mode 100644 index 00000000000..75b320ca6d6 --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -0,0 +1,317 @@ +/* + * + * 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. + * + */ + +#import + +/** + * Safety remark of a gRPC method as defined in RFC 2616 Section 9.1 + */ +typedef NS_ENUM(NSUInteger, GRPCCallSafety) { + /** Signal that there is no guarantees on how the call affects the server state. */ + 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. */ + GRPCCallSafetyCacheableRequest = 2, +}; + +// Compression algorithm to be used by a gRPC call +typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { + GRPCCompressNone = 0, + GRPCCompressDeflate, + GRPCCompressGzip, + GRPCStreamCompressGzip, +}; + +// The transport to be used by a gRPC call +typedef NS_ENUM(NSInteger, GRPCTransportType) { + // gRPC internal HTTP/2 stack with BoringSSL + GRPCTransportTypeDefault = 0, + // Cronet stack + GRPCTransportTypeCronet, + // Insecure channel. FOR TEST ONLY! + GRPCTransportTypeInsecure, +}; + +@protocol GRPCAuthorizationProtocol +- (void)getTokenWithHandler:(void (^)(NSString *token))hander; +@end + +@interface GRPCCallOptions : NSObject + +// Call parameters +/** + * The authority for the RPC. If nil, the default authority will be used. + * + * Note: This property must be nil when Cronet transport is enabled. + * Note: This property cannot be used to validate a self-signed server certificate. It control the + * :authority header field of the call and performs an extra check that server's certificate + * matches the :authority header. + */ +@property(readonly) NSString *serverAuthority; + +/** + * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to + * positive, the gRPC call returns with status GRPCErrorCodeDeadlineExceeded if it is not completed + * within \a timeout seconds. A negative value is not allowed. + */ +@property(readonly) NSTimeInterval timeout; + +// OAuth2 parameters. Users of gRPC may specify one of the following two parameters. + +/** + * The OAuth2 access token string. The string is prefixed with "Bearer " then used as value of the + * request's "authorization" header field. This parameter should not be used simultaneously with + * \a authTokenProvider. + */ +@property(copy, readonly) NSString *oauth2AccessToken; + +/** + * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when + * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. + */ +@property(readonly) id authTokenProvider; + +/** + * Initial metadata key-value pairs that should be included in the request. + */ +@property(copy, readwrite) NSDictionary *initialMetadata; + +// Channel parameters; take into account of channel signature. + +/** + * Custom string that is prefixed to a request's user-agent header field before gRPC's internal + * user-agent string. + */ +@property(copy, readonly) NSString *userAgentPrefix; + +/** + * The size limit for the response received from server. If it is exceeded, an error with status + * code GRPCErrorCodeResourceExhausted is returned. + */ +@property(readonly) NSUInteger responseSizeLimit; + +/** + * The compression algorithm to be used by the gRPC call. For more details refer to + * https://github.com/grpc/grpc/blob/master/doc/compression.md + */ +@property(readonly) GRPCCompressAlgorithm compressAlgorithm; + +/** + * Enable/Disable gRPC call's retry feature. The default is enabled. For details of this feature + * refer to + * https://github.com/grpc/proposal/blob/master/A6-client-retries.md + */ +@property(readonly) BOOL enableRetry; + +/** + * HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two + * PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the + * call should wait for PING ACK. If PING ACK is not received after this period, the call fails. + */ +@property(readonly) NSTimeInterval keepaliveInterval; +@property(readonly) NSTimeInterval keepaliveTimeout; + +// Parameters for connection backoff. For details of gRPC's backoff behavior, refer to +// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md +@property(readonly) NSTimeInterval connectMinTimeout; +@property(readonly) NSTimeInterval connectInitialBackoff; +@property(readonly) NSTimeInterval connectMaxBackoff; + +/** + * Specify channel args to be used for this call. For a list of channel args available, see + * grpc/grpc_types.h + */ +@property(copy, readonly) NSDictionary *additionalChannelArgs; + +// Parameters for SSL authentication. + +/** + * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default + * root certificates. + */ +@property(copy, readonly) NSString *pemRootCert; + +/** + * PEM format private key for client authentication, if required by the server. + */ +@property(copy, readonly) NSString *pemPrivateKey; + +/** + * PEM format certificate chain for client authentication, if required by the server. + */ +@property(copy, readonly) NSString *pemCertChain; + +/** + * Select the transport type to be used for this call. + */ +@property(readonly) GRPCTransportType transportType; + +/** + * Override the hostname during the TLS hostname validation process. + */ +@property(copy, readonly) NSString *hostNameOverride; + +/** + * Parameter used for internal logging. + */ +@property(readonly) id logContext; + +/** + * A string that specify the domain where channel is being cached. Channels with different domains + * will not get cached to the same connection. + */ +@property(copy, readonly) NSString *channelPoolDomain; + +/** + * Channel id allows a call to force creating a new channel (connection) rather than using a cached + * channel. Calls using distinct channelId will not get cached to the same connection. + */ +@property(readonly) NSUInteger channelId; + +@end + +@interface GRPCMutableCallOptions : GRPCCallOptions + +// Call parameters +/** + * The authority for the RPC. If nil, the default authority will be used. + * + * Note: This property must be nil when Cronet transport is enabled. + * Note: This property cannot be used to validate a self-signed server certificate. It control the + * :authority header field of the call and performs an extra check that server's certificate + * matches the :authority header. + */ +@property(readwrite) NSString *serverAuthority; + +/** + * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to + * positive, the gRPC call returns with status GRPCErrorCodeDeadlineExceeded if it is not completed + * within \a timeout seconds. A negative value is not allowed. + */ +@property(readwrite) NSTimeInterval timeout; + +// OAuth2 parameters. Users of gRPC may specify one of the following two parameters. + +/** + * The OAuth2 access token string. The string is prefixed with "Bearer " then used as value of the + * request's "authorization" header field. This parameter should not be used simultaneously with + * \a authTokenProvider. + */ +@property(copy, readwrite) NSString *oauth2AccessToken; + +/** + * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when + * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. + */ +@property(readwrite) id authTokenProvider; + +// Channel parameters; take into account of channel signature. + +/** + * Custom string that is prefixed to a request's user-agent header field before gRPC's internal + * user-agent string. + */ +@property(copy, readwrite) NSString *userAgentPrefix; + +/** + * The size limit for the response received from server. If it is exceeded, an error with status + * code GRPCErrorCodeResourceExhausted is returned. + */ +@property(readwrite) NSUInteger responseSizeLimit; + +/** + * The compression algorithm to be used by the gRPC call. For more details refer to + * https://github.com/grpc/grpc/blob/master/doc/compression.md + */ +@property(readwrite) GRPCCompressAlgorithm compressAlgorithm; + +/** + * Enable/Disable gRPC call's retry feature. The default is enabled. For details of this feature + * refer to + * https://github.com/grpc/proposal/blob/master/A6-client-retries.md + */ +@property(readwrite) BOOL enableRetry; + +/** + * HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two + * PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the + * call should wait for PING ACK. If PING ACK is not received after this period, the call fails. + */ +@property(readwrite) NSTimeInterval keepaliveInterval; +@property(readwrite) NSTimeInterval keepaliveTimeout; + +// Parameters for connection backoff. For details of gRPC's backoff behavior, refer to +// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md +@property(readwrite) NSTimeInterval connectMinTimeout; +@property(readwrite) NSTimeInterval connectInitialBackoff; +@property(readwrite) NSTimeInterval connectMaxBackoff; + +/** + * Specify channel args to be used for this call. For a list of channel args available, see + * grpc/grpc_types.h + */ +@property(copy, readwrite) NSDictionary *additionalChannelArgs; + +// Parameters for SSL authentication. + +/** + * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default + * root certificates. + */ +@property(copy, readwrite) NSString *pemRootCert; + +/** + * PEM format private key for client authentication, if required by the server. + */ +@property(copy, readwrite) NSString *pemPrivateKey; + +/** + * PEM format certificate chain for client authentication, if required by the server. + */ +@property(copy, readwrite) NSString *pemCertChain; + +/** + * Select the transport type to be used for this call. + */ +@property(readwrite) GRPCTransportType transportType; + +/** + * Override the hostname during the TLS hostname validation process. + */ +@property(copy, readwrite) NSString *hostNameOverride; + +/** + * Parameter used for internal logging. + */ +@property(copy, readwrite) id logContext; + +/** + * A string that specify the domain where channel is being cached. Channels with different domains + * will not get cached to the same connection. + */ +@property(copy, readwrite) NSString *channelPoolDomain; + +/** + * Channel id allows a call to force creating a new channel (connection) rather than using a cached + * channel. Calls using distinct channelId will not get cached to the same connection. + */ +@property(readwrite) NSUInteger channelId; + +@end diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m new file mode 100644 index 00000000000..ee76c2a6420 --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -0,0 +1,431 @@ +/* + * + * 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. + * + */ + +#import "GRPCCallOptions.h" + +static NSString *const kDefaultServerAuthority = nil; +static const NSTimeInterval kDefaultTimeout = 0; +static NSDictionary *const kDefaultInitialMetadata = nil; +static NSString *const kDefaultUserAgentPrefix = nil; +static const NSUInteger kDefaultResponseSizeLimit = 0; +static const GRPCCompressAlgorithm kDefaultCompressAlgorithm = GRPCCompressNone; +static const BOOL kDefaultEnableRetry = YES; +static const NSTimeInterval kDefaultKeepaliveInterval = 0; +static const NSTimeInterval kDefaultKeepaliveTimeout = 0; +static const NSTimeInterval kDefaultConnectMinTimeout = 0; +static const NSTimeInterval kDefaultConnectInitialBackoff = 0; +static const NSTimeInterval kDefaultConnectMaxBackoff = 0; +static NSDictionary *const kDefaultAdditionalChannelArgs = nil; +static NSString *const kDefaultPemRootCert = nil; +static NSString *const kDefaultPemPrivateKey = nil; +static NSString *const kDefaultPemCertChain = nil; +static NSString *const kDefaultOauth2AccessToken = nil; +static const id kDefaultAuthTokenProvider = nil; +static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeDefault; +static NSString *const kDefaultHostNameOverride = nil; +static const id kDefaultLogContext = nil; +static NSString *kDefaultChannelPoolDomain = nil; +static NSUInteger kDefaultChannelId = 0; + +@implementation GRPCCallOptions { + @protected + NSString *_serverAuthority; + NSTimeInterval _timeout; + NSString *_oauth2AccessToken; + id _authTokenProvider; + NSDictionary *_initialMetadata; + NSString *_userAgentPrefix; + NSUInteger _responseSizeLimit; + GRPCCompressAlgorithm _compressAlgorithm; + BOOL _enableRetry; + NSTimeInterval _keepaliveInterval; + NSTimeInterval _keepaliveTimeout; + NSTimeInterval _connectMinTimeout; + NSTimeInterval _connectInitialBackoff; + NSTimeInterval _connectMaxBackoff; + NSDictionary *_additionalChannelArgs; + NSString *_pemRootCert; + NSString *_pemPrivateKey; + NSString *_pemCertChain; + GRPCTransportType _transportType; + NSString *_hostNameOverride; + id _logContext; + NSString *_channelPoolDomain; + NSUInteger _channelId; +} + +@synthesize serverAuthority = _serverAuthority; +@synthesize timeout = _timeout; +@synthesize oauth2AccessToken = _oauth2AccessToken; +@synthesize authTokenProvider = _authTokenProvider; +@synthesize initialMetadata = _initialMetadata; +@synthesize userAgentPrefix = _userAgentPrefix; +@synthesize responseSizeLimit = _responseSizeLimit; +@synthesize compressAlgorithm = _compressAlgorithm; +@synthesize enableRetry = _enableRetry; +@synthesize keepaliveInterval = _keepaliveInterval; +@synthesize keepaliveTimeout = _keepaliveTimeout; +@synthesize connectMinTimeout = _connectMinTimeout; +@synthesize connectInitialBackoff = _connectInitialBackoff; +@synthesize connectMaxBackoff = _connectMaxBackoff; +@synthesize additionalChannelArgs = _additionalChannelArgs; +@synthesize pemRootCert = _pemRootCert; +@synthesize pemPrivateKey = _pemPrivateKey; +@synthesize pemCertChain = _pemCertChain; +@synthesize transportType = _transportType; +@synthesize hostNameOverride = _hostNameOverride; +@synthesize logContext = _logContext; +@synthesize channelPoolDomain = _channelPoolDomain; +@synthesize channelId = _channelId; + +- (instancetype)init { + return [self initWithServerAuthority:kDefaultServerAuthority + timeout:kDefaultTimeout + oauth2AccessToken:kDefaultOauth2AccessToken + authTokenProvider:kDefaultAuthTokenProvider + initialMetadata:kDefaultInitialMetadata + userAgentPrefix:kDefaultUserAgentPrefix + responseSizeLimit:kDefaultResponseSizeLimit + compressAlgorithm:kDefaultCompressAlgorithm + enableRetry:kDefaultEnableRetry + keepaliveInterval:kDefaultKeepaliveInterval + keepaliveTimeout:kDefaultKeepaliveTimeout + connectMinTimeout:kDefaultConnectMinTimeout + connectInitialBackoff:kDefaultConnectInitialBackoff + connectMaxBackoff:kDefaultConnectMaxBackoff + additionalChannelArgs:kDefaultAdditionalChannelArgs + pemRootCert:kDefaultPemRootCert + pemPrivateKey:kDefaultPemPrivateKey + pemCertChain:kDefaultPemCertChain + transportType:kDefaultTransportType + hostNameOverride:kDefaultHostNameOverride + logContext:kDefaultLogContext + channelPoolDomain:kDefaultChannelPoolDomain + channelId:kDefaultChannelId]; +} + +- (instancetype)initWithServerAuthority:(NSString *)serverAuthority + timeout:(NSTimeInterval)timeout + oauth2AccessToken:(NSString *)oauth2AccessToken + authTokenProvider:(id)authTokenProvider + initialMetadata:(NSDictionary *)initialMetadata + userAgentPrefix:(NSString *)userAgentPrefix + responseSizeLimit:(NSUInteger)responseSizeLimit + compressAlgorithm:(GRPCCompressAlgorithm)compressAlgorithm + enableRetry:(BOOL)enableRetry + keepaliveInterval:(NSTimeInterval)keepaliveInterval + keepaliveTimeout:(NSTimeInterval)keepaliveTimeout + connectMinTimeout:(NSTimeInterval)connectMinTimeout + connectInitialBackoff:(NSTimeInterval)connectInitialBackoff + connectMaxBackoff:(NSTimeInterval)connectMaxBackoff + additionalChannelArgs:(NSDictionary *)additionalChannelArgs + pemRootCert:(NSString *)pemRootCert + pemPrivateKey:(NSString *)pemPrivateKey + pemCertChain:(NSString *)pemCertChain + transportType:(GRPCTransportType)transportType + hostNameOverride:(NSString *)hostNameOverride + logContext:(id)logContext + channelPoolDomain:(NSString *)channelPoolDomain + channelId:(NSUInteger)channelId { + if ((self = [super init])) { + _serverAuthority = serverAuthority; + _timeout = timeout; + _oauth2AccessToken = oauth2AccessToken; + _authTokenProvider = authTokenProvider; + _initialMetadata = initialMetadata; + _userAgentPrefix = userAgentPrefix; + _responseSizeLimit = responseSizeLimit; + _compressAlgorithm = compressAlgorithm; + _enableRetry = enableRetry; + _keepaliveInterval = keepaliveInterval; + _keepaliveTimeout = keepaliveTimeout; + _connectMinTimeout = connectMinTimeout; + _connectInitialBackoff = connectInitialBackoff; + _connectMaxBackoff = connectMaxBackoff; + _additionalChannelArgs = additionalChannelArgs; + _pemRootCert = pemRootCert; + _pemPrivateKey = pemPrivateKey; + _pemCertChain = pemCertChain; + _transportType = transportType; + _hostNameOverride = hostNameOverride; + _logContext = logContext; + _channelPoolDomain = channelPoolDomain; + _channelId = channelId; + } + return self; +} + +- (nonnull id)copyWithZone:(NSZone *)zone { + GRPCCallOptions *newOptions = + [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority + timeout:_timeout + oauth2AccessToken:_oauth2AccessToken + authTokenProvider:_authTokenProvider + initialMetadata:_initialMetadata + userAgentPrefix:_userAgentPrefix + responseSizeLimit:_responseSizeLimit + compressAlgorithm:_compressAlgorithm + enableRetry:_enableRetry + keepaliveInterval:_keepaliveInterval + keepaliveTimeout:_keepaliveTimeout + connectMinTimeout:_connectMinTimeout + connectInitialBackoff:_connectInitialBackoff + connectMaxBackoff:_connectMaxBackoff + additionalChannelArgs:[_additionalChannelArgs copy] + pemRootCert:_pemRootCert + pemPrivateKey:_pemPrivateKey + pemCertChain:_pemCertChain + transportType:_transportType + hostNameOverride:_hostNameOverride + logContext:_logContext + channelPoolDomain:_channelPoolDomain + channelId:_channelId]; + return newOptions; +} + +- (nonnull id)mutableCopyWithZone:(NSZone *)zone { + GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] + initWithServerAuthority:_serverAuthority + timeout:_timeout + oauth2AccessToken:_oauth2AccessToken + authTokenProvider:_authTokenProvider + initialMetadata:_initialMetadata + userAgentPrefix:_userAgentPrefix + responseSizeLimit:_responseSizeLimit + compressAlgorithm:_compressAlgorithm + enableRetry:_enableRetry + keepaliveInterval:_keepaliveInterval + keepaliveTimeout:_keepaliveTimeout + connectMinTimeout:_connectMinTimeout + connectInitialBackoff:_connectInitialBackoff + connectMaxBackoff:_connectMaxBackoff + additionalChannelArgs:[_additionalChannelArgs copy] + pemRootCert:_pemRootCert + pemPrivateKey:_pemPrivateKey + pemCertChain:_pemCertChain + transportType:_transportType + hostNameOverride:_hostNameOverride + logContext:_logContext + channelPoolDomain:_channelPoolDomain + channelId:_channelId]; + return newOptions; +} + +@end + +@implementation GRPCMutableCallOptions + +@dynamic serverAuthority; +@dynamic timeout; +@dynamic oauth2AccessToken; +@dynamic authTokenProvider; +@dynamic initialMetadata; +@dynamic userAgentPrefix; +@dynamic responseSizeLimit; +@dynamic compressAlgorithm; +@dynamic enableRetry; +@dynamic keepaliveInterval; +@dynamic keepaliveTimeout; +@dynamic connectMinTimeout; +@dynamic connectInitialBackoff; +@dynamic connectMaxBackoff; +@dynamic additionalChannelArgs; +@dynamic pemRootCert; +@dynamic pemPrivateKey; +@dynamic pemCertChain; +@dynamic transportType; +@dynamic hostNameOverride; +@dynamic logContext; +@dynamic channelPoolDomain; +@dynamic channelId; + +- (instancetype)init { + return [self initWithServerAuthority:kDefaultServerAuthority + timeout:kDefaultTimeout + oauth2AccessToken:kDefaultOauth2AccessToken + authTokenProvider:kDefaultAuthTokenProvider + initialMetadata:kDefaultInitialMetadata + userAgentPrefix:kDefaultUserAgentPrefix + responseSizeLimit:kDefaultResponseSizeLimit + compressAlgorithm:kDefaultCompressAlgorithm + enableRetry:kDefaultEnableRetry + keepaliveInterval:kDefaultKeepaliveInterval + keepaliveTimeout:kDefaultKeepaliveTimeout + connectMinTimeout:kDefaultConnectMinTimeout + connectInitialBackoff:kDefaultConnectInitialBackoff + connectMaxBackoff:kDefaultConnectMaxBackoff + additionalChannelArgs:kDefaultAdditionalChannelArgs + pemRootCert:kDefaultPemRootCert + pemPrivateKey:kDefaultPemPrivateKey + pemCertChain:kDefaultPemCertChain + transportType:kDefaultTransportType + hostNameOverride:kDefaultHostNameOverride + logContext:kDefaultLogContext + channelPoolDomain:kDefaultChannelPoolDomain + channelId:kDefaultChannelId]; +} + +- (nonnull id)copyWithZone:(NSZone *)zone { + GRPCCallOptions *newOptions = + [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority + timeout:_timeout + oauth2AccessToken:_oauth2AccessToken + authTokenProvider:_authTokenProvider + initialMetadata:_initialMetadata + userAgentPrefix:_userAgentPrefix + responseSizeLimit:_responseSizeLimit + compressAlgorithm:_compressAlgorithm + enableRetry:_enableRetry + keepaliveInterval:_keepaliveInterval + keepaliveTimeout:_keepaliveTimeout + connectMinTimeout:_connectMinTimeout + connectInitialBackoff:_connectInitialBackoff + connectMaxBackoff:_connectMaxBackoff + additionalChannelArgs:[_additionalChannelArgs copy] + pemRootCert:_pemRootCert + pemPrivateKey:_pemPrivateKey + pemCertChain:_pemCertChain + transportType:_transportType + hostNameOverride:_hostNameOverride + logContext:_logContext + channelPoolDomain:_channelPoolDomain + channelId:_channelId]; + return newOptions; +} + +- (nonnull id)mutableCopyWithZone:(NSZone *)zone { + GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] + initWithServerAuthority:_serverAuthority + timeout:_timeout + oauth2AccessToken:_oauth2AccessToken + authTokenProvider:_authTokenProvider + initialMetadata:_initialMetadata + userAgentPrefix:_userAgentPrefix + responseSizeLimit:_responseSizeLimit + compressAlgorithm:_compressAlgorithm + enableRetry:_enableRetry + keepaliveInterval:_keepaliveInterval + keepaliveTimeout:_keepaliveTimeout + connectMinTimeout:_connectMinTimeout + connectInitialBackoff:_connectInitialBackoff + connectMaxBackoff:_connectMaxBackoff + additionalChannelArgs:[_additionalChannelArgs copy] + pemRootCert:_pemRootCert + pemPrivateKey:_pemPrivateKey + pemCertChain:_pemCertChain + transportType:_transportType + hostNameOverride:_hostNameOverride + logContext:_logContext + channelPoolDomain:_channelPoolDomain + channelId:_channelId]; + return newOptions; +} + +- (void)setServerAuthority:(NSString *)serverAuthority { + _serverAuthority = serverAuthority; +} + +- (void)setTimeout:(NSTimeInterval)timeout { + _timeout = timeout; +} + +- (void)setOauth2AccessToken:(NSString *)oauth2AccessToken { + _oauth2AccessToken = oauth2AccessToken; +} + +- (void)setAuthTokenProvider:(id)authTokenProvider { + _authTokenProvider = authTokenProvider; +} + +- (void)setInitialMetadata:(NSDictionary *)initialMetadata { + _initialMetadata = initialMetadata; +} + +- (void)setUserAgentPrefix:(NSString *)userAgentPrefix { + _userAgentPrefix = userAgentPrefix; +} + +- (void)setResponseSizeLimit:(NSUInteger)responseSizeLimit { + _responseSizeLimit = responseSizeLimit; +} + +- (void)setCompressAlgorithm:(GRPCCompressAlgorithm)compressAlgorithm { + _compressAlgorithm = compressAlgorithm; +} + +- (void)setEnableRetry:(BOOL)enableRetry { + _enableRetry = enableRetry; +} + +- (void)setKeepaliveInterval:(NSTimeInterval)keepaliveInterval { + _keepaliveInterval = keepaliveInterval; +} + +- (void)setKeepaliveTimeout:(NSTimeInterval)keepaliveTimeout { + _keepaliveTimeout = keepaliveTimeout; +} + +- (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout { + _connectMinTimeout = connectMinTimeout; +} + +- (void)setConnectInitialBackoff:(NSTimeInterval)connectInitialBackoff { + _connectInitialBackoff = connectInitialBackoff; +} + +- (void)setConnectMaxBackoff:(NSTimeInterval)connectMaxBackoff { + _connectMaxBackoff = connectMaxBackoff; +} + +- (void)setAdditionalChannelArgs:(NSDictionary *)additionalChannelArgs { + _additionalChannelArgs = additionalChannelArgs; +} + +- (void)setPemRootCert:(NSString *)pemRootCert { + _pemRootCert = pemRootCert; +} + +- (void)setPemPrivateKey:(NSString *)pemPrivateKey { + _pemPrivateKey = pemPrivateKey; +} + +- (void)setPemCertChain:(NSString *)pemCertChain { + _pemCertChain = pemCertChain; +} + +- (void)setTransportType:(GRPCTransportType)transportType { + _transportType = transportType; +} + +- (void)setHostNameOverride:(NSString *)hostNameOverride { + _hostNameOverride = hostNameOverride; +} + +- (void)setLogContext:(id)logContext { + _logContext = logContext; +} + +- (void)setChannelPoolDomain:(NSString *)channelPoolDomain { + _channelPoolDomain = channelPoolDomain; +} + +- (void)setChannelId:(NSUInteger)channelId { + _channelId = channelId; +} + +@end From 0fd4727defda5f8bef106a1f3b59263886b9b6c6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 8 Oct 2018 15:51:39 -0700 Subject: [PATCH 004/534] deprecated old API --- .../GRPCClient/GRPCCall+ChannelArg.h | 34 +------------------ .../GRPCClient/GRPCCall+ChannelArg.m | 5 +-- .../GRPCClient/GRPCCall+ChannelCredentials.h | 10 +----- src/objective-c/GRPCClient/GRPCCall+Cronet.h | 13 +------ src/objective-c/GRPCClient/GRPCCall+OAuth2.h | 29 +++------------- src/objective-c/GRPCClient/GRPCCall+Tests.h | 25 ++------------ src/objective-c/GRPCClient/GRPCCall+Tests.m | 4 ++- 7 files changed, 15 insertions(+), 105 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h index 803f19dedfe..2ddd53a5c66 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h @@ -19,52 +19,20 @@ #include -typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { - GRPCCompressNone, - GRPCCompressDeflate, - GRPCCompressGzip, -}; - -/** - * Methods to configure GRPC channel options. - */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (ChannelArg) -/** - * Use the provided @c userAgentPrefix at the beginning of the HTTP User Agent string for all calls - * to the specified @c host. - */ + (void)setUserAgentPrefix:(nonnull NSString *)userAgentPrefix forHost:(nonnull NSString *)host; - -/** 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, " "and might be removed or modified at any " "time."); - + (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 - * check if the transport is still alive. After waiting for \a timeout ms, if the client does not - * receive the ping ack, it closes the transport; all pending calls to this host will fail with - * error GRPC_STATUS_INTERNAL with error information "keepalive watchdog timeout". */ + (void)setKeepaliveWithInterval:(int)interval timeout:(int)timeout forHost:(nonnull NSString *)host; - -/** Enable/Disable automatic retry of gRPC calls on the channel. If automatic retry is enabled, the - * retry is controlled by server's service config. If automatic retry is disabled, failed calls are - * immediately returned to the application layer. */ + (void)enableRetry:(BOOL)enabled forHost:(nonnull NSString *)host; - -/** Set channel connection timeout and backoff parameters. All parameters are positive integers in - * milliseconds. Set a parameter to 0 to make gRPC use default value for that parameter. - * - * Refer to gRPC's doc at https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md for the - * details of each parameter. */ + (void)setMinConnectTimeout:(unsigned int)timeout initialBackoff:(unsigned int)initialBackoff maxBackoff:(unsigned int)maxBackoff diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index 0e631fb3adf..d01d0c0d4fd 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -18,6 +18,7 @@ #import "GRPCCall+ChannelArg.h" +#import "private/GRPCChannel.h" #import "private/GRPCHost.h" #import @@ -31,11 +32,11 @@ + (void)setResponseSizeLimit:(NSUInteger)limit forHost:(nonnull NSString *)host { GRPCHost *hostConfig = [GRPCHost hostWithAddress:host]; - hostConfig.responseSizeLimitOverride = @(limit); + hostConfig.responseSizeLimitOverride = limit; } + (void)closeOpenConnections { - [GRPCHost flushChannelCache]; + [GRPCChannel closeOpenConnections]; } + (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host { diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h b/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h index d7d15c4ee38..7d6f79b7655 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h @@ -18,20 +18,12 @@ #import "GRPCCall.h" -/** Helpers for setting TLS Trusted Roots, Client Certificates, and Private Key */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (ChannelCredentials) -/** - * Use the provided @c pemRootCert as the set of trusted root Certificate Authorities for @c host. - */ + (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCert forHost:(nonnull NSString *)host error:(NSError *_Nullable *_Nullable)errorPtr; -/** - * Configures @c host with TLS/SSL Client Credentials and optionally trusted root Certificate - * Authorities. If @c pemRootCerts is nil, the default CA Certificates bundled with gRPC will be - * used. - */ + (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCerts withPrivateKey:(nullable NSString *)pemPrivateKey withCertChain:(nullable NSString *)pemCertChain diff --git a/src/objective-c/GRPCClient/GRPCCall+Cronet.h b/src/objective-c/GRPCClient/GRPCCall+Cronet.h index 2a5f6e9cf0e..3059c6f1860 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Cronet.h +++ b/src/objective-c/GRPCClient/GRPCCall+Cronet.h @@ -20,22 +20,11 @@ #import "GRPCCall.h" -/** - * Methods for using cronet transport. - */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (Cronet) -/** - * This method should be called before issuing the first RPC. It should be - * called only once. Create an instance of Cronet engine in your app elsewhere - * and pass the instance pointer in the stream_engine parameter. Once set, - * all subsequent RPCs will use Cronet transport. The method is not thread - * safe. - */ + (void)useCronetWithEngine:(stream_engine*)engine; - + (stream_engine*)cronetEngine; - + (BOOL)isUsingCronet; @end diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h index adb1042aa0e..3054bfc5a7a 100644 --- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h +++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h @@ -18,34 +18,13 @@ #import "GRPCCall.h" -/** - * The protocol of an OAuth2 token object from which GRPCCall can acquire a token. - */ -@protocol GRPCAuthorizationProtocol -- (void)getTokenWithHandler:(void (^)(NSString *token))hander; -@end +#import "GRPCCallOptions.h" -/** Helpers for setting and reading headers compatible with OAuth2. */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (OAuth2) -/** - * Setting this property is equivalent to setting "Bearer " as the value of the - * request header with key "authorization" (the authorization header). Setting it to nil removes the - * authorization header from the request. - * The value obtained by getting the property is the OAuth2 bearer token if the authorization header - * of the request has the form "Bearer ", or nil otherwise. - */ -@property(atomic, copy) NSString *oauth2AccessToken; - -/** Returns the value (if any) of the "www-authenticate" response header (the challenge header). */ -@property(atomic, readonly) NSString *oauth2ChallengeHeader; - -/** - * The authorization token object to be used when starting the call. If the value is set to nil, no - * oauth authentication will be used. - * - * If tokenProvider exists, it takes precedence over the token set by oauth2AccessToken. - */ +@property(atomic, copy) NSString* oauth2AccessToken; +@property(atomic, readonly) NSString* oauth2ChallengeHeader; @property(atomic, strong) id tokenProvider; @end diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.h b/src/objective-c/GRPCClient/GRPCCall+Tests.h index 5d35182ae52..edaa5ed582c 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Tests.h +++ b/src/objective-c/GRPCClient/GRPCCall+Tests.h @@ -18,34 +18,13 @@ #import "GRPCCall.h" -/** - * Methods to let tune down the security of gRPC connections for specific hosts. These shouldn't be - * used in releases, but are sometimes needed for testing. - */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (Tests) -/** - * Establish all SSL connections to the provided host using the passed SSL target name and the root - * certificates found in the file at |certsPath|. - * - * Must be called before any gRPC call to that host is made. It's illegal to pass the same host to - * more than one invocation of the methods of this category. - */ + (void)useTestCertsPath:(NSString *)certsPath testName:(NSString *)testName forHost:(NSString *)host; - -/** - * Establish all connections to the provided host using cleartext instead of SSL. - * - * Must be called before any gRPC call to that host is made. It's illegal to pass the same host to - * more than one invocation of the methods of this category. - */ + (void)useInsecureConnectionsForHost:(NSString *)host; - -/** - * Resets all host configurations to their default values, and flushes all connections from the - * cache. - */ + (void)resetHostSettings; + @end diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.m b/src/objective-c/GRPCClient/GRPCCall+Tests.m index 0db3ad6b399..ac3b6a658f9 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Tests.m +++ b/src/objective-c/GRPCClient/GRPCCall+Tests.m @@ -20,6 +20,8 @@ #import "private/GRPCHost.h" +#import "GRPCCallOptions.h" + @implementation GRPCCall (Tests) + (void)useTestCertsPath:(NSString *)certsPath @@ -42,7 +44,7 @@ + (void)useInsecureConnectionsForHost:(NSString *)host { GRPCHost *hostConfig = [GRPCHost hostWithAddress:host]; - hostConfig.secure = NO; + hostConfig.transportType = GRPCTransportTypeInsecure; } + (void)resetHostSettings { From 309ba191525a96c5314e5762ecaa2fffbc9eccbb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 8 Oct 2018 15:52:27 -0700 Subject: [PATCH 005/534] Channel pool --- .../GRPCClient/private/ChannelArgsUtil.h | 25 ++ .../GRPCClient/private/ChannelArgsUtil.m | 95 +++++ .../GRPCClient/private/GRPCChannel.h | 43 +- .../GRPCClient/private/GRPCChannel.m | 242 ++++------- .../GRPCClient/private/GRPCChannelFactory.h | 32 ++ .../GRPCClient/private/GRPCChannelPool.h | 69 ++++ .../GRPCClient/private/GRPCChannelPool.m | 387 ++++++++++++++++++ .../private/GRPCCronetChannelFactory.h | 36 ++ .../private/GRPCCronetChannelFactory.m | 94 +++++ src/objective-c/GRPCClient/private/GRPCHost.h | 31 +- src/objective-c/GRPCClient/private/GRPCHost.m | 261 ++---------- .../private/GRPCInsecureChannelFactory.h | 35 ++ .../private/GRPCInsecureChannelFactory.m | 48 +++ .../private/GRPCSecureChannelFactory.h | 38 ++ .../private/GRPCSecureChannelFactory.m | 129 ++++++ .../GRPCClient/private/GRPCWrappedCall.h | 3 +- .../GRPCClient/private/GRPCWrappedCall.m | 18 +- 17 files changed, 1138 insertions(+), 448 deletions(-) create mode 100644 src/objective-c/GRPCClient/private/ChannelArgsUtil.h create mode 100644 src/objective-c/GRPCClient/private/ChannelArgsUtil.m create mode 100644 src/objective-c/GRPCClient/private/GRPCChannelFactory.h create mode 100644 src/objective-c/GRPCClient/private/GRPCChannelPool.h create mode 100644 src/objective-c/GRPCClient/private/GRPCChannelPool.m create mode 100644 src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h create mode 100644 src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m create mode 100644 src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h create mode 100644 src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m create mode 100644 src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h create mode 100644 src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h new file mode 100644 index 00000000000..d9d6933c6bb --- /dev/null +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h @@ -0,0 +1,25 @@ +/* + * + * 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. + * + */ + +#import + +#include + +void FreeChannelArgs(grpc_channel_args* channel_args); + +grpc_channel_args* BuildChannelArgs(NSDictionary* dictionary); diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m new file mode 100644 index 00000000000..8ebf3a26593 --- /dev/null +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -0,0 +1,95 @@ +/* + * + * 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. + * + */ + +#import "ChannelArgsUtil.h" + +#include +#include + +static void *copy_pointer_arg(void *p) { + // Add ref count to the object when making copy + id obj = (__bridge id)p; + return (__bridge_retained void *)obj; +} + +static void destroy_pointer_arg(void *p) { + // Decrease ref count to the object when destroying + CFRelease((CFTreeRef)p); +} + +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}; + +void FreeChannelArgs(grpc_channel_args *channel_args) { + for (size_t i = 0; i < channel_args->num_args; ++i) { + grpc_arg *arg = &channel_args->args[i]; + gpr_free(arg->key); + if (arg->type == GRPC_ARG_STRING) { + gpr_free(arg->value.string); + } + } + gpr_free(channel_args->args); + gpr_free(channel_args); +} + +/** + * Allocates a @c grpc_channel_args and populates it with the options specified in the + * @c dictionary. Keys must be @c NSString. If the value responds to @c @selector(UTF8String) then + * it will be mapped to @c GRPC_ARG_STRING. If not, it will be mapped to @c GRPC_ARG_INTEGER if the + * value responds to @c @selector(intValue). Otherwise, an exception will be raised. The caller of + * this function is responsible for calling @c freeChannelArgs on a non-NULL returned value. + */ +grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { + if (!dictionary) { + return NULL; + } + + NSArray *keys = [dictionary allKeys]; + NSUInteger argCount = [keys count]; + + grpc_channel_args *channelArgs = gpr_malloc(sizeof(grpc_channel_args)); + channelArgs->num_args = argCount; + channelArgs->args = gpr_malloc(argCount * sizeof(grpc_arg)); + + // TODO(kriswuollett) Check that keys adhere to GRPC core library requirements + + for (NSUInteger i = 0; i < argCount; ++i) { + grpc_arg *arg = &channelArgs->args[i]; + arg->key = gpr_strdup([keys[i] UTF8String]); + + id value = dictionary[keys[i]]; + if ([value respondsToSelector:@selector(UTF8String)]) { + arg->type = GRPC_ARG_STRING; + arg->value.string = gpr_strdup([value UTF8String]); + } else if ([value respondsToSelector:@selector(intValue)]) { + arg->type = GRPC_ARG_INTEGER; + arg->value.integer = [value intValue]; + } else if (value != nil) { + arg->type = GRPC_ARG_POINTER; + arg->value.pointer.p = (__bridge_retained void *)value; + arg->value.pointer.vtable = &objc_arg_vtable; + } else { + [NSException raise:NSInvalidArgumentException + format:@"Invalid value type: %@", [value class]]; + } + } + + return channelArgs; +} diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 6499d4398c8..7d5039a8a20 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -21,6 +21,8 @@ #include @class GRPCCompletionQueue; +@class GRPCCallOptions; +@class GRPCChannelConfiguration; struct grpc_channel_credentials; /** @@ -28,41 +30,30 @@ struct grpc_channel_credentials; */ @interface GRPCChannel : NSObject -@property(nonatomic, readonly, nonnull) struct grpc_channel *unmanagedChannel; - - (nullable instancetype)init NS_UNAVAILABLE; /** - * Creates a secure channel to the specified @c host using default credentials and channel - * arguments. If certificates could not be found to create a secure channel, then @c nil is - * returned. + * Returns a channel connecting to \a host with options as \a callOptions. The channel may be new + * or a cached channel that is already connected. */ -+ (nullable GRPCChannel *)secureChannelWithHost:(nonnull NSString *)host; ++ (nullable instancetype)channelWithHost:(nonnull NSString *)host + callOptions:(nullable GRPCCallOptions *)callOptions; /** - * Creates a secure channel to the specified @c host using Cronet as a transport mechanism. - */ -#ifdef GRPC_COMPILE_WITH_CRONET -+ (nullable GRPCChannel *)secureCronetChannelWithHost:(nonnull NSString *)host - channelArgs:(nonnull NSDictionary *)channelArgs; -#endif -/** - * Creates a secure channel to the specified @c host using the specified @c credentials and - * @c channelArgs. Only in tests should @c GRPC_SSL_TARGET_NAME_OVERRIDE_ARG channel arg be set. + * Get a grpc core call object from this channel. */ -+ (nonnull GRPCChannel *)secureChannelWithHost:(nonnull NSString *)host - credentials: - (nonnull struct grpc_channel_credentials *)credentials - channelArgs:(nullable NSDictionary *)channelArgs; +- (nullable grpc_call *)unmanagedCallWithPath:(nonnull NSString *)path + completionQueue:(nonnull GRPCCompletionQueue *)queue + callOptions:(nonnull GRPCCallOptions *)callOptions; + +- (void)unmanagedCallUnref; /** - * Creates an insecure channel to the specified @c host using the specified @c channelArgs. + * Create a channel object with the signature \a config. This function is used for testing only. Use + * channelWithHost:callOptions: in production. */ -+ (nonnull GRPCChannel *)insecureChannelWithHost:(nonnull NSString *)host - channelArgs:(nullable NSDictionary *)channelArgs; ++ (nullable instancetype)createChannelWithConfiguration:(nonnull GRPCChannelConfiguration *)config; -- (nullable grpc_call *)unmanagedCallWithPath:(nonnull NSString *)path - serverName:(nonnull NSString *)serverName - timeout:(NSTimeInterval)timeout - completionQueue:(nonnull GRPCCompletionQueue *)queue; +// TODO (mxyan): deprecate with GRPCCall:closeOpenConnections ++ (void)closeOpenConnections; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index b1f6ea270ef..cf44b96e220 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -18,206 +18,106 @@ #import "GRPCChannel.h" -#include -#ifdef GRPC_COMPILE_WITH_CRONET -#include -#endif -#include #include -#include -#ifdef GRPC_COMPILE_WITH_CRONET -#import -#import -#endif +#import "ChannelArgsUtil.h" +#import "GRPCChannelFactory.h" +#import "GRPCChannelPool.h" #import "GRPCCompletionQueue.h" +#import "GRPCConnectivityMonitor.h" +#import "GRPCCronetChannelFactory.h" +#import "GRPCInsecureChannelFactory.h" +#import "GRPCSecureChannelFactory.h" +#import "version.h" -static void *copy_pointer_arg(void *p) { - // Add ref count to the object when making copy - id obj = (__bridge id)p; - return (__bridge_retained void *)obj; -} - -static void destroy_pointer_arg(void *p) { - // Decrease ref count to the object when destroying - CFRelease((CFTreeRef)p); -} - -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 void FreeChannelArgs(grpc_channel_args *channel_args) { - for (size_t i = 0; i < channel_args->num_args; ++i) { - grpc_arg *arg = &channel_args->args[i]; - gpr_free(arg->key); - if (arg->type == GRPC_ARG_STRING) { - gpr_free(arg->value.string); - } - } - gpr_free(channel_args->args); - gpr_free(channel_args); -} - -/** - * Allocates a @c grpc_channel_args and populates it with the options specified in the - * @c dictionary. Keys must be @c NSString. If the value responds to @c @selector(UTF8String) then - * it will be mapped to @c GRPC_ARG_STRING. If not, it will be mapped to @c GRPC_ARG_INTEGER if the - * value responds to @c @selector(intValue). Otherwise, an exception will be raised. The caller of - * this function is responsible for calling @c freeChannelArgs on a non-NULL returned value. - */ -static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { - if (!dictionary) { - return NULL; - } - - NSArray *keys = [dictionary allKeys]; - NSUInteger argCount = [keys count]; - - grpc_channel_args *channelArgs = gpr_malloc(sizeof(grpc_channel_args)); - channelArgs->num_args = argCount; - channelArgs->args = gpr_malloc(argCount * sizeof(grpc_arg)); - - // TODO(kriswuollett) Check that keys adhere to GRPC core library requirements - - for (NSUInteger i = 0; i < argCount; ++i) { - grpc_arg *arg = &channelArgs->args[i]; - arg->key = gpr_strdup([keys[i] UTF8String]); - - id value = dictionary[keys[i]]; - if ([value respondsToSelector:@selector(UTF8String)]) { - arg->type = GRPC_ARG_STRING; - arg->value.string = gpr_strdup([value UTF8String]); - } else if ([value respondsToSelector:@selector(intValue)]) { - arg->type = GRPC_ARG_INTEGER; - arg->value.integer = [value intValue]; - } else if (value != nil) { - arg->type = GRPC_ARG_POINTER; - arg->value.pointer.p = (__bridge_retained void *)value; - arg->value.pointer.vtable = &objc_arg_vtable; - } else { - [NSException raise:NSInvalidArgumentException - format:@"Invalid value type: %@", [value class]]; - } - } - - return channelArgs; -} +#import +#import @implementation GRPCChannel { - // Retain arguments to channel_create because they may not be used on the thread that invoked - // the channel_create function. - NSString *_host; - grpc_channel_args *_channelArgs; + GRPCChannelConfiguration *_configuration; + grpc_channel *_unmanagedChannel; } -#ifdef GRPC_COMPILE_WITH_CRONET -- (instancetype)initWithHost:(NSString *)host - cronetEngine:(stream_engine *)cronetEngine - channelArgs:(NSDictionary *)channelArgs { - if (!host) { - [NSException raise:NSInvalidArgumentException format:@"host argument missing"]; +- (grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(nonnull GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions { + NSString *serverAuthority = callOptions.serverAuthority; + NSTimeInterval timeout = callOptions.timeout; + GPR_ASSERT(timeout >= 0); + grpc_slice host_slice = grpc_empty_slice(); + if (serverAuthority) { + host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); } - - if (self = [super init]) { - _channelArgs = BuildChannelArgs(channelArgs); - _host = [host copy]; - _unmanagedChannel = - grpc_cronet_secure_channel_create(cronetEngine, _host.UTF8String, _channelArgs, NULL); + 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_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, + serverAuthority ? &host_slice : NULL, deadline_ms, NULL); + if (serverAuthority) { + grpc_slice_unref(host_slice); } - - return self; + grpc_slice_unref(path_slice); + return call; } -#endif - -- (instancetype)initWithHost:(NSString *)host - secure:(BOOL)secure - credentials:(struct grpc_channel_credentials *)credentials - channelArgs:(NSDictionary *)channelArgs { - if (!host) { - [NSException raise:NSInvalidArgumentException format:@"host argument missing"]; - } - if (secure && !credentials) { - return nil; - } +- (void)unmanagedCallUnref { + [kChannelPool unrefChannelWithConfiguration:_configuration]; +} - if (self = [super init]) { - _channelArgs = BuildChannelArgs(channelArgs); - _host = [host copy]; - if (secure) { - _unmanagedChannel = - grpc_secure_channel_create(credentials, _host.UTF8String, _channelArgs, NULL); - } else { - _unmanagedChannel = grpc_insecure_channel_create(_host.UTF8String, _channelArgs, NULL); - } +- (nullable instancetype)initWithUnmanagedChannel:(nullable grpc_channel *)unmanagedChannel + configuration:(GRPCChannelConfiguration *)configuration { + if ((self = [super init])) { + _unmanagedChannel = unmanagedChannel; + _configuration = configuration; } - return self; } - (void)dealloc { - // TODO(jcanizales): Be sure to add a test with a server that closes the connection prematurely, - // as in the past that made this call to crash. grpc_channel_destroy(_unmanagedChannel); - FreeChannelArgs(_channelArgs); } -#ifdef GRPC_COMPILE_WITH_CRONET -+ (GRPCChannel *)secureCronetChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)channelArgs { - stream_engine *engine = [GRPCCall cronetEngine]; - if (!engine) { - [NSException raise:NSInvalidArgumentException format:@"cronet_engine is NULL. Set it first."]; ++ (nullable instancetype)createChannelWithConfiguration:(GRPCChannelConfiguration *)config { + NSString *host = config.host; + if (host == nil || [host length] == 0) { return nil; } - return [[GRPCChannel alloc] initWithHost:host cronetEngine:engine channelArgs:channelArgs]; -} -#endif -+ (GRPCChannel *)secureChannelWithHost:(NSString *)host { - return [[GRPCChannel alloc] initWithHost:host secure:YES credentials:NULL channelArgs:NULL]; + NSMutableDictionary *channelArgs = config.channelArgs; + [channelArgs addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; + id factory = config.channelFactory; + grpc_channel *unmanaged_channel = [factory createChannelWithHost:host channelArgs:channelArgs]; + return [[GRPCChannel alloc] initWithUnmanagedChannel:unmanaged_channel configuration:config]; } -+ (GRPCChannel *)secureChannelWithHost:(NSString *)host - credentials:(struct grpc_channel_credentials *)credentials - channelArgs:(NSDictionary *)channelArgs { - return [[GRPCChannel alloc] initWithHost:host - secure:YES - credentials:credentials - channelArgs:channelArgs]; -} +static dispatch_once_t initChannelPool; +static GRPCChannelPool *kChannelPool; -+ (GRPCChannel *)insecureChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)channelArgs { - return [[GRPCChannel alloc] initWithHost:host secure:NO credentials:NULL channelArgs:channelArgs]; -} ++ (nullable instancetype)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions { + dispatch_once(&initChannelPool, ^{ + kChannelPool = [[GRPCChannelPool alloc] init]; + }); -- (grpc_call *)unmanagedCallWithPath:(NSString *)path - serverName:(NSString *)serverName - timeout:(NSTimeInterval)timeout - completionQueue:(GRPCCompletionQueue *)queue { - GPR_ASSERT(timeout >= 0); - if (timeout < 0) { - timeout = 0; + NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:host]]; + if (hostURL.host && !hostURL.port) { + host = [hostURL.host stringByAppendingString:@":443"]; } - grpc_slice host_slice = grpc_empty_slice(); - if (serverName) { - 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_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); - if (serverName) { - grpc_slice_unref(host_slice); - } - grpc_slice_unref(path_slice); - return call; + + GRPCChannelConfiguration *channelConfig = + [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; + return [kChannelPool channelWithConfiguration:channelConfig + createChannel:^{ + return + [GRPCChannel createChannelWithConfiguration:channelConfig]; + }]; +} + ++ (void)closeOpenConnections { + [kChannelPool clear]; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h new file mode 100644 index 00000000000..e44f8260dfd --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -0,0 +1,32 @@ +/* + * + * 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. + * + */ + +#import + +#include + +NS_ASSUME_NONNULL_BEGIN + +@protocol GRPCChannelFactory + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableDictionary *)args; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h new file mode 100644 index 00000000000..1145039549c --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -0,0 +1,69 @@ +/* + * + * 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. + * + */ + +/** + * Signature for the channel. If two channel's signatures are the same, they share the same + * underlying \a GRPCChannel object. + */ + +#import + +#import "GRPCChannelFactory.h" + +NS_ASSUME_NONNULL_BEGIN + +@class GRPCChannel; + +@interface GRPCChannelConfiguration : NSObject + +@property(atomic, strong, readwrite) NSString *host; +@property(atomic, strong, readwrite) GRPCCallOptions *callOptions; + +@property(readonly) id channelFactory; +@property(readonly) NSMutableDictionary *channelArgs; + +- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; + +@end + +/** + * Manage the pool of connected channels. When a channel is no longer referenced by any call, + * destroy the channel after a certain period of time elapsed. + */ +@interface GRPCChannelPool : NSObject + +- (instancetype)init; + +- (instancetype)initWithChannelDestroyDelay:(NSTimeInterval)channelDestroyDelay; + +/** + * Return a channel with a particular configuration. If the channel does not exist, execute \a + * createChannel then add it in the pool. If the channel exists, increase its reference count. + */ +- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration + createChannel:(GRPCChannel * (^)(void))createChannel; + +/** Decrease a channel's refcount. */ +- (void)unrefChannelWithConfiguration:configuration; + +/** Clear all channels in the pool. */ +- (void)clear; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m new file mode 100644 index 00000000000..b5f0949ef73 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -0,0 +1,387 @@ +/* + * + * Copyright 2015 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 "GRPCChannelFactory.h" +#import "GRPCChannelPool.h" +#import "GRPCConnectivityMonitor.h" +#import "GRPCCronetChannelFactory.h" +#import "GRPCInsecureChannelFactory.h" +#import "GRPCSecureChannelFactory.h" +#import "version.h" + +#import +#include + +extern const char *kCFStreamVarName; + +// When all calls of a channel are destroyed, destroy the channel after this much seconds. +const NSTimeInterval kChannelDestroyDelay = 30; + +@implementation GRPCChannelConfiguration + +- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { + if ((self = [super init])) { + _host = host; + _callOptions = callOptions; + } + return self; +} + +- (id)channelFactory { + NSError *error; + id factory; + GRPCTransportType type = _callOptions.transportType; + switch (type) { + case GRPCTransportTypeDefault: + // TODO (mxyan): Remove when the API is deprecated +#ifdef GRPC_COMPILE_WITH_CRONET + if (![GRPCCall isUsingCronet]) { +#endif + factory = [GRPCSecureChannelFactory factoryWithPEMRootCerts:_callOptions.pemRootCert + privateKey:_callOptions.pemPrivateKey + certChain:_callOptions.pemCertChain + error:&error]; + if (error) { + NSLog(@"Error creating secure channel factory: %@", error); + return nil; + } + return factory; +#ifdef GRPC_COMPILE_WITH_CRONET + } +#endif + // fallthrough + case GRPCTransportTypeCronet: + return [GRPCCronetChannelFactory sharedInstance]; + case GRPCTransportTypeInsecure: + return [GRPCInsecureChannelFactory sharedInstance]; + default: + GPR_UNREACHABLE_CODE(return nil); + } +} + +- (NSMutableDictionary *)channelArgs { + NSMutableDictionary *args = [NSMutableDictionary new]; + + NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; + NSString *userAgentPrefix = _callOptions.userAgentPrefix; + if (userAgentPrefix) { + args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = + [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; + } else { + args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = userAgent; + } + + NSString *hostNameOverride = _callOptions.hostNameOverride; + if (hostNameOverride) { + args[@GRPC_SSL_TARGET_NAME_OVERRIDE_ARG] = hostNameOverride; + } + + if (_callOptions.responseSizeLimit) { + args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = + [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; + } + + if (_callOptions.compressAlgorithm != GRPC_COMPRESS_NONE) { + args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = + [NSNumber numberWithInt:_callOptions.compressAlgorithm]; + } + + if (_callOptions.keepaliveInterval != 0) { + args[@GRPC_ARG_KEEPALIVE_TIME_MS] = + [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.keepaliveInterval * 1000)]; + args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = + [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.keepaliveTimeout * 1000)]; + } + + if (_callOptions.enableRetry == NO) { + args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.enableRetry]; + } + + if (_callOptions.connectMinTimeout > 0) { + args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = + [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.connectMinTimeout * 1000)]; + } + if (_callOptions.connectInitialBackoff > 0) { + args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber + numberWithUnsignedInteger:(unsigned int)(_callOptions.connectInitialBackoff * 1000)]; + } + if (_callOptions.connectMaxBackoff > 0) { + args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = + [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.connectMaxBackoff * 1000)]; + } + + if (_callOptions.logContext != nil) { + args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = _callOptions.logContext; + } + + if (_callOptions.channelPoolDomain != nil) { + args[@GRPC_ARG_CHANNEL_POOL_DOMAIN] = _callOptions.channelPoolDomain; + } + + [args addEntriesFromDictionary:_callOptions.additionalChannelArgs]; + + return args; +} + +- (nonnull id)copyWithZone:(nullable NSZone *)zone { + GRPCChannelConfiguration *newConfig = [[GRPCChannelConfiguration alloc] init]; + newConfig.host = _host; + newConfig.callOptions = _callOptions; + + return newConfig; +} + +- (BOOL)isEqual:(id)object { + NSAssert([object isKindOfClass:[GRPCChannelConfiguration class]], @"Illegal :isEqual"); + GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; + if (!(obj.host == _host || [obj.host isEqualToString:_host])) return NO; + if (!(obj.callOptions.userAgentPrefix == _callOptions.userAgentPrefix || + [obj.callOptions.userAgentPrefix isEqualToString:_callOptions.userAgentPrefix])) + return NO; + if (!(obj.callOptions.responseSizeLimit == _callOptions.responseSizeLimit)) return NO; + if (!(obj.callOptions.compressAlgorithm == _callOptions.compressAlgorithm)) return NO; + if (!(obj.callOptions.enableRetry == _callOptions.enableRetry)) return NO; + if (!(obj.callOptions.keepaliveInterval == _callOptions.keepaliveInterval)) return NO; + if (!(obj.callOptions.keepaliveTimeout == _callOptions.keepaliveTimeout)) return NO; + if (!(obj.callOptions.connectMinTimeout == _callOptions.connectMinTimeout)) return NO; + if (!(obj.callOptions.connectInitialBackoff == _callOptions.connectInitialBackoff)) return NO; + if (!(obj.callOptions.connectMaxBackoff == _callOptions.connectMaxBackoff)) return NO; + if (!(obj.callOptions.additionalChannelArgs == _callOptions.additionalChannelArgs || + [obj.callOptions.additionalChannelArgs + isEqualToDictionary:_callOptions.additionalChannelArgs])) + return NO; + if (!(obj.callOptions.pemRootCert == _callOptions.pemRootCert || + [obj.callOptions.pemRootCert isEqualToString:_callOptions.pemRootCert])) + return NO; + if (!(obj.callOptions.pemPrivateKey == _callOptions.pemPrivateKey || + [obj.callOptions.pemPrivateKey isEqualToString:_callOptions.pemPrivateKey])) + return NO; + if (!(obj.callOptions.pemCertChain == _callOptions.pemCertChain || + [obj.callOptions.pemCertChain isEqualToString:_callOptions.pemCertChain])) + return NO; + if (!(obj.callOptions.hostNameOverride == _callOptions.hostNameOverride || + [obj.callOptions.hostNameOverride isEqualToString:_callOptions.hostNameOverride])) + return NO; + if (!(obj.callOptions.transportType == _callOptions.transportType)) return NO; + if (!(obj.callOptions.logContext == _callOptions.logContext || + [obj.callOptions.logContext isEqual:_callOptions.logContext])) + return NO; + if (!(obj.callOptions.channelPoolDomain == _callOptions.channelPoolDomain || + [obj.callOptions.channelPoolDomain isEqualToString:_callOptions.channelPoolDomain])) + return NO; + if (!(obj.callOptions.channelId == _callOptions.channelId)) return NO; + + return YES; +} + +- (NSUInteger)hash { + NSUInteger result = 0; + result ^= _host.hash; + result ^= _callOptions.userAgentPrefix.hash; + result ^= _callOptions.responseSizeLimit; + result ^= _callOptions.compressAlgorithm; + result ^= _callOptions.enableRetry; + result ^= (unsigned int)(_callOptions.keepaliveInterval * 1000); + result ^= (unsigned int)(_callOptions.keepaliveTimeout * 1000); + result ^= (unsigned int)(_callOptions.connectMinTimeout * 1000); + result ^= (unsigned int)(_callOptions.connectInitialBackoff * 1000); + result ^= (unsigned int)(_callOptions.connectMaxBackoff * 1000); + result ^= _callOptions.additionalChannelArgs.hash; + result ^= _callOptions.pemRootCert.hash; + result ^= _callOptions.pemPrivateKey.hash; + result ^= _callOptions.pemCertChain.hash; + result ^= _callOptions.hostNameOverride.hash; + result ^= _callOptions.transportType; + result ^= [_callOptions.logContext hash]; + result ^= _callOptions.channelPoolDomain.hash; + result ^= _callOptions.channelId; + + return result; +} + +@end + +/** + * Time the channel destroy when the channel's calls are unreffed. If there's new call, reset the + * timer. + */ +@interface GRPCChannelCallRef : NSObject + +- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)configuration + destroyDelay:(NSTimeInterval)destroyDelay + dispatchQueue:(dispatch_queue_t)dispatchQueue + destroyChannel:(void (^)())destroyChannel; + +/** Add call ref count to the channel and maybe reset the timer. */ +- (void)refChannel; + +/** Reduce call ref count to the channel and maybe set the timer. */ +- (void)unrefChannel; + +@end + +@implementation GRPCChannelCallRef { + GRPCChannelConfiguration *_configuration; + NSTimeInterval _destroyDelay; + // We use dispatch queue for this purpose since timer invalidation must happen on the same + // thread which issued the timer. + dispatch_queue_t _dispatchQueue; + void (^_destroyChannel)(); + + NSUInteger _refCount; + NSTimer *_timer; +} + +- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)configuration + destroyDelay:(NSTimeInterval)destroyDelay + dispatchQueue:(dispatch_queue_t)dispatchQueue + destroyChannel:(void (^)())destroyChannel { + if ((self = [super init])) { + _configuration = configuration; + _destroyDelay = destroyDelay; + _dispatchQueue = dispatchQueue; + _destroyChannel = destroyChannel; + + _refCount = 0; + _timer = nil; + } + return self; +} + +// This function is protected by channel pool dispatch queue. +- (void)refChannel { + _refCount++; + if (_timer) { + [_timer invalidate]; + } + _timer = nil; +} + +// This function is protected by channel spool dispatch queue. +- (void)unrefChannel { + self->_refCount--; + if (self->_refCount == 0) { + if (self->_timer) { + [self->_timer invalidate]; + } + self->_timer = [NSTimer scheduledTimerWithTimeInterval:self->_destroyDelay + target:self + selector:@selector(timerFire:) + userInfo:nil + repeats:NO]; + } +} + +- (void)timerFire:(NSTimer *)timer { + dispatch_sync(_dispatchQueue, ^{ + if (self->_timer == nil || self->_timer != timer) { + return; + } + self->_timer = nil; + self->_destroyChannel(self->_configuration); + }); +} + +@end + +#pragma mark GRPCChannelPool + +@implementation GRPCChannelPool { + NSTimeInterval _channelDestroyDelay; + NSMutableDictionary *_channelPool; + NSMutableDictionary *_callRefs; + // Dedicated queue for timer + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)init { + return [self initWithChannelDestroyDelay:kChannelDestroyDelay]; +} + +- (instancetype)initWithChannelDestroyDelay:(NSTimeInterval)channelDestroyDelay { + if ((self = [super init])) { + _channelDestroyDelay = channelDestroyDelay; + _channelPool = [NSMutableDictionary dictionary]; + _callRefs = [NSMutableDictionary dictionary]; + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)]; + } + } + return self; +} + +- (void)dealloc { + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor unregisterObserver:self]; + } +} + +- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration + createChannel:(GRPCChannel * (^)(void))createChannel { + __block GRPCChannel *channel; + dispatch_sync(_dispatchQueue, ^{ + if ([self->_channelPool objectForKey:configuration]) { + [self->_callRefs[configuration] refChannel]; + channel = self->_channelPool[configuration]; + } else { + channel = createChannel(); + self->_channelPool[configuration] = channel; + + GRPCChannelCallRef *callRef = [[GRPCChannelCallRef alloc] + initWithChannelConfiguration:configuration + destroyDelay:self->_channelDestroyDelay + dispatchQueue:self->_dispatchQueue + destroyChannel:^(GRPCChannelConfiguration *configuration) { + [self->_channelPool removeObjectForKey:configuration]; + [self->_callRefs removeObjectForKey:configuration]; + }]; + [callRef refChannel]; + self->_callRefs[configuration] = callRef; + } + }); + return channel; +} + +- (void)unrefChannelWithConfiguration:configuration { + dispatch_sync(_dispatchQueue, ^{ + if ([self->_channelPool objectForKey:configuration]) { + [self->_callRefs[configuration] unrefChannel]; + } + }); +} + +- (void)clear { + dispatch_sync(_dispatchQueue, ^{ + self->_channelPool = [NSMutableDictionary dictionary]; + self->_callRefs = [NSMutableDictionary dictionary]; + }); +} + +- (void)connectivityChange:(NSNotification *)note { + [self clear]; +} + +@end diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h new file mode 100644 index 00000000000..97e1ae920a0 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h @@ -0,0 +1,36 @@ +/* + * + * 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. + * + */ +#import "GRPCChannelFactory.h" + +@class GRPCChannel; +typedef struct stream_engine stream_engine; + +NS_ASSUME_NONNULL_BEGIN + +@interface GRPCCronetChannelFactory : NSObject + ++ (nullable instancetype)sharedInstance; + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableDictionary *)args; + +- (nullable instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m new file mode 100644 index 00000000000..5c0fe16d39b --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -0,0 +1,94 @@ +/* + * + * 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. + * + */ + +#import "GRPCCronetChannelFactory.h" + +#import "ChannelArgsUtil.h" +#import "GRPCChannel.h" + +#ifdef GRPC_COMPILE_WITH_CRONET + +#import +#include + +NS_ASSUME_NONNULL_BEGIN + +@implementation GRPCCronetChannelFactory { + stream_engine *_cronetEngine; +} + ++ (nullable instancetype)sharedInstance { + static GRPCCronetChannelFactory *instance; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [[self alloc] initWithEngine:[Cronet getGlobalEngine]]; + }); + return instance; +} + +- (nullable instancetype)initWithEngine:(stream_engine *)engine { + if (!engine) { + [NSException raise:NSInvalidArgumentException format:@"Cronet engine is NULL. Set it first."]; + return nil; + } + if ((self = [super init])) { + _cronetEngine = engine; + } + return self; +} + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableDictionary *)args { + // Remove client authority filter since that is not supported + args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; + + grpc_channel_args *channelArgs = BuildChannelArgs(args); + grpc_channel *unmanagedChannel = + grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); + FreeChannelArgs(channelArgs); + return unmanagedChannel; +} + +@end + +NS_ASSUME_NONNULL_END + +#else + +NS_ASSUME_NONNULL_BEGIN + +@implementation GRPCCronetChannelFactory + ++ (nullable instancetype)sharedInstance { + [NSException raise:NSInvalidArgumentException + format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; + return nil; +} + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableArray *)args { + [NSException raise:NSInvalidArgumentException + format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; + return nil; +} + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h index 291b07df377..32d3585351e 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.h +++ b/src/objective-c/GRPCClient/private/GRPCHost.h @@ -20,6 +20,10 @@ #import +#import "GRPCChannelFactory.h" + +#import + NS_ASSUME_NONNULL_BEGIN @class GRPCCompletionQueue; @@ -28,12 +32,10 @@ struct grpc_channel_credentials; @interface GRPCHost : NSObject -+ (void)flushChannelCache; + (void)resetAllHostSettings; @property(nonatomic, readonly) NSString *address; @property(nonatomic, copy, nullable) NSString *userAgentPrefix; -@property(nonatomic, nullable) struct grpc_channel_credentials *channelCreds; @property(nonatomic) grpc_compression_algorithm compressAlgorithm; @property(nonatomic) int keepaliveInterval; @property(nonatomic) int keepaliveTimeout; @@ -44,14 +46,14 @@ struct grpc_channel_credentials; @property(nonatomic) unsigned int initialConnectBackoff; @property(nonatomic) unsigned int maxConnectBackoff; -/** The following properties should only be modified for testing: */ +@property(nonatomic) id channelFactory; -@property(nonatomic, getter=isSecure) BOOL secure; +/** The following properties should only be modified for testing: */ @property(nonatomic, copy, nullable) NSString *hostNameOverride; /** The default response size limit is 4MB. Set this to override that default. */ -@property(nonatomic, strong, nullable) NSNumber *responseSizeLimitOverride; +@property(nonatomic) NSUInteger responseSizeLimitOverride; - (nullable instancetype)init NS_UNAVAILABLE; /** Host objects initialized with the same address are the same. */ @@ -62,19 +64,12 @@ struct grpc_channel_credentials; withCertChain:(nullable NSString *)pemCertChain error:(NSError **)errorPtr; -/** Create a grpc_call object to the provided path on this host. */ -- (nullable struct grpc_call *)unmanagedCallWithPath:(NSString *)path - serverName:(NSString *)serverName - timeout:(NSTimeInterval)timeout - completionQueue:(GRPCCompletionQueue *)queue; - -// TODO: There's a race when a new RPC is coming through just as an existing one is getting -// notified that there's no connectivity. If connectivity comes back at that moment, the new RPC -// will have its channel destroyed by the other RPC, and will never get notified of a problem, so -// it'll hang (the C layer logs a timeout, with exponential back off). One solution could be to pass -// the GRPCChannel to the GRPCCall, renaming this as "disconnectChannel:channel", which would only -// act on that specific channel. -- (void)disconnect; +@property(atomic, readwrite) GRPCTransportType transportType; + +@property(readonly) GRPCMutableCallOptions *callOptions; + ++ (BOOL)isHostConfigured:(NSString *)address; + @end NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 862909f2384..0e3fa610f9e 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -18,46 +18,35 @@ #import "GRPCHost.h" +#import #import + #include #include -#ifdef GRPC_COMPILE_WITH_CRONET -#import -#import -#endif -#import "GRPCChannel.h" +#import +#import "GRPCChannelFactory.h" #import "GRPCCompletionQueue.h" #import "GRPCConnectivityMonitor.h" +#import "GRPCCronetChannelFactory.h" +#import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" #import "version.h" NS_ASSUME_NONNULL_BEGIN -extern const char *kCFStreamVarName; - static NSMutableDictionary *kHostCache; @implementation GRPCHost { - // TODO(mlumish): Investigate whether caching channels with strong links is a good idea. - GRPCChannel *_channel; + NSString *_pemRootCerts; + NSString *_pemPrivateKey; + NSString *_pemCertChain; } + (nullable instancetype)hostWithAddress:(NSString *)address { return [[self alloc] initWithAddress:address]; } -- (void)dealloc { - if (_channelCreds != nil) { - grpc_channel_credentials_release(_channelCreds); - } - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor unregisterObserver:self]; - } -} - // Default initializer. - (nullable instancetype)initWithAddress:(NSString *)address { if (!address) { @@ -86,230 +75,58 @@ static NSMutableDictionary *kHostCache; if ((self = [super init])) { _address = address; - _secure = YES; - kHostCache[address] = self; - _compressAlgorithm = GRPC_COMPRESS_NONE; _retryEnabled = YES; - } - - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)]; + kHostCache[address] = self; } } return self; } -+ (void)flushChannelCache { - @synchronized(kHostCache) { - [kHostCache enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, GRPCHost *_Nonnull host, - BOOL *_Nonnull stop) { - [host disconnect]; - }]; - } -} - + (void)resetAllHostSettings { @synchronized(kHostCache) { kHostCache = [NSMutableDictionary dictionary]; } } -- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path - serverName:(NSString *)serverName - timeout:(NSTimeInterval)timeout - completionQueue:(GRPCCompletionQueue *)queue { - // The __block attribute is to allow channel take refcount inside @synchronized block. Without - // this attribute, retain of channel object happens after objc_sync_exit in release builds, which - // may result in channel released before used. See grpc/#15033. - __block GRPCChannel *channel; - // This is racing -[GRPCHost disconnect]. - @synchronized(self) { - if (!_channel) { - _channel = [self newChannel]; - } - channel = _channel; - } - return [channel unmanagedCallWithPath:path - serverName:serverName - timeout:timeout - completionQueue:queue]; -} - -- (NSData *)nullTerminatedDataWithString:(NSString *)string { - // dataUsingEncoding: does not return a null-terminated string. - NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; - NSMutableData *nullTerminated = [NSMutableData dataWithData:data]; - [nullTerminated appendBytes:"\0" length:1]; - return nullTerminated; -} - - (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCerts withPrivateKey:(nullable NSString *)pemPrivateKey withCertChain:(nullable NSString *)pemCertChain error:(NSError **)errorPtr { - static NSData *kDefaultRootsASCII; - static NSError *kDefaultRootsError; - static dispatch_once_t loading; - dispatch_once(&loading, ^{ - NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem - // Do not use NSBundle.mainBundle, as it's nil for tests of library projects. - NSBundle *bundle = [NSBundle bundleForClass:self.class]; - NSString *path = [bundle pathForResource:defaultPath ofType:@"pem"]; - 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]; - if (contentInUTF8 == nil) { - kDefaultRootsError = error; - return; - } - kDefaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8]; - }); - - NSData *rootsASCII; - if (pemRootCerts != nil) { - rootsASCII = [self nullTerminatedDataWithString:pemRootCerts]; - } else { - if (kDefaultRootsASCII == nil) { - if (errorPtr) { - *errorPtr = kDefaultRootsError; - } - 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: %@", - kDefaultRootsError); - return NO; - } - rootsASCII = kDefaultRootsASCII; - } - - grpc_channel_credentials *creds; - if (pemPrivateKey == nil && pemCertChain == nil) { - creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL, NULL); - } else { - grpc_ssl_pem_key_cert_pair key_cert_pair; - NSData *privateKeyASCII = [self nullTerminatedDataWithString:pemPrivateKey]; - NSData *certChainASCII = [self nullTerminatedDataWithString:pemCertChain]; - 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, NULL); - } - - @synchronized(self) { - if (_channelCreds != nil) { - grpc_channel_credentials_release(_channelCreds); - } - _channelCreds = creds; - } - + _pemRootCerts = pemRootCerts; + _pemPrivateKey = pemPrivateKey; + _pemCertChain = pemCertChain; return YES; } -- (NSDictionary *)channelArgsUsingCronet:(BOOL)useCronet { - NSMutableDictionary *args = [NSMutableDictionary dictionary]; - - // TODO(jcanizales): Add OS and device information (see - // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#user-agents ). - NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; - if (_userAgentPrefix) { - userAgent = [_userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; - } - args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = userAgent; - - if (_secure && _hostNameOverride) { - args[@GRPC_SSL_TARGET_NAME_OVERRIDE_ARG] = _hostNameOverride; - } - - if (_responseSizeLimitOverride) { - args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = _responseSizeLimitOverride; - } - - if (_compressAlgorithm != GRPC_COMPRESS_NONE) { - args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = [NSNumber numberWithInt:_compressAlgorithm]; - } - - if (_keepaliveInterval != 0) { - args[@GRPC_ARG_KEEPALIVE_TIME_MS] = [NSNumber numberWithInt:_keepaliveInterval]; - args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = [NSNumber numberWithInt:_keepaliveTimeout]; - } - - id logContext = self.logContext; - if (logContext != nil) { - args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = logContext; - } - - if (useCronet) { - args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; - } - - if (_retryEnabled == NO) { - args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:0]; - } - - if (_minConnectTimeout > 0) { - args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_minConnectTimeout]; - } - if (_initialConnectBackoff > 0) { - args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_initialConnectBackoff]; - } - if (_maxConnectBackoff > 0) { - args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_maxConnectBackoff]; - } - - return args; -} - -- (GRPCChannel *)newChannel { - BOOL useCronet = NO; -#ifdef GRPC_COMPILE_WITH_CRONET - useCronet = [GRPCCall isUsingCronet]; -#endif - NSDictionary *args = [self channelArgsUsingCronet:useCronet]; - if (_secure) { - GRPCChannel *channel; - @synchronized(self) { - if (_channelCreds == nil) { - [self setTLSPEMRootCerts:nil withPrivateKey:nil withCertChain:nil error:nil]; - } -#ifdef GRPC_COMPILE_WITH_CRONET - if (useCronet) { - channel = [GRPCChannel secureCronetChannelWithHost:_address channelArgs:args]; - } else -#endif - { - channel = - [GRPCChannel secureChannelWithHost:_address credentials:_channelCreds channelArgs:args]; - } - } - return channel; - } else { - return [GRPCChannel insecureChannelWithHost:_address channelArgs:args]; - } -} - -- (NSString *)hostName { - // TODO(jcanizales): Default to nil instead of _address when Issue #2635 is clarified. - return _hostNameOverride ?: _address; +- (GRPCCallOptions *)callOptions { + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.userAgentPrefix = _userAgentPrefix; + options.responseSizeLimit = _responseSizeLimitOverride; + options.compressAlgorithm = (GRPCCompressAlgorithm)_compressAlgorithm; + options.enableRetry = _retryEnabled; + options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000; + options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000; + options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000; + options.connectInitialBackoff = (NSTimeInterval)_initialConnectBackoff / 1000; + options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000; + options.pemRootCert = _pemRootCerts; + options.pemPrivateKey = _pemPrivateKey; + options.pemCertChain = _pemCertChain; + options.hostNameOverride = _hostNameOverride; + options.transportType = _transportType; + options.logContext = _logContext; + + return options; } -- (void)disconnect { - // This is racing -[GRPCHost unmanagedCallWithPath:completionQueue:]. - @synchronized(self) { - _channel = nil; ++ (BOOL)isHostConfigured:(NSString *)address { + // TODO (mxyan): Remove when old API is deprecated + NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:address]]; + if (hostURL.host && !hostURL.port) { + address = [hostURL.host stringByAppendingString:@":443"]; } -} - -// Flushes the host cache when connectivity status changes or when connection switch between Wifi -// and Cellular data, so that a new call will use a new channel. Otherwise, a new call will still -// use the cached channel which is no longer available and will cause gRPC to hang. -- (void)connectivityChange:(NSNotification *)note { - [self disconnect]; + GRPCHost *cachedHost = kHostCache[address]; + return (cachedHost != nil); } @end diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h new file mode 100644 index 00000000000..905a181ca78 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h @@ -0,0 +1,35 @@ +/* + * + * 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. + * + */ +#import "GRPCChannelFactory.h" + +@class GRPCChannel; + +NS_ASSUME_NONNULL_BEGIN + +@interface GRPCInsecureChannelFactory : NSObject + ++ (nullable instancetype)sharedInstance; + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableDictionary *)args; + +- (nullable instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m new file mode 100644 index 00000000000..41860bf6ff5 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -0,0 +1,48 @@ +/* + * + * 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. + * + */ + +#import "GRPCInsecureChannelFactory.h" + +#import "ChannelArgsUtil.h" +#import "GRPCChannel.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation GRPCInsecureChannelFactory + ++ (nullable instancetype)sharedInstance { + static GRPCInsecureChannelFactory *instance; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [[self alloc] init]; + }); + return instance; +} + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableDictionary *)args { + grpc_channel_args *coreChannelArgs = BuildChannelArgs([args copy]); + grpc_channel *unmanagedChannel = + grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); + FreeChannelArgs(coreChannelArgs); + return unmanagedChannel; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h new file mode 100644 index 00000000000..ab5eee478e1 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -0,0 +1,38 @@ +/* + * + * 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. + * + */ +#import "GRPCChannelFactory.h" + +@class GRPCChannel; + +NS_ASSUME_NONNULL_BEGIN + +@interface GRPCSecureChannelFactory : NSObject + ++ (nullable instancetype)factoryWithPEMRootCerts:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr; + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableDictionary *)args; + +- (nullable instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m new file mode 100644 index 00000000000..a0d56e4bdc7 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -0,0 +1,129 @@ +/* + * + * 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. + * + */ + +#import "GRPCSecureChannelFactory.h" + +#include + +#import "ChannelArgsUtil.h" +#import "GRPCChannel.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation GRPCSecureChannelFactory { + grpc_channel_credentials *_channelCreds; +} + ++ (nullable instancetype)factoryWithPEMRootCerts:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr { + return [[self alloc] initWithPEMRootCerts:rootCerts + privateKey:privateKey + certChain:certChain + error:errorPtr]; +} + +- (NSData *)nullTerminatedDataWithString:(NSString *)string { + // dataUsingEncoding: does not return a null-terminated string. + NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; + NSMutableData *nullTerminated = [NSMutableData dataWithData:data]; + [nullTerminated appendBytes:"\0" length:1]; + return nullTerminated; +} + +- (nullable instancetype)initWithPEMRootCerts:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr { + static NSData *kDefaultRootsASCII; + static NSError *kDefaultRootsError; + static dispatch_once_t loading; + dispatch_once(&loading, ^{ + NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem + // Do not use NSBundle.mainBundle, as it's nil for tests of library projects. + NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSString *path = [bundle pathForResource:defaultPath ofType:@"pem"]; + 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]; + if (contentInUTF8 == nil) { + kDefaultRootsError = error; + return; + } + kDefaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8]; + }); + + NSData *rootsASCII; + if (rootCerts != nil) { + rootsASCII = [self nullTerminatedDataWithString:rootCerts]; + } else { + if (kDefaultRootsASCII == nil) { + if (errorPtr) { + *errorPtr = kDefaultRootsError; + } + 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: %@", + kDefaultRootsError); + return nil; + } + rootsASCII = kDefaultRootsASCII; + } + + grpc_channel_credentials *creds; + if (privateKey == nil && certChain == nil) { + creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL, NULL); + } else { + grpc_ssl_pem_key_cert_pair key_cert_pair; + NSData *privateKeyASCII = [self nullTerminatedDataWithString:privateKey]; + NSData *certChainASCII = [self nullTerminatedDataWithString:certChain]; + 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, NULL); + } + + if ((self = [super init])) { + _channelCreds = creds; + } + return self; +} + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableArray *)args { + grpc_channel_args *coreChannelArgs = BuildChannelArgs([args copy]); + grpc_channel *unmanagedChannel = + grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); + FreeChannelArgs(coreChannelArgs); + return unmanagedChannel; +} + +- (void)dealloc { + if (_channelCreds != nil) { + grpc_channel_credentials_release(_channelCreds); + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h index f711850c2f0..19aa5367c77 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h @@ -74,9 +74,8 @@ @interface GRPCWrappedCall : NSObject - (instancetype)initWithHost:(NSString *)host - serverName:(NSString *)serverName path:(NSString *)path - timeout:(NSTimeInterval)timeout NS_DESIGNATED_INITIALIZER; + callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; - (void)startBatchWithOperations:(NSArray *)ops errorHandler:(void (^)(void))errorHandler; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 7781d27ca4f..1c03bc9efdd 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -23,6 +23,7 @@ #include #include +#import "GRPCChannel.h" #import "GRPCCompletionQueue.h" #import "GRPCHost.h" #import "NSData+GRPC.h" @@ -235,31 +236,28 @@ @implementation GRPCWrappedCall { GRPCCompletionQueue *_queue; + GRPCChannel *_channel; grpc_call *_call; } - (instancetype)init { - return [self initWithHost:nil serverName:nil path:nil timeout:0]; + return [self initWithHost:nil path:nil callOptions:[[GRPCCallOptions alloc] init]]; } - (instancetype)initWithHost:(NSString *)host - serverName:(NSString *)serverName path:(NSString *)path - timeout:(NSTimeInterval)timeout { + callOptions:(GRPCCallOptions *)callOptions { if (!path || !host) { [NSException raise:NSInvalidArgumentException format:@"path and host cannot be nil."]; } - if (self = [super init]) { + if ((self = [super init])) { // Each completion queue consumes one thread. There's a trade to be made between creating and // consuming too many threads and having contention of multiple calls in a single completion // queue. Currently we use a singleton queue. _queue = [GRPCCompletionQueue completionQueue]; - - _call = [[GRPCHost hostWithAddress:host] unmanagedCallWithPath:path - serverName:serverName - timeout:timeout - completionQueue:_queue]; + _channel = [GRPCChannel channelWithHost:host callOptions:callOptions]; + _call = [_channel unmanagedCallWithPath:path completionQueue:_queue callOptions:callOptions]; if (_call == NULL) { return nil; } @@ -313,6 +311,8 @@ - (void)dealloc { grpc_call_unref(_call); + [_channel unmanagedCallUnref]; + _channel = nil; } @end From 21c32e8f013986d6b120c852b34e058c82a4cf6d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:33:41 -0700 Subject: [PATCH 006/534] Remove redundant forward declaration --- src/objective-c/GRPCClient/GRPCCall.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 3f6ec75c04e..f396ffe599c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -39,8 +39,6 @@ #include "GRPCCallOptions.h" -@class GRPCCallOptions; - #pragma mark gRPC errors /** Domain of NSError objects produced by gRPC. */ From 553664f59bc947d48c73e6c1976e054fe35147f5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:34:21 -0700 Subject: [PATCH 007/534] Make dispatcheQueue of responseHandler required --- src/objective-c/GRPCClient/GRPCCall.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index f396ffe599c..64a6df3134c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -150,14 +150,18 @@ extern id const kGRPCTrailersKey; /** An object can implement this protocol to receive responses from server from a call. */ @protocol GRPCResponseHandler + @optional + /** Issued when initial metadata is received from the server. */ - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; + /** * Issued when a message is received from the server. The message may be raw data from the server * (when using \a GRPCCall2 directly) or deserialized proto object (when using \a ProtoRPC). */ - (void)receivedMessage:(id)message; + /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error @@ -166,9 +170,13 @@ extern id const kGRPCTrailersKey; */ - (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error; +@required + /** * All the responses must be issued to a user-provided dispatch queue. This property specifies the - * dispatch queue to be used for issuing the notifications. + * dispatch queue to be used for issuing the notifications. A serial queue should be provided if + * the order of responses (initial metadata, message, message, ..., message, trailing metadata) + * needs to be maintained. */ @property(atomic, readonly) dispatch_queue_t dispatchQueue; From 5715719afb061feb3c7de931cc8e7126bc9560e5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:36:09 -0700 Subject: [PATCH 008/534] Make multiple -init and +new UNAVAILABLE; identify designated initializer --- src/objective-c/GRPCClient/GRPCCall.h | 6 +++++- src/objective-c/ProtoRPC/ProtoRPC.h | 12 ++++++++++-- src/objective-c/ProtoRPC/ProtoService.h | 4 ++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 64a6df3134c..2ee181b93ba 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -190,8 +190,10 @@ extern id const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + /** Initialize with all properties. */ -- (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety; +- (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety NS_DESIGNATED_INITIALIZER; /** The host serving the RPC service. */ @property(copy, readonly) NSString *host; @@ -214,6 +216,8 @@ extern id const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + /** * Designated initializer for a call. * \param requestOptions Protobuf generated parameters for the call. diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 1a27cac2a32..a045ef10a6c 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -26,6 +26,10 @@ /** A unary-request RPC call with Protobuf. */ @interface GRPCUnaryProtoCall : NSObject +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + /** * Users should not use this initializer directly. Call objects will be created, initialized, and * returned to users by methods of the generated service. @@ -34,7 +38,7 @@ message:(GPBMessage *)message responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions - responseClass:(Class)responseClass; + responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** Cancel the call at best effort. */ - (void)cancel; @@ -44,6 +48,10 @@ /** A client-streaming RPC call with Protobuf. */ @interface GRPCStreamingProtoCall : NSObject +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + /** * Users should not use this initializer directly. Call objects will be created, initialized, and * returned to users by methods of the generated service. @@ -51,7 +59,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions - responseClass:(Class)responseClass; + responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** Cancel the call at best effort. */ - (void)cancel; diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 2105de78a38..2985c5cb2dc 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -30,6 +30,10 @@ __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService : NSObject +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + - (instancetype)initWithHost : (NSString *)host packageName : (NSString *)packageName serviceName : (NSString *)serviceName callOptions From 0865a6098880b91235348cb9ffe49ddbb13ebdc6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:37:08 -0700 Subject: [PATCH 009/534] Typo and doc fix --- src/objective-c/GRPCClient/GRPCCall.h | 3 ++- src/objective-c/GRPCClient/GRPCCallOptions.m | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 2ee181b93ba..01d04807cc6 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -228,7 +228,8 @@ extern id const kGRPCTrailersKey; handler:(id)handler callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; /** - * Convevience initializer for a call that uses default call options. + * Convenience initializer for a call that uses default call options (see GRPCCallOptions.m for + * the default options). */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions handler:(id)handler; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index ee76c2a6420..072b980af42 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -18,6 +18,7 @@ #import "GRPCCallOptions.h" +// The default values for the call options. static NSString *const kDefaultServerAuthority = nil; static const NSTimeInterval kDefaultTimeout = 0; static NSDictionary *const kDefaultInitialMetadata = nil; From efa359b02b0122c90decfbcd5e1659198b565b4e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:50:12 -0700 Subject: [PATCH 010/534] Rename handler->responseHandler in function signature --- src/objective-c/GRPCClient/GRPCCall.h | 6 +++--- src/objective-c/GRPCClient/GRPCCall.m | 8 ++++---- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 01d04807cc6..8554860aded 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -221,18 +221,18 @@ extern id const kGRPCTrailersKey; /** * Designated initializer for a call. * \param requestOptions Protobuf generated parameters for the call. - * \param handler The object to which responses should be issed. + * \param responseHandler The object to which responses should be issed. * \param callOptions Options for the call. */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - handler:(id)handler + responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; /** * Convenience initializer for a call that uses default call options (see GRPCCallOptions.m for * the default options). */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - handler:(id)handler; + responseHandler:(id)responseHandler; /** * Starts the call. Can only be called once. diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 519f91e5229..6eb9e2e4066 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -95,7 +95,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - handler:(id)handler + responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *)callOptions { if (!requestOptions || !requestOptions.host || !requestOptions.path) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; @@ -104,7 +104,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; if ((self = [super init])) { _requestOptions = [requestOptions copy]; _callOptions = [callOptions copy]; - _handler = handler; + _handler = responseHandler; _initialMetadataPublished = NO; _pipe = [GRXBufferedPipe pipe]; _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); @@ -114,8 +114,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - handler:(id)handler { - return [self initWithRequestOptions:requestOptions handler:handler callOptions:nil]; + responseHandler:(id)responseHandler { + return [self initWithRequestOptions:requestOptions responseHandler:responseHandler callOptions:nil]; } - (void)start { diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index f89c1606507..34fd54a2162 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -86,7 +86,7 @@ - (void)start { _call = [[GRPCCall2 alloc] initWithRequestOptions:_requestOptions - handler:self + responseHandler:self callOptions:_callOptions]; [_call start]; } From eab498bef453e221abd4602e6ceff16da659b3c1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:44:00 -0700 Subject: [PATCH 011/534] Handle GRPCCall2:start: twice --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 8554860aded..5f6afab08cb 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -235,7 +235,7 @@ extern id const kGRPCTrailersKey; responseHandler:(id)responseHandler; /** - * Starts the call. Can only be called once. + * Starts the call. This function should only be called once; additional calls will be discarded. */ - (void)start; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 6eb9e2e4066..9cb4aa34c24 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -92,6 +92,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; BOOL _initialMetadataPublished; GRXBufferedPipe *_pipe; dispatch_queue_t _dispatchQueue; + bool _started; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -108,6 +109,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _initialMetadataPublished = NO; _pipe = [GRXBufferedPipe pipe]; _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + _started = NO; } return self; @@ -120,6 +122,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)start { dispatch_async(_dispatchQueue, ^{ + if (self->_started) { + return; + } + self->_started = YES; if (!self->_callOptions) { self->_callOptions = [[GRPCCallOptions alloc] init]; } From fe8a899b631b3fd804b59ca32639ef2a14bb597f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:56:00 -0700 Subject: [PATCH 012/534] Rename writeWithData to writeData --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- src/objective-c/tests/GRPCClientTests.m | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 5f6afab08cb..c8f3919a633 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -249,7 +249,7 @@ extern id const kGRPCTrailersKey; /** * Send a message to the server. Data are sent as raw bytes in gRPC message frames. */ -- (void)writeWithData:(NSData *)data; +- (void)writeData:(NSData *)data; /** * Finish the RPC request and half-close the call. The server may still send messages and/or diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9cb4aa34c24..7fdc8fcac26 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -206,7 +206,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; }); } -- (void)writeWithData:(NSData *)data { +- (void)writeData:(NSData *)data { dispatch_async(_dispatchQueue, ^{ [self->_pipe writeValue:data]; }); diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 34fd54a2162..957d6365341 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -120,7 +120,7 @@ dispatch_async(_dispatchQueue, ^{ if (_call) { - [_call writeWithData:[message data]]; + [_call writeData:[message data]]; } }); } diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index bad22d30cbb..db7265c7120 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -332,7 +332,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; callOptions:options]; [call start]; - [call writeWithData:[request data]]; + [call writeData:[request data]]; [call finish]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; @@ -495,7 +495,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; } }] callOptions:options]; - [call writeWithData:[NSData data]]; + [call writeData:[NSData data]]; [call start]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; @@ -632,7 +632,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; callOptions:options]; [call start]; - [call writeWithData:[request data]]; + [call writeData:[request data]]; [call finish]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; From 50dac6721425b225e3e031251c7eb888ec61f07e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 18:09:01 -0700 Subject: [PATCH 013/534] Update GRPCCall2:cancel: docs --- src/objective-c/GRPCClient/GRPCCall.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index c8f3919a633..354bdb7cfa2 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -240,9 +240,9 @@ extern id const kGRPCTrailersKey; - (void)start; /** - * Cancel the request of this call at best effort; notifies the server that the RPC should be - * cancelled, and issue callback to the user with an error code CANCELED if the call is not - * finished. + * Cancel the request of this call at best effort. It attempts to notify the server that the RPC + * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code + * CANCELED if no other error code has already been issued. */ - (void)cancel; From 161dc27b2d3882ab3f8a8bcc26733a729e034583 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 18:09:42 -0700 Subject: [PATCH 014/534] Copy string fix --- src/objective-c/GRPCClient/GRPCCall.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 7fdc8fcac26..c0413ec6c2d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -68,8 +68,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { if ((self = [super init])) { - _host = host; - _path = path; + _host = [host copy]; + _path = [path copy]; _safety = safety; } return self; @@ -77,7 +77,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (id)copyWithZone:(NSZone *)zone { GRPCRequestOptions *request = - [[GRPCRequestOptions alloc] initWithHost:[_host copy] path:[_path copy] safety:_safety]; + [[GRPCRequestOptions alloc] initWithHost:_host path:_path safety:_safety]; return request; } From 413077101eab400635732b813da4f1e4a5b69c5a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 18:10:21 -0700 Subject: [PATCH 015/534] requestOptions precondition check polishing --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index c0413ec6c2d..c9ee5084868 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -98,7 +98,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *)callOptions { - if (!requestOptions || !requestOptions.host || !requestOptions.path) { + if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; } From f18b08a1a4454f8232c2815f0110427c1a86878f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 18:55:28 -0700 Subject: [PATCH 016/534] Check if optional method of GRPCCallOptions are implemented --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 32 ++++++++++++++++++--------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 354bdb7cfa2..304fb17cca5 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -149,7 +149,7 @@ extern id const kGRPCHeadersKey; extern id const kGRPCTrailersKey; /** An object can implement this protocol to receive responses from server from a call. */ -@protocol GRPCResponseHandler +@protocol GRPCResponseHandler @optional diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index c9ee5084868..e1039a1b2a7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -149,12 +149,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; } if (headers) { dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:headers]; + if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + [handler receivedInitialMetadata:headers]; + } }); } if (value) { dispatch_async(handler.dispatchQueue, ^{ - [handler receivedMessage:value]; + if ([handler respondsToSelector:@selector(receivedMessage:)]) { + [handler receivedMessage:value]; + } }); } } @@ -171,11 +175,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; } if (headers) { dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:headers]; + if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + [handler receivedInitialMetadata:headers]; + } }); } dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + [handler closedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + } }); } }); @@ -193,13 +201,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (self->_handler) { id handler = self->_handler; dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + [handler closedWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + } }); self->_handler = nil; } From 7b08066d8ff5cca57ee6eaa4cae014d07e4aa8e1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 10:56:51 -0700 Subject: [PATCH 017/534] Fix CI failures --- src/objective-c/tests/GRPCClientTests.m | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index db7265c7120..8a4eddb1b70 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -306,7 +306,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; options.oauth2AccessToken = @"bogusToken"; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:callRequest - handler:[[ClientTestsBlockCallbacks alloc] + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { init_md = initialMetadata; } @@ -446,7 +446,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; options.initialMetadata = headers; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:request - handler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( NSDictionary *initialMetadata) { NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; // Test the regex is correct @@ -609,7 +609,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; options.transportType = GRPCTransportTypeInsecure; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions - handler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id message) { NSData *data = (NSData *)message; XCTAssertNotNil(data, @"nil value received as response."); @@ -739,7 +739,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions - handler: + responseHandler: [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id data) { XCTFail( @@ -835,9 +835,9 @@ static GRPCProtoMethod *kFullDuplexCallMethod; const double kMargin = 0.1; __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; - NSString *const kDummyAddress = [NSString stringWithFormat:@"8.8.8.8:1"]; + NSString *const kDummyAddress = [NSString stringWithFormat:@"127.0.0.1:10000"]; GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kDummyAddress path:@"" safety:GRPCCallSafetyDefault]; + [[GRPCRequestOptions alloc] initWithHost:kDummyAddress path:@"/dummy/path" safety:GRPCCallSafetyDefault]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.connectMinTimeout = timeout; options.connectInitialBackoff = backoff; @@ -846,7 +846,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; NSDate *startTime = [NSDate date]; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions - handler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id data) { XCTFail(@"Received message. Should not reach here."); } From 5d16c2ff92eb49319d9028cbe99bb80bf41e0578 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 11:20:26 -0700 Subject: [PATCH 018/534] Move issuance of response in helper functions --- src/objective-c/GRPCClient/GRPCCall.m | 54 ++++++++++++++++----------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e1039a1b2a7..1e9bc41b41b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -141,25 +141,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) { dispatch_async(self->_dispatchQueue, ^{ if (self->_handler) { - id handler = self->_handler; NSDictionary *headers = nil; if (!self->_initialMetadataPublished) { headers = self->_call.responseHeaders; self->_initialMetadataPublished = YES; } if (headers) { - dispatch_async(handler.dispatchQueue, ^{ - if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { - [handler receivedInitialMetadata:headers]; - } - }); + [self issueInitialMetadata:headers]; } if (value) { - dispatch_async(handler.dispatchQueue, ^{ - if ([handler respondsToSelector:@selector(receivedMessage:)]) { - [handler receivedMessage:value]; - } - }); + [self issueMessage:value]; } } }); @@ -167,24 +158,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; completionHandler:^(NSError *errorOrNil) { dispatch_async(self->_dispatchQueue, ^{ if (self->_handler) { - id handler = self->_handler; NSDictionary *headers = nil; if (!self->_initialMetadataPublished) { headers = self->_call.responseHeaders; self->_initialMetadataPublished = YES; } if (headers) { - dispatch_async(handler.dispatchQueue, ^{ - if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { - [handler receivedInitialMetadata:headers]; - } - }); + [self issueInitialMetadata:headers]; } - dispatch_async(handler.dispatchQueue, ^{ - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [handler closedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; - } - }); + [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; } }); }]; @@ -230,6 +212,34 @@ const char *kCFStreamVarName = "grpc_cfstream"; }); } +- (void)issueInitialMetadata:(NSDictionary *)initialMetadata { + id handler = self->_handler; + if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedInitialMetadata:initialMetadata]; + }); + } +} + +- (void)issueMessage:(id)message { + id handler = self->_handler; + if ([handler respondsToSelector:@selector(receivedMessage:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedMessage:message]; + }); + } +} + +- (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata + error:(NSError *)error { + id handler = self->_handler; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:self->_call.responseTrailers error:error]; + }); + } +} + @end // The following methods of a C gRPC call object aren't reentrant, and thus From 92e81c80efb8d5dcbc6362206be09b2ef9107a2b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 11:33:27 -0700 Subject: [PATCH 019/534] Add comment on clearing GRPCCall2._handler --- src/objective-c/GRPCClient/GRPCCall.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 1e9bc41b41b..ace149fad5a 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -167,6 +167,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self issueInitialMetadata:headers]; } [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + + // Clean up _handler so that no more responses are reported to the handler. + self->_handler = nil; } }); }]; @@ -193,6 +196,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; }]]; } }); + + // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; } }); From b634447d2cb762b47365218e1affd317a4ccd8b3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:15:45 -0700 Subject: [PATCH 020/534] Resetting _call and _handler on finish --- src/objective-c/GRPCClient/GRPCCall.m | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index ace149fad5a..d0495f6cbf1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -170,6 +170,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; + + // If server terminated the call we should close the send path too. + if (self->_call) { + [self->_pipe writesFinishedWithError:nil]; + self->_call = nil; + self->_pipe = nil; + } } }); }]; @@ -182,6 +189,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (self->_call) { [self->_call cancel]; self->_call = nil; + self->_pipe = nil; } if (self->_handler) { id handler = self->_handler; @@ -214,6 +222,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (self->_call) { [self->_pipe writesFinishedWithError:nil]; } + self->_call = nil; + self->_pipe = nil; }); } From aabce5e19ca93c54fc0560116e0e8cb53dabdc19 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:16:09 -0700 Subject: [PATCH 021/534] Initialize flag --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index d0495f6cbf1..40db83155b4 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -541,7 +541,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)sendHeaders { // TODO (mxyan): Remove after deprecated methods are removed - uint32_t callSafetyFlags; + uint32_t callSafetyFlags = 0; switch (_callSafety) { case GRPCCallSafetyDefault: callSafetyFlags = 0; From fb9d054ac7da0cad67cb7431fc91823c7349df33 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:16:35 -0700 Subject: [PATCH 022/534] Check string length --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 40db83155b4..0f2c367331f 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -738,7 +738,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } else { callOptions = [[GRPCMutableCallOptions alloc] init]; } - if (_serverName != nil) { + if (_serverName.length != 0) { callOptions.serverAuthority = _serverName; } if (_timeout != 0) { From bca7e68ccbf15eab3d3a8a09d0e3d50d7db49cf9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:17:40 -0700 Subject: [PATCH 023/534] use strong self for authTokenProvider --- src/objective-c/GRPCClient/GRPCCall.m | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 0f2c367331f..28d3b52d5e1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -761,15 +761,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; } if (_callOptions.authTokenProvider != nil) { self.isWaitingForToken = YES; - __weak typeof(self) weakSelf = self; [self.tokenProvider getTokenWithHandler:^(NSString *token) { - typeof(self) strongSelf = weakSelf; - if (strongSelf && strongSelf.isWaitingForToken) { + if (self.isWaitingForToken) { if (token) { - strongSelf->_fetchedOauth2AccessToken = token; + self->_fetchedOauth2AccessToken = [token copy]; } - [strongSelf startCallWithWriteable:writeable]; - strongSelf.isWaitingForToken = NO; + [self startCallWithWriteable:writeable]; + self.isWaitingForToken = NO; } }]; } else { From 8592dc27223e9ec41f4f52634f662c4485bd119b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:31:07 -0700 Subject: [PATCH 024/534] Rename GRPCTransportTypeDefault to GRPCTransportTypeChttp2CFStream --- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- src/objective-c/tests/ChannelTests/ChannelPoolTest.m | 2 +- src/objective-c/tests/ChannelTests/ChannelTests.m | 4 ++-- src/objective-c/tests/InteropTests.m | 2 +- src/objective-c/tests/InteropTestsLocalSSL.m | 2 +- .../InteropTestsMultipleChannels.m | 2 +- src/objective-c/tests/InteropTestsRemote.m | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 75b320ca6d6..1093044c0c8 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -42,7 +42,7 @@ typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { // The transport to be used by a gRPC call typedef NS_ENUM(NSInteger, GRPCTransportType) { // gRPC internal HTTP/2 stack with BoringSSL - GRPCTransportTypeDefault = 0, + GRPCTransportTypeChttp2BoringSSL = 0, // Cronet stack GRPCTransportTypeCronet, // Insecure channel. FOR TEST ONLY! diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 072b980af42..0216342817b 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -37,7 +37,7 @@ static NSString *const kDefaultPemPrivateKey = nil; static NSString *const kDefaultPemCertChain = nil; static NSString *const kDefaultOauth2AccessToken = nil; static const id kDefaultAuthTokenProvider = nil; -static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeDefault; +static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2BoringSSL; static NSString *const kDefaultHostNameOverride = nil; static const id kDefaultLogContext = nil; static NSString *kDefaultChannelPoolDomain = nil; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index b5f0949ef73..340f4f3c83e 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -49,7 +49,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; id factory; GRPCTransportType type = _callOptions.transportType; switch (type) { - case GRPCTransportTypeDefault: + case GRPCTransportTypeChttp2BoringSSL: // TODO (mxyan): Remove when the API is deprecated #ifdef GRPC_COMPILE_WITH_CRONET if (![GRPCCall isUsingCronet]) { diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index 3b6b10b1a5f..9e1c9eca746 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -127,7 +127,7 @@ NSString *kDummyHost = @"dummy.host"; GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; options1.transportType = GRPCTransportTypeInsecure; GRPCMutableCallOptions *options2 = [[GRPCMutableCallOptions alloc] init]; - options2.transportType = GRPCTransportTypeDefault; + options2.transportType = GRPCTransportTypeChttp2BoringSSL; GRPCChannelConfiguration *config1 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelConfiguration *config2 = diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 0a8b7ae6ee6..64c3356b13f 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -72,7 +72,7 @@ - (void)testDifferentChannelParameters { NSString *host = @"grpc-test.sandbox.googleapis.com"; GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeDefault; + options1.transportType = GRPCTransportTypeChttp2BoringSSL; NSMutableDictionary *args = [NSMutableDictionary new]; args[@"abc"] = @"xyz"; options1.additionalChannelArgs = [args copy]; @@ -80,7 +80,7 @@ options2.transportType = GRPCTransportTypeInsecure; options2.additionalChannelArgs = [args copy]; GRPCMutableCallOptions *options3 = [[GRPCMutableCallOptions alloc] init]; - options3.transportType = GRPCTransportTypeDefault; + options3.transportType = GRPCTransportTypeChttp2BoringSSL; args[@"def"] = @"uvw"; options3.additionalChannelArgs = [args copy]; GRPCChannel *channel1 = [GRPCChannel channelWithHost:host callOptions:options1]; diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 54af7036c35..16d5040a733 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -144,7 +144,7 @@ BOOL isRemoteInteropTest(NSString *host) { } + (GRPCTransportType)transportType { - return GRPCTransportTypeDefault; + return GRPCTransportTypeChttp2BoringSSL; } + (NSString *)pemRootCert { diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m index eb72dd1d311..997dd87eeea 100644 --- a/src/objective-c/tests/InteropTestsLocalSSL.m +++ b/src/objective-c/tests/InteropTestsLocalSSL.m @@ -57,7 +57,7 @@ static int32_t kLocalInteropServerOverhead = 10; } + (GRPCTransportType)transportType { - return GRPCTransportTypeDefault; + return GRPCTransportTypeChttp2BoringSSL; } - (void)setUp { diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m index eb0ba7f34b3..b1d663584c8 100644 --- a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m +++ b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m @@ -114,7 +114,7 @@ dispatch_once_t initCronet; XCTAssertNil(error); options = [[GRPCCallOptions alloc] init]; - options.transportType = GRPCTransportTypeDefault; + options.transportType = GRPCTransportTypeChttp2BoringSSL; options.pemRootCert = certs; options.hostNameOverride = @"foo.test.google.fr"; _localSSLService.options = options; diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m index 516a1f432a5..30670facad0 100644 --- a/src/objective-c/tests/InteropTestsRemote.m +++ b/src/objective-c/tests/InteropTestsRemote.m @@ -59,7 +59,7 @@ static int32_t kRemoteInteropServerOverhead = 12; } #else + (GRPCTransportType)transportType { - return GRPCTransportTypeDefault; + return GRPCTransportTypeChttp2BoringSSL; } #endif From 96709ecb8cde75f2750d96dc288167292790eb5a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:34:24 -0700 Subject: [PATCH 025/534] Fix another NSString* != nil to NSString.length != 0 --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 340f4f3c83e..2b08eb8d5e3 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -131,7 +131,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = _callOptions.logContext; } - if (_callOptions.channelPoolDomain != nil) { + if (_callOptions.channelPoolDomain.length != 0) { args[@GRPC_ARG_CHANNEL_POOL_DOMAIN] = _callOptions.channelPoolDomain; } From 0d4ac971df9d2a795eac674e0a105d0c51f7387b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:45:43 -0700 Subject: [PATCH 026/534] Restrict NSTimeInterval parameters to non-negative --- src/objective-c/GRPCClient/GRPCCallOptions.h | 29 +++++++++------- src/objective-c/GRPCClient/GRPCCallOptions.m | 36 ++++++++++++++++---- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 1093044c0c8..70dd7741fd1 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -120,15 +120,15 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ @property(readonly) BOOL enableRetry; -/** - * HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two - * PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the - * call should wait for PING ACK. If PING ACK is not received after this period, the call fails. - */ +// HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two +// PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the +// call should wait for PING ACK. If PING ACK is not received after this period, the call fails. +// Negative values are not allowed. @property(readonly) NSTimeInterval keepaliveInterval; @property(readonly) NSTimeInterval keepaliveTimeout; -// Parameters for connection backoff. For details of gRPC's backoff behavior, refer to +// Parameters for connection backoff. Negative values are not allowed. +// For details of gRPC's backoff behavior, refer to // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md @property(readonly) NSTimeInterval connectMinTimeout; @property(readonly) NSTimeInterval connectInitialBackoff; @@ -203,7 +203,8 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to * positive, the gRPC call returns with status GRPCErrorCodeDeadlineExceeded if it is not completed - * within \a timeout seconds. A negative value is not allowed. + * within \a timeout seconds. Negative value is invalid; setting the parameter to negative value + * will reset the parameter to 0. */ @property(readwrite) NSTimeInterval timeout; @@ -249,15 +250,17 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ @property(readwrite) BOOL enableRetry; -/** - * HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two - * PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the - * call should wait for PING ACK. If PING ACK is not received after this period, the call fails. - */ +// HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two +// PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the +// call should wait for PING ACK. If PING ACK is not received after this period, the call fails. +// Negative values are invalid; setting these parameters to negative value will reset the +// corresponding parameter to 0. @property(readwrite) NSTimeInterval keepaliveInterval; @property(readwrite) NSTimeInterval keepaliveTimeout; -// Parameters for connection backoff. For details of gRPC's backoff behavior, refer to +// Parameters for connection backoff. Negative value is invalid; setting the parameters to negative +// value will reset corresponding parameter to 0. +// For details of gRPC's backoff behavior, refer to // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md @property(readwrite) NSTimeInterval connectMinTimeout; @property(readwrite) NSTimeInterval connectInitialBackoff; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 0216342817b..1f25df7d53b 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -342,7 +342,11 @@ static NSUInteger kDefaultChannelId = 0; } - (void)setTimeout:(NSTimeInterval)timeout { - _timeout = timeout; + if (timeout < 0) { + _timeout = 0; + } else { + _timeout = timeout; + } } - (void)setOauth2AccessToken:(NSString *)oauth2AccessToken { @@ -374,23 +378,43 @@ static NSUInteger kDefaultChannelId = 0; } - (void)setKeepaliveInterval:(NSTimeInterval)keepaliveInterval { - _keepaliveInterval = keepaliveInterval; + if (keepaliveInterval < 0) { + _keepaliveInterval = 0; + } else { + _keepaliveInterval = keepaliveInterval; + } } - (void)setKeepaliveTimeout:(NSTimeInterval)keepaliveTimeout { - _keepaliveTimeout = keepaliveTimeout; + if (keepaliveTimeout < 0) { + _keepaliveTimeout = 0; + } else { + _keepaliveTimeout = keepaliveTimeout; + } } - (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout { - _connectMinTimeout = connectMinTimeout; + if (connectMinTimeout < 0) { + connectMinTimeout = 0; + } else { + _connectMinTimeout = connectMinTimeout; + } } - (void)setConnectInitialBackoff:(NSTimeInterval)connectInitialBackoff { - _connectInitialBackoff = connectInitialBackoff; + if (connectInitialBackoff < 0) { + _connectInitialBackoff = 0; + } else { + _connectInitialBackoff = connectInitialBackoff; + } } - (void)setConnectMaxBackoff:(NSTimeInterval)connectMaxBackoff { - _connectMaxBackoff = connectMaxBackoff; + if (connectMaxBackoff < 0) { + _connectMaxBackoff = 0; + } else { + _connectMaxBackoff = connectMaxBackoff; + } } - (void)setAdditionalChannelArgs:(NSDictionary *)additionalChannelArgs { From a397862fd56bca95da49062b7ca622a0823bc15a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:52:24 -0700 Subject: [PATCH 027/534] property attribute fixes --- src/objective-c/GRPCClient/GRPCCallOptions.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 70dd7741fd1..abfe3965115 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -64,7 +64,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * :authority header field of the call and performs an extra check that server's certificate * matches the :authority header. */ -@property(readonly) NSString *serverAuthority; +@property(copy, readonly) NSString *serverAuthority; /** * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to @@ -91,7 +91,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * Initial metadata key-value pairs that should be included in the request. */ -@property(copy, readwrite) NSDictionary *initialMetadata; +@property(copy, readonly) NSDictionary *initialMetadata; // Channel parameters; take into account of channel signature. @@ -198,7 +198,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * :authority header field of the call and performs an extra check that server's certificate * matches the :authority header. */ -@property(readwrite) NSString *serverAuthority; +@property(copy, readwrite) NSString *serverAuthority; /** * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to From 2c1c22c3f1b9c0fe36589da691fbabc60ad1aa25 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 14:31:05 -0700 Subject: [PATCH 028/534] Do not nullify GRPCCall2._call on half-close --- src/objective-c/GRPCClient/GRPCCall.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 28d3b52d5e1..36cb71399ca 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -171,7 +171,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; - // If server terminated the call we should close the send path too. if (self->_call) { [self->_pipe writesFinishedWithError:nil]; self->_call = nil; @@ -222,7 +221,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (self->_call) { [self->_pipe writesFinishedWithError:nil]; } - self->_call = nil; self->_pipe = nil; }); } @@ -247,10 +245,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - id handler = self->_handler; + id handler = _handler; + NSDictionary *trailers = _call.responseTrailers; if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:self->_call.responseTrailers error:error]; + [handler closedWithTrailingMetadata:trailers error:error]; }); } } From 0fc040d19acc960ed3ab331ed92b38b43d32a284 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 14:33:00 -0700 Subject: [PATCH 029/534] Rename pemXxx parameters to PEMXxx --- src/objective-c/GRPCClient/GRPCCallOptions.h | 12 +-- src/objective-c/GRPCClient/GRPCCallOptions.m | 84 +++++++++---------- .../GRPCClient/private/GRPCChannelPool.m | 24 +++--- src/objective-c/GRPCClient/private/GRPCHost.m | 14 ++-- src/objective-c/tests/InteropTests.h | 2 +- src/objective-c/tests/InteropTests.m | 8 +- .../tests/InteropTestsLocalCleartext.m | 2 +- src/objective-c/tests/InteropTestsLocalSSL.m | 2 +- .../InteropTestsMultipleChannels.m | 2 +- src/objective-c/tests/InteropTestsRemote.m | 2 +- 10 files changed, 76 insertions(+), 76 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index abfe3965115..ea7c1bf22db 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -146,17 +146,17 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default * root certificates. */ -@property(copy, readonly) NSString *pemRootCert; +@property(copy, readonly) NSString *PEMRootCertificates; /** * PEM format private key for client authentication, if required by the server. */ -@property(copy, readonly) NSString *pemPrivateKey; +@property(copy, readonly) NSString *PEMPrivateKey; /** * PEM format certificate chain for client authentication, if required by the server. */ -@property(copy, readonly) NSString *pemCertChain; +@property(copy, readonly) NSString *PEMCertChain; /** * Select the transport type to be used for this call. @@ -278,17 +278,17 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default * root certificates. */ -@property(copy, readwrite) NSString *pemRootCert; +@property(copy, readwrite) NSString *PEMRootCertificates; /** * PEM format private key for client authentication, if required by the server. */ -@property(copy, readwrite) NSString *pemPrivateKey; +@property(copy, readwrite) NSString *PEMPrivateKey; /** * PEM format certificate chain for client authentication, if required by the server. */ -@property(copy, readwrite) NSString *pemCertChain; +@property(copy, readwrite) NSString *PEMCertChain; /** * Select the transport type to be used for this call. diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 1f25df7d53b..539cb9929db 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -32,9 +32,9 @@ static const NSTimeInterval kDefaultConnectMinTimeout = 0; static const NSTimeInterval kDefaultConnectInitialBackoff = 0; static const NSTimeInterval kDefaultConnectMaxBackoff = 0; static NSDictionary *const kDefaultAdditionalChannelArgs = nil; -static NSString *const kDefaultPemRootCert = nil; -static NSString *const kDefaultPemPrivateKey = nil; -static NSString *const kDefaultPemCertChain = nil; +static NSString *const kDefaultPEMRootCertificates = nil; +static NSString *const kDefaultPEMPrivateKey = nil; +static NSString *const kDefaultPEMCertChain = nil; static NSString *const kDefaultOauth2AccessToken = nil; static const id kDefaultAuthTokenProvider = nil; static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2BoringSSL; @@ -60,9 +60,9 @@ static NSUInteger kDefaultChannelId = 0; NSTimeInterval _connectInitialBackoff; NSTimeInterval _connectMaxBackoff; NSDictionary *_additionalChannelArgs; - NSString *_pemRootCert; - NSString *_pemPrivateKey; - NSString *_pemCertChain; + NSString *_PEMRootCertificates; + NSString *_PEMPrivateKey; + NSString *_PEMCertChain; GRPCTransportType _transportType; NSString *_hostNameOverride; id _logContext; @@ -85,9 +85,9 @@ static NSUInteger kDefaultChannelId = 0; @synthesize connectInitialBackoff = _connectInitialBackoff; @synthesize connectMaxBackoff = _connectMaxBackoff; @synthesize additionalChannelArgs = _additionalChannelArgs; -@synthesize pemRootCert = _pemRootCert; -@synthesize pemPrivateKey = _pemPrivateKey; -@synthesize pemCertChain = _pemCertChain; +@synthesize PEMRootCertificates = _PEMRootCertificates; +@synthesize PEMPrivateKey = _PEMPrivateKey; +@synthesize PEMCertChain = _PEMCertChain; @synthesize transportType = _transportType; @synthesize hostNameOverride = _hostNameOverride; @synthesize logContext = _logContext; @@ -110,9 +110,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:kDefaultConnectInitialBackoff connectMaxBackoff:kDefaultConnectMaxBackoff additionalChannelArgs:kDefaultAdditionalChannelArgs - pemRootCert:kDefaultPemRootCert - pemPrivateKey:kDefaultPemPrivateKey - pemCertChain:kDefaultPemCertChain + PEMRootCertificates:kDefaultPEMRootCertificates + PEMPrivateKey:kDefaultPEMPrivateKey + PEMCertChain:kDefaultPEMCertChain transportType:kDefaultTransportType hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext @@ -135,9 +135,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:(NSTimeInterval)connectInitialBackoff connectMaxBackoff:(NSTimeInterval)connectMaxBackoff additionalChannelArgs:(NSDictionary *)additionalChannelArgs - pemRootCert:(NSString *)pemRootCert - pemPrivateKey:(NSString *)pemPrivateKey - pemCertChain:(NSString *)pemCertChain + PEMRootCertificates:(NSString *)PEMRootCertificates + PEMPrivateKey:(NSString *)PEMPrivateKey + PEMCertChain:(NSString *)PEMCertChain transportType:(GRPCTransportType)transportType hostNameOverride:(NSString *)hostNameOverride logContext:(id)logContext @@ -159,9 +159,9 @@ static NSUInteger kDefaultChannelId = 0; _connectInitialBackoff = connectInitialBackoff; _connectMaxBackoff = connectMaxBackoff; _additionalChannelArgs = additionalChannelArgs; - _pemRootCert = pemRootCert; - _pemPrivateKey = pemPrivateKey; - _pemCertChain = pemCertChain; + _PEMRootCertificates = PEMRootCertificates; + _PEMPrivateKey = PEMPrivateKey; + _PEMCertChain = PEMCertChain; _transportType = transportType; _hostNameOverride = hostNameOverride; _logContext = logContext; @@ -188,9 +188,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - pemRootCert:_pemRootCert - pemPrivateKey:_pemPrivateKey - pemCertChain:_pemCertChain + PEMRootCertificates:_PEMRootCertificates + PEMPrivateKey:_PEMPrivateKey + PEMCertChain:_PEMCertChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -216,9 +216,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - pemRootCert:_pemRootCert - pemPrivateKey:_pemPrivateKey - pemCertChain:_pemCertChain + PEMRootCertificates:_PEMRootCertificates + PEMPrivateKey:_PEMPrivateKey + PEMCertChain:_PEMCertChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -246,9 +246,9 @@ static NSUInteger kDefaultChannelId = 0; @dynamic connectInitialBackoff; @dynamic connectMaxBackoff; @dynamic additionalChannelArgs; -@dynamic pemRootCert; -@dynamic pemPrivateKey; -@dynamic pemCertChain; +@dynamic PEMRootCertificates; +@dynamic PEMPrivateKey; +@dynamic PEMCertChain; @dynamic transportType; @dynamic hostNameOverride; @dynamic logContext; @@ -271,9 +271,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:kDefaultConnectInitialBackoff connectMaxBackoff:kDefaultConnectMaxBackoff additionalChannelArgs:kDefaultAdditionalChannelArgs - pemRootCert:kDefaultPemRootCert - pemPrivateKey:kDefaultPemPrivateKey - pemCertChain:kDefaultPemCertChain + PEMRootCertificates:kDefaultPEMRootCertificates + PEMPrivateKey:kDefaultPEMPrivateKey + PEMCertChain:kDefaultPEMCertChain transportType:kDefaultTransportType hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext @@ -298,9 +298,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - pemRootCert:_pemRootCert - pemPrivateKey:_pemPrivateKey - pemCertChain:_pemCertChain + PEMRootCertificates:_PEMRootCertificates + PEMPrivateKey:_PEMPrivateKey + PEMCertChain:_PEMCertChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -326,9 +326,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - pemRootCert:_pemRootCert - pemPrivateKey:_pemPrivateKey - pemCertChain:_pemCertChain + PEMRootCertificates:_PEMRootCertificates + PEMPrivateKey:_PEMPrivateKey + PEMCertChain:_PEMCertChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -421,16 +421,16 @@ static NSUInteger kDefaultChannelId = 0; _additionalChannelArgs = additionalChannelArgs; } -- (void)setPemRootCert:(NSString *)pemRootCert { - _pemRootCert = pemRootCert; +- (void)setPEMRootCertificates:(NSString *)PEMRootCertificates { + _PEMRootCertificates = PEMRootCertificates; } -- (void)setPemPrivateKey:(NSString *)pemPrivateKey { - _pemPrivateKey = pemPrivateKey; +- (void)setPEMPrivateKey:(NSString *)PEMPrivateKey { + _PEMPrivateKey = PEMPrivateKey; } -- (void)setPemCertChain:(NSString *)pemCertChain { - _pemCertChain = pemCertChain; +- (void)setPEMCertChain:(NSString *)PEMCertChain { + _PEMCertChain = PEMCertChain; } - (void)setTransportType:(GRPCTransportType)transportType { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 2b08eb8d5e3..9007f5fed51 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -54,9 +54,9 @@ const NSTimeInterval kChannelDestroyDelay = 30; #ifdef GRPC_COMPILE_WITH_CRONET if (![GRPCCall isUsingCronet]) { #endif - factory = [GRPCSecureChannelFactory factoryWithPEMRootCerts:_callOptions.pemRootCert - privateKey:_callOptions.pemPrivateKey - certChain:_callOptions.pemCertChain + factory = [GRPCSecureChannelFactory factoryWithPEMRootCerts:_callOptions.PEMRootCertificates + privateKey:_callOptions.PEMPrivateKey + certChain:_callOptions.PEMCertChain error:&error]; if (error) { NSLog(@"Error creating secure channel factory: %@", error); @@ -167,14 +167,14 @@ const NSTimeInterval kChannelDestroyDelay = 30; [obj.callOptions.additionalChannelArgs isEqualToDictionary:_callOptions.additionalChannelArgs])) return NO; - if (!(obj.callOptions.pemRootCert == _callOptions.pemRootCert || - [obj.callOptions.pemRootCert isEqualToString:_callOptions.pemRootCert])) + if (!(obj.callOptions.PEMRootCertificates == _callOptions.PEMRootCertificates || + [obj.callOptions.PEMRootCertificates isEqualToString:_callOptions.PEMRootCertificates])) return NO; - if (!(obj.callOptions.pemPrivateKey == _callOptions.pemPrivateKey || - [obj.callOptions.pemPrivateKey isEqualToString:_callOptions.pemPrivateKey])) + if (!(obj.callOptions.PEMPrivateKey == _callOptions.PEMPrivateKey || + [obj.callOptions.PEMPrivateKey isEqualToString:_callOptions.PEMPrivateKey])) return NO; - if (!(obj.callOptions.pemCertChain == _callOptions.pemCertChain || - [obj.callOptions.pemCertChain isEqualToString:_callOptions.pemCertChain])) + if (!(obj.callOptions.PEMCertChain == _callOptions.PEMCertChain || + [obj.callOptions.PEMCertChain isEqualToString:_callOptions.PEMCertChain])) return NO; if (!(obj.callOptions.hostNameOverride == _callOptions.hostNameOverride || [obj.callOptions.hostNameOverride isEqualToString:_callOptions.hostNameOverride])) @@ -204,9 +204,9 @@ const NSTimeInterval kChannelDestroyDelay = 30; result ^= (unsigned int)(_callOptions.connectInitialBackoff * 1000); result ^= (unsigned int)(_callOptions.connectMaxBackoff * 1000); result ^= _callOptions.additionalChannelArgs.hash; - result ^= _callOptions.pemRootCert.hash; - result ^= _callOptions.pemPrivateKey.hash; - result ^= _callOptions.pemCertChain.hash; + result ^= _callOptions.PEMRootCertificates.hash; + result ^= _callOptions.PEMPrivateKey.hash; + result ^= _callOptions.PEMCertChain.hash; result ^= _callOptions.hostNameOverride.hash; result ^= _callOptions.transportType; result ^= [_callOptions.logContext hash]; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 0e3fa610f9e..429958b4083 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -38,8 +38,8 @@ NS_ASSUME_NONNULL_BEGIN static NSMutableDictionary *kHostCache; @implementation GRPCHost { - NSString *_pemRootCerts; - NSString *_pemPrivateKey; + NSString *_PEMRootCertificates; + NSString *_PEMPrivateKey; NSString *_pemCertChain; } @@ -92,8 +92,8 @@ static NSMutableDictionary *kHostCache; withPrivateKey:(nullable NSString *)pemPrivateKey withCertChain:(nullable NSString *)pemCertChain error:(NSError **)errorPtr { - _pemRootCerts = pemRootCerts; - _pemPrivateKey = pemPrivateKey; + _PEMRootCertificates = pemRootCerts; + _PEMPrivateKey = pemPrivateKey; _pemCertChain = pemCertChain; return YES; } @@ -109,9 +109,9 @@ static NSMutableDictionary *kHostCache; options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000; options.connectInitialBackoff = (NSTimeInterval)_initialConnectBackoff / 1000; options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000; - options.pemRootCert = _pemRootCerts; - options.pemPrivateKey = _pemPrivateKey; - options.pemCertChain = _pemCertChain; + options.PEMRootCertificates = _PEMRootCertificates; + options.PEMPrivateKey = _PEMPrivateKey; + options.PEMCertChain = _pemCertChain; options.hostNameOverride = _hostNameOverride; options.transportType = _transportType; options.logContext = _logContext; diff --git a/src/objective-c/tests/InteropTests.h b/src/objective-c/tests/InteropTests.h index e223839d3ac..038f24b62e5 100644 --- a/src/objective-c/tests/InteropTests.h +++ b/src/objective-c/tests/InteropTests.h @@ -51,7 +51,7 @@ * The root certificates to be used. The base implementation returns nil. Subclasses should override * to appropriate settings. */ -+ (NSString *)pemRootCert; ++ (NSString *)PEMRootCertificates; /** * The root certificates to be used. The base implementation returns nil. Subclasses should override diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 16d5040a733..0835ff909f5 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -147,7 +147,7 @@ BOOL isRemoteInteropTest(NSString *host) { return GRPCTransportTypeChttp2BoringSSL; } -+ (NSString *)pemRootCert { ++ (NSString *)PEMRootCertificates { return nil; } @@ -202,7 +202,7 @@ BOOL isRemoteInteropTest(NSString *host) { GPBEmpty *request = [GPBEmpty message]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = self.class.transportType; - options.pemRootCert = self.class.pemRootCert; + options.PEMRootCertificates = self.class.PEMRootCertificates; options.hostNameOverride = self.class.hostNameOverride; [_service @@ -484,7 +484,7 @@ BOOL isRemoteInteropTest(NSString *host) { requestedResponseSize:responses[index]]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = self.class.transportType; - options.pemRootCert = self.class.pemRootCert; + options.PEMRootCertificates = self.class.PEMRootCertificates; options.hostNameOverride = self.class.hostNameOverride; __block GRPCStreamingProtoCall *call = [_service @@ -629,7 +629,7 @@ BOOL isRemoteInteropTest(NSString *host) { GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = self.class.transportType; - options.pemRootCert = self.class.pemRootCert; + options.PEMRootCertificates = self.class.PEMRootCertificates; options.hostNameOverride = self.class.hostNameOverride; id request = diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTestsLocalCleartext.m index 42e327a3303..a9c69183332 100644 --- a/src/objective-c/tests/InteropTestsLocalCleartext.m +++ b/src/objective-c/tests/InteropTestsLocalCleartext.m @@ -41,7 +41,7 @@ static int32_t kLocalInteropServerOverhead = 10; return kLocalCleartextHost; } -+ (NSString *)pemRootCert { ++ (NSString *)PEMRootCertificates { return nil; } diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m index 997dd87eeea..759a080380d 100644 --- a/src/objective-c/tests/InteropTestsLocalSSL.m +++ b/src/objective-c/tests/InteropTestsLocalSSL.m @@ -40,7 +40,7 @@ static int32_t kLocalInteropServerOverhead = 10; return kLocalSSLHost; } -+ (NSString *)pemRootCert { ++ (NSString *)PEMRootCertificates { NSBundle *bundle = [NSBundle bundleForClass:self.class]; NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m index b1d663584c8..237804d23de 100644 --- a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m +++ b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m @@ -115,7 +115,7 @@ dispatch_once_t initCronet; options = [[GRPCCallOptions alloc] init]; options.transportType = GRPCTransportTypeChttp2BoringSSL; - options.pemRootCert = certs; + options.PEMRootCertificates = certs; options.hostNameOverride = @"foo.test.google.fr"; _localSSLService.options = options; } diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m index 30670facad0..c1cd9b81efc 100644 --- a/src/objective-c/tests/InteropTestsRemote.m +++ b/src/objective-c/tests/InteropTestsRemote.m @@ -41,7 +41,7 @@ static int32_t kRemoteInteropServerOverhead = 12; return kRemoteSSLHost; } -+ (NSString *)pemRootCert { ++ (NSString *)PEMRootCertificates { return nil; } From 521ffacd7c6b90b884aae72bc342d134e41053fb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 14:44:55 -0700 Subject: [PATCH 030/534] Add example to channelPoolDomain --- src/objective-c/GRPCClient/GRPCCallOptions.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index ea7c1bf22db..dcd4de62233 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -307,7 +307,9 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * A string that specify the domain where channel is being cached. Channels with different domains - * will not get cached to the same connection. + * will not get cached to the same connection. For example, a gRPC example app may use the channel + * pool domain 'io.grpc.example' so that its calls do not reuse the channel created by other modules + * in the same process. */ @property(copy, readwrite) NSString *channelPoolDomain; From 2c47c953380d0a02df4bc7e4d7772b235cd7da9c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 16:17:03 -0700 Subject: [PATCH 031/534] Rename channelId->channelID --- src/objective-c/GRPCClient/GRPCCallOptions.h | 14 +++++----- src/objective-c/GRPCClient/GRPCCallOptions.m | 28 +++++++++---------- .../GRPCClient/private/GRPCChannelPool.m | 4 +-- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index dcd4de62233..9c6e00fd187 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -181,9 +181,9 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * Channel id allows a call to force creating a new channel (connection) rather than using a cached - * channel. Calls using distinct channelId will not get cached to the same connection. + * channel. Calls using distinct channelID will not get cached to the same connection. */ -@property(readonly) NSUInteger channelId; +@property(readonly) NSUInteger channelID; @end @@ -307,16 +307,16 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * A string that specify the domain where channel is being cached. Channels with different domains - * will not get cached to the same connection. For example, a gRPC example app may use the channel - * pool domain 'io.grpc.example' so that its calls do not reuse the channel created by other modules - * in the same process. + * will not get cached to the same channel. For example, a gRPC example app may use the channel pool + * domain 'io.grpc.example' so that its calls do not reuse the channel created by other modules in + * the same process. */ @property(copy, readwrite) NSString *channelPoolDomain; /** * Channel id allows a call to force creating a new channel (connection) rather than using a cached - * channel. Calls using distinct channelId will not get cached to the same connection. + * channel. Calls using distinct channelID's will not get cached to the same channel. */ -@property(readwrite) NSUInteger channelId; +@property(readwrite) NSUInteger channelID; @end diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 539cb9929db..ad90fb829e8 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -41,7 +41,7 @@ static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2Bo static NSString *const kDefaultHostNameOverride = nil; static const id kDefaultLogContext = nil; static NSString *kDefaultChannelPoolDomain = nil; -static NSUInteger kDefaultChannelId = 0; +static NSUInteger kDefaultChannelID = 0; @implementation GRPCCallOptions { @protected @@ -67,7 +67,7 @@ static NSUInteger kDefaultChannelId = 0; NSString *_hostNameOverride; id _logContext; NSString *_channelPoolDomain; - NSUInteger _channelId; + NSUInteger _channelID; } @synthesize serverAuthority = _serverAuthority; @@ -92,7 +92,7 @@ static NSUInteger kDefaultChannelId = 0; @synthesize hostNameOverride = _hostNameOverride; @synthesize logContext = _logContext; @synthesize channelPoolDomain = _channelPoolDomain; -@synthesize channelId = _channelId; +@synthesize channelID = _channelID; - (instancetype)init { return [self initWithServerAuthority:kDefaultServerAuthority @@ -117,7 +117,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext channelPoolDomain:kDefaultChannelPoolDomain - channelId:kDefaultChannelId]; + channelID:kDefaultChannelID]; } - (instancetype)initWithServerAuthority:(NSString *)serverAuthority @@ -142,7 +142,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:(NSString *)hostNameOverride logContext:(id)logContext channelPoolDomain:(NSString *)channelPoolDomain - channelId:(NSUInteger)channelId { + channelID:(NSUInteger)channelID { if ((self = [super init])) { _serverAuthority = serverAuthority; _timeout = timeout; @@ -166,7 +166,7 @@ static NSUInteger kDefaultChannelId = 0; _hostNameOverride = hostNameOverride; _logContext = logContext; _channelPoolDomain = channelPoolDomain; - _channelId = channelId; + _channelID = channelID; } return self; } @@ -195,7 +195,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:_hostNameOverride logContext:_logContext channelPoolDomain:_channelPoolDomain - channelId:_channelId]; + channelID:_channelID]; return newOptions; } @@ -223,7 +223,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:_hostNameOverride logContext:_logContext channelPoolDomain:_channelPoolDomain - channelId:_channelId]; + channelID:_channelID]; return newOptions; } @@ -253,7 +253,7 @@ static NSUInteger kDefaultChannelId = 0; @dynamic hostNameOverride; @dynamic logContext; @dynamic channelPoolDomain; -@dynamic channelId; +@dynamic channelID; - (instancetype)init { return [self initWithServerAuthority:kDefaultServerAuthority @@ -278,7 +278,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext channelPoolDomain:kDefaultChannelPoolDomain - channelId:kDefaultChannelId]; + channelID:kDefaultChannelID]; } - (nonnull id)copyWithZone:(NSZone *)zone { @@ -305,7 +305,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:_hostNameOverride logContext:_logContext channelPoolDomain:_channelPoolDomain - channelId:_channelId]; + channelID:_channelID]; return newOptions; } @@ -333,7 +333,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:_hostNameOverride logContext:_logContext channelPoolDomain:_channelPoolDomain - channelId:_channelId]; + channelID:_channelID]; return newOptions; } @@ -449,8 +449,8 @@ static NSUInteger kDefaultChannelId = 0; _channelPoolDomain = channelPoolDomain; } -- (void)setChannelId:(NSUInteger)channelId { - _channelId = channelId; +- (void)setChannelID:(NSUInteger)channelID { + _channelID = channelID; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 9007f5fed51..37e42f8c75b 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -186,7 +186,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; if (!(obj.callOptions.channelPoolDomain == _callOptions.channelPoolDomain || [obj.callOptions.channelPoolDomain isEqualToString:_callOptions.channelPoolDomain])) return NO; - if (!(obj.callOptions.channelId == _callOptions.channelId)) return NO; + if (!(obj.callOptions.channelID == _callOptions.channelID)) return NO; return YES; } @@ -211,7 +211,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; result ^= _callOptions.transportType; result ^= [_callOptions.logContext hash]; result ^= _callOptions.channelPoolDomain.hash; - result ^= _callOptions.channelId; + result ^= _callOptions.channelID; return result; } From 229651a371ac590f47793cdacc8d28c0ac74bf48 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 16:17:38 -0700 Subject: [PATCH 032/534] Check range of value-typed channel arg --- src/objective-c/GRPCClient/private/ChannelArgsUtil.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index 8ebf3a26593..04a5cc8345a 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -21,6 +21,8 @@ #include #include +#include + static void *copy_pointer_arg(void *p) { // Add ref count to the object when making copy id obj = (__bridge id)p; @@ -79,6 +81,11 @@ grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { arg->type = GRPC_ARG_STRING; arg->value.string = gpr_strdup([value UTF8String]); } else if ([value respondsToSelector:@selector(intValue)]) { + if ([value compare:[NSNumber numberWithInteger:INT_MAX]] == NSOrderedDescending || + [value compare:[NSNumber numberWithInteger:INT_MIN]] == NSOrderedAscending) { + [NSException raise:NSInvalidArgumentException + format:@"Range exceeded for a value typed channel argument: %@", value]; + } arg->type = GRPC_ARG_INTEGER; arg->value.integer = [value intValue]; } else if (value != nil) { From ecf85f045975265d19a94b116e94f7fea42a9d38 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 16:23:25 -0700 Subject: [PATCH 033/534] Copy fields in GRPCCallOptions initializer --- src/objective-c/GRPCClient/GRPCCallOptions.m | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index ad90fb829e8..f9706b18467 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -144,12 +144,12 @@ static NSUInteger kDefaultChannelID = 0; channelPoolDomain:(NSString *)channelPoolDomain channelID:(NSUInteger)channelID { if ((self = [super init])) { - _serverAuthority = serverAuthority; + _serverAuthority = [serverAuthority copy]; _timeout = timeout; - _oauth2AccessToken = oauth2AccessToken; + _oauth2AccessToken = [oauth2AccessToken copy]; _authTokenProvider = authTokenProvider; - _initialMetadata = initialMetadata; - _userAgentPrefix = userAgentPrefix; + _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; + _userAgentPrefix = [userAgentPrefix copy]; _responseSizeLimit = responseSizeLimit; _compressAlgorithm = compressAlgorithm; _enableRetry = enableRetry; @@ -158,14 +158,14 @@ static NSUInteger kDefaultChannelID = 0; _connectMinTimeout = connectMinTimeout; _connectInitialBackoff = connectInitialBackoff; _connectMaxBackoff = connectMaxBackoff; - _additionalChannelArgs = additionalChannelArgs; - _PEMRootCertificates = PEMRootCertificates; - _PEMPrivateKey = PEMPrivateKey; - _PEMCertChain = PEMCertChain; + _additionalChannelArgs = [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; + _PEMRootCertificates = [PEMRootCertificates copy]; + _PEMPrivateKey = [PEMPrivateKey copy]; + _PEMCertChain = [PEMCertChain copy]; _transportType = transportType; - _hostNameOverride = hostNameOverride; + _hostNameOverride = [hostNameOverride copy]; _logContext = logContext; - _channelPoolDomain = channelPoolDomain; + _channelPoolDomain = [channelPoolDomain copy]; _channelID = channelID; } return self; From 1c8751f366fc4b51a49cc83aa8477dd2b12664a8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 16:33:02 -0700 Subject: [PATCH 034/534] Avoid copy in GRPCCallOptions:copyWithZone: --- src/objective-c/GRPCClient/GRPCCallOptions.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index f9706b18467..c700bba794a 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -187,7 +187,7 @@ static NSUInteger kDefaultChannelID = 0; connectMinTimeout:_connectMinTimeout connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff - additionalChannelArgs:[_additionalChannelArgs copy] + additionalChannelArgs:_additionalChannelArgs PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey PEMCertChain:_PEMCertChain From 454966e36cab39ee1b18828575a23c75d812d895 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 16:38:14 -0700 Subject: [PATCH 035/534] Copy in GRPCCallOptions setters --- src/objective-c/GRPCClient/GRPCCallOptions.m | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index c700bba794a..b19917d7784 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -338,7 +338,7 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setServerAuthority:(NSString *)serverAuthority { - _serverAuthority = serverAuthority; + _serverAuthority = [serverAuthority copy]; } - (void)setTimeout:(NSTimeInterval)timeout { @@ -350,7 +350,7 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setOauth2AccessToken:(NSString *)oauth2AccessToken { - _oauth2AccessToken = oauth2AccessToken; + _oauth2AccessToken = [oauth2AccessToken copy]; } - (void)setAuthTokenProvider:(id)authTokenProvider { @@ -358,11 +358,11 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setInitialMetadata:(NSDictionary *)initialMetadata { - _initialMetadata = initialMetadata; + _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; } - (void)setUserAgentPrefix:(NSString *)userAgentPrefix { - _userAgentPrefix = userAgentPrefix; + _userAgentPrefix = [userAgentPrefix copy]; } - (void)setResponseSizeLimit:(NSUInteger)responseSizeLimit { @@ -418,19 +418,19 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setAdditionalChannelArgs:(NSDictionary *)additionalChannelArgs { - _additionalChannelArgs = additionalChannelArgs; + _additionalChannelArgs = [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; } - (void)setPEMRootCertificates:(NSString *)PEMRootCertificates { - _PEMRootCertificates = PEMRootCertificates; + _PEMRootCertificates = [PEMRootCertificates copy]; } - (void)setPEMPrivateKey:(NSString *)PEMPrivateKey { - _PEMPrivateKey = PEMPrivateKey; + _PEMPrivateKey = [PEMPrivateKey copy]; } - (void)setPEMCertChain:(NSString *)PEMCertChain { - _PEMCertChain = PEMCertChain; + _PEMCertChain = [PEMCertChain copy]; } - (void)setTransportType:(GRPCTransportType)transportType { @@ -438,7 +438,7 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setHostNameOverride:(NSString *)hostNameOverride { - _hostNameOverride = hostNameOverride; + _hostNameOverride = [hostNameOverride copy]; } - (void)setLogContext:(id)logContext { @@ -446,7 +446,7 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setChannelPoolDomain:(NSString *)channelPoolDomain { - _channelPoolDomain = channelPoolDomain; + _channelPoolDomain = [channelPoolDomain copy]; } - (void)setChannelID:(NSUInteger)channelID { From 92d6e285d174bf6c8b2e60054f82d7288231da14 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 16:42:53 -0700 Subject: [PATCH 036/534] Polish exception message --- src/objective-c/GRPCClient/private/ChannelArgsUtil.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index 04a5cc8345a..b26fb12d597 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -84,7 +84,7 @@ grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { if ([value compare:[NSNumber numberWithInteger:INT_MAX]] == NSOrderedDescending || [value compare:[NSNumber numberWithInteger:INT_MIN]] == NSOrderedAscending) { [NSException raise:NSInvalidArgumentException - format:@"Range exceeded for a value typed channel argument: %@", value]; + format:@"Out of range for a value-typed channel argument: %@", value]; } arg->type = GRPC_ARG_INTEGER; arg->value.integer = [value intValue]; @@ -94,7 +94,7 @@ grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { arg->value.pointer.vtable = &objc_arg_vtable; } else { [NSException raise:NSInvalidArgumentException - format:@"Invalid value type: %@", [value class]]; + format:@"Invalid channel argument type: %@", [value class]]; } } From e457b0dacc70a28fffd42064236fbf240952e3b4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 12 Oct 2018 09:02:52 -0700 Subject: [PATCH 037/534] Fix missing initialMetadata in GRPCMutableCallOptions --- src/objective-c/GRPCClient/GRPCCallOptions.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 9c6e00fd187..68d3eb4fbb3 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -223,6 +223,11 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ @property(readwrite) id authTokenProvider; +/** + * Initial metadata key-value pairs that should be included in the request. + */ +@property(copy, readonly) NSDictionary *initialMetadata; + // Channel parameters; take into account of channel signature. /** From e69a7cc7f7497e67232843a3843f543740480c4e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 12 Oct 2018 11:21:52 -0700 Subject: [PATCH 038/534] patch the previous fix --- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 68d3eb4fbb3..ff575d09cf8 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -226,7 +226,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * Initial metadata key-value pairs that should be included in the request. */ -@property(copy, readonly) NSDictionary *initialMetadata; +@property(copy, readwrite) NSDictionary *initialMetadata; // Channel parameters; take into account of channel signature. From 519654b4b2438493d33c07ef4ed6be5a5e72dadf Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Tue, 16 Oct 2018 11:08:41 -0700 Subject: [PATCH 039/534] Initial commit to let lb policy intercept recv trailing metadata --- .../filters/client_channel/client_channel.cc | 15 ++++++- .../ext/filters/client_channel/lb_policy.h | 7 ++++ .../ext/filters/client_channel/subchannel.cc | 39 ++++++++++++++----- .../ext/filters/client_channel/subchannel.h | 6 ++- 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index bb3ea400d15..fc77a51eb31 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1990,6 +1990,16 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { } // Not retrying, so commit the call. retry_commit(elem, retry_state); + // Now that the try is committed, give the trailer to the lb policy as needed + if (calld->pick.recv_trailing_metadata_ready != nullptr) { + GPR_ASSERT(calld->pick.recv_trailing_metadata != nullptr); + *calld->pick.recv_trailing_metadata = md_batch; + GRPC_CLOSURE_SCHED( + calld->pick.recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); + calld->pick.recv_trailing_metadata = nullptr; + calld->pick.recv_trailing_metadata_ready = nullptr; + } // Run any necessary closures. run_closures_for_completed_call(batch_data, GRPC_ERROR_REF(error)); } @@ -2592,7 +2602,10 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { parent_data_size // parent_data_size }; grpc_error* new_error = calld->pick.connected_subchannel->CreateCall( - call_args, &calld->subchannel_call); + &calld->subchannel_call, + call_args, + &calld->pick.recv_trailing_metadata_ready, + &calld->pick.recv_trailing_metadata); if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", chand, calld, calld->subchannel_call, grpc_error_string(new_error)); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 21f80b7b947..9ef0033aebd 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -73,6 +73,13 @@ class LoadBalancingPolicy /// Closure to run when pick is complete, if not completed synchronously. /// If null, pick will fail if a result is not available synchronously. grpc_closure* on_complete; + + // Callback set by lb policy if the trailing metadata should be intercepted. + grpc_closure* recv_trailing_metadata_ready; + // If \a recv_trailing_metadata_ready \a is set, the client_channel sets + // this pointer to the metadata batch and schedules the closure. + grpc_metadata_batch** recv_trailing_metadata; + /// Will be set to the selected subchannel, or nullptr on failure or when /// the LB policy decides to drop the call. RefCountedPtr connected_subchannel; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 3a1c14c6f10..a45c579861e 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -151,6 +151,12 @@ struct grpc_subchannel_call { grpc_closure* original_recv_trailing_metadata; grpc_metadata_batch* recv_trailing_metadata; grpc_millis deadline; + + // state needed to support lb interception of recv trailing metadata. + // This points into grpc_core::LoadBalancingPolicy::PickState to avoid + // creating a circular dependency. + grpc_closure** lb_recv_trailing_metadata_ready; + grpc_metadata_batch*** lb_recv_trailing_metadata; }; #define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ @@ -775,11 +781,20 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { get_call_status(call, md_batch, GRPC_ERROR_REF(error), &status); grpc_core::channelz::SubchannelNode* channelz_subchannel = call->connection->channelz_subchannel(); - GPR_ASSERT(channelz_subchannel != nullptr); - if (status == GRPC_STATUS_OK) { - channelz_subchannel->RecordCallSucceeded(); - } else { - channelz_subchannel->RecordCallFailed(); + if (channelz_subchannel != nullptr) { + if (status == GRPC_STATUS_OK) { + channelz_subchannel->RecordCallSucceeded(); + } else { + channelz_subchannel->RecordCallFailed(); + } + } + if (*call->lb_recv_trailing_metadata_ready != nullptr) { + GPR_ASSERT(*call->lb_recv_trailing_metadata != nullptr); + **call->lb_recv_trailing_metadata = md_batch; + GRPC_CLOSURE_SCHED(*call->lb_recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); + *call->lb_recv_trailing_metadata = nullptr; + *call->lb_recv_trailing_metadata_ready = nullptr; } GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata, GRPC_ERROR_REF(error)); @@ -793,8 +808,9 @@ static void maybe_intercept_recv_trailing_metadata( if (!batch->recv_trailing_metadata) { return; } - // only add interceptor is channelz is enabled. - if (call->connection->channelz_subchannel() == nullptr) { + // only add interceptor if channelz is enabled or lb policy wants the trailers + if (call->connection->channelz_subchannel() == nullptr && + *call->lb_recv_trailing_metadata_ready == nullptr) { return; } GRPC_CLOSURE_INIT(&call->recv_trailing_metadata_ready, @@ -922,8 +938,11 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate, elem->filter->start_transport_op(elem, op); } -grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, - grpc_subchannel_call** call) { +grpc_error* ConnectedSubchannel::CreateCall( + grpc_subchannel_call** call, + const CallArgs& args, + grpc_closure** lb_recv_trailing_metadata_ready, + grpc_metadata_batch*** lb_recv_trailing_metadata) { size_t allocation_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)); if (args.parent_data_size > 0) { @@ -959,6 +978,8 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, return error; } grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); + *(*call)->lb_recv_trailing_metadata_ready = *lb_recv_trailing_metadata_ready; + *(*call)->lb_recv_trailing_metadata = *lb_recv_trailing_metadata; return GRPC_ERROR_NONE; } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index c53b13e37e8..dc5e53be780 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -97,7 +97,11 @@ class ConnectedSubchannel : public RefCountedWithTracing { grpc_connectivity_state* state, grpc_closure* closure); void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); - grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call); + grpc_error* CreateCall( + grpc_subchannel_call** call, + const CallArgs& args, + grpc_closure** lb_recv_trailing_metadata_ready, + grpc_metadata_batch*** lb_recv_trailing_metadata); channelz::SubchannelNode* channelz_subchannel() { return channelz_subchannel_.get(); } From bf092064962664a1a949750c9f9b273f7d27c529 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 15:34:39 -0700 Subject: [PATCH 040/534] Separate GRPCProtoResponseHandler from GRPCResponseHandler --- src/objective-c/GRPCClient/GRPCCall.h | 6 +- src/objective-c/GRPCClient/GRPCCall.m | 4 +- src/objective-c/ProtoRPC/ProtoRPC.h | 37 +++++++++++- src/objective-c/ProtoRPC/ProtoRPC.m | 76 ++++++++++++++----------- src/objective-c/tests/GRPCClientTests.m | 2 +- src/objective-c/tests/InteropTests.m | 4 +- 6 files changed, 85 insertions(+), 44 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 304fb17cca5..48f4514a06f 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -157,10 +157,10 @@ extern id const kGRPCTrailersKey; - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; /** - * Issued when a message is received from the server. The message may be raw data from the server - * (when using \a GRPCCall2 directly) or deserialized proto object (when using \a ProtoRPC). + * Issued when a message is received from the server. The message is the raw data received from the + * server, with decompression and without proto deserialization. */ -- (void)receivedMessage:(id)message; +- (void)receivedRawMessage:(id)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 36cb71399ca..eb9b21eccb0 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -236,9 +236,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)issueMessage:(id)message { id handler = self->_handler; - if ([handler respondsToSelector:@selector(receivedMessage:)]) { + if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { dispatch_async(handler.dispatchQueue, ^{ - [handler receivedMessage:message]; + [handler receivedRawMessage:message]; }); } } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index a045ef10a6c..d20098ce8c9 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -23,6 +23,39 @@ @class GPBMessage; +/** An object can implement this protocol to receive responses from server from a call. */ +@protocol GRPCProtoResponseHandler + +@optional + +/** Issued when initial metadata is received from the server. */ +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; + +/** + * Issued when a message is received from the server. The message is the deserialized proto object. + */ +- (void)receivedProtoMessage:(id)message; + +/** + * Issued when a call finished. If the call finished successfully, \a error is nil and \a + * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error + * is non-nil and contains the corresponding error information, including gRPC error codes and + * error descriptions. + */ +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error; + +@required + +/** + * All the responses must be issued to a user-provided dispatch queue. This property specifies the + * dispatch queue to be used for issuing the notifications. A serial queue should be provided if + * the order of responses (initial metadata, message, message, ..., message, trailing metadata) + * needs to be maintained. + */ +@property(atomic, readonly) dispatch_queue_t dispatchQueue; + +@end + /** A unary-request RPC call with Protobuf. */ @interface GRPCUnaryProtoCall : NSObject @@ -36,7 +69,7 @@ */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message - responseHandler:(id)handler + responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; @@ -57,7 +90,7 @@ * returned to users by methods of the generated service. */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - responseHandler:(id)handler + responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 957d6365341..7a57affbf15 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -33,7 +33,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message - responseHandler:(id)handler + responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { if ((self = [super init])) { @@ -60,7 +60,7 @@ @implementation GRPCStreamingProtoCall { GRPCRequestOptions *_requestOptions; - id _handler; + id _handler; GRPCCallOptions *_callOptions; Class _responseClass; @@ -69,7 +69,7 @@ } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - responseHandler:(id)handler + responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { if ((self = [super init])) { @@ -98,16 +98,18 @@ _call = nil; } if (_handler) { - id handler = _handler; - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; - }); + id handler = _handler; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); + } _handler = nil; } }); @@ -136,27 +138,33 @@ - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { if (_handler) { - id handler = _handler; - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:initialMetadata]; - }); + id handler = _handler; + if ([handler respondsToSelector:@selector(initialMetadata:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedInitialMetadata:initialMetadata]; + }); + } } } -- (void)receivedMessage:(NSData *)message { +- (void)receivedRawMessage:(NSData *)message { if (_handler) { - id handler = _handler; + id handler = _handler; NSError *error = nil; id parsed = [_responseClass parseFromData:message error:&error]; if (parsed) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedMessage:parsed]; - }); + if ([handler respondsToSelector:@selector(receivedProtoMessage:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedProtoMessage:parsed]; + }); + } } else { - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:nil error:error]; - }); - handler = nil; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:nil error:error]; + }); + } + _handler = nil; [_call cancel]; _call = nil; } @@ -165,16 +173,16 @@ - (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { if (_handler) { - id handler = _handler; - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:trailingMetadata error:error]; - }); + id handler = _handler; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:trailingMetadata error:error]; + }); + } _handler = nil; } - if (_call) { - [_call cancel]; - _call = nil; - } + [_call cancel]; + _call = nil; } - (dispatch_queue_t)dispatchQueue { diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 8a4eddb1b70..f961b6a86fd 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -120,7 +120,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; } } -- (void)receivedMessage:(id)message { +- (void)receivedProtoMessage:(id)message { if (_messageCallback) { _messageCallback(message); } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 0835ff909f5..11d4b95663a 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -75,7 +75,7 @@ BOOL isRemoteInteropTest(NSString *host) { } // Convenience class to use blocks as callbacks -@interface InteropTestsBlockCallbacks : NSObject +@interface InteropTestsBlockCallbacks : NSObject - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback messageCallback:(void (^)(id))messageCallback @@ -108,7 +108,7 @@ BOOL isRemoteInteropTest(NSString *host) { } } -- (void)receivedMessage:(id)message { +- (void)receivedProtoMessage:(id)message { if (_messageCallback) { _messageCallback(message); } From 9f47e76fc8b72c432e9b3d4711c7b2898236f37b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 16:06:54 -0700 Subject: [PATCH 041/534] QoS for internal dispatch queues --- src/objective-c/GRPCClient/GRPCCall.m | 11 ++++++++--- src/objective-c/ProtoRPC/ProtoRPC.m | 6 +++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index eb9b21eccb0..df50d43e076 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -108,7 +108,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; _handler = responseHandler; _initialMetadataPublished = NO; _pipe = [GRXBufferedPipe pipe]; - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + if (@available(iOS 8.0, *)) { + _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + } else { + // Fallback on earlier versions + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } _started = NO; } @@ -226,7 +231,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - id handler = self->_handler; + id handler = _handler; if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { dispatch_async(handler.dispatchQueue, ^{ [handler receivedInitialMetadata:initialMetadata]; @@ -235,7 +240,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueMessage:(id)message { - id handler = self->_handler; + id handler = _handler; if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { dispatch_async(handler.dispatchQueue, ^{ [handler receivedRawMessage:message]; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 7a57affbf15..b860515d4e4 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -77,7 +77,11 @@ _handler = handler; _callOptions = [callOptions copy]; _responseClass = responseClass; - _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + if (@available(iOS 8.0, *)) { + _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + } else { + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } [self start]; } From b3d236d1bf4acebce821fb7f36c262e34104a9b1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 16:07:35 -0700 Subject: [PATCH 042/534] Prevent empty string --- src/objective-c/GRPCClient/GRPCCall.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index df50d43e076..7b100cb02a1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -380,8 +380,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; callSafety:(GRPCCallSafety)safety requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { - if (!host || !path) { - [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; + if (host.length == 0 || path.length == 0) { + [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil or empty."]; } if (requestWriter.state != GRXWriterStateNotStarted) { [NSException raise:NSInvalidArgumentException From da43545ff7b4b1a6e310ff7fdeec6eb21f0e26b8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 16:38:04 -0700 Subject: [PATCH 043/534] Check callSafety in -init in GRPCCall --- src/objective-c/GRPCClient/GRPCCall.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 7b100cb02a1..50c38ed99ed 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -383,6 +383,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (host.length == 0 || path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil or empty."]; } + if (safety > GRPCCallSafetyCacheableRequest) { + [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; + } if (requestWriter.state != GRXWriterStateNotStarted) { [NSException raise:NSInvalidArgumentException format:@"The requests writer can't be already started."]; @@ -556,8 +559,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; case GRPCCallSafetyCacheableRequest: callSafetyFlags = GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; break; - default: - [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; } uint32_t callFlag = callSafetyFlags; From 7d32a2cb25275e03a44184ad9f8a3e494e62dd0d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 17:10:32 -0700 Subject: [PATCH 044/534] Set user's dispatch queue's handler to internal serial queue --- src/objective-c/GRPCClient/GRPCCall.h | 4 +--- src/objective-c/GRPCClient/GRPCCall.m | 7 +++++++ src/objective-c/ProtoRPC/ProtoRPC.h | 4 +--- src/objective-c/ProtoRPC/ProtoRPC.m | 11 +++++++++++ 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 48f4514a06f..6adecec144a 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -174,9 +174,7 @@ extern id const kGRPCTrailersKey; /** * All the responses must be issued to a user-provided dispatch queue. This property specifies the - * dispatch queue to be used for issuing the notifications. A serial queue should be provided if - * the order of responses (initial metadata, message, message, ..., message, trailing metadata) - * needs to be maintained. + * dispatch queue to be used for issuing the notifications. */ @property(atomic, readonly) dispatch_queue_t dispatchQueue; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 50c38ed99ed..917788e9f2e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -101,6 +101,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; } + if (requestOptions.safety > GRPCCallSafetyCacheableRequest) { + [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; + } + if (responseHandler == nil) { + [NSException raise:NSInvalidArgumentException format:@"Response handler required."]; + } if ((self = [super init])) { _requestOptions = [requestOptions copy]; @@ -114,6 +120,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Fallback on earlier versions _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } + dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); _started = NO; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index d20098ce8c9..db1e8c6deb3 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -48,9 +48,7 @@ /** * All the responses must be issued to a user-provided dispatch queue. This property specifies the - * dispatch queue to be used for issuing the notifications. A serial queue should be provided if - * the order of responses (initial metadata, message, message, ..., message, trailing metadata) - * needs to be maintained. + * dispatch queue to be used for issuing the notifications. */ @property(atomic, readonly) dispatch_queue_t dispatchQueue; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index b860515d4e4..9fb398408bf 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -72,6 +72,16 @@ responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { + if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { + [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; + } + if (requestOptions.safety > GRPCCallSafetyCacheableRequest) { + [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; + } + if (handler == nil) { + [NSException raise:NSInvalidArgumentException format:@"Response handler required."]; + } + if ((self = [super init])) { _requestOptions = [requestOptions copy]; _handler = handler; @@ -82,6 +92,7 @@ } else { _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } + dispatch_set_target_queue(handler.dispatchQueue, _dispatchQueue); [self start]; } From a8b07a37df7680bbe853f4efa0c358447db946fe Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 17:39:51 -0700 Subject: [PATCH 045/534] Synchronized access to kHostCache --- src/objective-c/GRPCClient/private/GRPCHost.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 429958b4083..de6f09a44b2 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -125,7 +125,10 @@ static NSMutableDictionary *kHostCache; if (hostURL.host && !hostURL.port) { address = [hostURL.host stringByAppendingString:@":443"]; } - GRPCHost *cachedHost = kHostCache[address]; + __block GRPCHost *cachedHost; + @synchronized (kHostCache) { + cachedHost = kHostCache[address]; + } return (cachedHost != nil); } From 543fbf38c0ad1690558f7be3d1c58ff445a8714f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 17:40:35 -0700 Subject: [PATCH 046/534] timeout > 0 --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 917788e9f2e..16acca249d6 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -753,7 +753,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (_serverName.length != 0) { callOptions.serverAuthority = _serverName; } - if (_timeout != 0) { + if (_timeout > 0) { callOptions.timeout = _timeout; } uint32_t callFlags = [GRPCCall callFlagsForHost:_host path:_path]; From 6032e960d43af5912d06553adc22012d3f7c758a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 18:06:13 -0700 Subject: [PATCH 047/534] Polish channelID comments --- src/objective-c/GRPCClient/GRPCCallOptions.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index ff575d09cf8..e1a63f83b2e 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -41,6 +41,7 @@ typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { // The transport to be used by a gRPC call typedef NS_ENUM(NSInteger, GRPCTransportType) { + GRPCTransportTypeDefault = 0, // gRPC internal HTTP/2 stack with BoringSSL GRPCTransportTypeChttp2BoringSSL = 0, // Cronet stack @@ -180,8 +181,10 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { @property(copy, readonly) NSString *channelPoolDomain; /** - * Channel id allows a call to force creating a new channel (connection) rather than using a cached - * channel. Calls using distinct channelID will not get cached to the same connection. + * Channel id allows control of channel caching within a channelPoolDomain. A call with a unique + * channelID will create a new channel (connection) instead of reusing an existing one. Multiple + * calls in the same channelPoolDomain using identical channelID are allowed to share connection + * if other channel options are also the same. */ @property(readonly) NSUInteger channelID; From 62fb609df7b9534f188804c43401f6219345577c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 18:10:02 -0700 Subject: [PATCH 048/534] rename kChannelPool->gChannelPool --- src/objective-c/GRPCClient/private/GRPCChannel.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index cf44b96e220..ae90821de03 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -64,7 +64,7 @@ } - (void)unmanagedCallUnref { - [kChannelPool unrefChannelWithConfiguration:_configuration]; + [gChannelPool unrefChannelWithConfiguration:_configuration]; } - (nullable instancetype)initWithUnmanagedChannel:(nullable grpc_channel *)unmanagedChannel @@ -94,12 +94,12 @@ } static dispatch_once_t initChannelPool; -static GRPCChannelPool *kChannelPool; +static GRPCChannelPool *gChannelPool; + (nullable instancetype)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { dispatch_once(&initChannelPool, ^{ - kChannelPool = [[GRPCChannelPool alloc] init]; + gChannelPool = [[GRPCChannelPool alloc] init]; }); NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:host]]; @@ -109,7 +109,7 @@ static GRPCChannelPool *kChannelPool; GRPCChannelConfiguration *channelConfig = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; - return [kChannelPool channelWithConfiguration:channelConfig + return [gChannelPool channelWithConfiguration:channelConfig createChannel:^{ return [GRPCChannel createChannelWithConfiguration:channelConfig]; @@ -117,7 +117,7 @@ static GRPCChannelPool *kChannelPool; } + (void)closeOpenConnections { - [kChannelPool clear]; + [gChannelPool clear]; } @end From 549db7b80b3e6e91aaf08f9f9bf2f932050cc310 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 18:10:48 -0700 Subject: [PATCH 049/534] host == nil -> host.length == 0 --- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index ae90821de03..495af5ebe87 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -82,7 +82,7 @@ + (nullable instancetype)createChannelWithConfiguration:(GRPCChannelConfiguration *)config { NSString *host = config.host; - if (host == nil || [host length] == 0) { + if (host.length == 0) { return nil; } From bc292b87c26ea8f6465443a152e86b3ed71e585b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 18:14:34 -0700 Subject: [PATCH 050/534] polish attributes of GRPCChannelConfiguration --- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 4 ++-- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 1145039549c..2a99089d2f2 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -31,8 +31,8 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCChannelConfiguration : NSObject -@property(atomic, strong, readwrite) NSString *host; -@property(atomic, strong, readwrite) GRPCCallOptions *callOptions; +@property(copy, readonly) NSString *host; +@property(strong, readonly) GRPCCallOptions *callOptions; @property(readonly) id channelFactory; @property(readonly) NSMutableDictionary *channelArgs; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 37e42f8c75b..10a15f5255b 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -141,9 +141,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; } - (nonnull id)copyWithZone:(nullable NSZone *)zone { - GRPCChannelConfiguration *newConfig = [[GRPCChannelConfiguration alloc] init]; - newConfig.host = _host; - newConfig.callOptions = _callOptions; + GRPCChannelConfiguration *newConfig = [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; return newConfig; } From ad5485ae4ef4ec31cb6b3ed54876fd9868343388 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 18:28:16 -0700 Subject: [PATCH 051/534] Make channel args immutable --- src/objective-c/GRPCClient/private/GRPCChannel.m | 10 ++++++++-- .../GRPCClient/private/GRPCChannelFactory.h | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- .../GRPCClient/private/GRPCCronetChannelFactory.h | 2 +- .../GRPCClient/private/GRPCCronetChannelFactory.m | 4 ++-- .../GRPCClient/private/GRPCInsecureChannelFactory.h | 2 +- .../GRPCClient/private/GRPCInsecureChannelFactory.m | 2 +- .../GRPCClient/private/GRPCSecureChannelFactory.h | 2 +- .../GRPCClient/private/GRPCSecureChannelFactory.m | 2 +- 10 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 495af5ebe87..2274fa5d6ab 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -86,8 +86,14 @@ return nil; } - NSMutableDictionary *channelArgs = config.channelArgs; - [channelArgs addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; + NSDictionary *channelArgs; + if (config.callOptions.additionalChannelArgs.count != 0) { + NSMutableDictionary *args = [config.channelArgs copy]; + [args addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; + channelArgs = args; + } else { + channelArgs = config.channelArgs; + } id factory = config.channelFactory; grpc_channel *unmanaged_channel = [factory createChannelWithHost:host channelArgs:channelArgs]; return [[GRPCChannel alloc] initWithUnmanagedChannel:unmanaged_channel configuration:config]; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h index e44f8260dfd..492145da80b 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN @protocol GRPCChannelFactory - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableDictionary *)args; + channelArgs:(nullable NSDictionary *)args; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 2a99089d2f2..1984919fa75 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN @property(strong, readonly) GRPCCallOptions *callOptions; @property(readonly) id channelFactory; -@property(readonly) NSMutableDictionary *channelArgs; +@property(readonly) NSDictionary *channelArgs; - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 10a15f5255b..11c9d4be8dd 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -76,7 +76,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; } } -- (NSMutableDictionary *)channelArgs { +- (NSDictionary *)channelArgs { NSMutableDictionary *args = [NSMutableDictionary new]; NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h index 97e1ae920a0..738dfdb7370 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h @@ -27,7 +27,7 @@ NS_ASSUME_NONNULL_BEGIN + (nullable instancetype)sharedInstance; - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableDictionary *)args; + channelArgs:(nullable NSDictionary *)args; - (nullable instancetype)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 5c0fe16d39b..00b388ebbe0 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -53,7 +53,7 @@ NS_ASSUME_NONNULL_BEGIN } - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableDictionary *)args { + channelArgs:(nullable NSDictionary *)args { // Remove client authority filter since that is not supported args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; @@ -81,7 +81,7 @@ NS_ASSUME_NONNULL_BEGIN } - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableArray *)args { + channelArgs:(nullable NSDictionary *)args { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return nil; diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h index 905a181ca78..2d471aebed6 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h @@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN + (nullable instancetype)sharedInstance; - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableDictionary *)args; + channelArgs:(nullable NSDictionary *)args; - (nullable instancetype)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index 41860bf6ff5..d969b887b40 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN } - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableDictionary *)args { + channelArgs:(nullable NSDictionary *)args { grpc_channel_args *coreChannelArgs = BuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index ab5eee478e1..82af0dc3e68 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN error:(NSError **)errorPtr; - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableDictionary *)args; + channelArgs:(nullable NSDictionary *)args; - (nullable instancetype)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index a0d56e4bdc7..277823c4e33 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -110,7 +110,7 @@ NS_ASSUME_NONNULL_BEGIN } - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableArray *)args { + channelArgs:(nullable NSDictionary *)args { grpc_channel_args *coreChannelArgs = BuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); From da42aa1c1ba38a12450e6b75b20281d6603b3d7e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 10:06:07 -0700 Subject: [PATCH 052/534] Add designated initializer annotation --- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 1984919fa75..5ceb0b6d821 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init; -- (instancetype)initWithChannelDestroyDelay:(NSTimeInterval)channelDestroyDelay; +- (instancetype)initWithChannelDestroyDelay:(NSTimeInterval)channelDestroyDelay NS_DESIGNATED_INITIALIZER; /** * Return a channel with a particular configuration. If the channel does not exist, execute \a From 677ab86b4a8567197550d6969a4d5bd76b8206e1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 10:33:38 -0700 Subject: [PATCH 053/534] rename createChannel -> createChannelCallback --- src/objective-c/GRPCClient/private/GRPCChannel.m | 8 ++++---- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 2274fa5d6ab..bea75d25a98 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -116,10 +116,10 @@ static GRPCChannelPool *gChannelPool; GRPCChannelConfiguration *channelConfig = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; return [gChannelPool channelWithConfiguration:channelConfig - createChannel:^{ - return - [GRPCChannel createChannelWithConfiguration:channelConfig]; - }]; + createChannelCallback:^{ + return + [GRPCChannel createChannelWithConfiguration:channelConfig]; + }]; } + (void)closeOpenConnections { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 5ceb0b6d821..48c35eacb01 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -56,7 +56,7 @@ NS_ASSUME_NONNULL_BEGIN * createChannel then add it in the pool. If the channel exists, increase its reference count. */ - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration - createChannel:(GRPCChannel * (^)(void))createChannel; + createChannelCallback:(GRPCChannel * (^)(void))createChannelCallback; /** Decrease a channel's refcount. */ - (void)unrefChannelWithConfiguration:configuration; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 11c9d4be8dd..680b268dcfa 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -338,14 +338,14 @@ const NSTimeInterval kChannelDestroyDelay = 30; } - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration - createChannel:(GRPCChannel * (^)(void))createChannel { + createChannelCallback:(GRPCChannel * (^)(void))createChannelCallback { __block GRPCChannel *channel; dispatch_sync(_dispatchQueue, ^{ if ([self->_channelPool objectForKey:configuration]) { [self->_callRefs[configuration] refChannel]; channel = self->_channelPool[configuration]; } else { - channel = createChannel(); + channel = createChannelCallback(); self->_channelPool[configuration] = channel; GRPCChannelCallRef *callRef = [[GRPCChannelCallRef alloc] From 86ff72bb4736cb9333505baeb324386cfa24bcb9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 10:49:30 -0700 Subject: [PATCH 054/534] Add missing type information --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 680b268dcfa..c46b9ddfc80 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -363,7 +363,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; return channel; } -- (void)unrefChannelWithConfiguration:configuration { +- (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { dispatch_sync(_dispatchQueue, ^{ if ([self->_channelPool objectForKey:configuration]) { [self->_callRefs[configuration] unrefChannel]; From 8fef0c87893ceda1c5bb7aaa09ddb8dfaefacbdb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 16:59:00 -0700 Subject: [PATCH 055/534] Rewrite the channel pool --- src/objective-c/GRPCClient/GRPCCall.m | 9 +- .../GRPCClient/private/GRPCChannel.h | 13 +- .../GRPCClient/private/GRPCChannel.m | 204 +++++++++++++++--- .../GRPCClient/private/GRPCChannelPool.h | 14 +- .../GRPCClient/private/GRPCChannelPool.m | 139 ++---------- .../tests/ChannelTests/ChannelPoolTest.m | 109 ++++------ 6 files changed, 262 insertions(+), 226 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 16acca249d6..5ffdfbaa89f 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -718,7 +718,14 @@ const char *kCFStreamVarName = "grpc_cfstream"; [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; - NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?"); + if (_wrappedCall == nil) { + [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : @"Failed to create call from channel." + }]]; + return; + } [self sendHeaders]; [self invokeCall]; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 7d5039a8a20..7a40638dc33 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -39,6 +39,11 @@ struct grpc_channel_credentials; + (nullable instancetype)channelWithHost:(nonnull NSString *)host callOptions:(nullable GRPCCallOptions *)callOptions; +/** + * Create a channel object with the signature \a config. + */ ++ (nullable instancetype)createChannelWithConfiguration:(nonnull GRPCChannelConfiguration *)config; + /** * Get a grpc core call object from this channel. */ @@ -46,13 +51,11 @@ struct grpc_channel_credentials; completionQueue:(nonnull GRPCCompletionQueue *)queue callOptions:(nonnull GRPCCallOptions *)callOptions; +- (void)unmanagedCallRef; + - (void)unmanagedCallUnref; -/** - * Create a channel object with the signature \a config. This function is used for testing only. Use - * channelWithHost:callOptions: in production. - */ -+ (nullable instancetype)createChannelWithConfiguration:(nonnull GRPCChannelConfiguration *)config; +- (void)disconnect; // TODO (mxyan): deprecate with GRPCCall:closeOpenConnections + (void)closeOpenConnections; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index bea75d25a98..9e7e1ea1fc6 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -24,7 +24,6 @@ #import "GRPCChannelFactory.h" #import "GRPCChannelPool.h" #import "GRPCCompletionQueue.h" -#import "GRPCConnectivityMonitor.h" #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" @@ -33,38 +32,180 @@ #import #import +// When all calls of a channel are destroyed, destroy the channel after this much seconds. +NSTimeInterval kChannelDestroyDelay = 30; + +/** + * Time the channel destroy when the channel's calls are unreffed. If there's new call, reset the + * timer. + */ +@interface GRPCChannelRef : NSObject + +- (instancetype)initWithDestroyDelay:(NSTimeInterval)destroyDelay + destroyChannelCallback:(void (^)())destroyChannelCallback; + +/** Add call ref count to the channel and maybe reset the timer. */ +- (void)refChannel; + +/** Reduce call ref count to the channel and maybe set the timer. */ +- (void)unrefChannel; + +/** Disconnect the channel immediately. */ +- (void)disconnect; + +@end + +@implementation GRPCChannelRef { + NSTimeInterval _destroyDelay; + // We use dispatch queue for this purpose since timer invalidation must happen on the same + // thread which issued the timer. + dispatch_queue_t _dispatchQueue; + void (^_destroyChannelCallback)(); + + NSUInteger _refCount; + NSTimer *_timer; + BOOL _disconnected; +} + +- (instancetype)initWithDestroyDelay:(NSTimeInterval)destroyDelay + destroyChannelCallback:(void (^)())destroyChannelCallback { + if ((self = [super init])) { + _destroyDelay = destroyDelay; + _destroyChannelCallback = destroyChannelCallback; + + _refCount = 1; + _timer = nil; + _disconnected = NO; + } + return self; +} + +// This function is protected by channel dispatch queue. +- (void)refChannel { + if (!_disconnected) { + _refCount++; + if (_timer) { + [_timer invalidate]; + _timer = nil; + } + } +} + +// This function is protected by channel dispatch queue. +- (void)unrefChannel { + if (!_disconnected) { + _refCount--; + if (_refCount == 0) { + if (_timer) { + [_timer invalidate]; + } + _timer = [NSTimer scheduledTimerWithTimeInterval:self->_destroyDelay + target:self + selector:@selector(timerFire:) + userInfo:nil + repeats:NO]; + } + } +} + +// This function is protected by channel dispatch queue. +- (void)disconnect { + if (!_disconnected) { + if (self->_timer != nil) { + [self->_timer invalidate]; + self->_timer = nil; + } + _disconnected = YES; + // Break retain loop + _destroyChannelCallback = nil; + } +} + +// This function is protected by channel dispatch queue. +- (void)timerFire:(NSTimer *)timer { + if (_disconnected || _timer == nil || _timer != timer) { + return; + } + _timer = nil; + _destroyChannelCallback(); + // Break retain loop + _destroyChannelCallback = nil; + _disconnected = YES; +} + +@end + @implementation GRPCChannel { GRPCChannelConfiguration *_configuration; grpc_channel *_unmanagedChannel; + GRPCChannelRef *_channelRef; + dispatch_queue_t _dispatchQueue; } - (grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(nonnull GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions { - NSString *serverAuthority = callOptions.serverAuthority; - NSTimeInterval timeout = callOptions.timeout; - GPR_ASSERT(timeout >= 0); - grpc_slice host_slice = grpc_empty_slice(); - if (serverAuthority) { - host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); - } - grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); - gpr_timespec deadline_ms = + __block grpc_call *call = nil; + dispatch_sync(_dispatchQueue, ^{ + if (self->_unmanagedChannel) { + NSString *serverAuthority = callOptions.serverAuthority; + NSTimeInterval timeout = callOptions.timeout; + GPR_ASSERT(timeout >= 0); + grpc_slice host_slice = grpc_empty_slice(); + if (serverAuthority) { + host_slice = grpc_slice_from_copied_string(serverAuthority.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_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, - serverAuthority ? &host_slice : NULL, deadline_ms, NULL); - if (serverAuthority) { - grpc_slice_unref(host_slice); - } - grpc_slice_unref(path_slice); + : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + call = grpc_channel_create_call( + self->_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, + serverAuthority ? &host_slice : NULL, deadline_ms, NULL); + if (serverAuthority) { + grpc_slice_unref(host_slice); + } + grpc_slice_unref(path_slice); + } + }); return call; } +- (void)unmanagedCallRef { + dispatch_async(_dispatchQueue, ^{ + if (self->_unmanagedChannel) { + [self->_channelRef refChannel]; + } + }); +} + - (void)unmanagedCallUnref { - [gChannelPool unrefChannelWithConfiguration:_configuration]; + dispatch_async(_dispatchQueue, ^{ + if (self->_unmanagedChannel) { + [self->_channelRef unrefChannel]; + } + }); +} + +- (void)disconnect { + dispatch_async(_dispatchQueue, ^{ + if (self->_unmanagedChannel) { + grpc_channel_destroy(self->_unmanagedChannel); + self->_unmanagedChannel = nil; + [self->_channelRef disconnect]; + } + }); +} + +- (void)destroyChannel { + dispatch_async(_dispatchQueue, ^{ + if (self->_unmanagedChannel) { + grpc_channel_destroy(self->_unmanagedChannel); + self->_unmanagedChannel = nil; + [gChannelPool removeChannelWithConfiguration:self->_configuration]; + } + }); } - (nullable instancetype)initWithUnmanagedChannel:(nullable grpc_channel *)unmanagedChannel @@ -72,12 +213,22 @@ if ((self = [super init])) { _unmanagedChannel = unmanagedChannel; _configuration = configuration; + _channelRef = [[GRPCChannelRef alloc] initWithDestroyDelay:kChannelDestroyDelay destroyChannelCallback:^{ + [self destroyChannel]; + }]; + if (@available(iOS 8.0, *)) { + _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + } else { + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } } return self; } - (void)dealloc { - grpc_channel_destroy(_unmanagedChannel); + if (_unmanagedChannel) { + grpc_channel_destroy(_unmanagedChannel); + } } + (nullable instancetype)createChannelWithConfiguration:(GRPCChannelConfiguration *)config { @@ -88,7 +239,7 @@ NSDictionary *channelArgs; if (config.callOptions.additionalChannelArgs.count != 0) { - NSMutableDictionary *args = [config.channelArgs copy]; + NSMutableDictionary *args = [config.channelArgs mutableCopy]; [args addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; channelArgs = args; } else { @@ -115,15 +266,12 @@ static GRPCChannelPool *gChannelPool; GRPCChannelConfiguration *channelConfig = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; - return [gChannelPool channelWithConfiguration:channelConfig - createChannelCallback:^{ - return - [GRPCChannel createChannelWithConfiguration:channelConfig]; - }]; + + return [gChannelPool channelWithConfiguration:channelConfig]; } + (void)closeOpenConnections { - [gChannelPool clear]; + [gChannelPool removeAndCloseAllChannels]; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 48c35eacb01..bd1350c15d2 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -49,20 +49,20 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init; -- (instancetype)initWithChannelDestroyDelay:(NSTimeInterval)channelDestroyDelay NS_DESIGNATED_INITIALIZER; - /** * Return a channel with a particular configuration. If the channel does not exist, execute \a * createChannel then add it in the pool. If the channel exists, increase its reference count. */ -- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration - createChannelCallback:(GRPCChannel * (^)(void))createChannelCallback; +- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration; -/** Decrease a channel's refcount. */ -- (void)unrefChannelWithConfiguration:configuration; +/** Remove a channel with particular configuration. */ +- (void)removeChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; /** Clear all channels in the pool. */ -- (void)clear; +- (void)removeAllChannels; + +/** Clear all channels in the pool and destroy the channels. */ +- (void)removeAndCloseAllChannels; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index c46b9ddfc80..7c0a8a8621d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -18,6 +18,7 @@ #import +#import "GRPCChannel.h" #import "GRPCChannelFactory.h" #import "GRPCChannelPool.h" #import "GRPCConnectivityMonitor.h" @@ -31,9 +32,6 @@ extern const char *kCFStreamVarName; -// When all calls of a channel are destroyed, destroy the channel after this much seconds. -const NSTimeInterval kChannelDestroyDelay = 30; - @implementation GRPCChannelConfiguration - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { @@ -216,109 +214,22 @@ const NSTimeInterval kChannelDestroyDelay = 30; @end -/** - * Time the channel destroy when the channel's calls are unreffed. If there's new call, reset the - * timer. - */ -@interface GRPCChannelCallRef : NSObject - -- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)configuration - destroyDelay:(NSTimeInterval)destroyDelay - dispatchQueue:(dispatch_queue_t)dispatchQueue - destroyChannel:(void (^)())destroyChannel; - -/** Add call ref count to the channel and maybe reset the timer. */ -- (void)refChannel; - -/** Reduce call ref count to the channel and maybe set the timer. */ -- (void)unrefChannel; - -@end - -@implementation GRPCChannelCallRef { - GRPCChannelConfiguration *_configuration; - NSTimeInterval _destroyDelay; - // We use dispatch queue for this purpose since timer invalidation must happen on the same - // thread which issued the timer. - dispatch_queue_t _dispatchQueue; - void (^_destroyChannel)(); - - NSUInteger _refCount; - NSTimer *_timer; -} - -- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)configuration - destroyDelay:(NSTimeInterval)destroyDelay - dispatchQueue:(dispatch_queue_t)dispatchQueue - destroyChannel:(void (^)())destroyChannel { - if ((self = [super init])) { - _configuration = configuration; - _destroyDelay = destroyDelay; - _dispatchQueue = dispatchQueue; - _destroyChannel = destroyChannel; - - _refCount = 0; - _timer = nil; - } - return self; -} - -// This function is protected by channel pool dispatch queue. -- (void)refChannel { - _refCount++; - if (_timer) { - [_timer invalidate]; - } - _timer = nil; -} - -// This function is protected by channel spool dispatch queue. -- (void)unrefChannel { - self->_refCount--; - if (self->_refCount == 0) { - if (self->_timer) { - [self->_timer invalidate]; - } - self->_timer = [NSTimer scheduledTimerWithTimeInterval:self->_destroyDelay - target:self - selector:@selector(timerFire:) - userInfo:nil - repeats:NO]; - } -} - -- (void)timerFire:(NSTimer *)timer { - dispatch_sync(_dispatchQueue, ^{ - if (self->_timer == nil || self->_timer != timer) { - return; - } - self->_timer = nil; - self->_destroyChannel(self->_configuration); - }); -} - -@end - #pragma mark GRPCChannelPool @implementation GRPCChannelPool { - NSTimeInterval _channelDestroyDelay; NSMutableDictionary *_channelPool; - NSMutableDictionary *_callRefs; // Dedicated queue for timer dispatch_queue_t _dispatchQueue; } - (instancetype)init { - return [self initWithChannelDestroyDelay:kChannelDestroyDelay]; -} - -- (instancetype)initWithChannelDestroyDelay:(NSTimeInterval)channelDestroyDelay { if ((self = [super init])) { - _channelDestroyDelay = channelDestroyDelay; _channelPool = [NSMutableDictionary dictionary]; - _callRefs = [NSMutableDictionary dictionary]; - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + if (@available(iOS 8.0, *)) { + _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + } else { + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); @@ -337,49 +248,43 @@ const NSTimeInterval kChannelDestroyDelay = 30; } } -- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration - createChannelCallback:(GRPCChannel * (^)(void))createChannelCallback { +- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration { __block GRPCChannel *channel; dispatch_sync(_dispatchQueue, ^{ if ([self->_channelPool objectForKey:configuration]) { - [self->_callRefs[configuration] refChannel]; channel = self->_channelPool[configuration]; + [channel unmanagedCallRef]; } else { - channel = createChannelCallback(); + channel = [GRPCChannel createChannelWithConfiguration:configuration]; self->_channelPool[configuration] = channel; - - GRPCChannelCallRef *callRef = [[GRPCChannelCallRef alloc] - initWithChannelConfiguration:configuration - destroyDelay:self->_channelDestroyDelay - dispatchQueue:self->_dispatchQueue - destroyChannel:^(GRPCChannelConfiguration *configuration) { - [self->_channelPool removeObjectForKey:configuration]; - [self->_callRefs removeObjectForKey:configuration]; - }]; - [callRef refChannel]; - self->_callRefs[configuration] = callRef; } }); return channel; } -- (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { +- (void)removeChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { + dispatch_async(_dispatchQueue, ^{ + [self->_channelPool removeObjectForKey:configuration]; + }); +} + +- (void)removeAllChannels { dispatch_sync(_dispatchQueue, ^{ - if ([self->_channelPool objectForKey:configuration]) { - [self->_callRefs[configuration] unrefChannel]; - } + self->_channelPool = [NSMutableDictionary dictionary]; }); } -- (void)clear { +- (void)removeAndCloseAllChannels { dispatch_sync(_dispatchQueue, ^{ + [self->_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannel * _Nonnull obj, BOOL * _Nonnull stop) { + [obj disconnect]; + }]; self->_channelPool = [NSMutableDictionary dictionary]; - self->_callRefs = [NSMutableDictionary dictionary]; }); } - (void)connectivityChange:(NSNotification *)note { - [self clear]; + [self removeAndCloseAllChannels]; } @end diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index 9e1c9eca746..b195b747a12 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -44,83 +44,68 @@ NSString *kDummyHost = @"dummy.host"; [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelConfiguration *config2 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initWithChannelDestroyDelay:1]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - __weak XCTestExpectation *expectCreateChannel = - [self expectationWithDescription:@"Create first channel"]; - GRPCChannel *channel1 = - [pool channelWithConfiguration:config1 - createChannel:^{ - [expectCreateChannel fulfill]; - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; - GRPCChannel *channel2 = [pool channelWithConfiguration:config2 - createChannel:^{ - XCTFail(@"Should not create a second channel."); - return (GRPCChannel *)nil; - }]; + GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; + GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; XCTAssertEqual(channel1, channel2); } -- (void)testChannelTimeout { - NSTimeInterval kChannelDestroyDelay = 1.0; +- (void)testChannelRemove { GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; options1.transportType = GRPCTransportTypeInsecure; GRPCChannelConfiguration *config1 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelPool *pool = - [[GRPCChannelPool alloc] initWithChannelDestroyDelay:kChannelDestroyDelay]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCChannel *channel1 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; - [pool unrefChannelWithConfiguration:config1]; - __weak XCTestExpectation *expectTimerDone = [self expectationWithDescription:@"Timer elapse."]; - NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:kChannelDestroyDelay + 1 - repeats:NO - block:^(NSTimer *_Nonnull timer) { - [expectTimerDone fulfill]; - }]; - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; - timer = nil; + [pool channelWithConfiguration:config1]; + [pool removeChannelWithConfiguration:config1]; GRPCChannel *channel2 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; + [pool channelWithConfiguration:config1]; XCTAssertNotEqual(channel1, channel2); } +extern NSTimeInterval kChannelDestroyDelay; + - (void)testChannelTimeoutCancel { - NSTimeInterval kChannelDestroyDelay = 3.0; + NSTimeInterval kOriginalInterval = kChannelDestroyDelay; + kChannelDestroyDelay = 3.0; GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; options1.transportType = GRPCTransportTypeInsecure; GRPCChannelConfiguration *config1 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelPool *pool = - [[GRPCChannelPool alloc] initWithChannelDestroyDelay:kChannelDestroyDelay]; + [[GRPCChannelPool alloc] init]; GRPCChannel *channel1 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; + [pool channelWithConfiguration:config1]; [channel1 unmanagedCallUnref]; sleep(1); GRPCChannel *channel2 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; + [pool channelWithConfiguration:config1]; XCTAssertEqual(channel1, channel2); sleep((int)kChannelDestroyDelay + 2); GRPCChannel *channel3 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; + [pool channelWithConfiguration:config1]; XCTAssertEqual(channel1, channel3); + kChannelDestroyDelay = kOriginalInterval; +} + +- (void)testChannelDisconnect { + NSString *kDummyHost = @"dummy.host"; + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; + options1.transportType = GRPCTransportTypeInsecure; + GRPCCallOptions *options2 = [options1 copy]; + GRPCChannelConfiguration *config1 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; + GRPCChannelConfiguration *config2 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + + + GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; + [pool removeAndCloseAllChannels]; + GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; + XCTAssertNotEqual(channel1, channel2); } - (void)testClearChannels { @@ -132,31 +117,19 @@ NSString *kDummyHost = @"dummy.host"; [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelConfiguration *config2 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initWithChannelDestroyDelay:1]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCChannel *channel1 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; + [pool channelWithConfiguration:config1]; GRPCChannel *channel2 = - [pool channelWithConfiguration:config2 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config2]; - }]; + [pool channelWithConfiguration:config2]; XCTAssertNotEqual(channel1, channel2); - [pool clear]; + [pool removeAndCloseAllChannels]; GRPCChannel *channel3 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; + [pool channelWithConfiguration:config1]; GRPCChannel *channel4 = - [pool channelWithConfiguration:config2 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config2]; - }]; + [pool channelWithConfiguration:config2]; XCTAssertNotEqual(channel1, channel3); XCTAssertNotEqual(channel2, channel4); } From d47f4b4c23a9dab2813e9b521d2545ea26d0105c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 17:06:16 -0700 Subject: [PATCH 056/534] Check return value rather than error --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 7c0a8a8621d..740eeaf6cf8 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -36,8 +36,8 @@ extern const char *kCFStreamVarName; - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { if ((self = [super init])) { - _host = host; - _callOptions = callOptions; + _host = [host copy]; + _callOptions = [callOptions copy]; } return self; } @@ -56,9 +56,8 @@ extern const char *kCFStreamVarName; privateKey:_callOptions.PEMPrivateKey certChain:_callOptions.PEMCertChain error:&error]; - if (error) { + if (factory == nil) { NSLog(@"Error creating secure channel factory: %@", error); - return nil; } return factory; #ifdef GRPC_COMPILE_WITH_CRONET From f48c90606f246afab3a2aa1e1547578c4c34292a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 17:46:09 -0700 Subject: [PATCH 057/534] Add isChannelOptionsEqualTo: to GRPCCallOptions --- src/objective-c/GRPCClient/GRPCCallOptions.h | 5 +++ src/objective-c/GRPCClient/GRPCCallOptions.m | 40 +++++++++++++++++++ .../GRPCClient/private/GRPCChannelPool.m | 38 +----------------- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index e1a63f83b2e..bf03938b272 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -188,6 +188,11 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ @property(readonly) NSUInteger channelID; +/** + * Return if the channel options are equal to another object. + */ +- (BOOL)isChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; + @end @interface GRPCMutableCallOptions : GRPCCallOptions diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index b19917d7784..1fc8c9fb1af 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -227,6 +227,46 @@ static NSUInteger kDefaultChannelID = 0; return newOptions; } +- (BOOL)isChannelOptionsEqualTo:(GRPCCallOptions *)callOptions { + if (!(callOptions.userAgentPrefix == _userAgentPrefix || + [callOptions.userAgentPrefix isEqualToString:_userAgentPrefix])) + return NO; + if (!(callOptions.responseSizeLimit == _responseSizeLimit)) return NO; + if (!(callOptions.compressAlgorithm == _compressAlgorithm)) return NO; + if (!(callOptions.enableRetry == _enableRetry)) return NO; + if (!(callOptions.keepaliveInterval == _keepaliveInterval)) return NO; + if (!(callOptions.keepaliveTimeout == _keepaliveTimeout)) return NO; + if (!(callOptions.connectMinTimeout == _connectMinTimeout)) return NO; + if (!(callOptions.connectInitialBackoff == _connectInitialBackoff)) return NO; + if (!(callOptions.connectMaxBackoff == _connectMaxBackoff)) return NO; + if (!(callOptions.additionalChannelArgs == _additionalChannelArgs || + [callOptions.additionalChannelArgs + isEqualToDictionary:_additionalChannelArgs])) + return NO; + if (!(callOptions.PEMRootCertificates == _PEMRootCertificates || + [callOptions.PEMRootCertificates isEqualToString:_PEMRootCertificates])) + return NO; + if (!(callOptions.PEMPrivateKey == _PEMPrivateKey || + [callOptions.PEMPrivateKey isEqualToString:_PEMPrivateKey])) + return NO; + if (!(callOptions.PEMCertChain == _PEMCertChain || + [callOptions.PEMCertChain isEqualToString:_PEMCertChain])) + return NO; + if (!(callOptions.hostNameOverride == _hostNameOverride || + [callOptions.hostNameOverride isEqualToString:_hostNameOverride])) + return NO; + if (!(callOptions.transportType == _transportType)) return NO; + if (!(callOptions.logContext == _logContext || + [callOptions.logContext isEqual:_logContext])) + return NO; + if (!(callOptions.channelPoolDomain == _channelPoolDomain || + [callOptions.channelPoolDomain isEqualToString:_channelPoolDomain])) + return NO; + if (!(callOptions.channelID == _channelID)) return NO; + + return YES; +} + @end @implementation GRPCMutableCallOptions diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 740eeaf6cf8..995212fdb6d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -68,8 +68,6 @@ extern const char *kCFStreamVarName; return [GRPCCronetChannelFactory sharedInstance]; case GRPCTransportTypeInsecure: return [GRPCInsecureChannelFactory sharedInstance]; - default: - GPR_UNREACHABLE_CODE(return nil); } } @@ -147,41 +145,7 @@ extern const char *kCFStreamVarName; NSAssert([object isKindOfClass:[GRPCChannelConfiguration class]], @"Illegal :isEqual"); GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; if (!(obj.host == _host || [obj.host isEqualToString:_host])) return NO; - if (!(obj.callOptions.userAgentPrefix == _callOptions.userAgentPrefix || - [obj.callOptions.userAgentPrefix isEqualToString:_callOptions.userAgentPrefix])) - return NO; - if (!(obj.callOptions.responseSizeLimit == _callOptions.responseSizeLimit)) return NO; - if (!(obj.callOptions.compressAlgorithm == _callOptions.compressAlgorithm)) return NO; - if (!(obj.callOptions.enableRetry == _callOptions.enableRetry)) return NO; - if (!(obj.callOptions.keepaliveInterval == _callOptions.keepaliveInterval)) return NO; - if (!(obj.callOptions.keepaliveTimeout == _callOptions.keepaliveTimeout)) return NO; - if (!(obj.callOptions.connectMinTimeout == _callOptions.connectMinTimeout)) return NO; - if (!(obj.callOptions.connectInitialBackoff == _callOptions.connectInitialBackoff)) return NO; - if (!(obj.callOptions.connectMaxBackoff == _callOptions.connectMaxBackoff)) return NO; - if (!(obj.callOptions.additionalChannelArgs == _callOptions.additionalChannelArgs || - [obj.callOptions.additionalChannelArgs - isEqualToDictionary:_callOptions.additionalChannelArgs])) - return NO; - if (!(obj.callOptions.PEMRootCertificates == _callOptions.PEMRootCertificates || - [obj.callOptions.PEMRootCertificates isEqualToString:_callOptions.PEMRootCertificates])) - return NO; - if (!(obj.callOptions.PEMPrivateKey == _callOptions.PEMPrivateKey || - [obj.callOptions.PEMPrivateKey isEqualToString:_callOptions.PEMPrivateKey])) - return NO; - if (!(obj.callOptions.PEMCertChain == _callOptions.PEMCertChain || - [obj.callOptions.PEMCertChain isEqualToString:_callOptions.PEMCertChain])) - return NO; - if (!(obj.callOptions.hostNameOverride == _callOptions.hostNameOverride || - [obj.callOptions.hostNameOverride isEqualToString:_callOptions.hostNameOverride])) - return NO; - if (!(obj.callOptions.transportType == _callOptions.transportType)) return NO; - if (!(obj.callOptions.logContext == _callOptions.logContext || - [obj.callOptions.logContext isEqual:_callOptions.logContext])) - return NO; - if (!(obj.callOptions.channelPoolDomain == _callOptions.channelPoolDomain || - [obj.callOptions.channelPoolDomain isEqualToString:_callOptions.channelPoolDomain])) - return NO; - if (!(obj.callOptions.channelID == _callOptions.channelID)) return NO; + if (!(obj.callOptions == _callOptions || [obj.callOptions isChannelOptionsEqualTo:_callOptions])) return NO; return YES; } From d578b4321812715de7fe615a1ae8624fd05f1c69 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 18:01:14 -0700 Subject: [PATCH 058/534] Add channelOptionsHash: to GRPCCChannelOptions --- src/objective-c/GRPCClient/GRPCCallOptions.h | 5 ++++ src/objective-c/GRPCClient/GRPCCallOptions.m | 24 +++++++++++++++++++ .../GRPCClient/private/GRPCChannelPool.m | 19 +-------------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index bf03938b272..8864bcb8a2f 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -193,6 +193,11 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ - (BOOL)isChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; +/** + * Hash for channel options. + */ +@property(readonly) NSUInteger channelOptionsHash; + @end @interface GRPCMutableCallOptions : GRPCCallOptions diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 1fc8c9fb1af..8d2b84b7484 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -267,6 +267,30 @@ static NSUInteger kDefaultChannelID = 0; return YES; } +- (NSUInteger)channelOptionsHash { + NSUInteger result = 0; + result ^= _userAgentPrefix.hash; + result ^= _responseSizeLimit; + result ^= _compressAlgorithm; + result ^= _enableRetry; + result ^= (unsigned int)(_keepaliveInterval * 1000); + result ^= (unsigned int)(_keepaliveTimeout * 1000); + result ^= (unsigned int)(_connectMinTimeout * 1000); + result ^= (unsigned int)(_connectInitialBackoff * 1000); + result ^= (unsigned int)(_connectMaxBackoff * 1000); + result ^= _additionalChannelArgs.hash; + result ^= _PEMRootCertificates.hash; + result ^= _PEMPrivateKey.hash; + result ^= _PEMCertChain.hash; + result ^= _hostNameOverride.hash; + result ^= _transportType; + result ^= [_logContext hash]; + result ^= _channelPoolDomain.hash; + result ^= _channelID; + + return result; +} + @end @implementation GRPCMutableCallOptions diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 995212fdb6d..4fae7d57ca2 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -153,24 +153,7 @@ extern const char *kCFStreamVarName; - (NSUInteger)hash { NSUInteger result = 0; result ^= _host.hash; - result ^= _callOptions.userAgentPrefix.hash; - result ^= _callOptions.responseSizeLimit; - result ^= _callOptions.compressAlgorithm; - result ^= _callOptions.enableRetry; - result ^= (unsigned int)(_callOptions.keepaliveInterval * 1000); - result ^= (unsigned int)(_callOptions.keepaliveTimeout * 1000); - result ^= (unsigned int)(_callOptions.connectMinTimeout * 1000); - result ^= (unsigned int)(_callOptions.connectInitialBackoff * 1000); - result ^= (unsigned int)(_callOptions.connectMaxBackoff * 1000); - result ^= _callOptions.additionalChannelArgs.hash; - result ^= _callOptions.PEMRootCertificates.hash; - result ^= _callOptions.PEMPrivateKey.hash; - result ^= _callOptions.PEMCertChain.hash; - result ^= _callOptions.hostNameOverride.hash; - result ^= _callOptions.transportType; - result ^= [_callOptions.logContext hash]; - result ^= _callOptions.channelPoolDomain.hash; - result ^= _callOptions.channelID; + result ^= _callOptions.channelOptionsHash; return result; } From 34e4db810fcf08f51ee5104561426fc736308216 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 18:04:42 -0700 Subject: [PATCH 059/534] Take advantage of nil messaging --- src/objective-c/GRPCClient/private/GRPCChannel.m | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 9e7e1ea1fc6..5e0b37c1b82 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -84,10 +84,8 @@ NSTimeInterval kChannelDestroyDelay = 30; - (void)refChannel { if (!_disconnected) { _refCount++; - if (_timer) { - [_timer invalidate]; - _timer = nil; - } + [_timer invalidate]; + _timer = nil; } } @@ -96,9 +94,7 @@ NSTimeInterval kChannelDestroyDelay = 30; if (!_disconnected) { _refCount--; if (_refCount == 0) { - if (_timer) { - [_timer invalidate]; - } + [_timer invalidate]; _timer = [NSTimer scheduledTimerWithTimeInterval:self->_destroyDelay target:self selector:@selector(timerFire:) @@ -111,10 +107,8 @@ NSTimeInterval kChannelDestroyDelay = 30; // This function is protected by channel dispatch queue. - (void)disconnect { if (!_disconnected) { - if (self->_timer != nil) { - [self->_timer invalidate]; - self->_timer = nil; - } + [_timer invalidate]; + _timer = nil; _disconnected = YES; // Break retain loop _destroyChannelCallback = nil; From be4ab30899f6ae91e07f02c33297ca462f778296 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 18:05:22 -0700 Subject: [PATCH 060/534] Remove dereferencing --- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 5e0b37c1b82..a17cc253feb 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -95,7 +95,7 @@ NSTimeInterval kChannelDestroyDelay = 30; _refCount--; if (_refCount == 0) { [_timer invalidate]; - _timer = [NSTimer scheduledTimerWithTimeInterval:self->_destroyDelay + _timer = [NSTimer scheduledTimerWithTimeInterval:_destroyDelay target:self selector:@selector(timerFire:) userInfo:nil From 67a4eb6623d0870992051d0280b78dd7a2b2c0ff Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 09:53:41 -0700 Subject: [PATCH 061/534] Lock GRPCCall in GRPCAuthorizatioProtocol --- src/objective-c/GRPCClient/GRPCCall.m | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 5ffdfbaa89f..68f0f8892d7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -461,10 +461,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)cancel { - if (!self.isWaitingForToken) { - [self cancelCall]; - } else { - self.isWaitingForToken = NO; + @synchronized (self) { + if (!self.isWaitingForToken) { + [self cancelCall]; + } else { + self.isWaitingForToken = NO; + } } [self maybeFinishWithError:[NSError @@ -779,14 +781,18 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = callOptions; } if (_callOptions.authTokenProvider != nil) { - self.isWaitingForToken = YES; + @synchronized (self) { + self.isWaitingForToken = YES; + } [self.tokenProvider getTokenWithHandler:^(NSString *token) { - if (self.isWaitingForToken) { - if (token) { - self->_fetchedOauth2AccessToken = [token copy]; + @synchronized (self) { + if (self.isWaitingForToken) { + if (token) { + self->_fetchedOauth2AccessToken = [token copy]; + } + [self startCallWithWriteable:writeable]; + self.isWaitingForToken = NO; } - [self startCallWithWriteable:writeable]; - self.isWaitingForToken = NO; } }]; } else { From ac211b4214b9a5bbc00631b61af396557837b9fb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 10:39:48 -0700 Subject: [PATCH 062/534] Use dispatch_after for delayed destroy of channel --- .../GRPCClient/private/GRPCChannel.m | 87 ++++++++++--------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index a17cc253feb..a91949684c4 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -57,14 +57,13 @@ NSTimeInterval kChannelDestroyDelay = 30; @implementation GRPCChannelRef { NSTimeInterval _destroyDelay; - // We use dispatch queue for this purpose since timer invalidation must happen on the same - // thread which issued the timer. - dispatch_queue_t _dispatchQueue; void (^_destroyChannelCallback)(); NSUInteger _refCount; - NSTimer *_timer; BOOL _disconnected; + dispatch_queue_t _dispatchQueue; + dispatch_queue_t _timerQueue; + NSDate *_lastDispatch; } - (instancetype)initWithDestroyDelay:(NSTimeInterval)destroyDelay @@ -74,57 +73,65 @@ NSTimeInterval kChannelDestroyDelay = 30; _destroyChannelCallback = destroyChannelCallback; _refCount = 1; - _timer = nil; _disconnected = NO; + if (@available(iOS 8.0, *)) { + _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + _timerQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_DEFAULT, -1)); + } else { + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + _timerQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); + } + _lastDispatch = nil; } return self; } -// This function is protected by channel dispatch queue. - (void)refChannel { - if (!_disconnected) { - _refCount++; - [_timer invalidate]; - _timer = nil; - } + dispatch_async(_dispatchQueue, ^{ + if (!self->_disconnected) { + self->_refCount++; + self->_lastDispatch = nil; + } + }); } -// This function is protected by channel dispatch queue. - (void)unrefChannel { - if (!_disconnected) { - _refCount--; - if (_refCount == 0) { - [_timer invalidate]; - _timer = [NSTimer scheduledTimerWithTimeInterval:_destroyDelay - target:self - selector:@selector(timerFire:) - userInfo:nil - repeats:NO]; + dispatch_async(_dispatchQueue, ^{ + if (!self->_disconnected) { + self->_refCount--; + if (self->_refCount == 0) { + self->_lastDispatch = [NSDate date]; + dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)kChannelDestroyDelay * 1e9); + dispatch_after(delay, self->_timerQueue, ^{ + [self timerFire]; + }); + } } - } + }); } -// This function is protected by channel dispatch queue. - (void)disconnect { - if (!_disconnected) { - [_timer invalidate]; - _timer = nil; - _disconnected = YES; - // Break retain loop - _destroyChannelCallback = nil; - } + dispatch_async(_dispatchQueue, ^{ + if (!self->_disconnected) { + self->_lastDispatch = nil; + self->_disconnected = YES; + // Break retain loop + self->_destroyChannelCallback = nil; + } + }); } -// This function is protected by channel dispatch queue. -- (void)timerFire:(NSTimer *)timer { - if (_disconnected || _timer == nil || _timer != timer) { - return; - } - _timer = nil; - _destroyChannelCallback(); - // Break retain loop - _destroyChannelCallback = nil; - _disconnected = YES; +- (void)timerFire { + dispatch_async(_dispatchQueue, ^{ + if (self->_disconnected || self->_lastDispatch == nil || -[self->_lastDispatch timeIntervalSinceNow] < -kChannelDestroyDelay) { + return; + } + self->_lastDispatch = nil; + self->_disconnected = YES; + self->_destroyChannelCallback(); + // Break retain loop + self->_destroyChannelCallback = nil; + }); } @end From 7871fedfd6e594ac5935d2018b9680e18979991c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 11:13:22 -0700 Subject: [PATCH 063/534] always unregister observer --- src/objective-c/GRPCClient/GRPCCall.m | 6 +----- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 68f0f8892d7..a142c669db0 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -445,11 +445,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; [_responseWriteable enqueueSuccessfulCompletion]; } - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor unregisterObserver:self]; - } + [GRPCConnectivityMonitor unregisterObserver:self]; // If the call isn't retained anywhere else, it can be deallocated now. _retainSelf = nil; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 4fae7d57ca2..5707e7f9507 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -187,11 +187,7 @@ extern const char *kCFStreamVarName; } - (void)dealloc { - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor unregisterObserver:self]; - } + [GRPCConnectivityMonitor unregisterObserver:self]; } - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration { From 4af17518c023cd32bc98c796d6f99e4f4978f49a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 11:42:41 -0700 Subject: [PATCH 064/534] Use simple locking in GRPCChannelPool --- .../GRPCClient/private/GRPCChannelPool.m | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 5707e7f9507..bfc624eb4ea 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -164,18 +164,11 @@ extern const char *kCFStreamVarName; @implementation GRPCChannelPool { NSMutableDictionary *_channelPool; - // Dedicated queue for timer - dispatch_queue_t _dispatchQueue; } - (instancetype)init { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; - if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); - } else { - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); @@ -192,37 +185,39 @@ extern const char *kCFStreamVarName; - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration { __block GRPCChannel *channel; - dispatch_sync(_dispatchQueue, ^{ - if ([self->_channelPool objectForKey:configuration]) { - channel = self->_channelPool[configuration]; + @synchronized(self) { + if ([_channelPool objectForKey:configuration]) { + channel = _channelPool[configuration]; [channel unmanagedCallRef]; } else { channel = [GRPCChannel createChannelWithConfiguration:configuration]; - self->_channelPool[configuration] = channel; + if (channel != nil) { + _channelPool[configuration] = channel; + } } - }); + } return channel; } - (void)removeChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { - dispatch_async(_dispatchQueue, ^{ + @synchronized(self) { [self->_channelPool removeObjectForKey:configuration]; - }); + } } - (void)removeAllChannels { - dispatch_sync(_dispatchQueue, ^{ - self->_channelPool = [NSMutableDictionary dictionary]; - }); + @synchronized(self) { + _channelPool = [NSMutableDictionary dictionary]; + } } - (void)removeAndCloseAllChannels { - dispatch_sync(_dispatchQueue, ^{ - [self->_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannel * _Nonnull obj, BOOL * _Nonnull stop) { + @synchronized(self) { + [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannel * _Nonnull obj, BOOL * _Nonnull stop) { [obj disconnect]; }]; - self->_channelPool = [NSMutableDictionary dictionary]; - }); + _channelPool = [NSMutableDictionary dictionary]; + } } - (void)connectivityChange:(NSNotification *)note { From 3bdf794bd031162913f533a2a9535f4066a41abd Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 11:50:00 -0700 Subject: [PATCH 065/534] Handle channel nil case --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index a142c669db0..0facf97e09e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -720,7 +720,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{ - NSLocalizedDescriptionKey : @"Failed to create call from channel." + NSLocalizedDescriptionKey : @"Failed to create call or channel." }]]; return; } From a0f83554bbe47d9d99d6e3146a8ec7ba3a129b63 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 12:11:29 -0700 Subject: [PATCH 066/534] remove channel from pool with pointer rather than config --- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 4 ++-- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 8 ++++++-- src/objective-c/tests/ChannelTests/ChannelPoolTest.m | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index a91949684c4..2420988f427 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -204,7 +204,7 @@ NSTimeInterval kChannelDestroyDelay = 30; if (self->_unmanagedChannel) { grpc_channel_destroy(self->_unmanagedChannel); self->_unmanagedChannel = nil; - [gChannelPool removeChannelWithConfiguration:self->_configuration]; + [gChannelPool removeChannel:self]; } }); } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index bd1350c15d2..e9c2ef2bd14 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -55,8 +55,8 @@ NS_ASSUME_NONNULL_BEGIN */ - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration; -/** Remove a channel with particular configuration. */ -- (void)removeChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; +/** Remove a channel from the pool. */ +- (void)removeChannel:(GRPCChannel *)channel; /** Clear all channels in the pool. */ - (void)removeAllChannels; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index bfc624eb4ea..b5b3ff60efa 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -199,9 +199,13 @@ extern const char *kCFStreamVarName; return channel; } -- (void)removeChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { +- (void)removeChannel:(GRPCChannel *)channel { @synchronized(self) { - [self->_channelPool removeObjectForKey:configuration]; + [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannel * _Nonnull obj, BOOL * _Nonnull stop) { + if (obj == channel) { + [self->_channelPool removeObjectForKey:key]; + } + }]; } } diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index b195b747a12..db64ac6339e 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -59,7 +59,7 @@ NSString *kDummyHost = @"dummy.host"; GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - [pool removeChannelWithConfiguration:config1]; + [pool removeChannel:channel1]; GRPCChannel *channel2 = [pool channelWithConfiguration:config1]; XCTAssertNotEqual(channel1, channel2); From 1a88be4edfba35732236956e6e835ecd5c9de13d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 13:56:03 -0700 Subject: [PATCH 067/534] Prefix functions in ChannelArgsUtil --- src/objective-c/GRPCClient/private/ChannelArgsUtil.h | 4 ++-- src/objective-c/GRPCClient/private/ChannelArgsUtil.m | 4 ++-- .../GRPCClient/private/GRPCInsecureChannelFactory.m | 4 ++-- src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h index d9d6933c6bb..d0be4849105 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h @@ -20,6 +20,6 @@ #include -void FreeChannelArgs(grpc_channel_args* channel_args); +void GRPCFreeChannelArgs(grpc_channel_args* channel_args); -grpc_channel_args* BuildChannelArgs(NSDictionary* dictionary); +grpc_channel_args* GRPCBuildChannelArgs(NSDictionary* dictionary); diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index b26fb12d597..8669f79992c 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -39,7 +39,7 @@ 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}; -void FreeChannelArgs(grpc_channel_args *channel_args) { +void GRPCFreeChannelArgs(grpc_channel_args *channel_args) { for (size_t i = 0; i < channel_args->num_args; ++i) { grpc_arg *arg = &channel_args->args[i]; gpr_free(arg->key); @@ -58,7 +58,7 @@ void FreeChannelArgs(grpc_channel_args *channel_args) { * value responds to @c @selector(intValue). Otherwise, an exception will be raised. The caller of * this function is responsible for calling @c freeChannelArgs on a non-NULL returned value. */ -grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { +grpc_channel_args *GRPCBuildChannelArgs(NSDictionary *dictionary) { if (!dictionary) { return NULL; } diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index d969b887b40..5773f2d9af1 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -36,10 +36,10 @@ NS_ASSUME_NONNULL_BEGIN - (nullable grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(nullable NSDictionary *)args { - grpc_channel_args *coreChannelArgs = BuildChannelArgs([args copy]); + grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); - FreeChannelArgs(coreChannelArgs); + GRPCFreeChannelArgs(coreChannelArgs); return unmanagedChannel; } diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 277823c4e33..8a00d080a11 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -111,10 +111,10 @@ NS_ASSUME_NONNULL_BEGIN - (nullable grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(nullable NSDictionary *)args { - grpc_channel_args *coreChannelArgs = BuildChannelArgs([args copy]); + grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); - FreeChannelArgs(coreChannelArgs); + GRPCFreeChannelArgs(coreChannelArgs); return unmanagedChannel; } From e114983643479d20e44536cb704f5738cb848329 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 13:57:53 -0700 Subject: [PATCH 068/534] NULL return for non-id type --- src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 00b388ebbe0..70675784678 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -84,7 +84,7 @@ NS_ASSUME_NONNULL_BEGIN channelArgs:(nullable NSDictionary *)args { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; - return nil; + return NULL; } @end From 31de6d67e7557208b9d1e8c37300fb3f6b45a47d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 14:00:07 -0700 Subject: [PATCH 069/534] Make GRPCHost.callOptions immutable --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/private/GRPCHost.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 0facf97e09e..3f77aaafb3a 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -751,7 +751,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRPCMutableCallOptions *callOptions; if ([GRPCHost isHostConfigured:_host]) { GRPCHost *hostConfig = [GRPCHost hostWithAddress:_host]; - callOptions = hostConfig.callOptions; + callOptions = [hostConfig.callOptions mutableCopy]; } else { callOptions = [[GRPCMutableCallOptions alloc] init]; } diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h index 32d3585351e..e321363bcbf 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.h +++ b/src/objective-c/GRPCClient/private/GRPCHost.h @@ -66,7 +66,7 @@ struct grpc_channel_credentials; @property(atomic, readwrite) GRPCTransportType transportType; -@property(readonly) GRPCMutableCallOptions *callOptions; +@property(readonly) GRPCCallOptions *callOptions; + (BOOL)isHostConfigured:(NSString *)address; From d92c62fcde8559393aee346e5518faecb6f1301b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 15:22:16 -0700 Subject: [PATCH 070/534] Enable Cronet with old API --- src/objective-c/GRPCClient/private/GRPCHost.m | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 7c31b106360..6bb5996a1ba 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -113,7 +113,21 @@ static NSMutableDictionary *kHostCache; options.PEMPrivateKey = _PEMPrivateKey; options.PEMCertChain = _pemCertChain; options.hostNameOverride = _hostNameOverride; - options.transportType = _transportType; +#ifdef GRPC_COMPILE_WITH_CRONET + // By old API logic, insecure channel precedes Cronet channel; Cronet channel preceeds default + // channel. + if ([GRPCCall isUsingCronet]) { + if (_transportType == GRPCTransportTypeInsecure) { + options.transportType = GRPCTransportTypeInsecure; + } else { + NSAssert(_transportType == GRPCTransportTypeDefault, @"Invalid transport type"); + options.transportType = GRPCTransportTypeCronet; + } + } else +#endif + { + options.transportType = _transportType; + } options.logContext = _logContext; return options; From 1084f49c310b62ff5a06fa5f6c262f813dce75a5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 15:22:38 -0700 Subject: [PATCH 071/534] rename kHostCache->gHostCache --- src/objective-c/GRPCClient/private/GRPCHost.m | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 6bb5996a1ba..c1992b84e99 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN -static NSMutableDictionary *kHostCache; +static NSMutableDictionary *gHostCache; @implementation GRPCHost { NSString *_PEMRootCertificates; @@ -65,10 +65,10 @@ static NSMutableDictionary *kHostCache; // Look up the GRPCHost in the cache. static dispatch_once_t cacheInitialization; dispatch_once(&cacheInitialization, ^{ - kHostCache = [NSMutableDictionary dictionary]; + gHostCache = [NSMutableDictionary dictionary]; }); - @synchronized(kHostCache) { - GRPCHost *cachedHost = kHostCache[address]; + @synchronized(gHostCache) { + GRPCHost *cachedHost = gHostCache[address]; if (cachedHost) { return cachedHost; } @@ -76,15 +76,15 @@ static NSMutableDictionary *kHostCache; if ((self = [super init])) { _address = address; _retryEnabled = YES; - kHostCache[address] = self; + gHostCache[address] = self; } } return self; } + (void)resetAllHostSettings { - @synchronized(kHostCache) { - kHostCache = [NSMutableDictionary dictionary]; + @synchronized(gHostCache) { + gHostCache = [NSMutableDictionary dictionary]; } } @@ -140,8 +140,8 @@ static NSMutableDictionary *kHostCache; address = [hostURL.host stringByAppendingString:@":443"]; } __block GRPCHost *cachedHost; - @synchronized (kHostCache) { - cachedHost = kHostCache[address]; + @synchronized (gHostCache) { + cachedHost = gHostCache[address]; } return (cachedHost != nil); } From b9e522420741024e05f8ef3ccde7fbeeaaea2234 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 15:28:15 -0700 Subject: [PATCH 072/534] more copy settings --- src/objective-c/GRPCClient/private/GRPCHost.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index c1992b84e99..032b274ffcc 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -92,9 +92,9 @@ static NSMutableDictionary *gHostCache; withPrivateKey:(nullable NSString *)pemPrivateKey withCertChain:(nullable NSString *)pemCertChain error:(NSError **)errorPtr { - _PEMRootCertificates = pemRootCerts; - _PEMPrivateKey = pemPrivateKey; - _pemCertChain = pemCertChain; + _PEMRootCertificates = [pemRootCerts copy]; + _PEMPrivateKey = [pemPrivateKey copy]; + _pemCertChain = [pemCertChain copy]; return YES; } From 4201ad1681064d591f6a47fa5b3c6f824cb7cecb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 16:05:18 -0700 Subject: [PATCH 073/534] add callOptionsForHost: to GRPCHost --- src/objective-c/GRPCClient/GRPCCall.m | 8 ++----- src/objective-c/GRPCClient/private/GRPCHost.h | 4 +--- src/objective-c/GRPCClient/private/GRPCHost.m | 22 ++++++++++++------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 3f77aaafb3a..399206a346c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -749,12 +749,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (_callOptions == nil) { GRPCMutableCallOptions *callOptions; - if ([GRPCHost isHostConfigured:_host]) { - GRPCHost *hostConfig = [GRPCHost hostWithAddress:_host]; - callOptions = [hostConfig.callOptions mutableCopy]; - } else { - callOptions = [[GRPCMutableCallOptions alloc] init]; - } + + callOptions = [[GRPCHost callOptionsForHost:_host] mutableCopy]; if (_serverName.length != 0) { callOptions.serverAuthority = _serverName; } diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h index e321363bcbf..f1d57196424 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.h +++ b/src/objective-c/GRPCClient/private/GRPCHost.h @@ -66,9 +66,7 @@ struct grpc_channel_credentials; @property(atomic, readwrite) GRPCTransportType transportType; -@property(readonly) GRPCCallOptions *callOptions; - -+ (BOOL)isHostConfigured:(NSString *)address; ++ (GRPCCallOptions *)callOptionsForHost:(NSString *)host; @end diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 032b274ffcc..5fe022a1bae 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -133,17 +133,23 @@ static NSMutableDictionary *gHostCache; return options; } -+ (BOOL)isHostConfigured:(NSString *)address { ++ (GRPCCallOptions *)callOptionsForHost:(NSString *)host { // TODO (mxyan): Remove when old API is deprecated - NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:address]]; - if (hostURL.host && !hostURL.port) { - address = [hostURL.host stringByAppendingString:@":443"]; + NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:host]]; + if (hostURL.host && hostURL.port == nil) { + host = [hostURL.host stringByAppendingString:@":443"]; + } + + __block GRPCCallOptions *callOptions = nil; + @synchronized(gHostCache) { + if ([gHostCache objectForKey:host]) { + callOptions = [gHostCache[host] callOptions]; + } } - __block GRPCHost *cachedHost; - @synchronized (gHostCache) { - cachedHost = gHostCache[address]; + if (callOptions == nil) { + callOptions = [[GRPCCallOptions alloc] init]; } - return (cachedHost != nil); + return callOptions; } @end From f00be37dd19842e2e2f906b71d0525c2dc913378 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 16:07:09 -0700 Subject: [PATCH 074/534] Spell out 'certificates' rather than 'certs' --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 8 ++++---- .../GRPCClient/private/GRPCSecureChannelFactory.h | 8 ++++---- .../GRPCClient/private/GRPCSecureChannelFactory.m | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index b5b3ff60efa..5d53cb2e99f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -52,10 +52,10 @@ extern const char *kCFStreamVarName; #ifdef GRPC_COMPILE_WITH_CRONET if (![GRPCCall isUsingCronet]) { #endif - factory = [GRPCSecureChannelFactory factoryWithPEMRootCerts:_callOptions.PEMRootCertificates - privateKey:_callOptions.PEMPrivateKey - certChain:_callOptions.PEMCertChain - error:&error]; + factory = [GRPCSecureChannelFactory factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates + privateKey:_callOptions.PEMPrivateKey + certChain:_callOptions.PEMCertChain + error:&error]; if (factory == nil) { NSLog(@"Error creating secure channel factory: %@", error); } diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index 82af0dc3e68..588239b7064 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -23,10 +23,10 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCSecureChannelFactory : NSObject -+ (nullable instancetype)factoryWithPEMRootCerts:(nullable NSString *)rootCerts - privateKey:(nullable NSString *)privateKey - certChain:(nullable NSString *)certChain - error:(NSError **)errorPtr; ++ (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr; - (nullable grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(nullable NSDictionary *)args; diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 8a00d080a11..b116c16ec0f 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -29,10 +29,10 @@ NS_ASSUME_NONNULL_BEGIN grpc_channel_credentials *_channelCreds; } -+ (nullable instancetype)factoryWithPEMRootCerts:(nullable NSString *)rootCerts - privateKey:(nullable NSString *)privateKey - certChain:(nullable NSString *)certChain - error:(NSError **)errorPtr { ++ (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr { return [[self alloc] initWithPEMRootCerts:rootCerts privateKey:privateKey certChain:certChain From 6ae2ea643d89f7b2e7839f9016a61361ce92b5d5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 16:32:42 -0700 Subject: [PATCH 075/534] obj.class->[obj class] --- .../GRPCClient/private/GRPCRequestHeaders.m | 4 +- .../private/GRPCSecureChannelFactory.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- src/objective-c/tests/InteropTests.m | 62 +++++++++---------- src/objective-c/tests/InteropTestsLocalSSL.m | 4 +- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m index fa4f022ff02..5f117f0607b 100644 --- a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m +++ b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m @@ -36,7 +36,7 @@ static void CheckIsNonNilASCII(NSString *name, NSString *value) { // Precondition: key isn't nil. static void CheckKeyValuePairIsValid(NSString *key, id value) { if ([key hasSuffix:@"-bin"]) { - if (![value isKindOfClass:NSData.class]) { + if (![value isKindOfClass:[NSData class]]) { [NSException raise:NSInvalidArgumentException format: @"Expected NSData value for header %@ ending in \"-bin\", " @@ -44,7 +44,7 @@ static void CheckKeyValuePairIsValid(NSString *key, id value) { key, value]; } } else { - if (![value isKindOfClass:NSString.class]) { + if (![value isKindOfClass:[NSString class]]) { [NSException raise:NSInvalidArgumentException format: @"Expected NSString value for header %@ not ending in \"-bin\", " diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index b116c16ec0f..13bca6c40d6 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -57,7 +57,7 @@ NS_ASSUME_NONNULL_BEGIN dispatch_once(&loading, ^{ NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem // Do not use NSBundle.mainBundle, as it's nil for tests of library projects. - NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *path = [bundle pathForResource:defaultPath ofType:@"pem"]; NSError *error; // Files in PEM format can have non-ASCII characters in their comments (e.g. for the name of the diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 9fb398408bf..d3005e30a51 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -252,7 +252,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } // A writer that serializes the proto messages to send. GRXWriter *bytesWriter = [requestsWriter map:^id(GPBMessage *proto) { - if (![proto isKindOfClass:GPBMessage.class]) { + if (![proto isKindOfClass:[GPBMessage class]]) { [NSException raise:NSInvalidArgumentException format:@"Request must be a proto message: %@", proto]; } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 11d4b95663a..ca49b5fc390 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -173,11 +173,11 @@ BOOL isRemoteInteropTest(NSString *host) { [GRPCCall resetHostSettings]; - _service = self.class.host ? [RMTTestService serviceWithHost:self.class.host] : nil; + _service = [[self class] host] ? [RMTTestService serviceWithHost:[[self class] host]] : nil; } - (void)testEmptyUnaryRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnary"]; GPBEmpty *request = [GPBEmpty message]; @@ -196,14 +196,14 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testEmptyUnaryRPCWithV2API { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnary"]; GPBEmpty *request = [GPBEmpty message]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = self.class.transportType; - options.PEMRootCertificates = self.class.PEMRootCertificates; - options.hostNameOverride = self.class.hostNameOverride; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; [_service emptyCallWithMessage:request @@ -223,7 +223,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testLargeUnaryRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -247,7 +247,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testPacketCoalescing { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -286,7 +286,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)test4MBResponsesAreAccepted { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"MaxResponseSize"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -304,7 +304,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testResponsesOverMaxSizeFailWithActionableMessage { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -330,7 +330,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testResponsesOver4MBAreAcceptedIfOptedIn { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"HigherResponseSizeLimit"]; @@ -338,7 +338,7 @@ BOOL isRemoteInteropTest(NSString *host) { const size_t kPayloadSize = 5 * 1024 * 1024; // 5MB request.responseSize = kPayloadSize; - [GRPCCall setResponseSizeLimit:6 * 1024 * 1024 forHost:self.class.host]; + [GRPCCall setResponseSizeLimit:6 * 1024 * 1024 forHost:[[self class] host]]; [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { @@ -351,7 +351,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testClientStreamingRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ClientStreaming"]; RMTStreamingInputCallRequest *request1 = [RMTStreamingInputCallRequest message]; @@ -386,7 +386,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testServerStreamingRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ServerStreaming"]; NSArray *expectedSizes = @[ @31415, @9, @2653, @58979 ]; @@ -425,7 +425,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testPingPongRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"]; NSArray *requests = @[ @27182, @8, @1828, @45904 ]; @@ -472,7 +472,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testPingPongRPCWithV2API { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"]; NSArray *requests = @[ @27182, @8, @1828, @45904 ]; @@ -483,9 +483,9 @@ BOOL isRemoteInteropTest(NSString *host) { id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] requestedResponseSize:responses[index]]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = self.class.transportType; - options.PEMRootCertificates = self.class.PEMRootCertificates; - options.hostNameOverride = self.class.hostNameOverride; + options.transportType = [[self class] transportType ]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; __block GRPCStreamingProtoCall *call = [_service fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] @@ -523,7 +523,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testEmptyStreamRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"]; [_service fullDuplexCallWithRequestsWriter:[GRXWriter emptyWriter] eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response, @@ -536,7 +536,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testCancelAfterBeginRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBegin"]; // A buffered pipe to which we never write any value acts as a writer that just hangs. @@ -561,7 +561,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testCancelAfterBeginRPCWithV2API { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBegin"]; // A buffered pipe to which we never write any value acts as a writer that just hangs. @@ -583,7 +583,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testCancelAfterFirstResponseRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterFirstResponse"]; @@ -619,7 +619,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testCancelAfterFirstResponseRPCWithV2API { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *completionExpectation = [self expectationWithDescription:@"Call completed."]; __weak XCTestExpectation *responseExpectation = @@ -630,7 +630,7 @@ BOOL isRemoteInteropTest(NSString *host) { GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = self.class.transportType; options.PEMRootCertificates = self.class.PEMRootCertificates; - options.hostNameOverride = self.class.hostNameOverride; + options.hostNameOverride = [[self class] hostNameOverride]; id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; @@ -656,7 +656,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testRPCAfterClosingOpenConnections { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC after closing connection"]; @@ -688,10 +688,10 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testCompressedUnaryRPC { // This test needs to be disabled for remote test because interop server grpc-test // does not support compression. - if (isRemoteInteropTest(self.class.host)) { + if (isRemoteInteropTest([[self class] host])) { return; } - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -699,7 +699,7 @@ BOOL isRemoteInteropTest(NSString *host) { request.responseSize = 314159; request.payload.body = [NSMutableData dataWithLength:271828]; request.expectCompressed.value = YES; - [GRPCCall setDefaultCompressMethod:GRPCCompressGzip forhost:self.class.host]; + [GRPCCall setDefaultCompressMethod:GRPCCompressGzip forhost:[[self class] host]]; [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { @@ -718,10 +718,10 @@ BOOL isRemoteInteropTest(NSString *host) { #ifndef GRPC_COMPILE_WITH_CRONET - (void)testKeepalive { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Keepalive"]; - [GRPCCall setKeepaliveWithInterval:1500 timeout:0 forHost:self.class.host]; + [GRPCCall setKeepaliveWithInterval:1500 timeout:0 forHost:[[self class] host]]; NSArray *requests = @[ @27182, @8 ]; NSArray *responses = @[ @31415, @9 ]; diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m index 759a080380d..e8222f602f4 100644 --- a/src/objective-c/tests/InteropTestsLocalSSL.m +++ b/src/objective-c/tests/InteropTestsLocalSSL.m @@ -41,7 +41,7 @@ static int32_t kLocalInteropServerOverhead = 10; } + (NSString *)PEMRootCertificates { - NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; NSError *error; @@ -64,7 +64,7 @@ static int32_t kLocalInteropServerOverhead = 10; [super setUp]; // Register test server certificates and name. - NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; [GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:kLocalSSLHost]; From 4264ea2b55f46c1904fc179fb0db7b733b8c3e4b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 17:04:03 -0700 Subject: [PATCH 076/534] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 10 +- src/objective-c/GRPCClient/GRPCCall.m | 34 +++--- src/objective-c/GRPCClient/GRPCCallOptions.m | 26 ++--- .../GRPCClient/private/GRPCChannel.m | 36 ++++--- .../GRPCClient/private/GRPCChannelPool.m | 35 +++--- src/objective-c/ProtoRPC/ProtoRPC.h | 6 +- src/objective-c/ProtoRPC/ProtoRPC.m | 10 +- src/objective-c/ProtoRPC/ProtoService.h | 13 +-- .../tests/ChannelTests/ChannelPoolTest.m | 35 +++--- src/objective-c/tests/GRPCClientTests.m | 101 +++++++++--------- src/objective-c/tests/InteropTests.m | 2 +- 11 files changed, 161 insertions(+), 147 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 6adecec144a..bd43a0a384b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -149,7 +149,7 @@ extern id const kGRPCHeadersKey; extern id const kGRPCTrailersKey; /** An object can implement this protocol to receive responses from server from a call. */ -@protocol GRPCResponseHandler +@protocol GRPCResponseHandler @optional @@ -188,10 +188,12 @@ extern id const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** Initialize with all properties. */ -- (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + safety:(GRPCCallSafety)safety NS_DESIGNATED_INITIALIZER; /** The host serving the RPC service. */ @property(copy, readonly) NSString *host; @@ -214,7 +216,7 @@ extern id const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Designated initializer for a call. diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 399206a346c..bd4b4e10f0f 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -28,8 +28,8 @@ #include #import "GRPCCallOptions.h" -#import "private/GRPCHost.h" #import "private/GRPCConnectivityMonitor.h" +#import "private/GRPCHost.h" #import "private/GRPCRequestHeaders.h" #import "private/GRPCWrappedCall.h" #import "private/NSData+GRPC.h" @@ -115,7 +115,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; _initialMetadataPublished = NO; _pipe = [GRXBufferedPipe pipe]; if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); } else { // Fallback on earlier versions _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); @@ -129,7 +131,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler { - return [self initWithRequestOptions:requestOptions responseHandler:responseHandler callOptions:nil]; + return + [self initWithRequestOptions:requestOptions responseHandler:responseHandler callOptions:nil]; } - (void)start { @@ -210,9 +213,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; } }); @@ -255,13 +258,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } -- (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata - error:(NSError *)error { +- (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { id handler = _handler; NSDictionary *trailers = _call.responseTrailers; if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:trailers error:error]; + [handler closedWithTrailingMetadata:trailers error:error]; }); } } @@ -388,7 +390,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { if (host.length == 0 || path.length == 0) { - [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil or empty."]; + [NSException raise:NSInvalidArgumentException + format:@"Neither host nor path can be nil or empty."]; } if (safety > GRPCCallSafetyCacheableRequest) { [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; @@ -457,7 +460,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)cancel { - @synchronized (self) { + @synchronized(self) { if (!self.isWaitingForToken) { [self cancelCall]; } else { @@ -720,8 +723,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{ - NSLocalizedDescriptionKey : @"Failed to create call or channel." - }]]; + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; return; } @@ -773,11 +777,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = callOptions; } if (_callOptions.authTokenProvider != nil) { - @synchronized (self) { + @synchronized(self) { self.isWaitingForToken = YES; } [self.tokenProvider getTokenWithHandler:^(NSString *token) { - @synchronized (self) { + @synchronized(self) { if (self.isWaitingForToken) { if (token) { self->_fetchedOauth2AccessToken = [token copy]; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 8d2b84b7484..37ed3ebd1d1 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -110,7 +110,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:kDefaultConnectInitialBackoff connectMaxBackoff:kDefaultConnectMaxBackoff additionalChannelArgs:kDefaultAdditionalChannelArgs - PEMRootCertificates:kDefaultPEMRootCertificates + PEMRootCertificates:kDefaultPEMRootCertificates PEMPrivateKey:kDefaultPEMPrivateKey PEMCertChain:kDefaultPEMCertChain transportType:kDefaultTransportType @@ -135,7 +135,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:(NSTimeInterval)connectInitialBackoff connectMaxBackoff:(NSTimeInterval)connectMaxBackoff additionalChannelArgs:(NSDictionary *)additionalChannelArgs - PEMRootCertificates:(NSString *)PEMRootCertificates + PEMRootCertificates:(NSString *)PEMRootCertificates PEMPrivateKey:(NSString *)PEMPrivateKey PEMCertChain:(NSString *)PEMCertChain transportType:(GRPCTransportType)transportType @@ -158,7 +158,8 @@ static NSUInteger kDefaultChannelID = 0; _connectMinTimeout = connectMinTimeout; _connectInitialBackoff = connectInitialBackoff; _connectMaxBackoff = connectMaxBackoff; - _additionalChannelArgs = [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; + _additionalChannelArgs = + [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; _PEMRootCertificates = [PEMRootCertificates copy]; _PEMPrivateKey = [PEMPrivateKey copy]; _PEMCertChain = [PEMCertChain copy]; @@ -188,7 +189,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:_additionalChannelArgs - PEMRootCertificates:_PEMRootCertificates + PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey PEMCertChain:_PEMCertChain transportType:_transportType @@ -216,7 +217,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - PEMRootCertificates:_PEMRootCertificates + PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey PEMCertChain:_PEMCertChain transportType:_transportType @@ -240,8 +241,7 @@ static NSUInteger kDefaultChannelID = 0; if (!(callOptions.connectInitialBackoff == _connectInitialBackoff)) return NO; if (!(callOptions.connectMaxBackoff == _connectMaxBackoff)) return NO; if (!(callOptions.additionalChannelArgs == _additionalChannelArgs || - [callOptions.additionalChannelArgs - isEqualToDictionary:_additionalChannelArgs])) + [callOptions.additionalChannelArgs isEqualToDictionary:_additionalChannelArgs])) return NO; if (!(callOptions.PEMRootCertificates == _PEMRootCertificates || [callOptions.PEMRootCertificates isEqualToString:_PEMRootCertificates])) @@ -256,8 +256,7 @@ static NSUInteger kDefaultChannelID = 0; [callOptions.hostNameOverride isEqualToString:_hostNameOverride])) return NO; if (!(callOptions.transportType == _transportType)) return NO; - if (!(callOptions.logContext == _logContext || - [callOptions.logContext isEqual:_logContext])) + if (!(callOptions.logContext == _logContext || [callOptions.logContext isEqual:_logContext])) return NO; if (!(callOptions.channelPoolDomain == _channelPoolDomain || [callOptions.channelPoolDomain isEqualToString:_channelPoolDomain])) @@ -335,7 +334,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:kDefaultConnectInitialBackoff connectMaxBackoff:kDefaultConnectMaxBackoff additionalChannelArgs:kDefaultAdditionalChannelArgs - PEMRootCertificates:kDefaultPEMRootCertificates + PEMRootCertificates:kDefaultPEMRootCertificates PEMPrivateKey:kDefaultPEMPrivateKey PEMCertChain:kDefaultPEMCertChain transportType:kDefaultTransportType @@ -362,7 +361,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - PEMRootCertificates:_PEMRootCertificates + PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey PEMCertChain:_PEMCertChain transportType:_transportType @@ -390,7 +389,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - PEMRootCertificates:_PEMRootCertificates + PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey PEMCertChain:_PEMCertChain transportType:_transportType @@ -482,7 +481,8 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setAdditionalChannelArgs:(NSDictionary *)additionalChannelArgs { - _additionalChannelArgs = [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; + _additionalChannelArgs = + [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; } - (void)setPEMRootCertificates:(NSString *)PEMRootCertificates { diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 2420988f427..63bc267a762 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -75,8 +75,12 @@ NSTimeInterval kChannelDestroyDelay = 30; _refCount = 1; _disconnected = NO; if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); - _timerQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_DEFAULT, -1)); + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + _timerQueue = + dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class( + DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_DEFAULT, -1)); } else { _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); _timerQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); @@ -101,7 +105,8 @@ NSTimeInterval kChannelDestroyDelay = 30; self->_refCount--; if (self->_refCount == 0) { self->_lastDispatch = [NSDate date]; - dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)kChannelDestroyDelay * 1e9); + dispatch_time_t delay = + dispatch_time(DISPATCH_TIME_NOW, (int64_t)kChannelDestroyDelay * 1e9); dispatch_after(delay, self->_timerQueue, ^{ [self timerFire]; }); @@ -123,7 +128,8 @@ NSTimeInterval kChannelDestroyDelay = 30; - (void)timerFire { dispatch_async(_dispatchQueue, ^{ - if (self->_disconnected || self->_lastDispatch == nil || -[self->_lastDispatch timeIntervalSinceNow] < -kChannelDestroyDelay) { + if (self->_disconnected || self->_lastDispatch == nil || + -[self->_lastDispatch timeIntervalSinceNow] < -kChannelDestroyDelay) { return; } self->_lastDispatch = nil; @@ -158,11 +164,12 @@ NSTimeInterval kChannelDestroyDelay = 30; } 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_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); - call = grpc_channel_create_call( - self->_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, + 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)); + call = grpc_channel_create_call(self->_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, + queue.unmanagedQueue, path_slice, serverAuthority ? &host_slice : NULL, deadline_ms, NULL); if (serverAuthority) { grpc_slice_unref(host_slice); @@ -214,11 +221,14 @@ NSTimeInterval kChannelDestroyDelay = 30; if ((self = [super init])) { _unmanagedChannel = unmanagedChannel; _configuration = configuration; - _channelRef = [[GRPCChannelRef alloc] initWithDestroyDelay:kChannelDestroyDelay destroyChannelCallback:^{ - [self destroyChannel]; - }]; + _channelRef = [[GRPCChannelRef alloc] initWithDestroyDelay:kChannelDestroyDelay + destroyChannelCallback:^{ + [self destroyChannel]; + }]; if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); } else { _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 5d53cb2e99f..6659d193c68 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -52,10 +52,11 @@ extern const char *kCFStreamVarName; #ifdef GRPC_COMPILE_WITH_CRONET if (![GRPCCall isUsingCronet]) { #endif - factory = [GRPCSecureChannelFactory factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates - privateKey:_callOptions.PEMPrivateKey - certChain:_callOptions.PEMCertChain - error:&error]; + factory = [GRPCSecureChannelFactory + factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates + privateKey:_callOptions.PEMPrivateKey + certChain:_callOptions.PEMCertChain + error:&error]; if (factory == nil) { NSLog(@"Error creating secure channel factory: %@", error); } @@ -136,7 +137,8 @@ extern const char *kCFStreamVarName; } - (nonnull id)copyWithZone:(nullable NSZone *)zone { - GRPCChannelConfiguration *newConfig = [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; + GRPCChannelConfiguration *newConfig = + [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; return newConfig; } @@ -145,7 +147,8 @@ extern const char *kCFStreamVarName; NSAssert([object isKindOfClass:[GRPCChannelConfiguration class]], @"Illegal :isEqual"); GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; if (!(obj.host == _host || [obj.host isEqualToString:_host])) return NO; - if (!(obj.callOptions == _callOptions || [obj.callOptions isChannelOptionsEqualTo:_callOptions])) return NO; + if (!(obj.callOptions == _callOptions || [obj.callOptions isChannelOptionsEqualTo:_callOptions])) + return NO; return YES; } @@ -201,11 +204,13 @@ extern const char *kCFStreamVarName; - (void)removeChannel:(GRPCChannel *)channel { @synchronized(self) { - [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannel * _Nonnull obj, BOOL * _Nonnull stop) { - if (obj == channel) { - [self->_channelPool removeObjectForKey:key]; - } - }]; + [_channelPool + enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, + GRPCChannel *_Nonnull obj, BOOL *_Nonnull stop) { + if (obj == channel) { + [self->_channelPool removeObjectForKey:key]; + } + }]; } } @@ -217,9 +222,11 @@ extern const char *kCFStreamVarName; - (void)removeAndCloseAllChannels { @synchronized(self) { - [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannel * _Nonnull obj, BOOL * _Nonnull stop) { - [obj disconnect]; - }]; + [_channelPool + enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, + GRPCChannel *_Nonnull obj, BOOL *_Nonnull stop) { + [obj disconnect]; + }]; _channelPool = [NSMutableDictionary dictionary]; } } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index db1e8c6deb3..f2ba5134952 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -24,7 +24,7 @@ @class GPBMessage; /** An object can implement this protocol to receive responses from server from a call. */ -@protocol GRPCProtoResponseHandler +@protocol GRPCProtoResponseHandler @optional @@ -59,7 +59,7 @@ - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Users should not use this initializer directly. Call objects will be created, initialized, and @@ -81,7 +81,7 @@ - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Users should not use this initializer directly. Call objects will be created, initialized, and diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index d3005e30a51..238faa33437 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -88,7 +88,9 @@ _callOptions = [callOptions copy]; _responseClass = responseClass; if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); } else { _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } @@ -120,9 +122,9 @@ error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; }); } _handler = nil; diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 2985c5cb2dc..3a16ab24026 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -30,14 +30,15 @@ __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService : NSObject -- (instancetype)init NS_UNAVAILABLE; + - + (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; - - - (instancetype)initWithHost : (NSString *)host packageName - : (NSString *)packageName serviceName : (NSString *)serviceName callOptions - : (GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithHost:(NSString *)host + packageName:(NSString *)packageName + serviceName:(NSString *)serviceName + callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index db64ac6339e..f4a9fb4a2c4 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -57,11 +57,9 @@ NSString *kDummyHost = @"dummy.host"; GRPCChannelConfiguration *config1 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - GRPCChannel *channel1 = - [pool channelWithConfiguration:config1]; + GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; [pool removeChannel:channel1]; - GRPCChannel *channel2 = - [pool channelWithConfiguration:config1]; + GRPCChannel *channel2 = [pool channelWithConfiguration:config1]; XCTAssertNotEqual(channel1, channel2); } @@ -74,18 +72,14 @@ extern NSTimeInterval kChannelDestroyDelay; options1.transportType = GRPCTransportTypeInsecure; GRPCChannelConfiguration *config1 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelPool *pool = - [[GRPCChannelPool alloc] init]; - GRPCChannel *channel1 = - [pool channelWithConfiguration:config1]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; [channel1 unmanagedCallUnref]; sleep(1); - GRPCChannel *channel2 = - [pool channelWithConfiguration:config1]; + GRPCChannel *channel2 = [pool channelWithConfiguration:config1]; XCTAssertEqual(channel1, channel2); sleep((int)kChannelDestroyDelay + 2); - GRPCChannel *channel3 = - [pool channelWithConfiguration:config1]; + GRPCChannel *channel3 = [pool channelWithConfiguration:config1]; XCTAssertEqual(channel1, channel3); kChannelDestroyDelay = kOriginalInterval; } @@ -96,12 +90,11 @@ extern NSTimeInterval kChannelDestroyDelay; options1.transportType = GRPCTransportTypeInsecure; GRPCCallOptions *options2 = [options1 copy]; GRPCChannelConfiguration *config1 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelConfiguration *config2 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; [pool removeAndCloseAllChannels]; GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; @@ -119,17 +112,13 @@ extern NSTimeInterval kChannelDestroyDelay; [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - GRPCChannel *channel1 = - [pool channelWithConfiguration:config1]; - GRPCChannel *channel2 = - [pool channelWithConfiguration:config2]; + GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; + GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; XCTAssertNotEqual(channel1, channel2); [pool removeAndCloseAllChannels]; - GRPCChannel *channel3 = - [pool channelWithConfiguration:config1]; - GRPCChannel *channel4 = - [pool channelWithConfiguration:config2]; + GRPCChannel *channel3 = [pool channelWithConfiguration:config1]; + GRPCChannel *channel4 = [pool channelWithConfiguration:config2]; XCTAssertNotEqual(channel1, channel3); XCTAssertNotEqual(channel2, channel4); } diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index f961b6a86fd..387fcab7e9f 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -446,42 +446,40 @@ static GRPCProtoMethod *kFullDuplexCallMethod; options.initialMetadata = headers; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:request - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( NSDictionary *initialMetadata) { - NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; - // 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:@")"]; - XCTAssertEqualObjects(userAgent, expectedUserAgent); - - NSError *error = nil; - // 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 = [regex - stringByReplacingMatchesInString:userAgent - options:0 - range:NSMakeRange(0, [userAgent length]) - withTemplate:@""]; - XCTAssertEqualObjects(customUserAgent, @"Foo"); - [recvInitialMd fulfill]; - } + NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; + // 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:@")"]; + XCTAssertEqualObjects(userAgent, expectedUserAgent); + + NSError *error = nil; + // 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 = + [regex stringByReplacingMatchesInString:userAgent + options:0 + range:NSMakeRange(0, [userAgent length]) + withTemplate:@""]; + XCTAssertEqualObjects(customUserAgent, @"Foo"); + [recvInitialMd fulfill]; + } messageCallback:^(id message) { XCTAssertNotNil(message); XCTAssertEqual([message length], 0, @@ -609,7 +607,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; options.transportType = GRPCTransportTypeInsecure; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id message) { NSData *data = (NSData *)message; XCTAssertNotNil(data, @"nil value received as response."); @@ -739,19 +737,18 @@ static GRPCProtoMethod *kFullDuplexCallMethod; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions - responseHandler: - [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id data) { - XCTFail( - @"Failure: response received; Expect: no response received."); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNotNil(error, - @"Failure: no error received; Expect: receive " - @"deadline exceeded."); - XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); - [completion fulfill]; - }] + responseHandler: + [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id data) { + XCTFail(@"Failure: response received; Expect: no response received."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Failure: no error received; Expect: receive " + @"deadline exceeded."); + XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); + [completion fulfill]; + }] callOptions:options]; [call start]; @@ -837,7 +834,9 @@ static GRPCProtoMethod *kFullDuplexCallMethod; __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; NSString *const kDummyAddress = [NSString stringWithFormat:@"127.0.0.1:10000"]; GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kDummyAddress path:@"/dummy/path" safety:GRPCCallSafetyDefault]; + [[GRPCRequestOptions alloc] initWithHost:kDummyAddress + path:@"/dummy/path" + safety:GRPCCallSafetyDefault]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.connectMinTimeout = timeout; options.connectInitialBackoff = backoff; @@ -846,7 +845,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; NSDate *startTime = [NSDate date]; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id data) { XCTFail(@"Received message. Should not reach here."); } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index ca49b5fc390..1188a75df77 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -483,7 +483,7 @@ BOOL isRemoteInteropTest(NSString *host) { id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] requestedResponseSize:responses[index]]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = [[self class] transportType ]; + options.transportType = [[self class] transportType]; options.PEMRootCertificates = [[self class] PEMRootCertificates]; options.hostNameOverride = [[self class] hostNameOverride]; From 799f8ac60cf6eb1006dbb378ab73ab638cea73fa Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Thu, 18 Oct 2018 17:13:46 -0700 Subject: [PATCH 077/534] undo changes to subchannel --- .../ext/filters/client_channel/subchannel.cc | 39 +++++-------------- .../ext/filters/client_channel/subchannel.h | 6 +-- 2 files changed, 10 insertions(+), 35 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index a45c579861e..3a1c14c6f10 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -151,12 +151,6 @@ struct grpc_subchannel_call { grpc_closure* original_recv_trailing_metadata; grpc_metadata_batch* recv_trailing_metadata; grpc_millis deadline; - - // state needed to support lb interception of recv trailing metadata. - // This points into grpc_core::LoadBalancingPolicy::PickState to avoid - // creating a circular dependency. - grpc_closure** lb_recv_trailing_metadata_ready; - grpc_metadata_batch*** lb_recv_trailing_metadata; }; #define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ @@ -781,20 +775,11 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { get_call_status(call, md_batch, GRPC_ERROR_REF(error), &status); grpc_core::channelz::SubchannelNode* channelz_subchannel = call->connection->channelz_subchannel(); - if (channelz_subchannel != nullptr) { - if (status == GRPC_STATUS_OK) { - channelz_subchannel->RecordCallSucceeded(); - } else { - channelz_subchannel->RecordCallFailed(); - } - } - if (*call->lb_recv_trailing_metadata_ready != nullptr) { - GPR_ASSERT(*call->lb_recv_trailing_metadata != nullptr); - **call->lb_recv_trailing_metadata = md_batch; - GRPC_CLOSURE_SCHED(*call->lb_recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); - *call->lb_recv_trailing_metadata = nullptr; - *call->lb_recv_trailing_metadata_ready = nullptr; + GPR_ASSERT(channelz_subchannel != nullptr); + if (status == GRPC_STATUS_OK) { + channelz_subchannel->RecordCallSucceeded(); + } else { + channelz_subchannel->RecordCallFailed(); } GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata, GRPC_ERROR_REF(error)); @@ -808,9 +793,8 @@ static void maybe_intercept_recv_trailing_metadata( if (!batch->recv_trailing_metadata) { return; } - // only add interceptor if channelz is enabled or lb policy wants the trailers - if (call->connection->channelz_subchannel() == nullptr && - *call->lb_recv_trailing_metadata_ready == nullptr) { + // only add interceptor is channelz is enabled. + if (call->connection->channelz_subchannel() == nullptr) { return; } GRPC_CLOSURE_INIT(&call->recv_trailing_metadata_ready, @@ -938,11 +922,8 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate, elem->filter->start_transport_op(elem, op); } -grpc_error* ConnectedSubchannel::CreateCall( - grpc_subchannel_call** call, - const CallArgs& args, - grpc_closure** lb_recv_trailing_metadata_ready, - grpc_metadata_batch*** lb_recv_trailing_metadata) { +grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, + grpc_subchannel_call** call) { size_t allocation_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)); if (args.parent_data_size > 0) { @@ -978,8 +959,6 @@ grpc_error* ConnectedSubchannel::CreateCall( return error; } grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); - *(*call)->lb_recv_trailing_metadata_ready = *lb_recv_trailing_metadata_ready; - *(*call)->lb_recv_trailing_metadata = *lb_recv_trailing_metadata; return GRPC_ERROR_NONE; } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index dc5e53be780..c53b13e37e8 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -97,11 +97,7 @@ class ConnectedSubchannel : public RefCountedWithTracing { grpc_connectivity_state* state, grpc_closure* closure); void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); - grpc_error* CreateCall( - grpc_subchannel_call** call, - const CallArgs& args, - grpc_closure** lb_recv_trailing_metadata_ready, - grpc_metadata_batch*** lb_recv_trailing_metadata); + grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call); channelz::SubchannelNode* channelz_subchannel() { return channelz_subchannel_.get(); } From 7cc2660ae570cd2157a544cd3e4a983613c366f6 Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Thu, 18 Oct 2018 18:24:12 -0700 Subject: [PATCH 078/534] Add a non-retries trailer interceptor --- .../filters/client_channel/client_channel.cc | 61 +++++++++++++++++-- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index fc77a51eb31..f57612b2413 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -932,6 +932,11 @@ typedef struct client_channel_call_data { grpc_core::LoadBalancingPolicy::PickState pick; grpc_closure pick_closure; grpc_closure pick_cancel_closure; + // A closure to fork notifying the lb interceptor and run the original trailer + // interception callback. + grpc_closure lb_intercept_recv_trailing_metadata_ready; + // The original trailer interception callback. + grpc_closure* before_lb_intercept_recv_trailing_metadata_ready; grpc_polling_entity* pollent; bool pollent_added_to_interested_parties; @@ -1268,6 +1273,51 @@ static void resume_pending_batch_in_call_combiner(void* arg, grpc_subchannel_call_process_op(subchannel_call, batch); } +// The callback to intercept trailing metadata if retries is not enabled +static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { + subchannel_batch_data* batch_data = static_cast(arg); + grpc_call_element* elem = batch_data->elem; + call_data* calld = static_cast(elem->call_data); + GPR_ASSERT(calld->pick.recv_trailing_metadata_ready != nullptr); + GPR_ASSERT(calld->pick.recv_trailing_metadata != nullptr); + + GRPC_CLOSURE_SCHED( + calld->pick.recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); + calld->pick.recv_trailing_metadata = nullptr; + calld->pick.recv_trailing_metadata_ready = nullptr; + + GRPC_CLOSURE_RUN( + calld->before_lb_intercept_recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); +} + +// Installs a interceptor to inform the lb of the trailing metadata, if needed +static void maybe_intercept_trailing_metadata_for_lb( + void* arg, grpc_transport_stream_op_batch* batch) { + subchannel_batch_data* batch_data = static_cast(arg); + grpc_call_element* elem = batch_data->elem; + call_data* calld = static_cast(elem->call_data); + if (calld->pick.recv_trailing_metadata_ready != nullptr) { + GPR_ASSERT(calld->pick.recv_trailing_metadata != nullptr); + // Unlike the retries case, the location of the trailing metadata is known + // already, so just point to it now. + *calld->pick.recv_trailing_metadata = + batch_data->batch.payload->recv_trailing_metadata + .recv_trailing_metadata; + + // There may be a pre-existing recv_trailing_metadata_ready callback + calld->before_lb_intercept_recv_trailing_metadata_ready = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + + GRPC_CLOSURE_INIT(&calld->lb_intercept_recv_trailing_metadata_ready, + recv_trailing_metadata_ready_for_lb, elem, + grpc_schedule_on_exec_ctx); + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->lb_intercept_recv_trailing_metadata_ready; + } +} + // This is called via the call combiner, so access to calld is synchronized. static void pending_batches_resume(grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); @@ -1292,6 +1342,7 @@ static void pending_batches_resume(grpc_call_element* elem) { pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { + maybe_intercept_trailing_metadata_for_lb(elem, batch); batch->handler_private.extra_arg = calld->subchannel_call; GRPC_CLOSURE_INIT(&batch->handler_private.closure, resume_pending_batch_in_call_combiner, batch, @@ -1947,7 +1998,8 @@ static void run_closures_for_completed_call(subchannel_batch_data* batch_data, // Intercepts recv_trailing_metadata_ready callback for retries. // Commits the call and returns the trailing metadata up the stack. -static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { +static void recv_trailing_metadata_ready_for_retries( + void* arg, grpc_error* error) { subchannel_batch_data* batch_data = static_cast(arg); grpc_call_element* elem = batch_data->elem; channel_data* chand = static_cast(elem->channel_data); @@ -2312,7 +2364,7 @@ static void add_retriable_recv_trailing_metadata_op( batch_data->batch.payload->recv_trailing_metadata.collect_stats = &retry_state->collect_stats; GRPC_CLOSURE_INIT(&retry_state->recv_trailing_metadata_ready, - recv_trailing_metadata_ready, batch_data, + recv_trailing_metadata_ready_for_retries, batch_data, grpc_schedule_on_exec_ctx); batch_data->batch.payload->recv_trailing_metadata .recv_trailing_metadata_ready = @@ -2602,10 +2654,7 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { parent_data_size // parent_data_size }; grpc_error* new_error = calld->pick.connected_subchannel->CreateCall( - &calld->subchannel_call, - call_args, - &calld->pick.recv_trailing_metadata_ready, - &calld->pick.recv_trailing_metadata); + call_args, &calld->subchannel_call); if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", chand, calld, calld->subchannel_call, grpc_error_string(new_error)); From 6d8340847caf0634853818ff4b8745e83c5279d3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:12:18 -0700 Subject: [PATCH 079/534] Name changes in compiler --- src/compiler/objective_c_generator.cc | 4 ++-- src/compiler/objective_c_plugin.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc index eb67e9bb88f..0a6b64f5952 100644 --- a/src/compiler/objective_c_generator.cc +++ b/src/compiler/objective_c_generator.cc @@ -127,11 +127,11 @@ void PrintV2Signature(Printer* printer, const MethodDescriptor* method, printer->Print(vars, "- ($return_type$)$method_name$With"); if (method->client_streaming()) { - printer->Print("ResponseHandler:(id)handler"); + printer->Print("ResponseHandler:(id)handler"); } else { printer->Print(vars, "Message:($request_class$ *)message " - "responseHandler:(id)handler"); + "responseHandler:(id)handler"); } printer->Print(" callOptions:(GRPCCallOptions *_Nullable)callOptions"); } diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc index d0ef9ed0d62..87977095d05 100644 --- a/src/compiler/objective_c_plugin.cc +++ b/src/compiler/objective_c_plugin.cc @@ -98,7 +98,7 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { "@class GRPCUnaryProtoCall;\n" "@class GRPCStreamingProtoCall;\n" "@class GRPCCallOptions;\n" - "@protocol GRPCResponseHandler;\n" + "@protocol GRPCProtoResponseHandler;\n" "\n"; ::grpc::string class_declarations = From 82d91964493ceb5893b3874109bc4bbc7d87b821 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:12:59 -0700 Subject: [PATCH 080/534] One more obj.class->[obj class] --- .../InteropTestsMultipleChannels/InteropTestsMultipleChannels.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m index 237804d23de..b0d4e4883a3 100644 --- a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m +++ b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m @@ -105,7 +105,7 @@ dispatch_once_t initCronet; // Local stack with SSL _localSSLService = [RMTTestService serviceWithHost:kLocalSSLHost]; - NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; NSError *error = nil; From b9667c6c17590c1f63435ad8dab0554775299003 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:13:27 -0700 Subject: [PATCH 081/534] handle NULL case when parsing certificate --- .../private/GRPCSecureChannelFactory.m | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 13bca6c40d6..90482cad219 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -42,6 +42,9 @@ NS_ASSUME_NONNULL_BEGIN - (NSData *)nullTerminatedDataWithString:(NSString *)string { // dataUsingEncoding: does not return a null-terminated string. NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; + if (data == nil) { + return nil; + } NSMutableData *nullTerminated = [NSMutableData dataWithData:data]; [nullTerminated appendBytes:"\0" length:1]; return nullTerminated; @@ -51,7 +54,7 @@ NS_ASSUME_NONNULL_BEGIN privateKey:(nullable NSString *)privateKey certChain:(nullable NSString *)certChain error:(NSError **)errorPtr { - static NSData *kDefaultRootsASCII; + static NSData *defaultRootsASCII; static NSError *kDefaultRootsError; static dispatch_once_t loading; dispatch_once(&loading, ^{ @@ -68,14 +71,14 @@ NS_ASSUME_NONNULL_BEGIN kDefaultRootsError = error; return; } - kDefaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8]; + defaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8]; }); NSData *rootsASCII; if (rootCerts != nil) { rootsASCII = [self nullTerminatedDataWithString:rootCerts]; } else { - if (kDefaultRootsASCII == nil) { + if (defaultRootsASCII == nil) { if (errorPtr) { *errorPtr = kDefaultRootsError; } @@ -88,11 +91,11 @@ NS_ASSUME_NONNULL_BEGIN kDefaultRootsError); return nil; } - rootsASCII = kDefaultRootsASCII; + rootsASCII = defaultRootsASCII; } - grpc_channel_credentials *creds; - if (privateKey == nil && certChain == nil) { + grpc_channel_credentials *creds = NULL; + if (privateKey.length == 0 && certChain.length == 0) { creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL, NULL); } else { grpc_ssl_pem_key_cert_pair key_cert_pair; @@ -100,7 +103,11 @@ NS_ASSUME_NONNULL_BEGIN NSData *certChainASCII = [self nullTerminatedDataWithString:certChain]; 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, NULL); + if (key_cert_pair.private_key == NULL || key_cert_pair.cert_chain == NULL) { + creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL, NULL); + } else { + creds = grpc_ssl_credentials_create(rootsASCII.bytes, &key_cert_pair, NULL, NULL); + } } if ((self = [super init])) { From 56d605230f2d8c2ddb5670e8d0f2ede6c2aca4d1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:17:11 -0700 Subject: [PATCH 082/534] nil->NULL --- src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 90482cad219..3f2769bf447 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -126,7 +126,7 @@ NS_ASSUME_NONNULL_BEGIN } - (void)dealloc { - if (_channelCreds != nil) { + if (_channelCreds != NULL) { grpc_channel_credentials_release(_channelCreds); } } From 75f8727a3e35ac3db8a3957d9318f2dfdd798e7f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:26:38 -0700 Subject: [PATCH 083/534] NSString == nil -> NSString.length == 0 --- src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 1c03bc9efdd..a7c50a17519 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -247,7 +247,7 @@ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path callOptions:(GRPCCallOptions *)callOptions { - if (!path || !host) { + if (host.length == 0 || path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"path and host cannot be nil."]; } From 066949ee56a84189006abeab2e947594787738f6 Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Fri, 19 Oct 2018 09:32:06 -0700 Subject: [PATCH 084/534] Address current PR comments. --- .../filters/client_channel/client_channel.cc | 96 ++++++++----------- .../ext/filters/client_channel/lb_policy.h | 7 +- 2 files changed, 46 insertions(+), 57 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index f57612b2413..9732b1753a8 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -934,9 +934,9 @@ typedef struct client_channel_call_data { grpc_closure pick_cancel_closure; // A closure to fork notifying the lb interceptor and run the original trailer // interception callback. - grpc_closure lb_intercept_recv_trailing_metadata_ready; + grpc_closure recv_trailing_metadata_ready_for_lb; // The original trailer interception callback. - grpc_closure* before_lb_intercept_recv_trailing_metadata_ready; + grpc_closure* original_recv_trailing_metadata_ready; grpc_polling_entity* pollent; bool pollent_added_to_interested_parties; @@ -999,6 +999,9 @@ static void start_internal_recv_trailing_metadata(grpc_call_element* elem); static void on_complete(void* arg, grpc_error* error); static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored); static void start_pick_locked(void* arg, grpc_error* ignored); +static void maybe_intercept_trailing_metadata_for_lb( + void* arg, grpc_transport_stream_op_batch* batch); +static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error); // // send op data caching @@ -1273,51 +1276,6 @@ static void resume_pending_batch_in_call_combiner(void* arg, grpc_subchannel_call_process_op(subchannel_call, batch); } -// The callback to intercept trailing metadata if retries is not enabled -static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); - grpc_call_element* elem = batch_data->elem; - call_data* calld = static_cast(elem->call_data); - GPR_ASSERT(calld->pick.recv_trailing_metadata_ready != nullptr); - GPR_ASSERT(calld->pick.recv_trailing_metadata != nullptr); - - GRPC_CLOSURE_SCHED( - calld->pick.recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); - calld->pick.recv_trailing_metadata = nullptr; - calld->pick.recv_trailing_metadata_ready = nullptr; - - GRPC_CLOSURE_RUN( - calld->before_lb_intercept_recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); -} - -// Installs a interceptor to inform the lb of the trailing metadata, if needed -static void maybe_intercept_trailing_metadata_for_lb( - void* arg, grpc_transport_stream_op_batch* batch) { - subchannel_batch_data* batch_data = static_cast(arg); - grpc_call_element* elem = batch_data->elem; - call_data* calld = static_cast(elem->call_data); - if (calld->pick.recv_trailing_metadata_ready != nullptr) { - GPR_ASSERT(calld->pick.recv_trailing_metadata != nullptr); - // Unlike the retries case, the location of the trailing metadata is known - // already, so just point to it now. - *calld->pick.recv_trailing_metadata = - batch_data->batch.payload->recv_trailing_metadata - .recv_trailing_metadata; - - // There may be a pre-existing recv_trailing_metadata_ready callback - calld->before_lb_intercept_recv_trailing_metadata_ready = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - - GRPC_CLOSURE_INIT(&calld->lb_intercept_recv_trailing_metadata_ready, - recv_trailing_metadata_ready_for_lb, elem, - grpc_schedule_on_exec_ctx); - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &calld->lb_intercept_recv_trailing_metadata_ready; - } -} - // This is called via the call combiner, so access to calld is synchronized. static void pending_batches_resume(grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); @@ -2043,15 +2001,12 @@ static void recv_trailing_metadata_ready_for_retries( // Not retrying, so commit the call. retry_commit(elem, retry_state); // Now that the try is committed, give the trailer to the lb policy as needed - if (calld->pick.recv_trailing_metadata_ready != nullptr) { - GPR_ASSERT(calld->pick.recv_trailing_metadata != nullptr); + if (calld->pick.recv_trailing_metadata != nullptr) { *calld->pick.recv_trailing_metadata = md_batch; - GRPC_CLOSURE_SCHED( - calld->pick.recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); - calld->pick.recv_trailing_metadata = nullptr; - calld->pick.recv_trailing_metadata_ready = nullptr; } + GRPC_CLOSURE_SCHED( + calld->pick.recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); // Run any necessary closures. run_closures_for_completed_call(batch_data, GRPC_ERROR_REF(error)); } @@ -2638,6 +2593,39 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { // LB pick // +// The callback to intercept trailing metadata if retries is not enabled +static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { + subchannel_batch_data* batch_data = static_cast(arg); + grpc_call_element* elem = batch_data->elem; + call_data* calld = static_cast(elem->call_data); + if (calld->pick.recv_trailing_metadata != nullptr) { + *calld->pick.recv_trailing_metadata = + batch_data->batch.payload->recv_trailing_metadata + .recv_trailing_metadata; + } + GRPC_CLOSURE_SCHED( + calld->pick.recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); + GRPC_CLOSURE_RUN( + calld->original_recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); +} + +// Installs a interceptor to inform the lb of the trailing metadata, if needed +static void maybe_intercept_trailing_metadata_for_lb( + void* arg, grpc_transport_stream_op_batch* batch) { + subchannel_batch_data* batch_data = static_cast(arg); + grpc_call_element* elem = batch_data->elem; + call_data* calld = static_cast(elem->call_data); + calld->original_recv_trailing_metadata_ready = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_for_lb, + recv_trailing_metadata_ready_for_lb, elem, + grpc_schedule_on_exec_ctx); + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->recv_trailing_metadata_ready_for_lb; +} + static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 9ef0033aebd..6c04b4b54cf 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -74,10 +74,11 @@ class LoadBalancingPolicy /// If null, pick will fail if a result is not available synchronously. grpc_closure* on_complete; - // Callback set by lb policy if the trailing metadata should be intercepted. + // Callback set by lb policy to be notified of trailing metadata. grpc_closure* recv_trailing_metadata_ready; - // If \a recv_trailing_metadata_ready \a is set, the client_channel sets - // this pointer to the metadata batch and schedules the closure. + // If this is not nullptr, then the client channel will point it to the + // call's trailing metadata before invoking recv_trailing_metadata_ready. + // If this is nullptr, then the callback will still be called. grpc_metadata_batch** recv_trailing_metadata; /// Will be set to the selected subchannel, or nullptr on failure or when From 2a9efc3d1f0ddb42d0797dee5f82ca7abedc0936 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:50:33 -0700 Subject: [PATCH 085/534] polish cancel message of proto calls --- src/objective-c/ProtoRPC/ProtoRPC.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index f2ba5134952..663c1610bcf 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -71,7 +71,11 @@ callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; -/** Cancel the call at best effort. */ +/** + * Cancel the request of this call at best effort. It attempts to notify the server that the RPC + * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code + * CANCELED if no other error code has already been issued. + */ - (void)cancel; @end @@ -92,7 +96,11 @@ callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; -/** Cancel the call at best effort. */ +/** + * Cancel the request of this call at best effort. It attempts to notify the server that the RPC + * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code + * CANCELED if no other error code has already been issued. + */ - (void)cancel; /** From 9925c13b2710a313d489fd040f0d7f312af0f1fc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:51:42 -0700 Subject: [PATCH 086/534] writeWithMessage->writeMessage --- src/objective-c/ProtoRPC/ProtoRPC.h | 2 +- src/objective-c/ProtoRPC/ProtoRPC.m | 4 ++-- src/objective-c/tests/InteropTests.m | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 663c1610bcf..4121d4f6af2 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -107,7 +107,7 @@ * Send a message to the server. The message should be a Protobuf message which will be serialized * internally. */ -- (void)writeWithMessage:(GPBMessage *)message; +- (void)writeMessage:(GPBMessage *)message; /** * Finish the RPC request and half-close the call. The server may still send messages and/or diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 238faa33437..b04b6aca67b 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -41,7 +41,7 @@ responseHandler:handler callOptions:callOptions responseClass:responseClass]; - [_call writeWithMessage:message]; + [_call writeMessage:message]; [_call finish]; } return self; @@ -132,7 +132,7 @@ }); } -- (void)writeWithMessage:(GPBMessage *)message { +- (void)writeMessage:(GPBMessage *)message { if (![message isKindOfClass:[GPBMessage class]]) { [NSException raise:NSInvalidArgumentException format:@"Data must be a valid protobuf type."]; } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 1188a75df77..d38e1e0d972 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -501,7 +501,7 @@ BOOL isRemoteInteropTest(NSString *host) { id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] requestedResponseSize:responses[index]]; - [call writeWithMessage:request]; + [call writeMessage:request]; } else { [call finish]; } @@ -517,7 +517,7 @@ BOOL isRemoteInteropTest(NSString *host) { [expectation fulfill]; }] callOptions:options]; - [call writeWithMessage:request]; + [call writeMessage:request]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } @@ -651,7 +651,7 @@ BOOL isRemoteInteropTest(NSString *host) { }] callOptions:options]; - [call writeWithMessage:request]; + [call writeMessage:request]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } From 2d903f4732ee21c5c319c88aa738671b56b2e729 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 10:15:02 -0700 Subject: [PATCH 087/534] More specific typing in response handlers --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/ProtoRPC/ProtoRPC.h | 2 +- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- src/objective-c/tests/GRPCClientTests.m | 2 +- src/objective-c/tests/InteropTests.m | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index bd43a0a384b..d8d3e3cf629 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -160,7 +160,7 @@ extern id const kGRPCTrailersKey; * Issued when a message is received from the server. The message is the raw data received from the * server, with decompression and without proto deserialization. */ -- (void)receivedRawMessage:(id)message; +- (void)receivedRawMessage:(NSData *)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 4121d4f6af2..34a519bee5d 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -34,7 +34,7 @@ /** * Issued when a message is received from the server. The message is the deserialized proto object. */ -- (void)receivedProtoMessage:(id)message; +- (void)receivedProtoMessage:(GPBMessage *)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index b04b6aca67b..44e9bfde0ab 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -168,7 +168,7 @@ if (_handler) { id handler = _handler; NSError *error = nil; - id parsed = [_responseClass parseFromData:message error:&error]; + GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; if (parsed) { if ([handler respondsToSelector:@selector(receivedProtoMessage:)]) { dispatch_async(handler.dispatchQueue, ^{ diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 387fcab7e9f..985e105b816 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -120,7 +120,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; } } -- (void)receivedProtoMessage:(id)message { +- (void)receivedProtoMessage:(GPBMessage *)message { if (_messageCallback) { _messageCallback(message); } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index d38e1e0d972..a9f33aab6f1 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -108,7 +108,7 @@ BOOL isRemoteInteropTest(NSString *host) { } } -- (void)receivedProtoMessage:(id)message { +- (void)receivedProtoMessage:(GPBMessage *)message { if (_messageCallback) { _messageCallback(message); } From a6e35201b5a00949379fd04fb784f6b90d06a88a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 11:07:00 -0700 Subject: [PATCH 088/534] polish comments --- src/objective-c/GRPCClient/GRPCCallOptions.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 8864bcb8a2f..6e16cd56a93 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -26,8 +26,10 @@ 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, }; @@ -39,14 +41,14 @@ typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { GRPCStreamCompressGzip, }; -// The transport to be used by a gRPC call +/** The transport to be used by a gRPC call */ typedef NS_ENUM(NSInteger, GRPCTransportType) { GRPCTransportTypeDefault = 0, - // gRPC internal HTTP/2 stack with BoringSSL + /** gRPC internal HTTP/2 stack with BoringSSL */ GRPCTransportTypeChttp2BoringSSL = 0, - // Cronet stack + /** Cronet stack */ GRPCTransportTypeCronet, - // Insecure channel. FOR TEST ONLY! + /** Insecure channel. FOR TEST ONLY! */ GRPCTransportTypeInsecure, }; From 590ab392520c0216690bc2626e2c9b55e95fc0fa Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 11:24:04 -0700 Subject: [PATCH 089/534] GRPCCompressAlgorithm->GRPCCompressionAlgorithm --- src/objective-c/GRPCClient/GRPCCallOptions.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 6e16cd56a93..b8bbb8a22d3 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -33,14 +33,19 @@ typedef NS_ENUM(NSUInteger, GRPCCallSafety) { GRPCCallSafetyCacheableRequest = 2, }; + + // Compression algorithm to be used by a gRPC call -typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { +typedef NS_ENUM(NSInteger, GRPCCompressionAlgorithm) { GRPCCompressNone = 0, GRPCCompressDeflate, GRPCCompressGzip, GRPCStreamCompressGzip, }; +// GRPCCompressAlgorithm is deprecated; use GRPCCompressionAlgorithm +typedef GRPCCompressionAlgorithm GRPCCompressAlgorithm; + /** The transport to be used by a gRPC call */ typedef NS_ENUM(NSInteger, GRPCTransportType) { GRPCTransportTypeDefault = 0, From cc9157a248e20a2f24972241ae1f2d41ea171a8b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 11:45:59 -0700 Subject: [PATCH 090/534] Polish comments --- src/objective-c/GRPCClient/GRPCCallOptions.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index b8bbb8a22d3..9a8362cbcca 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -67,7 +67,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The authority for the RPC. If nil, the default authority will be used. * - * Note: This property must be nil when Cronet transport is enabled. + * Note: This property does not have effect on Cronet transport and will be ignored. * Note: This property cannot be used to validate a self-signed server certificate. It control the * :authority header field of the call and performs an extra check that server's certificate * matches the :authority header. @@ -85,8 +85,8 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The OAuth2 access token string. The string is prefixed with "Bearer " then used as value of the - * request's "authorization" header field. This parameter should not be used simultaneously with - * \a authTokenProvider. + * request's "authorization" header field. This parameter takes precedence over \a + * oauth2AccessToken. */ @property(copy, readonly) NSString *oauth2AccessToken; @@ -213,7 +213,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The authority for the RPC. If nil, the default authority will be used. * - * Note: This property must be nil when Cronet transport is enabled. + * Note: This property does not have effect on Cronet transport and will be ignored. * Note: This property cannot be used to validate a self-signed server certificate. It control the * :authority header field of the call and performs an extra check that server's certificate * matches the :authority header. @@ -239,7 +239,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when - * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. + * initiating the call. This parameter takes precedence over \a oauth2AccessToken. */ @property(readwrite) id authTokenProvider; From 9f9141082bcd4167488780f93eeec8d40c17e007 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 11:57:18 -0700 Subject: [PATCH 091/534] compressAlgorithm->compressionAlgorithm --- src/objective-c/GRPCClient/GRPCCallOptions.h | 4 +-- src/objective-c/GRPCClient/GRPCCallOptions.m | 32 +++++++++---------- .../GRPCClient/private/GRPCChannelPool.m | 4 +-- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 9a8362cbcca..484f15fde6e 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -119,7 +119,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * The compression algorithm to be used by the gRPC call. For more details refer to * https://github.com/grpc/grpc/blob/master/doc/compression.md */ -@property(readonly) GRPCCompressAlgorithm compressAlgorithm; +@property(readonly) GRPCCompressionAlgorithm compressionAlgorithm; /** * Enable/Disable gRPC call's retry feature. The default is enabled. For details of this feature @@ -266,7 +266,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * The compression algorithm to be used by the gRPC call. For more details refer to * https://github.com/grpc/grpc/blob/master/doc/compression.md */ -@property(readwrite) GRPCCompressAlgorithm compressAlgorithm; +@property(readwrite) GRPCCompressionAlgorithm compressionAlgorithm; /** * Enable/Disable gRPC call's retry feature. The default is enabled. For details of this feature diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 37ed3ebd1d1..3dc21b72873 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -24,7 +24,7 @@ static const NSTimeInterval kDefaultTimeout = 0; static NSDictionary *const kDefaultInitialMetadata = nil; static NSString *const kDefaultUserAgentPrefix = nil; static const NSUInteger kDefaultResponseSizeLimit = 0; -static const GRPCCompressAlgorithm kDefaultCompressAlgorithm = GRPCCompressNone; +static const GRPCCompressionAlgorithm kDefaultCompressionAlgorithm = GRPCCompressNone; static const BOOL kDefaultEnableRetry = YES; static const NSTimeInterval kDefaultKeepaliveInterval = 0; static const NSTimeInterval kDefaultKeepaliveTimeout = 0; @@ -52,7 +52,7 @@ static NSUInteger kDefaultChannelID = 0; NSDictionary *_initialMetadata; NSString *_userAgentPrefix; NSUInteger _responseSizeLimit; - GRPCCompressAlgorithm _compressAlgorithm; + GRPCCompressionAlgorithm _compressionAlgorithm; BOOL _enableRetry; NSTimeInterval _keepaliveInterval; NSTimeInterval _keepaliveTimeout; @@ -77,7 +77,7 @@ static NSUInteger kDefaultChannelID = 0; @synthesize initialMetadata = _initialMetadata; @synthesize userAgentPrefix = _userAgentPrefix; @synthesize responseSizeLimit = _responseSizeLimit; -@synthesize compressAlgorithm = _compressAlgorithm; +@synthesize compressionAlgorithm = _compressionAlgorithm; @synthesize enableRetry = _enableRetry; @synthesize keepaliveInterval = _keepaliveInterval; @synthesize keepaliveTimeout = _keepaliveTimeout; @@ -102,7 +102,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:kDefaultInitialMetadata userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit - compressAlgorithm:kDefaultCompressAlgorithm + compressionAlgorithm:kDefaultCompressionAlgorithm enableRetry:kDefaultEnableRetry keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout @@ -127,7 +127,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:(NSDictionary *)initialMetadata userAgentPrefix:(NSString *)userAgentPrefix responseSizeLimit:(NSUInteger)responseSizeLimit - compressAlgorithm:(GRPCCompressAlgorithm)compressAlgorithm + compressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm enableRetry:(BOOL)enableRetry keepaliveInterval:(NSTimeInterval)keepaliveInterval keepaliveTimeout:(NSTimeInterval)keepaliveTimeout @@ -151,7 +151,7 @@ static NSUInteger kDefaultChannelID = 0; _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; _userAgentPrefix = [userAgentPrefix copy]; _responseSizeLimit = responseSizeLimit; - _compressAlgorithm = compressAlgorithm; + _compressionAlgorithm = compressionAlgorithm; _enableRetry = enableRetry; _keepaliveInterval = keepaliveInterval; _keepaliveTimeout = keepaliveTimeout; @@ -181,7 +181,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressAlgorithm:_compressAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -209,7 +209,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressAlgorithm:_compressAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -233,7 +233,7 @@ static NSUInteger kDefaultChannelID = 0; [callOptions.userAgentPrefix isEqualToString:_userAgentPrefix])) return NO; if (!(callOptions.responseSizeLimit == _responseSizeLimit)) return NO; - if (!(callOptions.compressAlgorithm == _compressAlgorithm)) return NO; + if (!(callOptions.compressionAlgorithm == _compressionAlgorithm)) return NO; if (!(callOptions.enableRetry == _enableRetry)) return NO; if (!(callOptions.keepaliveInterval == _keepaliveInterval)) return NO; if (!(callOptions.keepaliveTimeout == _keepaliveTimeout)) return NO; @@ -270,7 +270,7 @@ static NSUInteger kDefaultChannelID = 0; NSUInteger result = 0; result ^= _userAgentPrefix.hash; result ^= _responseSizeLimit; - result ^= _compressAlgorithm; + result ^= _compressionAlgorithm; result ^= _enableRetry; result ^= (unsigned int)(_keepaliveInterval * 1000); result ^= (unsigned int)(_keepaliveTimeout * 1000); @@ -301,7 +301,7 @@ static NSUInteger kDefaultChannelID = 0; @dynamic initialMetadata; @dynamic userAgentPrefix; @dynamic responseSizeLimit; -@dynamic compressAlgorithm; +@dynamic compressionAlgorithm; @dynamic enableRetry; @dynamic keepaliveInterval; @dynamic keepaliveTimeout; @@ -326,7 +326,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:kDefaultInitialMetadata userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit - compressAlgorithm:kDefaultCompressAlgorithm + compressionAlgorithm:kDefaultCompressionAlgorithm enableRetry:kDefaultEnableRetry keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout @@ -353,7 +353,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressAlgorithm:_compressAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -381,7 +381,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressAlgorithm:_compressAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -432,8 +432,8 @@ static NSUInteger kDefaultChannelID = 0; _responseSizeLimit = responseSizeLimit; } -- (void)setCompressAlgorithm:(GRPCCompressAlgorithm)compressAlgorithm { - _compressAlgorithm = compressAlgorithm; +- (void)setCompressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm { + _compressionAlgorithm = compressionAlgorithm; } - (void)setEnableRetry:(BOOL)enableRetry { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 6659d193c68..4908b82feac 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -94,9 +94,9 @@ extern const char *kCFStreamVarName; [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; } - if (_callOptions.compressAlgorithm != GRPC_COMPRESS_NONE) { + if (_callOptions.compressionAlgorithm != GRPC_COMPRESS_NONE) { args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = - [NSNumber numberWithInt:_callOptions.compressAlgorithm]; + [NSNumber numberWithInt:_callOptions.compressionAlgorithm]; } if (_callOptions.keepaliveInterval != 0) { diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 5fe022a1bae..41d3bec4efa 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -102,7 +102,7 @@ static NSMutableDictionary *gHostCache; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.userAgentPrefix = _userAgentPrefix; options.responseSizeLimit = _responseSizeLimitOverride; - options.compressAlgorithm = (GRPCCompressAlgorithm)_compressAlgorithm; + options.compressionAlgorithm = (GRPCCompressionAlgorithm)_compressAlgorithm; options.enableRetry = _retryEnabled; options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000; options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000; From 5eb9911a0eb13590fe558875df3512d6def20d3c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 13:55:31 -0700 Subject: [PATCH 092/534] Change extern type --- src/objective-c/GRPCClient/GRPCCall.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index d8d3e3cf629..7ce5a2faf2c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -145,8 +145,8 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { * Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by * the server. */ -extern id const kGRPCHeadersKey; -extern id const kGRPCTrailersKey; +extern NSString * const kGRPCHeadersKey; +extern NSString * const kGRPCTrailersKey; /** An object can implement this protocol to receive responses from server from a call. */ @protocol GRPCResponseHandler From 0242b022ccc804e498b2e631fd0e6c8478ac97c4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 14:28:25 -0700 Subject: [PATCH 093/534] Typo fix --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 7ce5a2faf2c..b8fccc37dc8 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -221,7 +221,7 @@ extern NSString * const kGRPCTrailersKey; /** * Designated initializer for a call. * \param requestOptions Protobuf generated parameters for the call. - * \param responseHandler The object to which responses should be issed. + * \param responseHandler The object to which responses should be issued. * \param callOptions Options for the call. */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions From e542e006eb4ffcd0c19488428a3cfe5605bf41e5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 14:29:08 -0700 Subject: [PATCH 094/534] Format fix --- src/objective-c/GRPCClient/GRPCCall.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index b8fccc37dc8..9fdcd93a30c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -254,7 +254,8 @@ extern NSString * const kGRPCTrailersKey; /** * Finish the RPC request and half-close the call. The server may still send messages and/or * trailers to the client. - */ -(void)finish; + */ +- (void)finish; /** * Get a copy of the original call options. From 422d3296b2d4fb3f8aa0991c2ffa895251ad8e91 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 15:42:39 -0700 Subject: [PATCH 095/534] Annotate Nullability --- src/objective-c/GRPCClient/GRPCCall.h | 12 ++++++++---- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.h | 14 +++++++++----- src/objective-c/ProtoRPC/ProtoRPC.m | 14 +++++++------- src/objective-c/tests/GRPCClientTests.m | 6 +++--- src/objective-c/tests/InteropTests.m | 6 +++--- 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 9fdcd93a30c..c862609b21c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -39,6 +39,8 @@ #include "GRPCCallOptions.h" +NS_ASSUME_NONNULL_BEGIN + #pragma mark gRPC errors /** Domain of NSError objects produced by gRPC. */ @@ -154,13 +156,13 @@ extern NSString * const kGRPCTrailersKey; @optional /** Issued when initial metadata is received from the server. */ -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; +- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata; /** * Issued when a message is received from the server. The message is the raw data received from the * server, with decompression and without proto deserialization. */ -- (void)receivedRawMessage:(NSData *)message; +- (void)receivedRawMessage:(NSData * _Nullable)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -168,7 +170,7 @@ extern NSString * const kGRPCTrailersKey; * is non-nil and contains the corresponding error information, including gRPC error codes and * error descriptions. */ -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error; +- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error; @required @@ -226,7 +228,7 @@ extern NSString * const kGRPCTrailersKey; */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler - callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; + callOptions:(GRPCCallOptions * _Nullable)callOptions NS_DESIGNATED_INITIALIZER; /** * Convenience initializer for a call that uses default call options (see GRPCCallOptions.m for * the default options). @@ -267,6 +269,8 @@ extern NSString * const kGRPCTrailersKey; @end +NS_ASSUME_NONNULL_END + /** * This interface is deprecated. Please use \a GRPCcall2. * diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index bd4b4e10f0f..1782078961d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -97,7 +97,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler - callOptions:(GRPCCallOptions *)callOptions { + callOptions:(GRPCCallOptions * _Nullable)callOptions { if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 34a519bee5d..3a7fd58fb16 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -21,6 +21,8 @@ #import "ProtoMethod.h" +NS_ASSUME_NONNULL_BEGIN + @class GPBMessage; /** An object can implement this protocol to receive responses from server from a call. */ @@ -29,12 +31,12 @@ @optional /** Issued when initial metadata is received from the server. */ -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; +- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata; /** * Issued when a message is received from the server. The message is the deserialized proto object. */ -- (void)receivedProtoMessage:(GPBMessage *)message; +- (void)receivedProtoMessage:(GPBMessage * _Nullable)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -42,7 +44,7 @@ * is non-nil and contains the corresponding error information, including gRPC error codes and * error descriptions. */ -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error; +- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error; @required @@ -68,7 +70,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message responseHandler:(id)handler - callOptions:(GRPCCallOptions *)callOptions + callOptions:(GRPCCallOptions * _Nullable)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** @@ -93,7 +95,7 @@ */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler - callOptions:(GRPCCallOptions *)callOptions + callOptions:(GRPCCallOptions * _Nullable)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** @@ -117,6 +119,8 @@ @end +NS_ASSUME_NONNULL_END + __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC : GRPCCall diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 44e9bfde0ab..f6e3298f623 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -34,7 +34,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message responseHandler:(id)handler - callOptions:(GRPCCallOptions *)callOptions + callOptions:(GRPCCallOptions * _Nullable)callOptions responseClass:(Class)responseClass { if ((self = [super init])) { _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions @@ -70,7 +70,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler - callOptions:(GRPCCallOptions *)callOptions + callOptions:(GRPCCallOptions * _Nullable)callOptions responseClass:(Class)responseClass { if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; @@ -153,8 +153,8 @@ }); } -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { - if (_handler) { +- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata { + if (_handler && initialMetadata != nil) { id handler = _handler; if ([handler respondsToSelector:@selector(initialMetadata:)]) { dispatch_async(handler.dispatchQueue, ^{ @@ -164,8 +164,8 @@ } } -- (void)receivedRawMessage:(NSData *)message { - if (_handler) { +- (void)receivedRawMessage:(NSData * _Nullable)message { + if (_handler && message != nil) { id handler = _handler; NSError *error = nil; GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; @@ -188,7 +188,7 @@ } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { +- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error { if (_handler) { id handler = _handler; if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 985e105b816..0a9ec97c488 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -114,19 +114,19 @@ static GRPCProtoMethod *kFullDuplexCallMethod; return self; } -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata { if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); } } -- (void)receivedProtoMessage:(GPBMessage *)message { +- (void)receivedProtoMessage:(GPBMessage * _Nullable)message { if (_messageCallback) { _messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { +- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error { if (_closeCallback) { _closeCallback(trailingMetadata, error); } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index a9f33aab6f1..fb49bb99e0a 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -102,19 +102,19 @@ BOOL isRemoteInteropTest(NSString *host) { return self; } -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata { if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); } } -- (void)receivedProtoMessage:(GPBMessage *)message { +- (void)receivedProtoMessage:(GPBMessage * _Nullable)message { if (_messageCallback) { _messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { +- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error { if (_closeCallback) { _closeCallback(trailingMetadata, error); } From 24d952b2b916030aa02f33afb7746b2582ca88e4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 15:43:46 -0700 Subject: [PATCH 096/534] Add comments to ivars of GRPCCall2 --- src/objective-c/GRPCClient/GRPCCall.m | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 1782078961d..74b284d924c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -85,13 +85,24 @@ const char *kCFStreamVarName = "grpc_cfstream"; @end @implementation GRPCCall2 { + /** Options for the call. */ GRPCCallOptions *_callOptions; + /** The handler of responses. */ id _handler; + // Thread safety of ivars below are protected by _dispatcheQueue. + + /** + * Make use of legacy GRPCCall to make calls. Nullified when call is finished. + */ GRPCCall *_call; + /** Flags whether initial metadata has been published to response handler. */ BOOL _initialMetadataPublished; + /** Streaming call writeable to the underlying call. */ GRXBufferedPipe *_pipe; + /** Serial dispatch queue for tasks inside the call. */ dispatch_queue_t _dispatchQueue; + /** Flags whether call has started. */ bool _started; } From c6de16fc801b654ff1cbb697c36fafa5c2ff0528 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 15:44:07 -0700 Subject: [PATCH 097/534] Remove redundant variable --- src/objective-c/GRPCClient/GRPCCall.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 74b284d924c..daa7e8dd4a1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -579,7 +579,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; callSafetyFlags = GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; break; } - uint32_t callFlag = callSafetyFlags; NSMutableDictionary *headers = _requestHeaders; if (_fetchedOauth2AccessToken != nil) { @@ -592,7 +591,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // TODO(jcanizales): Add error handlers for async failures GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] initWithMetadata:headers - flags:callFlag + flags:callSafetyFlags handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA if (!_unaryCall) { [_wrappedCall startBatchWithOperations:@[ op ]]; From cb745ceaf9f9ffd90447498a6e8a57d5ac600389 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 15:46:57 -0700 Subject: [PATCH 098/534] Synchronized access to fetchedOauth2AccessToken --- src/objective-c/GRPCClient/GRPCCall.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index daa7e8dd4a1..34a0e436eaa 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -581,8 +581,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; } NSMutableDictionary *headers = _requestHeaders; - if (_fetchedOauth2AccessToken != nil) { - headers[@"authorization"] = [kBearerPrefix stringByAppendingString:_fetchedOauth2AccessToken]; + __block NSString *fetchedOauth2AccessToken; + @synchronized(self) { + fetchedOauth2AccessToken = _fetchedOauth2AccessToken; + } + if (fetchedOauth2AccessToken != nil) { + headers[@"authorization"] = [kBearerPrefix stringByAppendingString:fetchedOauth2AccessToken]; } else if (_callOptions.oauth2AccessToken != nil) { headers[@"authorization"] = [kBearerPrefix stringByAppendingString:_callOptions.oauth2AccessToken]; From 789108d16d72c61b6df4135796116d3cffce0a58 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 17:24:23 -0700 Subject: [PATCH 099/534] add const attribute to defaults --- src/objective-c/GRPCClient/GRPCCallOptions.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 3dc21b72873..e148664925c 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -40,8 +40,8 @@ static const id kDefaultAuthTokenProvider = nil; static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2BoringSSL; static NSString *const kDefaultHostNameOverride = nil; static const id kDefaultLogContext = nil; -static NSString *kDefaultChannelPoolDomain = nil; -static NSUInteger kDefaultChannelID = 0; +static NSString *const kDefaultChannelPoolDomain = nil; +static const NSUInteger kDefaultChannelID = 0; @implementation GRPCCallOptions { @protected From 8cecb2a86dd5904c68f46d4b685b11c8cb0a8704 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 17:33:50 -0700 Subject: [PATCH 100/534] Write comments for functions in ChannelArgsUtil --- src/objective-c/GRPCClient/private/ChannelArgsUtil.h | 9 +++++++++ src/objective-c/GRPCClient/private/ChannelArgsUtil.m | 7 ------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h index d0be4849105..3fb876ecc4a 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h @@ -20,6 +20,15 @@ #include +/** Free resources in the grpc core struct grpc_channel_args */ void GRPCFreeChannelArgs(grpc_channel_args* channel_args); +/** + * Allocates a @c grpc_channel_args and populates it with the options specified in the + * @c dictionary. Keys must be @c NSString, @c NSNumber, or a pointer. If the value responds to + * @c @selector(UTF8String) then it will be mapped to @c GRPC_ARG_STRING. If the value responds to + * @c @selector(intValue), it will be mapped to @c GRPC_ARG_INTEGER. Otherwise, if the value is not + * nil, it is mapped as a pointer. The caller of this function is responsible for calling + * @c GRPCFreeChannelArgs to free the @c grpc_channel_args struct. + */ grpc_channel_args* GRPCBuildChannelArgs(NSDictionary* dictionary); diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index 8669f79992c..b8342a79e79 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -51,13 +51,6 @@ void GRPCFreeChannelArgs(grpc_channel_args *channel_args) { gpr_free(channel_args); } -/** - * Allocates a @c grpc_channel_args and populates it with the options specified in the - * @c dictionary. Keys must be @c NSString. If the value responds to @c @selector(UTF8String) then - * it will be mapped to @c GRPC_ARG_STRING. If not, it will be mapped to @c GRPC_ARG_INTEGER if the - * value responds to @c @selector(intValue). Otherwise, an exception will be raised. The caller of - * this function is responsible for calling @c freeChannelArgs on a non-NULL returned value. - */ grpc_channel_args *GRPCBuildChannelArgs(NSDictionary *dictionary) { if (!dictionary) { return NULL; From b3cb4e17f76624e563e51165954ebaa6224d806c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 17:56:42 -0700 Subject: [PATCH 101/534] Comment and rename GRPCChannel:ref and :unref --- src/objective-c/GRPCClient/private/GRPCChannel.h | 14 ++++++++++++-- src/objective-c/GRPCClient/private/GRPCChannel.m | 4 ++-- .../GRPCClient/private/GRPCChannelPool.m | 2 +- .../GRPCClient/private/GRPCWrappedCall.m | 2 +- .../tests/ChannelTests/ChannelPoolTest.m | 2 +- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 7a40638dc33..5f5fae04135 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -51,10 +51,20 @@ struct grpc_channel_credentials; completionQueue:(nonnull GRPCCompletionQueue *)queue callOptions:(nonnull GRPCCallOptions *)callOptions; -- (void)unmanagedCallRef; +/** + * Increase the refcount of the channel. If the channel was timed to be destroyed, cancel the timer. + */ +- (void)ref; -- (void)unmanagedCallUnref; +/** + * Decrease the refcount of the channel. If the refcount of the channel decrease to 0, start a timer + * to destroy the channel + */ +- (void)unref; +/** + * Force the channel to be disconnected and destroyed immediately. + */ - (void)disconnect; // TODO (mxyan): deprecate with GRPCCall:closeOpenConnections diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 63bc267a762..3e4db837658 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -180,7 +180,7 @@ NSTimeInterval kChannelDestroyDelay = 30; return call; } -- (void)unmanagedCallRef { +- (void)ref { dispatch_async(_dispatchQueue, ^{ if (self->_unmanagedChannel) { [self->_channelRef refChannel]; @@ -188,7 +188,7 @@ NSTimeInterval kChannelDestroyDelay = 30; }); } -- (void)unmanagedCallUnref { +- (void)unref { dispatch_async(_dispatchQueue, ^{ if (self->_unmanagedChannel) { [self->_channelRef unrefChannel]; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 4908b82feac..8e0f6976cf9 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -191,7 +191,7 @@ extern const char *kCFStreamVarName; @synchronized(self) { if ([_channelPool objectForKey:configuration]) { channel = _channelPool[configuration]; - [channel unmanagedCallRef]; + [channel ref]; } else { channel = [GRPCChannel createChannelWithConfiguration:configuration]; if (channel != nil) { diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index a7c50a17519..4d5257aca79 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -311,7 +311,7 @@ - (void)dealloc { grpc_call_unref(_call); - [_channel unmanagedCallUnref]; + [_channel unref]; _channel = nil; } diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index f4a9fb4a2c4..5c3f0edba0b 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -74,7 +74,7 @@ extern NSTimeInterval kChannelDestroyDelay; [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - [channel1 unmanagedCallUnref]; + [channel1 unref]; sleep(1); GRPCChannel *channel2 = [pool channelWithConfiguration:config1]; XCTAssertEqual(channel1, channel2); From 17d178363dafe3aa03d348bdbbbd0c3daed9e06e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 17:57:26 -0700 Subject: [PATCH 102/534] rename non-const variables --- .../GRPCClient/private/GRPCSecureChannelFactory.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 3f2769bf447..aa8b52e6b8f 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -55,7 +55,7 @@ NS_ASSUME_NONNULL_BEGIN certChain:(nullable NSString *)certChain error:(NSError **)errorPtr { static NSData *defaultRootsASCII; - static NSError *kDefaultRootsError; + static NSError *defaultRootsError; static dispatch_once_t loading; dispatch_once(&loading, ^{ NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem @@ -68,7 +68,7 @@ NS_ASSUME_NONNULL_BEGIN NSString *contentInUTF8 = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; if (contentInUTF8 == nil) { - kDefaultRootsError = error; + defaultRootsError = error; return; } defaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8]; @@ -80,15 +80,15 @@ NS_ASSUME_NONNULL_BEGIN } else { if (defaultRootsASCII == nil) { if (errorPtr) { - *errorPtr = kDefaultRootsError; + *errorPtr = defaultRootsError; } NSAssert( - kDefaultRootsASCII, + defaultRootsASCII, @"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: %@", - kDefaultRootsError); + defaultRootsError); return nil; } rootsASCII = defaultRootsASCII; From 5e3e744d448c8cd1271cae7e8d40d3bdeaff762f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 18:32:05 -0700 Subject: [PATCH 103/534] copy configuration --- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 3e4db837658..6bd852fd0d0 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -220,7 +220,7 @@ NSTimeInterval kChannelDestroyDelay = 30; configuration:(GRPCChannelConfiguration *)configuration { if ((self = [super init])) { _unmanagedChannel = unmanagedChannel; - _configuration = configuration; + _configuration = [configuration copy]; _channelRef = [[GRPCChannelRef alloc] initWithDestroyDelay:kChannelDestroyDelay destroyChannelCallback:^{ [self destroyChannel]; From 4186405287a6944e7b1eb59dcae5524ea2db674d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 09:40:22 -0700 Subject: [PATCH 104/534] GRPCChannel input parameter sanity check --- src/objective-c/GRPCClient/private/GRPCChannel.m | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 6bd852fd0d0..6b5d1fe0719 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -150,14 +150,17 @@ NSTimeInterval kChannelDestroyDelay = 30; } - (grpc_call *)unmanagedCallWithPath:(NSString *)path - completionQueue:(nonnull GRPCCompletionQueue *)queue + completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions { + NSAssert(path.length, @"path must not be empty."); + NSAssert(queue, @"completionQueue must not be empty."); + NSAssert(callOptions, @"callOptions must not be empty."); __block grpc_call *call = nil; dispatch_sync(_dispatchQueue, ^{ if (self->_unmanagedChannel) { NSString *serverAuthority = callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; - GPR_ASSERT(timeout >= 0); + NSAssert(timeout >= 0, @"Invalid timeout"); grpc_slice host_slice = grpc_empty_slice(); if (serverAuthority) { host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); @@ -216,8 +219,12 @@ NSTimeInterval kChannelDestroyDelay = 30; }); } -- (nullable instancetype)initWithUnmanagedChannel:(nullable grpc_channel *)unmanagedChannel +- (nullable instancetype)initWithUnmanagedChannel:(grpc_channel * _Nullable)unmanagedChannel configuration:(GRPCChannelConfiguration *)configuration { + NSAssert(configuration, @"Configuration must not be empty."); + if (!unmanagedChannel) { + return nil; + } if ((self = [super init])) { _unmanagedChannel = unmanagedChannel; _configuration = [configuration copy]; From 836640dc4a9e8d62fc0e1218e81076a06a3035a9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 09:41:34 -0700 Subject: [PATCH 105/534] Mark GRPCChannel:new: unavailable --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/private/GRPCChannel.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index c862609b21c..13dcfa07130 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -218,7 +218,7 @@ extern NSString * const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype) new NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; /** * Designated initializer for a call. diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 5f5fae04135..5fb18e0332e 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -32,6 +32,8 @@ struct grpc_channel_credentials; - (nullable instancetype)init NS_UNAVAILABLE; ++ (nullable instancetype)new NS_UNAVAILABLE; + /** * Returns a channel connecting to \a host with options as \a callOptions. The channel may be new * or a cached channel that is already connected. From c6fc07d384fe11ca4dc59111b61557053ed3dbac Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 09:44:44 -0700 Subject: [PATCH 106/534] Relocate global channel pool variables --- src/objective-c/GRPCClient/private/GRPCChannel.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 6b5d1fe0719..ac4b88f3049 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -32,9 +32,12 @@ #import #import -// When all calls of a channel are destroyed, destroy the channel after this much seconds. +/** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ NSTimeInterval kChannelDestroyDelay = 30; +/** Global instance of channel pool. */ +static GRPCChannelPool *gChannelPool; + /** * Time the channel destroy when the channel's calls are unreffed. If there's new call, reset the * timer. @@ -268,11 +271,9 @@ NSTimeInterval kChannelDestroyDelay = 30; return [[GRPCChannel alloc] initWithUnmanagedChannel:unmanaged_channel configuration:config]; } -static dispatch_once_t initChannelPool; -static GRPCChannelPool *gChannelPool; - + (nullable instancetype)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { + static dispatch_once_t initChannelPool; dispatch_once(&initChannelPool, ^{ gChannelPool = [[GRPCChannelPool alloc] init]; }); From ef830758cc90924e9fdd5be6a451774fad326db0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 09:50:36 -0700 Subject: [PATCH 107/534] Comments to methods of GRPCChannelConfiguration --- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index e9c2ef2bd14..43e07b98454 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -29,12 +29,22 @@ NS_ASSUME_NONNULL_BEGIN @class GRPCChannel; +/** Caching signature of a channel. */ @interface GRPCChannelConfiguration : NSObject +/** The host that this channel is connected to. */ @property(copy, readonly) NSString *host; + +/** + * Options of the corresponding call. Note that only the channel-related options are of interest to + * this class. + */ @property(strong, readonly) GRPCCallOptions *callOptions; +/** Acquire the factory to generate a new channel with current configurations. */ @property(readonly) id channelFactory; + +/** Acquire the dictionary of channel args with current configurations. */ @property(readonly) NSDictionary *channelArgs; - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; From dcf5f1ff384da2cf0dd6b38bb9062caed58e35c0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 10:03:59 -0700 Subject: [PATCH 108/534] Comments to GRPCChannelFactory --- src/objective-c/GRPCClient/private/GRPCChannelFactory.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h index 492145da80b..14dc7079ba3 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -22,8 +22,10 @@ NS_ASSUME_NONNULL_BEGIN +/** A factory interface which generates new channel. */ @protocol GRPCChannelFactory + /** Create a channel with specific channel args to a specific host. */ - (nullable grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(nullable NSDictionary *)args; From 4efa40d7cda4537e42adaa0dbd70097886d2c91c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 10:06:07 -0700 Subject: [PATCH 109/534] Validate parameters of GRPCChannelConfiguration:initWithHost: --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 8e0f6976cf9..80fa9c9151f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -35,6 +35,8 @@ extern const char *kCFStreamVarName; @implementation GRPCChannelConfiguration - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { + NSAssert(host.length, @"Host must not be empty."); + NSAssert(callOptions, @"callOptions must not be empty."); if ((self = [super init])) { _host = [host copy]; _callOptions = [callOptions copy]; From ed1e6c48e05e510186303e430a800078128dfc89 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 12:09:19 -0700 Subject: [PATCH 110/534] More verbose channel destroy message --- src/objective-c/GRPCClient/private/GRPCChannel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 5fb18e0332e..7151dbb6e9c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -59,8 +59,8 @@ struct grpc_channel_credentials; - (void)ref; /** - * Decrease the refcount of the channel. If the refcount of the channel decrease to 0, start a timer - * to destroy the channel + * Decrease the refcount of the channel. If the refcount of the channel decrease to 0, the channel + * is destroyed after 30 seconds. */ - (void)unref; From e667a3fb8f3465732926d44bc882dfaabc8dae54 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 12:25:25 -0700 Subject: [PATCH 111/534] Another copy --- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index ac4b88f3049..f3ac140599e 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -264,7 +264,7 @@ static GRPCChannelPool *gChannelPool; [args addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; channelArgs = args; } else { - channelArgs = config.channelArgs; + channelArgs = [config.channelArgs copy]; } id factory = config.channelFactory; grpc_channel *unmanaged_channel = [factory createChannelWithHost:host channelArgs:channelArgs]; From ae99d3a5ed45e135f8b9bd9235b252fed56aa417 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 12:41:05 -0700 Subject: [PATCH 112/534] Document GRPCAuthorizationProtocol --- src/objective-c/GRPCClient/GRPCCallOptions.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 484f15fde6e..4a93db84bc2 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -57,7 +57,15 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { GRPCTransportTypeInsecure, }; +/** + * Implement this protocol to provide a token to gRPC when a call is initiated. + */ @protocol GRPCAuthorizationProtocol + +/** + * This method is called when gRPC is about to start the call. When OAuth token is acquired, + * \a handler is expected to be called with \a token being the new token to be used for this call. + */ - (void)getTokenWithHandler:(void (^)(NSString *token))hander; @end From 9a15b6a5cfa81ab31afb4945cc1ccd8fe5be5665 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 13:00:38 -0700 Subject: [PATCH 113/534] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 16 +++++++++------- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 8 +++----- src/objective-c/GRPCClient/GRPCCallOptions.m | 14 +++++++------- .../GRPCClient/private/ChannelArgsUtil.h | 14 +++++++++----- src/objective-c/GRPCClient/private/GRPCChannel.h | 2 +- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- .../GRPCClient/private/GRPCChannelFactory.h | 2 +- src/objective-c/ProtoRPC/ProtoRPC.h | 11 ++++++----- src/objective-c/ProtoRPC/ProtoRPC.m | 11 ++++++----- src/objective-c/tests/GRPCClientTests.m | 7 ++++--- src/objective-c/tests/InteropTests.m | 7 ++++--- 12 files changed, 52 insertions(+), 44 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 13dcfa07130..b3936ad8fc1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -147,8 +147,8 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { * Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by * the server. */ -extern NSString * const kGRPCHeadersKey; -extern NSString * const kGRPCTrailersKey; +extern NSString *const kGRPCHeadersKey; +extern NSString *const kGRPCTrailersKey; /** An object can implement this protocol to receive responses from server from a call. */ @protocol GRPCResponseHandler @@ -156,13 +156,13 @@ extern NSString * const kGRPCTrailersKey; @optional /** Issued when initial metadata is received from the server. */ -- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata; +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; /** * Issued when a message is received from the server. The message is the raw data received from the * server, with decompression and without proto deserialization. */ -- (void)receivedRawMessage:(NSData * _Nullable)message; +- (void)receivedRawMessage:(NSData *_Nullable)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -170,7 +170,8 @@ extern NSString * const kGRPCTrailersKey; * is non-nil and contains the corresponding error information, including gRPC error codes and * error descriptions. */ -- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error; +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error; @required @@ -218,7 +219,7 @@ extern NSString * const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Designated initializer for a call. @@ -228,7 +229,8 @@ extern NSString * const kGRPCTrailersKey; */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler - callOptions:(GRPCCallOptions * _Nullable)callOptions NS_DESIGNATED_INITIALIZER; + callOptions:(GRPCCallOptions *_Nullable)callOptions + NS_DESIGNATED_INITIALIZER; /** * Convenience initializer for a call that uses default call options (see GRPCCallOptions.m for * the default options). diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 34a0e436eaa..60a946a472c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -108,7 +108,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler - callOptions:(GRPCCallOptions * _Nullable)callOptions { + callOptions:(GRPCCallOptions *_Nullable)callOptions { if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; } diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 4a93db84bc2..d1daaa1d822 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -27,14 +27,12 @@ typedef NS_ENUM(NSUInteger, GRPCCallSafety) { /** 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, }; - - // Compression algorithm to be used by a gRPC call typedef NS_ENUM(NSInteger, GRPCCompressionAlgorithm) { GRPCCompressNone = 0, diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index e148664925c..fe75c17b09a 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -102,7 +102,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:kDefaultInitialMetadata userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit - compressionAlgorithm:kDefaultCompressionAlgorithm + compressionAlgorithm:kDefaultCompressionAlgorithm enableRetry:kDefaultEnableRetry keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout @@ -127,7 +127,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:(NSDictionary *)initialMetadata userAgentPrefix:(NSString *)userAgentPrefix responseSizeLimit:(NSUInteger)responseSizeLimit - compressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm + compressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm enableRetry:(BOOL)enableRetry keepaliveInterval:(NSTimeInterval)keepaliveInterval keepaliveTimeout:(NSTimeInterval)keepaliveTimeout @@ -181,7 +181,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressionAlgorithm:_compressionAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -209,7 +209,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressionAlgorithm:_compressionAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -326,7 +326,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:kDefaultInitialMetadata userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit - compressionAlgorithm:kDefaultCompressionAlgorithm + compressionAlgorithm:kDefaultCompressionAlgorithm enableRetry:kDefaultEnableRetry keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout @@ -353,7 +353,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressionAlgorithm:_compressionAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -381,7 +381,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressionAlgorithm:_compressionAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h index 3fb876ecc4a..f271e846f00 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h @@ -24,11 +24,15 @@ void GRPCFreeChannelArgs(grpc_channel_args* channel_args); /** - * Allocates a @c grpc_channel_args and populates it with the options specified in the - * @c dictionary. Keys must be @c NSString, @c NSNumber, or a pointer. If the value responds to - * @c @selector(UTF8String) then it will be mapped to @c GRPC_ARG_STRING. If the value responds to - * @c @selector(intValue), it will be mapped to @c GRPC_ARG_INTEGER. Otherwise, if the value is not - * nil, it is mapped as a pointer. The caller of this function is responsible for calling + * Allocates a @c grpc_channel_args and populates it with the options specified + * in the + * @c dictionary. Keys must be @c NSString, @c NSNumber, or a pointer. If the + * value responds to + * @c @selector(UTF8String) then it will be mapped to @c GRPC_ARG_STRING. If the + * value responds to + * @c @selector(intValue), it will be mapped to @c GRPC_ARG_INTEGER. Otherwise, + * if the value is not nil, it is mapped as a pointer. The caller of this + * function is responsible for calling * @c GRPCFreeChannelArgs to free the @c grpc_channel_args struct. */ grpc_channel_args* GRPCBuildChannelArgs(NSDictionary* dictionary); diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 7151dbb6e9c..e1bf8fb1af4 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -32,7 +32,7 @@ struct grpc_channel_credentials; - (nullable instancetype)init NS_UNAVAILABLE; -+ (nullable instancetype)new NS_UNAVAILABLE; ++ (nullable instancetype) new NS_UNAVAILABLE; /** * Returns a channel connecting to \a host with options as \a callOptions. The channel may be new diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index f3ac140599e..018ed28a7ab 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -222,7 +222,7 @@ static GRPCChannelPool *gChannelPool; }); } -- (nullable instancetype)initWithUnmanagedChannel:(grpc_channel * _Nullable)unmanagedChannel +- (nullable instancetype)initWithUnmanagedChannel:(grpc_channel *_Nullable)unmanagedChannel configuration:(GRPCChannelConfiguration *)configuration { NSAssert(configuration, @"Configuration must not be empty."); if (!unmanagedChannel) { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h index 14dc7079ba3..a934e966e9d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN /** A factory interface which generates new channel. */ @protocol GRPCChannelFactory - /** Create a channel with specific channel args to a specific host. */ +/** Create a channel with specific channel args to a specific host. */ - (nullable grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(nullable NSDictionary *)args; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 3a7fd58fb16..960a9a12bd2 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -31,12 +31,12 @@ NS_ASSUME_NONNULL_BEGIN @optional /** Issued when initial metadata is received from the server. */ -- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata; +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; /** * Issued when a message is received from the server. The message is the deserialized proto object. */ -- (void)receivedProtoMessage:(GPBMessage * _Nullable)message; +- (void)receivedProtoMessage:(GPBMessage *_Nullable)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -44,7 +44,8 @@ NS_ASSUME_NONNULL_BEGIN * is non-nil and contains the corresponding error information, including gRPC error codes and * error descriptions. */ -- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error; +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error; @required @@ -70,7 +71,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message responseHandler:(id)handler - callOptions:(GRPCCallOptions * _Nullable)callOptions + callOptions:(GRPCCallOptions *_Nullable)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** @@ -95,7 +96,7 @@ NS_ASSUME_NONNULL_BEGIN */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler - callOptions:(GRPCCallOptions * _Nullable)callOptions + callOptions:(GRPCCallOptions *_Nullable)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index f6e3298f623..28c037e6092 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -34,7 +34,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message responseHandler:(id)handler - callOptions:(GRPCCallOptions * _Nullable)callOptions + callOptions:(GRPCCallOptions *_Nullable)callOptions responseClass:(Class)responseClass { if ((self = [super init])) { _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions @@ -70,7 +70,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler - callOptions:(GRPCCallOptions * _Nullable)callOptions + callOptions:(GRPCCallOptions *_Nullable)callOptions responseClass:(Class)responseClass { if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; @@ -153,7 +153,7 @@ }); } -- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { if (_handler && initialMetadata != nil) { id handler = _handler; if ([handler respondsToSelector:@selector(initialMetadata:)]) { @@ -164,7 +164,7 @@ } } -- (void)receivedRawMessage:(NSData * _Nullable)message { +- (void)receivedRawMessage:(NSData *_Nullable)message { if (_handler && message != nil) { id handler = _handler; NSError *error = nil; @@ -188,7 +188,8 @@ } } -- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error { +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error { if (_handler) { id handler = _handler; if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 0a9ec97c488..0d1b80e33c8 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -114,19 +114,20 @@ static GRPCProtoMethod *kFullDuplexCallMethod; return self; } -- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); } } -- (void)receivedProtoMessage:(GPBMessage * _Nullable)message { +- (void)receivedProtoMessage:(GPBMessage *_Nullable)message { if (_messageCallback) { _messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error { +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error { if (_closeCallback) { _closeCallback(trailingMetadata, error); } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index fb49bb99e0a..d67dc0743e8 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -102,19 +102,20 @@ BOOL isRemoteInteropTest(NSString *host) { return self; } -- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); } } -- (void)receivedProtoMessage:(GPBMessage * _Nullable)message { +- (void)receivedProtoMessage:(GPBMessage *_Nullable)message { if (_messageCallback) { _messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error { +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error { if (_closeCallback) { _closeCallback(trailingMetadata, error); } From 2b0470dcb3bd8306adb1c63a81c931482e86c5fa Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 13:07:02 -0700 Subject: [PATCH 114/534] Ignore serverAuthority when using Cronet transport --- src/objective-c/GRPCClient/private/GRPCChannel.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 018ed28a7ab..60c2e29a6ec 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -161,7 +161,8 @@ static GRPCChannelPool *gChannelPool; __block grpc_call *call = nil; dispatch_sync(_dispatchQueue, ^{ if (self->_unmanagedChannel) { - NSString *serverAuthority = callOptions.serverAuthority; + NSString *serverAuthority = + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); grpc_slice host_slice = grpc_empty_slice(); From 5c7ab989bed8e8b757db0de077571eeec66d3f2f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Oct 2018 11:13:39 -0700 Subject: [PATCH 115/534] bool->BOOL --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 60a946a472c..7e0640e8ae1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -103,7 +103,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; /** Serial dispatch queue for tasks inside the call. */ dispatch_queue_t _dispatchQueue; /** Flags whether call has started. */ - bool _started; + BOOL _started; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions From b03adfbf067cc4f7ef05eb7fa8cbf49c08b3bf6b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Oct 2018 12:14:43 -0700 Subject: [PATCH 116/534] More nullability specifier --- src/objective-c/GRPCClient/GRPCCall.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index b3936ad8fc1..2f23b879f13 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -304,7 +304,7 @@ NS_ASSUME_NONNULL_END * * The property is initialized to an empty NSMutableDictionary. */ -@property(atomic, readonly) NSMutableDictionary *requestHeaders; +@property(null_unspecified, atomic, readonly) NSMutableDictionary * requestHeaders; /** * This dictionary is populated with the HTTP headers received from the server. This happens before @@ -315,7 +315,7 @@ NS_ASSUME_NONNULL_END * The value of this property is nil until all response headers are received, and will change before * any of -writeValue: or -writesFinishedWithError: are sent to the writeable. */ -@property(atomic, readonly) NSDictionary *responseHeaders; +@property(null_unspecified, atomic, readonly) NSDictionary *responseHeaders; /** * Same as responseHeaders, but populated with the HTTP trailers received from the server before the @@ -324,7 +324,7 @@ NS_ASSUME_NONNULL_END * The value of this property is nil until all response trailers are received, and will change * before -writesFinishedWithError: is sent to the writeable. */ -@property(atomic, readonly) NSDictionary *responseTrailers; +@property(null_unspecified, atomic, readonly) NSDictionary *responseTrailers; /** * The request writer has to write NSData objects into the provided Writeable. The server will @@ -337,9 +337,9 @@ NS_ASSUME_NONNULL_END * 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 - path:(NSString *)path - requestsWriter:(GRXWriter *)requestWriter; +- (instancetype _Null_unspecified)initWithHost:(NSString * _Null_unspecified)host + path:(NSString * _Null_unspecified)path + requestsWriter:(GRXWriter * _Null_unspecified)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -350,10 +350,10 @@ NS_ASSUME_NONNULL_END /** * The following methods are deprecated. */ -+ (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path; -@property(atomic, copy, readwrite) NSString *serverName; ++ (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString * _Null_unspecified)host path:(NSString * _Null_unspecified)path; +@property(null_unspecified, atomic, copy, readwrite) NSString *serverName; @property NSTimeInterval timeout; -- (void)setResponseDispatchQueue:(dispatch_queue_t)queue; +- (void)setResponseDispatchQueue:(dispatch_queue_t _Null_unspecified)queue; @end @@ -364,11 +364,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (id)objectForKeyedSubscript:(id)key; -- (void)setObject:(id)obj forKeyedSubscript:(id)key; +- (id _Null_unspecified)objectForKeyedSubscript:(id _Null_unspecified)key; +- (void)setObject:(id _Null_unspecified)obj forKeyedSubscript:(id _Null_unspecified)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(id)key; +- (void)removeObjectForKey:(id _Null_unspecified)key; @end #pragma clang diagnostic push From fb1ebfef00e5153e30c1a008a350c53dde4335c3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Oct 2018 13:56:10 -0700 Subject: [PATCH 117/534] Fix test flake --- src/objective-c/tests/GRPCClientTests.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 0d1b80e33c8..2021540f28d 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -120,7 +120,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; } } -- (void)receivedProtoMessage:(GPBMessage *_Nullable)message { +- (void)receivedRawMessage:(GPBMessage *_Nullable)message { if (_messageCallback) { _messageCallback(message); } @@ -803,7 +803,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; NSString *const kDummyAddress = [NSString stringWithFormat:@"8.8.8.8:1"]; GRPCCall *call = [[GRPCCall alloc] initWithHost:kDummyAddress - path:@"" + path:@"/dummyPath" requestsWriter:[GRXWriter writerWithValue:[NSData data]]]; [GRPCCall setMinConnectTimeout:timeout * 1000 initialBackoff:backoff * 1000 From 3566540f16451ea87aff980b5de13c41a8debeb6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Oct 2018 14:45:38 -0700 Subject: [PATCH 118/534] nit: group includes --- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 41d3bec4efa..c0d75c0f319 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -20,11 +20,11 @@ #import #import +#import #include #include -#import #import "GRPCChannelFactory.h" #import "GRPCCompletionQueue.h" #import "GRPCConnectivityMonitor.h" From e13c8678264d85353bb2ce49ae829c03f6c9493f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Oct 2018 18:25:16 -0700 Subject: [PATCH 119/534] Do not issue more message when the call is canceled --- src/objective-c/GRPCClient/GRPCCall.m | 61 ++++++++++++++++++++------- src/objective-c/ProtoRPC/ProtoRPC.m | 43 ++++++++++++++----- 2 files changed, 78 insertions(+), 26 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 7e0640e8ae1..23c8d0f2d71 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -104,6 +104,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_queue_t _dispatchQueue; /** Flags whether call has started. */ BOOL _started; + /** + * Flags that the call has been canceled. When this is true, pending initial metadata and message + * should not be issued to \a _handler. This ivar must be accessed with lock to self. + */ + BOOL _canceled; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -135,6 +140,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); _started = NO; + _canceled = NO; } return self; @@ -217,6 +223,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; self->_pipe = nil; } if (self->_handler) { + @synchronized(self) { + self->_canceled = YES; + } id handler = self->_handler; dispatch_async(handler.dispatchQueue, ^{ if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { @@ -252,30 +261,50 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - id handler = _handler; - if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:initialMetadata]; - }); + if (_handler != nil && initialMetadata != nil) { + id handler = _handler; + if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + dispatch_async(handler.dispatchQueue, ^{ + // Do not issue initial metadata if the call is already canceled. + __block BOOL canceled = NO; + @synchronized(self) { + canceled = self->_canceled; + } + if (!canceled) { + [handler receivedInitialMetadata:initialMetadata]; + } + }); + } } } - (void)issueMessage:(id)message { - id handler = _handler; - if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedRawMessage:message]; - }); + if (_handler != nil && message != nil) { + id handler = _handler; + if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { + dispatch_async(handler.dispatchQueue, ^{ + // Do not issue message if the call is already canceled. + __block BOOL canceled = NO; + @synchronized(self) { + canceled = self->_canceled; + } + if (!canceled) { + [handler receivedRawMessage:message]; + } + }); + } } } - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - id handler = _handler; - NSDictionary *trailers = _call.responseTrailers; - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:trailers error:error]; - }); + if (_handler != nil) { + id handler = _handler; + NSDictionary *trailers = _call.responseTrailers; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:trailers error:error]; + }); + } } } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 28c037e6092..a6c88488fc2 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -66,6 +66,11 @@ GRPCCall2 *_call; dispatch_queue_t _dispatchQueue; + /** + * Flags that the call has been canceled. When this is true, pending initial metadata and message + * should not be issued to \a _handler. This ivar must be accessed with lock to self. + */ + BOOL _canceled; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -95,6 +100,7 @@ _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } dispatch_set_target_queue(handler.dispatchQueue, _dispatchQueue); + _canceled = NO; [self start]; } @@ -110,12 +116,15 @@ - (void)cancel { dispatch_async(_dispatchQueue, ^{ - if (_call) { - [_call cancel]; - _call = nil; + if (self->_call) { + [self->_call cancel]; + self->_call = nil; } - if (_handler) { - id handler = _handler; + if (self->_handler) { + @synchronized(self) { + self->_canceled = YES; + } + id handler = self->_handler; if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(handler.dispatchQueue, ^{ [handler closedWithTrailingMetadata:nil @@ -127,7 +136,7 @@ }]]; }); } - _handler = nil; + self->_handler = nil; } }); } @@ -155,10 +164,17 @@ - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { if (_handler && initialMetadata != nil) { - id handler = _handler; + __block id handler = _handler; if ([handler respondsToSelector:@selector(initialMetadata:)]) { dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:initialMetadata]; + // Do not issue initial metadata if the call is already canceled. + __block BOOL canceled = NO; + @synchronized(self) { + canceled = self->_canceled; + } + if (!canceled) { + [handler receivedInitialMetadata:initialMetadata]; + } }); } } @@ -166,13 +182,20 @@ - (void)receivedRawMessage:(NSData *_Nullable)message { if (_handler && message != nil) { - id handler = _handler; + __block id handler = _handler; NSError *error = nil; GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; if (parsed) { if ([handler respondsToSelector:@selector(receivedProtoMessage:)]) { dispatch_async(handler.dispatchQueue, ^{ - [handler receivedProtoMessage:parsed]; + // Do not issue message if the call is already canceled. + __block BOOL canceled = NO; + @synchronized(self) { + canceled = self->_canceled; + } + if (!canceled) { + [handler receivedProtoMessage:parsed]; + } }); } } else { From 76ddfcb6cb87611addcbc68b01264e37a4705d27 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Oct 2018 18:36:59 -0700 Subject: [PATCH 120/534] Propagate internal error when failed parsing proto --- src/objective-c/ProtoRPC/ProtoRPC.m | 35 ++++++++++++++++------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index a6c88488fc2..6085f893560 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -27,6 +27,24 @@ #import #import +/** + * Generate an NSError object that represents a failure in parsing a proto class. + */ +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 " + @"with exponential backoff. Otherwise, query the server status before " + @"retrying.", + NSUnderlyingErrorKey : parsingError, + @"Expected class" : expectedClass, + @"Received value" : proto, + }; + // TODO(jcanizales): Use kGRPCErrorDomain and GRPCErrorCodeInternal when they're public. + return [NSError errorWithDomain:@"io.grpc" code:13 userInfo:info]; +} + @implementation GRPCUnaryProtoCall { GRPCStreamingProtoCall *_call; } @@ -201,7 +219,7 @@ } else { if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:nil error:error]; + [handler closedWithTrailingMetadata:nil error:ErrorForBadProto(message, _responseClass, error)]; }); } _handler = nil; @@ -232,21 +250,6 @@ @end -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 " - @"with exponential backoff. Otherwise, query the server status before " - @"retrying.", - NSUnderlyingErrorKey : parsingError, - @"Expected class" : expectedClass, - @"Received value" : proto, - }; - // TODO(jcanizales): Use kGRPCErrorDomain and GRPCErrorCodeInternal when they're public. - return [NSError errorWithDomain:@"io.grpc" code:13 userInfo:info]; -} - #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-implementations" @implementation ProtoRPC { From e39c146f0f7f1a56e0cd65ec5d707c8bb091366e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 10:03:48 -0700 Subject: [PATCH 121/534] Revert "Do not issue more message when the call is canceled" This reverts commit e13c8678264d85353bb2ce49ae829c03f6c9493f. --- src/objective-c/GRPCClient/GRPCCall.m | 61 +++++++-------------------- src/objective-c/ProtoRPC/ProtoRPC.m | 43 +++++-------------- 2 files changed, 26 insertions(+), 78 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 23c8d0f2d71..7e0640e8ae1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -104,11 +104,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_queue_t _dispatchQueue; /** Flags whether call has started. */ BOOL _started; - /** - * Flags that the call has been canceled. When this is true, pending initial metadata and message - * should not be issued to \a _handler. This ivar must be accessed with lock to self. - */ - BOOL _canceled; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -140,7 +135,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; } dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); _started = NO; - _canceled = NO; } return self; @@ -223,9 +217,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; self->_pipe = nil; } if (self->_handler) { - @synchronized(self) { - self->_canceled = YES; - } id handler = self->_handler; dispatch_async(handler.dispatchQueue, ^{ if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { @@ -261,50 +252,30 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - if (_handler != nil && initialMetadata != nil) { - id handler = _handler; - if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { - dispatch_async(handler.dispatchQueue, ^{ - // Do not issue initial metadata if the call is already canceled. - __block BOOL canceled = NO; - @synchronized(self) { - canceled = self->_canceled; - } - if (!canceled) { - [handler receivedInitialMetadata:initialMetadata]; - } - }); - } + id handler = _handler; + if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedInitialMetadata:initialMetadata]; + }); } } - (void)issueMessage:(id)message { - if (_handler != nil && message != nil) { - id handler = _handler; - if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { - dispatch_async(handler.dispatchQueue, ^{ - // Do not issue message if the call is already canceled. - __block BOOL canceled = NO; - @synchronized(self) { - canceled = self->_canceled; - } - if (!canceled) { - [handler receivedRawMessage:message]; - } - }); - } + id handler = _handler; + if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedRawMessage:message]; + }); } } - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - if (_handler != nil) { - id handler = _handler; - NSDictionary *trailers = _call.responseTrailers; - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:trailers error:error]; - }); - } + id handler = _handler; + NSDictionary *trailers = _call.responseTrailers; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:trailers error:error]; + }); } } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 6085f893560..294f3a4cf5c 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -84,11 +84,6 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing GRPCCall2 *_call; dispatch_queue_t _dispatchQueue; - /** - * Flags that the call has been canceled. When this is true, pending initial metadata and message - * should not be issued to \a _handler. This ivar must be accessed with lock to self. - */ - BOOL _canceled; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -118,7 +113,6 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } dispatch_set_target_queue(handler.dispatchQueue, _dispatchQueue); - _canceled = NO; [self start]; } @@ -134,15 +128,12 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)cancel { dispatch_async(_dispatchQueue, ^{ - if (self->_call) { - [self->_call cancel]; - self->_call = nil; + if (_call) { + [_call cancel]; + _call = nil; } - if (self->_handler) { - @synchronized(self) { - self->_canceled = YES; - } - id handler = self->_handler; + if (_handler) { + id handler = _handler; if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(handler.dispatchQueue, ^{ [handler closedWithTrailingMetadata:nil @@ -154,7 +145,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing }]]; }); } - self->_handler = nil; + _handler = nil; } }); } @@ -182,17 +173,10 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { if (_handler && initialMetadata != nil) { - __block id handler = _handler; + id handler = _handler; if ([handler respondsToSelector:@selector(initialMetadata:)]) { dispatch_async(handler.dispatchQueue, ^{ - // Do not issue initial metadata if the call is already canceled. - __block BOOL canceled = NO; - @synchronized(self) { - canceled = self->_canceled; - } - if (!canceled) { - [handler receivedInitialMetadata:initialMetadata]; - } + [handler receivedInitialMetadata:initialMetadata]; }); } } @@ -200,20 +184,13 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)receivedRawMessage:(NSData *_Nullable)message { if (_handler && message != nil) { - __block id handler = _handler; + id handler = _handler; NSError *error = nil; GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; if (parsed) { if ([handler respondsToSelector:@selector(receivedProtoMessage:)]) { dispatch_async(handler.dispatchQueue, ^{ - // Do not issue message if the call is already canceled. - __block BOOL canceled = NO; - @synchronized(self) { - canceled = self->_canceled; - } - if (!canceled) { - [handler receivedProtoMessage:parsed]; - } + [handler receivedProtoMessage:parsed]; }); } } else { From f3e9224f0b34a6265830600c67293d96964a4c5c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 10:22:18 -0700 Subject: [PATCH 122/534] Remove retain of handler in callbacks and dispatch to dispatchQueue --- src/objective-c/GRPCClient/GRPCCall.h | 11 +++-- src/objective-c/GRPCClient/GRPCCall.m | 21 +++------ src/objective-c/ProtoRPC/ProtoRPC.h | 8 +++- src/objective-c/ProtoRPC/ProtoRPC.m | 63 +++++++++++-------------- src/objective-c/tests/GRPCClientTests.m | 24 ++++++---- src/objective-c/tests/InteropTests.m | 24 ++++++---- 6 files changed, 77 insertions(+), 74 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 2f23b879f13..85d0a302d17 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -155,12 +155,16 @@ extern NSString *const kGRPCTrailersKey; @optional -/** Issued when initial metadata is received from the server. */ +/** + * Issued when initial metadata is received from the server. The task must be scheduled onto the + * dispatch queue in property \a dispatchQueue. + */ - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; /** * Issued when a message is received from the server. The message is the raw data received from the - * server, with decompression and without proto deserialization. + * server, with decompression and without proto deserialization. The task must be scheduled onto the + * dispatch queue in property \a dispatchQueue. */ - (void)receivedRawMessage:(NSData *_Nullable)message; @@ -168,7 +172,8 @@ extern NSString *const kGRPCTrailersKey; * Issued when a call finished. If the call finished successfully, \a error is nil and \a * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error * is non-nil and contains the corresponding error information, including gRPC error codes and - * error descriptions. + * error descriptions. The task must be scheduled onto the dispatch queue in property + * \a dispatchQueue. */ - (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata error:(NSError *_Nullable)error; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 7e0640e8ae1..29a0ed4e106 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -252,30 +252,21 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - id handler = _handler; - if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:initialMetadata]; - }); + if (initialMetadata != nil && [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + [_handler receivedInitialMetadata:initialMetadata]; } } - (void)issueMessage:(id)message { - id handler = _handler; - if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedRawMessage:message]; - }); + if (message != nil && [_handler respondsToSelector:@selector(receivedRawMessage:)]) { + [_handler receivedRawMessage:message]; } } - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - id handler = _handler; NSDictionary *trailers = _call.responseTrailers; - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:trailers error:error]; - }); + if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + [_handler closedWithTrailingMetadata:trailers error:error]; } } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 960a9a12bd2..6f4b9eed759 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -30,11 +30,14 @@ NS_ASSUME_NONNULL_BEGIN @optional -/** Issued when initial metadata is received from the server. */ +/** + * Issued when initial metadata is received from the server. The task must be scheduled onto the + * dispatch queue in property \a dispatchQueue. */ - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; /** * Issued when a message is received from the server. The message is the deserialized proto object. + * The task must be scheduled onto the dispatch queue in property \a dispatchQueue. */ - (void)receivedProtoMessage:(GPBMessage *_Nullable)message; @@ -42,7 +45,8 @@ NS_ASSUME_NONNULL_BEGIN * Issued when a call finished. If the call finished successfully, \a error is nil and \a * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error * is non-nil and contains the corresponding error information, including gRPC error codes and - * error descriptions. + * error descriptions. The task must be scheduled onto the dispatch queue in property + * \a dispatchQueue. */ - (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata error:(NSError *_Nullable)error; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 294f3a4cf5c..27070a891d5 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -172,53 +172,44 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { - if (_handler && initialMetadata != nil) { - id handler = _handler; - if ([handler respondsToSelector:@selector(initialMetadata:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:initialMetadata]; - }); + dispatch_async(_dispatchQueue, ^{ + if (initialMetadata != nil && [self->_handler respondsToSelector:@selector(initialMetadata:)]) { + [self->_handler receivedInitialMetadata:initialMetadata]; } - } + }); } - (void)receivedRawMessage:(NSData *_Nullable)message { - if (_handler && message != nil) { - id handler = _handler; - NSError *error = nil; - GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; - if (parsed) { - if ([handler respondsToSelector:@selector(receivedProtoMessage:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedProtoMessage:parsed]; - }); - } - } else { - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:nil error:ErrorForBadProto(message, _responseClass, error)]; - }); + dispatch_async(_dispatchQueue, ^{ + if (self->_handler && message != nil) { + NSError *error = nil; + GPBMessage *parsed = [self->_responseClass parseFromData:message error:&error]; + if (parsed) { + if ([self->_handler respondsToSelector:@selector(receivedProtoMessage:)]) { + [self->_handler receivedProtoMessage:parsed]; + } + } else { + if ([self->_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + [self->_handler closedWithTrailingMetadata:nil error:ErrorForBadProto(message, _responseClass, error)]; + } + self->_handler = nil; + [self->_call cancel]; + self->_call = nil; } - _handler = nil; - [_call cancel]; - _call = nil; } - } + }); } - (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata error:(NSError *_Nullable)error { - if (_handler) { - id handler = _handler; - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:trailingMetadata error:error]; - }); + dispatch_async(_dispatchQueue, ^{ + if ([self->_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + [self->_handler closedWithTrailingMetadata:trailingMetadata error:error]; } - _handler = nil; - } - [_call cancel]; - _call = nil; + self->_handler = nil; + [self->_call cancel]; + self->_call = nil; + }); } - (dispatch_queue_t)dispatchQueue { diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 2021540f28d..bbe81502dcf 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -115,22 +115,28 @@ static GRPCProtoMethod *kFullDuplexCallMethod; } - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { - if (_initialMetadataCallback) { - _initialMetadataCallback(initialMetadata); - } + dispatch_async(_dispatchQueue, ^{ + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } + }); } - (void)receivedRawMessage:(GPBMessage *_Nullable)message { - if (_messageCallback) { - _messageCallback(message); - } + dispatch_async(_dispatchQueue, ^{ + if (_messageCallback) { + _messageCallback(message); + } + }); } - (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata error:(NSError *_Nullable)error { - if (_closeCallback) { - _closeCallback(trailingMetadata, error); - } + dispatch_async(_dispatchQueue, ^{ + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } + }); } - (dispatch_queue_t)dispatchQueue { diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index d67dc0743e8..c42718f15ee 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -103,22 +103,28 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { - if (_initialMetadataCallback) { - _initialMetadataCallback(initialMetadata); - } + dispatch_async(_dispatchQueue, ^{ + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } + }); } - (void)receivedProtoMessage:(GPBMessage *_Nullable)message { - if (_messageCallback) { - _messageCallback(message); - } + dispatch_async(_dispatchQueue, ^{ + if (_messageCallback) { + _messageCallback(message); + } + }); } - (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata error:(NSError *_Nullable)error { - if (_closeCallback) { - _closeCallback(trailingMetadata, error); - } + dispatch_async(_dispatchQueue, ^{ + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } + }); } - (dispatch_queue_t)dispatchQueue { From 351b5d0f13138690b8ce75a7675306caec5c9e62 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 10:28:04 -0700 Subject: [PATCH 123/534] enableRetry->retryEnabled --- src/objective-c/GRPCClient/GRPCCallOptions.h | 4 +-- src/objective-c/GRPCClient/GRPCCallOptions.m | 32 +++++++++---------- .../GRPCClient/private/GRPCChannelPool.m | 4 +-- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index d1daaa1d822..4c8bb605eab 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -132,7 +132,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * refer to * https://github.com/grpc/proposal/blob/master/A6-client-retries.md */ -@property(readonly) BOOL enableRetry; +@property(readonly) BOOL retryEnabled; // HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two // PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the @@ -279,7 +279,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * refer to * https://github.com/grpc/proposal/blob/master/A6-client-retries.md */ -@property(readwrite) BOOL enableRetry; +@property(readwrite) BOOL retryEnabled; // HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two // PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index fe75c17b09a..85a5a9ac89e 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -25,7 +25,7 @@ static NSDictionary *const kDefaultInitialMetadata = nil; static NSString *const kDefaultUserAgentPrefix = nil; static const NSUInteger kDefaultResponseSizeLimit = 0; static const GRPCCompressionAlgorithm kDefaultCompressionAlgorithm = GRPCCompressNone; -static const BOOL kDefaultEnableRetry = YES; +static const BOOL kDefaultRetryEnabled = YES; static const NSTimeInterval kDefaultKeepaliveInterval = 0; static const NSTimeInterval kDefaultKeepaliveTimeout = 0; static const NSTimeInterval kDefaultConnectMinTimeout = 0; @@ -53,7 +53,7 @@ static const NSUInteger kDefaultChannelID = 0; NSString *_userAgentPrefix; NSUInteger _responseSizeLimit; GRPCCompressionAlgorithm _compressionAlgorithm; - BOOL _enableRetry; + BOOL _retryEnabled; NSTimeInterval _keepaliveInterval; NSTimeInterval _keepaliveTimeout; NSTimeInterval _connectMinTimeout; @@ -78,7 +78,7 @@ static const NSUInteger kDefaultChannelID = 0; @synthesize userAgentPrefix = _userAgentPrefix; @synthesize responseSizeLimit = _responseSizeLimit; @synthesize compressionAlgorithm = _compressionAlgorithm; -@synthesize enableRetry = _enableRetry; +@synthesize retryEnabled = _retryEnabled; @synthesize keepaliveInterval = _keepaliveInterval; @synthesize keepaliveTimeout = _keepaliveTimeout; @synthesize connectMinTimeout = _connectMinTimeout; @@ -103,7 +103,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit compressionAlgorithm:kDefaultCompressionAlgorithm - enableRetry:kDefaultEnableRetry + retryEnabled:kDefaultRetryEnabled keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout connectMinTimeout:kDefaultConnectMinTimeout @@ -128,7 +128,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:(NSString *)userAgentPrefix responseSizeLimit:(NSUInteger)responseSizeLimit compressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm - enableRetry:(BOOL)enableRetry + retryEnabled:(BOOL)retryEnabled keepaliveInterval:(NSTimeInterval)keepaliveInterval keepaliveTimeout:(NSTimeInterval)keepaliveTimeout connectMinTimeout:(NSTimeInterval)connectMinTimeout @@ -152,7 +152,7 @@ static const NSUInteger kDefaultChannelID = 0; _userAgentPrefix = [userAgentPrefix copy]; _responseSizeLimit = responseSizeLimit; _compressionAlgorithm = compressionAlgorithm; - _enableRetry = enableRetry; + _retryEnabled = retryEnabled; _keepaliveInterval = keepaliveInterval; _keepaliveTimeout = keepaliveTimeout; _connectMinTimeout = connectMinTimeout; @@ -182,7 +182,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - enableRetry:_enableRetry + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -210,7 +210,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - enableRetry:_enableRetry + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -234,7 +234,7 @@ static const NSUInteger kDefaultChannelID = 0; return NO; if (!(callOptions.responseSizeLimit == _responseSizeLimit)) return NO; if (!(callOptions.compressionAlgorithm == _compressionAlgorithm)) return NO; - if (!(callOptions.enableRetry == _enableRetry)) return NO; + if (!(callOptions.retryEnabled == _retryEnabled)) return NO; if (!(callOptions.keepaliveInterval == _keepaliveInterval)) return NO; if (!(callOptions.keepaliveTimeout == _keepaliveTimeout)) return NO; if (!(callOptions.connectMinTimeout == _connectMinTimeout)) return NO; @@ -271,7 +271,7 @@ static const NSUInteger kDefaultChannelID = 0; result ^= _userAgentPrefix.hash; result ^= _responseSizeLimit; result ^= _compressionAlgorithm; - result ^= _enableRetry; + result ^= _retryEnabled; result ^= (unsigned int)(_keepaliveInterval * 1000); result ^= (unsigned int)(_keepaliveTimeout * 1000); result ^= (unsigned int)(_connectMinTimeout * 1000); @@ -302,7 +302,7 @@ static const NSUInteger kDefaultChannelID = 0; @dynamic userAgentPrefix; @dynamic responseSizeLimit; @dynamic compressionAlgorithm; -@dynamic enableRetry; +@dynamic retryEnabled; @dynamic keepaliveInterval; @dynamic keepaliveTimeout; @dynamic connectMinTimeout; @@ -327,7 +327,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit compressionAlgorithm:kDefaultCompressionAlgorithm - enableRetry:kDefaultEnableRetry + retryEnabled:kDefaultRetryEnabled keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout connectMinTimeout:kDefaultConnectMinTimeout @@ -354,7 +354,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - enableRetry:_enableRetry + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -382,7 +382,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - enableRetry:_enableRetry + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -436,8 +436,8 @@ static const NSUInteger kDefaultChannelID = 0; _compressionAlgorithm = compressionAlgorithm; } -- (void)setEnableRetry:(BOOL)enableRetry { - _enableRetry = enableRetry; +- (void)setRetryEnabled:(BOOL)retryEnabled { + _retryEnabled = retryEnabled; } - (void)setKeepaliveInterval:(NSTimeInterval)keepaliveInterval { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 80fa9c9151f..1dfae32342d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -108,8 +108,8 @@ extern const char *kCFStreamVarName; [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.keepaliveTimeout * 1000)]; } - if (_callOptions.enableRetry == NO) { - args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.enableRetry]; + if (_callOptions.retryEnabled == NO) { + args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.retryEnabled]; } if (_callOptions.connectMinTimeout > 0) { diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index c0d75c0f319..38b31c2ebcb 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -103,7 +103,7 @@ static NSMutableDictionary *gHostCache; options.userAgentPrefix = _userAgentPrefix; options.responseSizeLimit = _responseSizeLimitOverride; options.compressionAlgorithm = (GRPCCompressionAlgorithm)_compressAlgorithm; - options.enableRetry = _retryEnabled; + options.retryEnabled = _retryEnabled; options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000; options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000; options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000; From 8986cfe6259fe7efc6ad438abb9e904f190c0515 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 10:39:39 -0700 Subject: [PATCH 124/534] Assert mutual exclusion of authTokenProvider and oauth2AccessToken --- src/objective-c/GRPCClient/GRPCCall.m | 3 +++ src/objective-c/GRPCClient/GRPCCallOptions.h | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 29a0ed4e106..85a2837336d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -781,6 +781,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; } _callOptions = callOptions; } + + NSAssert(_callOptions.authTokenProvider != nil || _callOptions.oauth2AccessToken != nil, + @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); if (_callOptions.authTokenProvider != nil) { @synchronized(self) { self.isWaitingForToken = YES; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 4c8bb605eab..27834b20088 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -91,8 +91,8 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The OAuth2 access token string. The string is prefixed with "Bearer " then used as value of the - * request's "authorization" header field. This parameter takes precedence over \a - * oauth2AccessToken. + * request's "authorization" header field. This parameter should not be used simultaneously with + * \a authTokenProvider. */ @property(copy, readonly) NSString *oauth2AccessToken; @@ -245,7 +245,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when - * initiating the call. This parameter takes precedence over \a oauth2AccessToken. + * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. */ @property(readwrite) id authTokenProvider; From 3c8e9886aca311ee2b26e7f7ef827ac7efb42716 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 10:53:11 -0700 Subject: [PATCH 125/534] Mark channelArg as copy --- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 60c2e29a6ec..777cbab8092 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -265,7 +265,7 @@ static GRPCChannelPool *gChannelPool; [args addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; channelArgs = args; } else { - channelArgs = [config.channelArgs copy]; + channelArgs = config.channelArgs; } id factory = config.channelFactory; grpc_channel *unmanaged_channel = [factory createChannelWithHost:host channelArgs:channelArgs]; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 43e07b98454..2244361df2c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN @property(readonly) id channelFactory; /** Acquire the dictionary of channel args with current configurations. */ -@property(readonly) NSDictionary *channelArgs; +@property(copy, readonly) NSDictionary *channelArgs; - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; From 647e24c190465e9547583a631ac5b33de98ae812 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 11:31:36 -0700 Subject: [PATCH 126/534] Put logContext in class extension --- gRPC.podspec | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 10 ----- src/objective-c/GRPCClient/GRPCCallOptions.m | 1 + .../internal/GRPCCallOptions+internal.h | 37 +++++++++++++++++++ .../GRPCClient/private/GRPCChannelPool.m | 1 + src/objective-c/GRPCClient/private/GRPCHost.m | 1 + templates/gRPC.podspec.template | 2 +- 7 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h diff --git a/gRPC.podspec b/gRPC.podspec index 5e513cb1276..47a130d12d1 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -58,7 +58,7 @@ Pod::Spec.new do |s| ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}" ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}" - ss.private_header_files = "#{src_dir}/private/*.h" + ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/GRPCCallOptions+Internal.h" ss.dependency 'gRPC-Core', version end diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 27834b20088..4f02b344b15 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -182,11 +182,6 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ @property(copy, readonly) NSString *hostNameOverride; -/** - * Parameter used for internal logging. - */ -@property(readonly) id logContext; - /** * A string that specify the domain where channel is being cached. Channels with different domains * will not get cached to the same connection. @@ -331,11 +326,6 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ @property(copy, readwrite) NSString *hostNameOverride; -/** - * Parameter used for internal logging. - */ -@property(copy, readwrite) id logContext; - /** * A string that specify the domain where channel is being cached. Channels with different domains * will not get cached to the same channel. For example, a gRPC example app may use the channel pool diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 85a5a9ac89e..cd90bc68933 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -17,6 +17,7 @@ */ #import "GRPCCallOptions.h" +#import "internal/GRPCCallOptions+internal.h" // The default values for the call options. static NSString *const kDefaultServerAuthority = nil; diff --git a/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h b/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h new file mode 100644 index 00000000000..406f268ef21 --- /dev/null +++ b/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h @@ -0,0 +1,37 @@ +/* + * + * 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. + * + */ + +#import + +@interface GRPCCallOptions () + +/** + * Parameter used for internal logging. + */ +@property(readonly) id logContext; + +@end + +@interface GRPCMutableCallOptions () + +/** + * Parameter used for internal logging. + */ +@property(readwrite) id logContext; + +@end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 1dfae32342d..86f76678518 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -26,6 +26,7 @@ #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "version.h" +#import "../internal/GRPCCallOptions+internal.h" #import #include diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 38b31c2ebcb..592e8fe776d 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -32,6 +32,7 @@ #import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" #import "version.h" +#import "../internal/GRPCCallOptions+internal.h" NS_ASSUME_NONNULL_BEGIN diff --git a/templates/gRPC.podspec.template b/templates/gRPC.podspec.template index a3190c2d8e6..a3ed1d78584 100644 --- a/templates/gRPC.podspec.template +++ b/templates/gRPC.podspec.template @@ -60,7 +60,7 @@ ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}" ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}" - ss.private_header_files = "#{src_dir}/private/*.h" + ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/GRPCCallOptions+Internal.h" ss.dependency 'gRPC-Core', version end From 35f6ab959e7f3d05d35aa7baeeeddeba559969f6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 13:10:44 -0700 Subject: [PATCH 127/534] unsigned int -> NSUInteger --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 86f76678518..7b800686d01 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -104,9 +104,9 @@ extern const char *kCFStreamVarName; if (_callOptions.keepaliveInterval != 0) { args[@GRPC_ARG_KEEPALIVE_TIME_MS] = - [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.keepaliveInterval * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = - [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.keepaliveTimeout * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; } if (_callOptions.retryEnabled == NO) { @@ -115,15 +115,15 @@ extern const char *kCFStreamVarName; if (_callOptions.connectMinTimeout > 0) { args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = - [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.connectMinTimeout * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMinTimeout * 1000)]; } if (_callOptions.connectInitialBackoff > 0) { args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber - numberWithUnsignedInteger:(unsigned int)(_callOptions.connectInitialBackoff * 1000)]; + numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectInitialBackoff * 1000)]; } if (_callOptions.connectMaxBackoff > 0) { args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = - [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.connectMaxBackoff * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMaxBackoff * 1000)]; } if (_callOptions.logContext != nil) { From cc58524994eddfbbc7cd800efe1462a7ec28d4f0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 13:11:06 -0700 Subject: [PATCH 128/534] isChannelOptionsEqualTo->hasChannelOptionsEqualTo --- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 4f02b344b15..9683bd3c638 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -199,7 +199,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * Return if the channel options are equal to another object. */ -- (BOOL)isChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; +- (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; /** * Hash for channel options. diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index cd90bc68933..ba3255f0e4f 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -229,7 +229,7 @@ static const NSUInteger kDefaultChannelID = 0; return newOptions; } -- (BOOL)isChannelOptionsEqualTo:(GRPCCallOptions *)callOptions { +- (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions { if (!(callOptions.userAgentPrefix == _userAgentPrefix || [callOptions.userAgentPrefix isEqualToString:_userAgentPrefix])) return NO; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 7b800686d01..61f5a55077a 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -150,7 +150,7 @@ extern const char *kCFStreamVarName; NSAssert([object isKindOfClass:[GRPCChannelConfiguration class]], @"Illegal :isEqual"); GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; if (!(obj.host == _host || [obj.host isEqualToString:_host])) return NO; - if (!(obj.callOptions == _callOptions || [obj.callOptions isChannelOptionsEqualTo:_callOptions])) + if (!(obj.callOptions == _callOptions || [obj.callOptions hasChannelOptionsEqualTo:_callOptions])) return NO; return YES; From 26108e1106cffd1767f0b7fb6ff4b0672ed6a640 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 13:14:24 -0700 Subject: [PATCH 129/534] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 18 +++++++------ src/objective-c/GRPCClient/GRPCCallOptions.m | 10 +++---- .../GRPCClient/private/GRPCChannelPool.m | 2 +- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.h | 4 +-- src/objective-c/ProtoRPC/ProtoRPC.m | 26 ++++++++++--------- 6 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 85d0a302d17..a1f139fc186 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -156,9 +156,9 @@ extern NSString *const kGRPCTrailersKey; @optional /** - * Issued when initial metadata is received from the server. The task must be scheduled onto the - * dispatch queue in property \a dispatchQueue. - */ + * Issued when initial metadata is received from the server. The task must be scheduled onto the + * dispatch queue in property \a dispatchQueue. + */ - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; /** @@ -309,7 +309,7 @@ NS_ASSUME_NONNULL_END * * The property is initialized to an empty NSMutableDictionary. */ -@property(null_unspecified, atomic, readonly) NSMutableDictionary * requestHeaders; +@property(null_unspecified, atomic, readonly) NSMutableDictionary *requestHeaders; /** * This dictionary is populated with the HTTP headers received from the server. This happens before @@ -342,9 +342,9 @@ NS_ASSUME_NONNULL_END * 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 _Null_unspecified)initWithHost:(NSString * _Null_unspecified)host - path:(NSString * _Null_unspecified)path - requestsWriter:(GRXWriter * _Null_unspecified)requestWriter; +- (instancetype _Null_unspecified)initWithHost:(NSString *_Null_unspecified)host + path:(NSString *_Null_unspecified)path + requestsWriter:(GRXWriter *_Null_unspecified)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -355,7 +355,9 @@ NS_ASSUME_NONNULL_END /** * The following methods are deprecated. */ -+ (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString * _Null_unspecified)host path:(NSString * _Null_unspecified)path; ++ (void)setCallSafety:(GRPCCallSafety)callSafety + host:(NSString *_Null_unspecified)host + path:(NSString *_Null_unspecified)path; @property(null_unspecified, atomic, copy, readwrite) NSString *serverName; @property NSTimeInterval timeout; - (void)setResponseDispatchQueue:(dispatch_queue_t _Null_unspecified)queue; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index ba3255f0e4f..0977a4ccdbc 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -183,7 +183,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - retryEnabled:_retryEnabled + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -211,7 +211,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - retryEnabled:_retryEnabled + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -328,7 +328,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit compressionAlgorithm:kDefaultCompressionAlgorithm - retryEnabled:kDefaultRetryEnabled + retryEnabled:kDefaultRetryEnabled keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout connectMinTimeout:kDefaultConnectMinTimeout @@ -355,7 +355,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - retryEnabled:_retryEnabled + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -383,7 +383,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - retryEnabled:_retryEnabled + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 61f5a55077a..56f76450b22 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -18,6 +18,7 @@ #import +#import "../internal/GRPCCallOptions+internal.h" #import "GRPCChannel.h" #import "GRPCChannelFactory.h" #import "GRPCChannelPool.h" @@ -26,7 +27,6 @@ #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "version.h" -#import "../internal/GRPCCallOptions+internal.h" #import #include diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 592e8fe776d..ab5b69cc4e9 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -25,6 +25,7 @@ #include #include +#import "../internal/GRPCCallOptions+internal.h" #import "GRPCChannelFactory.h" #import "GRPCCompletionQueue.h" #import "GRPCConnectivityMonitor.h" @@ -32,7 +33,6 @@ #import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" #import "version.h" -#import "../internal/GRPCCallOptions+internal.h" NS_ASSUME_NONNULL_BEGIN diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 6f4b9eed759..635ba0c90ee 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -31,8 +31,8 @@ NS_ASSUME_NONNULL_BEGIN @optional /** - * Issued when initial metadata is received from the server. The task must be scheduled onto the - * dispatch queue in property \a dispatchQueue. */ + * Issued when initial metadata is received from the server. The task must be scheduled onto the + * dispatch queue in property \a dispatchQueue. */ - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; /** diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 27070a891d5..34891e8953b 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -28,19 +28,19 @@ #import /** - * Generate an NSError object that represents a failure in parsing a proto class. - */ + * Generate an NSError object that represents a failure in parsing a proto class. + */ 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 " - @"with exponential backoff. Otherwise, query the server status before " - @"retrying.", - NSUnderlyingErrorKey : parsingError, - @"Expected class" : expectedClass, - @"Received value" : proto, - }; + NSLocalizedDescriptionKey : @"Unable to parse response from the server", + NSLocalizedRecoverySuggestionErrorKey : + @"If this RPC is idempotent, retry " + @"with exponential backoff. Otherwise, query the server status before " + @"retrying.", + NSUnderlyingErrorKey : parsingError, + @"Expected class" : expectedClass, + @"Received value" : proto, + }; // TODO(jcanizales): Use kGRPCErrorDomain and GRPCErrorCodeInternal when they're public. return [NSError errorWithDomain:@"io.grpc" code:13 userInfo:info]; } @@ -190,7 +190,9 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } } else { if ([self->_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [self->_handler closedWithTrailingMetadata:nil error:ErrorForBadProto(message, _responseClass, error)]; + [self->_handler + closedWithTrailingMetadata:nil + error:ErrorForBadProto(message, _responseClass, error)]; } self->_handler = nil; [self->_call cancel]; From c62c3b920c4df9c52a51d3941814317ce8acc483 Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Tue, 23 Oct 2018 16:50:31 -0700 Subject: [PATCH 130/534] Add fake lb policy for test. Tweak existing interception code. --- .../filters/client_channel/client_channel.cc | 53 ++--- test/cpp/end2end/client_lb_end2end_test.cc | 188 +++++++++++++++++- 2 files changed, 216 insertions(+), 25 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 9732b1753a8..5a74ccc2a05 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -937,6 +937,7 @@ typedef struct client_channel_call_data { grpc_closure recv_trailing_metadata_ready_for_lb; // The original trailer interception callback. grpc_closure* original_recv_trailing_metadata_ready; + grpc_transport_stream_op_batch* recv_trailing_metadata_op_batch; grpc_polling_entity* pollent; bool pollent_added_to_interested_parties; @@ -1000,8 +1001,7 @@ static void on_complete(void* arg, grpc_error* error); static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored); static void start_pick_locked(void* arg, grpc_error* ignored); static void maybe_intercept_trailing_metadata_for_lb( - void* arg, grpc_transport_stream_op_batch* batch); -static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error); + grpc_call_element* arg, grpc_transport_stream_op_batch* batch); // // send op data caching @@ -1977,6 +1977,16 @@ static void recv_trailing_metadata_ready_for_retries( grpc_mdelem* server_pushback_md = nullptr; grpc_metadata_batch* md_batch = batch_data->batch.payload->recv_trailing_metadata.recv_trailing_metadata; + // If the lb policy asks for the trailing metadata, set its receiving ptr + if (calld->pick.recv_trailing_metadata != nullptr) { + *calld->pick.recv_trailing_metadata = md_batch; + } + // We use GRPC_CLOSURE_RUN synchronously on the callback. In the case of + // a retry, we would have already freed the metadata before returning from + // this function. + GRPC_CLOSURE_RUN( + calld->pick.recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, &server_pushback_md); if (grpc_client_channel_trace.enabled()) { @@ -2000,13 +2010,6 @@ static void recv_trailing_metadata_ready_for_retries( } // Not retrying, so commit the call. retry_commit(elem, retry_state); - // Now that the try is committed, give the trailer to the lb policy as needed - if (calld->pick.recv_trailing_metadata != nullptr) { - *calld->pick.recv_trailing_metadata = md_batch; - } - GRPC_CLOSURE_SCHED( - calld->pick.recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); // Run any necessary closures. run_closures_for_completed_call(batch_data, GRPC_ERROR_REF(error)); } @@ -2595,13 +2598,12 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { // The callback to intercept trailing metadata if retries is not enabled static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); - grpc_call_element* elem = batch_data->elem; + grpc_call_element* elem = static_cast(arg); call_data* calld = static_cast(elem->call_data); if (calld->pick.recv_trailing_metadata != nullptr) { *calld->pick.recv_trailing_metadata = - batch_data->batch.payload->recv_trailing_metadata - .recv_trailing_metadata; + calld->recv_trailing_metadata_op_batch->payload + ->recv_trailing_metadata.recv_trailing_metadata; } GRPC_CLOSURE_SCHED( calld->pick.recv_trailing_metadata_ready, @@ -2611,19 +2613,22 @@ static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { GRPC_ERROR_REF(error)); } -// Installs a interceptor to inform the lb of the trailing metadata, if needed +// If needed, intercepts the recv_trailing_metadata_ready callback to return +// trailing metadata to the LB policy. static void maybe_intercept_trailing_metadata_for_lb( - void* arg, grpc_transport_stream_op_batch* batch) { - subchannel_batch_data* batch_data = static_cast(arg); - grpc_call_element* elem = batch_data->elem; + grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { call_data* calld = static_cast(elem->call_data); - calld->original_recv_trailing_metadata_ready = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_for_lb, - recv_trailing_metadata_ready_for_lb, elem, - grpc_schedule_on_exec_ctx); - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &calld->recv_trailing_metadata_ready_for_lb; + if (!batch->recv_trailing_metadata) { + return; + } + if (calld->pick.recv_trailing_metadata_ready != nullptr) { + calld->recv_trailing_metadata_op_batch = batch; + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_for_lb, + recv_trailing_metadata_ready_for_lb, elem, + grpc_schedule_on_exec_ctx); + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->recv_trailing_metadata_ready_for_lb; + } } static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index a9d68ab0582..acd8ab46c59 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -36,12 +36,17 @@ #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/channel/channelz.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/debug_location.h" +#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/tcp_client.h" - +#include "src/core/lib/transport/connectivity_state.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -996,6 +1001,187 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { WaitForServer(stub, 0, DEBUG_LOCATION); } + +const char intercept_trailing_name[] = "intercept_trailing_metadata"; + +// LoadBalancingPolicy implementations are not designed to be extended. +// A hacky forwarding class to avoid implementing a standalone test LB. +class InterceptTrailing : public grpc_core::LoadBalancingPolicy { + public: + InterceptTrailing(const Args& args) + : grpc_core::LoadBalancingPolicy(args) { + UpdateLocked(*args.args); + grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, + intercept_trailing_name); + } + + bool PickLocked(PickState* pick, grpc_error** error) override { + GRPC_CLOSURE_INIT( + &recv_trailing_metadata_ready_, + InterceptTrailing::RecordRecvTrailingMetadata, + /*cb_arg=*/ nullptr, + grpc_schedule_on_exec_ctx); + pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; + pick->recv_trailing_metadata = &recv_trailing_metadata_; + pick->connected_subchannel = + grpc_subchannel_get_connected_subchannel(hardcoded_subchannel_); + + if (pick->connected_subchannel.get() != nullptr) { + *error = GRPC_ERROR_NONE; + return true; + } + + if (pick->on_complete == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "No pick result available but synchronous result required."); + return true; + } else { + on_complete_ = pick->on_complete; + // TODO(zpencer): call on_completed_ at some point + return false; + } + } + + void UpdateLocked(const grpc_channel_args& args) override { + const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); + grpc_lb_addresses* addresses = + static_cast(arg->value.pointer.p); + grpc_arg addr_arg = + grpc_create_subchannel_address_arg(&addresses->addresses[0].address); + static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS, + GRPC_ARG_LB_ADDRESSES}; + grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( + &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg, 1); + gpr_free(addr_arg.value.string); + grpc_subchannel_args sc_args; + memset(&sc_args, 0, sizeof(grpc_subchannel_args)); + sc_args.args = new_args; + if (hardcoded_subchannel_ != nullptr) { + GRPC_SUBCHANNEL_UNREF(hardcoded_subchannel_, "new pick"); + } + hardcoded_subchannel_ = grpc_client_channel_factory_create_subchannel( + client_channel_factory(), &sc_args); + grpc_channel_args_destroy(new_args); + } + + void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + void CancelPickLocked(PickState* pick, + grpc_error* error) override { + pick->connected_subchannel.reset(); + GRPC_CLOSURE_SCHED(pick->on_complete, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Pick Cancelled", &error, 1)); + + GRPC_ERROR_UNREF(error); + } + + grpc_connectivity_state CheckConnectivityLocked( + grpc_error** error) override { + return grpc_connectivity_state_get(&state_tracker_, error); + } + + void NotifyOnStateChangeLocked(grpc_connectivity_state* current, + grpc_closure* notify) override { + grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, + notify); + } + + void ShutdownLocked() override { + grpc_error* error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); + grpc_connectivity_state_set( + &state_tracker_, + GRPC_CHANNEL_SHUTDOWN, + GRPC_ERROR_REF(error), + "intercept_trailing_shutdown"); + } + + ~InterceptTrailing() { + grpc_connectivity_state_destroy(&state_tracker_); + } + + private: + grpc_closure* on_complete_ = nullptr; + grpc_closure recv_trailing_metadata_ready_; + grpc_metadata_batch* recv_trailing_metadata_ = nullptr; + grpc_subchannel* hardcoded_subchannel_ = nullptr; + grpc_connectivity_state_tracker state_tracker_; + + static void RecordRecvTrailingMetadata( + void* ignored_arg, grpc_error* ignored_err) { + gpr_log(GPR_INFO, "trailer intercepted by lb"); + } +}; + +// A factory for a test LB policy that intercepts trailing metadata. +// The LB policy is implemented as a wrapper around a delegate LB policy. +class InterceptTrailingFactory : public grpc_core::LoadBalancingPolicyFactory { + public: + InterceptTrailingFactory(){} + + grpc_core::OrphanablePtr + CreateLoadBalancingPolicy( + const grpc_core::LoadBalancingPolicy::Args& args) const override { + return grpc_core::OrphanablePtr( + grpc_core::New(args)); + } + + const char* name() const override { + return intercept_trailing_name; + } +}; + +class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { + protected: + void SetUp() override { + ClientLbEnd2endTest::SetUp(); + grpc_core::LoadBalancingPolicyRegistry::Builder:: + RegisterLoadBalancingPolicyFactory( + grpc_core::UniquePtr( + grpc_core::New())); + } + + void TearDown() override { + ClientLbEnd2endTest::TearDown(); + } +}; + +TEST_F(ClientLbInterceptTrailingMetadataTest, Intercepts_retries_disabled) { + const int kNumServers = 1; + StartServers(kNumServers); + auto channel = BuildChannel(intercept_trailing_name); + auto stub = BuildStub(channel); + std::vector ports; + for (size_t i = 0; i < servers_.size(); ++i) { + ports.emplace_back(servers_[i]->port_); + } + SetNextResolution(ports); + + for (size_t i = 0; i < servers_.size(); ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + // All requests should have gone to a single server. + bool found = false; + for (size_t i = 0; i < servers_.size(); ++i) { + const int request_count = servers_[i]->service_.request_count(); + if (request_count == kNumServers) { + found = true; + } else { + EXPECT_EQ(0, request_count); + } + } + EXPECT_TRUE(found); + // Check LB policy name for the channel. + EXPECT_EQ( + intercept_trailing_name, + channel->GetLoadBalancingPolicyName()); +} + } // namespace } // namespace testing } // namespace grpc From c9d8237efccd3e434bf4628763fa9cd7fc4c509f Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Wed, 24 Oct 2018 11:39:27 -0700 Subject: [PATCH 131/534] Use channel's combiner --- src/core/ext/filters/client_channel/client_channel.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 5a74ccc2a05..f803b0c265c 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -2617,6 +2617,7 @@ static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { // trailing metadata to the LB policy. static void maybe_intercept_trailing_metadata_for_lb( grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { + channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (!batch->recv_trailing_metadata) { return; @@ -2625,7 +2626,7 @@ static void maybe_intercept_trailing_metadata_for_lb( calld->recv_trailing_metadata_op_batch = batch; GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_for_lb, recv_trailing_metadata_ready_for_lb, elem, - grpc_schedule_on_exec_ctx); + grpc_combiner_scheduler(chand->combiner)); batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = &calld->recv_trailing_metadata_ready_for_lb; } From 1cbb484729706cf89b140b8a746562a53d916e8b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 24 Oct 2018 10:45:07 -0700 Subject: [PATCH 132/534] Fix build failure --- .../GRPCClient/internal/GRPCCallOptions+internal.h | 2 ++ .../GRPCClient/private/GRPCCronetChannelFactory.m | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h b/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h index 406f268ef21..eb691b3acb1 100644 --- a/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h +++ b/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h @@ -18,6 +18,8 @@ #import +#import "../GRPCCallOptions.h" + @interface GRPCCallOptions () /** diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 70675784678..f976e1e06a9 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -53,14 +53,14 @@ NS_ASSUME_NONNULL_BEGIN } - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args { + channelArgs:(NSDictionary *)args { // Remove client authority filter since that is not supported args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; - grpc_channel_args *channelArgs = BuildChannelArgs(args); + grpc_channel_args *channelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); - FreeChannelArgs(channelArgs); + GRPCFreeChannelArgs(channelArgs); return unmanagedChannel; } From 3c33020357e58202a9909d739353f4c20f78e817 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 24 Oct 2018 13:31:45 -0700 Subject: [PATCH 133/534] Polish nullabitily --- .../GRPCClient/private/GRPCChannelFactory.h | 4 ++-- .../private/GRPCCronetChannelFactory.h | 8 ++++---- .../private/GRPCCronetChannelFactory.m | 14 +++++++------- .../private/GRPCInsecureChannelFactory.h | 8 ++++---- .../private/GRPCInsecureChannelFactory.m | 6 +++--- .../private/GRPCSecureChannelFactory.h | 12 ++++++------ .../private/GRPCSecureChannelFactory.m | 18 +++++++++--------- 7 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h index a934e966e9d..287233f246c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -26,8 +26,8 @@ NS_ASSUME_NONNULL_BEGIN @protocol GRPCChannelFactory /** Create a channel with specific channel args to a specific host. */ -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args; +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args; @end diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h index 738dfdb7370..18e84b81fa2 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h @@ -24,12 +24,12 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCCronetChannelFactory : NSObject -+ (nullable instancetype)sharedInstance; ++ (instancetype _Nullable)sharedInstance; -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args; +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args; -- (nullable instancetype)init NS_UNAVAILABLE; +- (instancetype _Nullable)init NS_UNAVAILABLE; @end diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index f976e1e06a9..b2ab03b6488 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -32,7 +32,7 @@ NS_ASSUME_NONNULL_BEGIN stream_engine *_cronetEngine; } -+ (nullable instancetype)sharedInstance { ++ (instancetype _Nullable)sharedInstance { static GRPCCronetChannelFactory *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -41,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN return instance; } -- (nullable instancetype)initWithEngine:(stream_engine *)engine { +- (instancetype _Nullable)initWithEngine:(stream_engine *)engine { if (!engine) { [NSException raise:NSInvalidArgumentException format:@"Cronet engine is NULL. Set it first."]; return nil; @@ -52,8 +52,8 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)args { +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args { // Remove client authority filter since that is not supported args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; @@ -74,14 +74,14 @@ NS_ASSUME_NONNULL_BEGIN @implementation GRPCCronetChannelFactory -+ (nullable instancetype)sharedInstance { ++ (instancetype _Nullable)sharedInstance { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return nil; } -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args { +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return NULL; diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h index 2d471aebed6..1175483c680 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h @@ -23,12 +23,12 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCInsecureChannelFactory : NSObject -+ (nullable instancetype)sharedInstance; ++ (instancetype _Nullable)sharedInstance; -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args; +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args; -- (nullable instancetype)init NS_UNAVAILABLE; +- (instancetype _Nullable)init NS_UNAVAILABLE; @end diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index 5773f2d9af1..44e94831e95 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN @implementation GRPCInsecureChannelFactory -+ (nullable instancetype)sharedInstance { ++ (instancetype _Nullable)sharedInstance { static GRPCInsecureChannelFactory *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -34,8 +34,8 @@ NS_ASSUME_NONNULL_BEGIN return instance; } -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args { +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index 588239b7064..565f58a4fab 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -23,15 +23,15 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCSecureChannelFactory : NSObject -+ (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts - privateKey:(nullable NSString *)privateKey - certChain:(nullable NSString *)certChain ++ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString * _Nullable)rootCerts + privateKey:(NSString * _Nullable)privateKey + certChain:(NSString * _Nullable)certChain error:(NSError **)errorPtr; -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args; +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args; -- (nullable instancetype)init NS_UNAVAILABLE; +- (instancetype _Nullable)init NS_UNAVAILABLE; @end diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index aa8b52e6b8f..03cfff2ed4a 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -29,9 +29,9 @@ NS_ASSUME_NONNULL_BEGIN grpc_channel_credentials *_channelCreds; } -+ (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts - privateKey:(nullable NSString *)privateKey - certChain:(nullable NSString *)certChain ++ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString * _Nullable)rootCerts + privateKey:(NSString * _Nullable)privateKey + certChain:(NSString * _Nullable)certChain error:(NSError **)errorPtr { return [[self alloc] initWithPEMRootCerts:rootCerts privateKey:privateKey @@ -39,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN error:errorPtr]; } -- (NSData *)nullTerminatedDataWithString:(NSString *)string { +- (NSData * _Nullable)nullTerminatedDataWithString:(NSString * _Nullable)string { // dataUsingEncoding: does not return a null-terminated string. NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; if (data == nil) { @@ -50,9 +50,9 @@ NS_ASSUME_NONNULL_BEGIN return nullTerminated; } -- (nullable instancetype)initWithPEMRootCerts:(nullable NSString *)rootCerts - privateKey:(nullable NSString *)privateKey - certChain:(nullable NSString *)certChain +- (instancetype _Nullable)initWithPEMRootCerts:(NSString * _Nullable)rootCerts + privateKey:(NSString * _Nullable)privateKey + certChain:(NSString * _Nullable)certChain error:(NSError **)errorPtr { static NSData *defaultRootsASCII; static NSError *defaultRootsError; @@ -116,8 +116,8 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args { +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); From c2bb7550377898e6985662d0ca9048c07bde6810 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 24 Oct 2018 16:55:23 -0700 Subject: [PATCH 134/534] Move GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER into core --- .../cronet/client/secure/cronet_channel_create.cc | 14 ++++++++++++-- .../GRPCClient/private/GRPCCronetChannelFactory.m | 3 --- .../GRPCClient/private/GRPCWrappedCall.m | 4 +++- .../CoreCronetEnd2EndTests.mm | 6 ------ .../tests/CronetUnitTests/CronetUnitTests.m | 13 +------------ 5 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc index 40a30e4a31d..dffb61b082d 100644 --- a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc +++ b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc @@ -46,9 +46,19 @@ GRPCAPI grpc_channel* grpc_cronet_secure_channel_create( "grpc_create_cronet_transport: stream_engine = %p, target=%s", engine, target); + // Disable client authority filter when using Cronet + grpc_arg arg; + arg.key = const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); + arg.type = GRPC_ARG_INTEGER; + arg.value.integer = 1; + grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &arg, 1); + grpc_transport* ct = - grpc_create_cronet_transport(engine, target, args, reserved); + grpc_create_cronet_transport(engine, target, new_args, reserved); grpc_core::ExecCtx exec_ctx; - return grpc_channel_create(target, args, GRPC_CLIENT_DIRECT_CHANNEL, ct); + grpc_channel* channel = + grpc_channel_create(target, new_args, GRPC_CLIENT_DIRECT_CHANNEL, ct); + grpc_channel_args_destroy(new_args); + return channel; } diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index b2ab03b6488..51d8df0fb71 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -54,9 +54,6 @@ NS_ASSUME_NONNULL_BEGIN - (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary * _Nullable)args { - // Remove client authority filter since that is not supported - args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; - grpc_channel_args *channelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 4d5257aca79..100d4cf2914 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -310,7 +310,9 @@ } - (void)dealloc { - grpc_call_unref(_call); + if (_call) { + grpc_call_unref(_call); + } [_channel unref]; _channel = nil; } diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm index 80fa0f47852..fe85e915d4d 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm @@ -81,13 +81,7 @@ static void cronet_init_client_secure_fullstack(grpc_end2end_test_fixture *f, grpc_channel_args *client_args, stream_engine *cronetEngine) { fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; - grpc_arg arg; - arg.key = const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); - 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); - grpc_channel_args_destroy(client_args); GPR_ASSERT(f->client != NULL); } diff --git a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m index 84893b92c1a..d732bc6ba99 100644 --- a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m +++ b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m @@ -124,14 +124,6 @@ unsigned int parse_h2_length(const char *field) { ((unsigned int)(unsigned char)(field[2])); } -grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *args) { - grpc_arg arg; - arg.key = const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); - arg.type = GRPC_ARG_INTEGER; - arg.value.integer = 1; - return grpc_channel_args_copy_and_add(args, &arg, 1); -} - - (void)testInternalError { grpc_call *c; grpc_slice request_payload_slice = grpc_slice_from_copied_string("hello world"); @@ -151,9 +143,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_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_args_destroy(client_args); + grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, NULL, NULL); cq_verifier *cqv = cq_verifier_create(cq); grpc_op ops[6]; @@ -265,7 +255,6 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a arg.type = GRPC_ARG_INTEGER; arg.value.integer = useCoalescing ? 1 : 0; grpc_channel_args *args = grpc_channel_args_copy_and_add(NULL, &arg, 1); - args = add_disable_client_authority_filter_args(args); grpc_call *c; grpc_slice request_payload_slice = grpc_slice_from_copied_string("hello world"); From a8a7c2bdd10eb7dc9e072327da2ddb70e5785cf7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 24 Oct 2018 17:05:38 -0700 Subject: [PATCH 135/534] clang-format --- .../GRPCClient/private/GRPCChannelFactory.h | 4 ++-- .../private/GRPCCronetChannelFactory.h | 4 ++-- .../private/GRPCCronetChannelFactory.m | 8 +++---- .../private/GRPCInsecureChannelFactory.h | 4 ++-- .../private/GRPCInsecureChannelFactory.m | 4 ++-- .../private/GRPCSecureChannelFactory.h | 12 +++++----- .../private/GRPCSecureChannelFactory.m | 22 +++++++++---------- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h index 287233f246c..3a3500fc95e 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -26,8 +26,8 @@ NS_ASSUME_NONNULL_BEGIN @protocol GRPCChannelFactory /** Create a channel with specific channel args to a specific host. */ -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args; +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args; @end diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h index 18e84b81fa2..5e35576ea10 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h @@ -26,8 +26,8 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype _Nullable)sharedInstance; -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args; +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args; - (instancetype _Nullable)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 51d8df0fb71..781881d211b 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -52,8 +52,8 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args { +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args { grpc_channel_args *channelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); @@ -77,8 +77,8 @@ NS_ASSUME_NONNULL_BEGIN return nil; } -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args { +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return NULL; diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h index 1175483c680..98a985fe84d 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h @@ -25,8 +25,8 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype _Nullable)sharedInstance; -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args; +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args; - (instancetype _Nullable)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index 44e94831e95..99698877124 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -34,8 +34,8 @@ NS_ASSUME_NONNULL_BEGIN return instance; } -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args { +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index 565f58a4fab..02e7052996d 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -23,13 +23,13 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCSecureChannelFactory : NSObject -+ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString * _Nullable)rootCerts - privateKey:(NSString * _Nullable)privateKey - certChain:(NSString * _Nullable)certChain - error:(NSError **)errorPtr; ++ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString *_Nullable)rootCerts + privateKey:(NSString *_Nullable)privateKey + certChain:(NSString *_Nullable)certChain + error:(NSError **)errorPtr; -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args; +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args; - (instancetype _Nullable)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 03cfff2ed4a..1f6458c5247 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -29,17 +29,17 @@ NS_ASSUME_NONNULL_BEGIN grpc_channel_credentials *_channelCreds; } -+ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString * _Nullable)rootCerts - privateKey:(NSString * _Nullable)privateKey - certChain:(NSString * _Nullable)certChain - error:(NSError **)errorPtr { ++ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString *_Nullable)rootCerts + privateKey:(NSString *_Nullable)privateKey + certChain:(NSString *_Nullable)certChain + error:(NSError **)errorPtr { return [[self alloc] initWithPEMRootCerts:rootCerts privateKey:privateKey certChain:certChain error:errorPtr]; } -- (NSData * _Nullable)nullTerminatedDataWithString:(NSString * _Nullable)string { +- (NSData *_Nullable)nullTerminatedDataWithString:(NSString *_Nullable)string { // dataUsingEncoding: does not return a null-terminated string. NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; if (data == nil) { @@ -50,10 +50,10 @@ NS_ASSUME_NONNULL_BEGIN return nullTerminated; } -- (instancetype _Nullable)initWithPEMRootCerts:(NSString * _Nullable)rootCerts - privateKey:(NSString * _Nullable)privateKey - certChain:(NSString * _Nullable)certChain - error:(NSError **)errorPtr { +- (instancetype _Nullable)initWithPEMRootCerts:(NSString *_Nullable)rootCerts + privateKey:(NSString *_Nullable)privateKey + certChain:(NSString *_Nullable)certChain + error:(NSError **)errorPtr { static NSData *defaultRootsASCII; static NSError *defaultRootsError; static dispatch_once_t loading; @@ -116,8 +116,8 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args { +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); From 2808bd0ba05fa3ddc0b6ef814db09c435e4e9676 Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Thu, 25 Oct 2018 15:47:13 -0700 Subject: [PATCH 136/534] Use forwarding LB test policy. Fix trailer interception code. --- .../filters/client_channel/client_channel.cc | 11 +- .../ext/filters/client_channel/lb_policy.h | 2 + test/cpp/end2end/client_lb_end2end_test.cc | 255 +++++++++--------- 3 files changed, 144 insertions(+), 124 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index f803b0c265c..0647fb7160c 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -2608,16 +2608,16 @@ static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { GRPC_CLOSURE_SCHED( calld->pick.recv_trailing_metadata_ready, GRPC_ERROR_REF(error)); - GRPC_CLOSURE_RUN( + GRPC_CLOSURE_SCHED( calld->original_recv_trailing_metadata_ready, GRPC_ERROR_REF(error)); + GRPC_ERROR_UNREF(error); } // If needed, intercepts the recv_trailing_metadata_ready callback to return // trailing metadata to the LB policy. static void maybe_intercept_trailing_metadata_for_lb( grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { - channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (!batch->recv_trailing_metadata) { return; @@ -2625,8 +2625,11 @@ static void maybe_intercept_trailing_metadata_for_lb( if (calld->pick.recv_trailing_metadata_ready != nullptr) { calld->recv_trailing_metadata_op_batch = batch; GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_for_lb, - recv_trailing_metadata_ready_for_lb, elem, - grpc_combiner_scheduler(chand->combiner)); + recv_trailing_metadata_ready_for_lb, + elem, + grpc_schedule_on_exec_ctx); + calld->original_recv_trailing_metadata_ready = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = &calld->recv_trailing_metadata_ready_for_lb; } diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 6c04b4b54cf..fd8464dc08e 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -75,10 +75,12 @@ class LoadBalancingPolicy grpc_closure* on_complete; // Callback set by lb policy to be notified of trailing metadata. + // The callback is scheduled on grpc_schedule_on_exec_ctx. grpc_closure* recv_trailing_metadata_ready; // If this is not nullptr, then the client channel will point it to the // call's trailing metadata before invoking recv_trailing_metadata_ready. // If this is nullptr, then the callback will still be called. + // The lb does not have ownership of the metadata. grpc_metadata_batch** recv_trailing_metadata; /// Will be set to the selected subchannel, or nullptr on failure or when diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index acd8ab46c59..201edfb4963 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -47,11 +47,14 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/status_metadata.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" + #include using grpc::testing::EchoRequest; @@ -1001,139 +1004,77 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { WaitForServer(stub, 0, DEBUG_LOCATION); } - -const char intercept_trailing_name[] = "intercept_trailing_metadata"; - -// LoadBalancingPolicy implementations are not designed to be extended. -// A hacky forwarding class to avoid implementing a standalone test LB. -class InterceptTrailing : public grpc_core::LoadBalancingPolicy { +// A minimal forwarding class to avoid implementing a standalone test LB. +class ForwardingLoadBalancingPolicy : public grpc_core::LoadBalancingPolicy { public: - InterceptTrailing(const Args& args) - : grpc_core::LoadBalancingPolicy(args) { - UpdateLocked(*args.args); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, - intercept_trailing_name); + ForwardingLoadBalancingPolicy( + const Args& args, + const std::string& delegate_policy_name) + : grpc_core::LoadBalancingPolicy(args), args_{args} { + delegate_ = grpc_core::LoadBalancingPolicyRegistry + ::CreateLoadBalancingPolicy(delegate_policy_name.c_str(), args); + grpc_pollset_set_add_pollset_set( + delegate_->interested_parties(), + interested_parties()); } - bool PickLocked(PickState* pick, grpc_error** error) override { - GRPC_CLOSURE_INIT( - &recv_trailing_metadata_ready_, - InterceptTrailing::RecordRecvTrailingMetadata, - /*cb_arg=*/ nullptr, - grpc_schedule_on_exec_ctx); - pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; - pick->recv_trailing_metadata = &recv_trailing_metadata_; - pick->connected_subchannel = - grpc_subchannel_get_connected_subchannel(hardcoded_subchannel_); - - if (pick->connected_subchannel.get() != nullptr) { - *error = GRPC_ERROR_NONE; - return true; - } + void UpdateLocked(const grpc_channel_args& args) override { + delegate_->UpdateLocked(args); + } - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - return true; - } else { - on_complete_ = pick->on_complete; - // TODO(zpencer): call on_completed_ at some point - return false; - } + bool PickLocked(PickState* pick, grpc_error** error) override { + return delegate_->PickLocked(pick, error); } - void UpdateLocked(const grpc_channel_args& args) override { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - grpc_arg addr_arg = - grpc_create_subchannel_address_arg(&addresses->addresses[0].address); - static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS, - GRPC_ARG_LB_ADDRESSES}; - grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( - &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg, 1); - gpr_free(addr_arg.value.string); - grpc_subchannel_args sc_args; - memset(&sc_args, 0, sizeof(grpc_subchannel_args)); - sc_args.args = new_args; - if (hardcoded_subchannel_ != nullptr) { - GRPC_SUBCHANNEL_UNREF(hardcoded_subchannel_, "new pick"); - } - hardcoded_subchannel_ = grpc_client_channel_factory_create_subchannel( - client_channel_factory(), &sc_args); - grpc_channel_args_destroy(new_args); + void CancelPickLocked(PickState* pick, grpc_error* error) override { + delegate_->CancelPickLocked(pick, error); } void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, uint32_t initial_metadata_flags_eq, grpc_error* error) override { - GRPC_ERROR_UNREF(error); + delegate_->CancelMatchingPicksLocked( + initial_metadata_flags_mask, + initial_metadata_flags_eq, + error); } - void CancelPickLocked(PickState* pick, - grpc_error* error) override { - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - - GRPC_ERROR_UNREF(error); + void NotifyOnStateChangeLocked(grpc_connectivity_state* state, + grpc_closure* closure) override { + delegate_->NotifyOnStateChangeLocked(state, closure); } grpc_connectivity_state CheckConnectivityLocked( - grpc_error** error) override { - return grpc_connectivity_state_get(&state_tracker_, error); + grpc_error** connectivity_error) override { + return delegate_->CheckConnectivityLocked(connectivity_error); } - void NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* notify) override { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - notify); + void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { + delegate_->HandOffPendingPicksLocked(new_policy); } - void ShutdownLocked() override { - grpc_error* error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); - grpc_connectivity_state_set( - &state_tracker_, - GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), - "intercept_trailing_shutdown"); + void ExitIdleLocked() override{ + delegate_->ExitIdleLocked(); } - ~InterceptTrailing() { - grpc_connectivity_state_destroy(&state_tracker_); + void ResetBackoffLocked() override { + delegate_->ResetBackoffLocked(); } - private: - grpc_closure* on_complete_ = nullptr; - grpc_closure recv_trailing_metadata_ready_; - grpc_metadata_batch* recv_trailing_metadata_ = nullptr; - grpc_subchannel* hardcoded_subchannel_ = nullptr; - grpc_connectivity_state_tracker state_tracker_; - - static void RecordRecvTrailingMetadata( - void* ignored_arg, grpc_error* ignored_err) { - gpr_log(GPR_INFO, "trailer intercepted by lb"); + void FillChildRefsForChannelz( + grpc_core::channelz::ChildRefsList* child_subchannels, + grpc_core::channelz::ChildRefsList* ignored) override { + delegate_->FillChildRefsForChannelz(child_subchannels, ignored); } -}; - -// A factory for a test LB policy that intercepts trailing metadata. -// The LB policy is implemented as a wrapper around a delegate LB policy. -class InterceptTrailingFactory : public grpc_core::LoadBalancingPolicyFactory { - public: - InterceptTrailingFactory(){} - grpc_core::OrphanablePtr - CreateLoadBalancingPolicy( - const grpc_core::LoadBalancingPolicy::Args& args) const override { - return grpc_core::OrphanablePtr( - grpc_core::New(args)); + protected: + void ShutdownLocked() override { + // noop } + Args args_; - const char* name() const override { - return intercept_trailing_name; - } + private: + grpc_core::OrphanablePtr delegate_; }; class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { @@ -1143,43 +1084,117 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { grpc_core::LoadBalancingPolicyRegistry::Builder:: RegisterLoadBalancingPolicyFactory( grpc_core::UniquePtr( - grpc_core::New())); + grpc_core::New(this))); } void TearDown() override { ClientLbEnd2endTest::TearDown(); } + + class InterceptTrailingLb : public ForwardingLoadBalancingPolicy { + public: + InterceptTrailingLb( + const Args& args, + const std::string& delegate_lb_policy_name, + ClientLbInterceptTrailingMetadataTest* test) + : ForwardingLoadBalancingPolicy(args, delegate_lb_policy_name), + test_{test} { + } + + bool PickLocked(PickState* pick, grpc_error** error) override { + bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); + // If these asserts fail, then we will need to add code to + // proxy the results to the delegate LB. + GPR_ASSERT(pick->recv_trailing_metadata == nullptr); + GPR_ASSERT(pick->recv_trailing_metadata_ready == nullptr); + // OK to add add callbacks for test + GRPC_CLOSURE_INIT( + &recv_trailing_metadata_ready_, + InterceptTrailingLb::RecordRecvTrailingMetadata, + this, + grpc_schedule_on_exec_ctx); + pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; + pick->recv_trailing_metadata = &recv_trailing_metadata_; + return ret; + } + + static void RecordRecvTrailingMetadata(void* arg, grpc_error* err) { + InterceptTrailingLb* lb = static_cast(arg); + GPR_ASSERT(err == GRPC_ERROR_NONE); + GPR_ASSERT(lb->recv_trailing_metadata_ != nullptr); + // an simple check to make sure the trailing metadata is valid + GPR_ASSERT(grpc_get_status_code_from_metadata( + lb->recv_trailing_metadata_->idx.named.grpc_status->md) == + grpc_status_code::GRPC_STATUS_OK); + GRPC_ERROR_UNREF(err); + lb->test_->ReportTrailerIntercepted(); + } + + private: + grpc_closure recv_trailing_metadata_ready_; + grpc_metadata_batch* recv_trailing_metadata_; + ClientLbInterceptTrailingMetadataTest* test_; + }; + + // A factory for a test LB policy that intercepts trailing metadata. + // The LB policy is implemented as a wrapper around a delegate LB policy. + class InterceptTrailingFactory : + public grpc_core::LoadBalancingPolicyFactory { + public: + InterceptTrailingFactory(ClientLbInterceptTrailingMetadataTest* test): + test_{test} {} + + grpc_core::OrphanablePtr + CreateLoadBalancingPolicy( + const grpc_core::LoadBalancingPolicy::Args& args) const override { + return grpc_core::OrphanablePtr( + grpc_core::New( + args, + /*delegate_lb_policy_name=*/ "pick_first", + test_)); + } + + const char* name() const override { + return "intercept_trailing_metadata_lb"; + } + + private: + ClientLbInterceptTrailingMetadataTest* test_; + }; + + void ReportTrailerIntercepted() { + std::unique_lock lock(mu_); + trailers_intercepted_++; + } + + uint32_t trailers_intercepted() { + std::unique_lock lock(mu_); + return trailers_intercepted_; + } + + private: + std::mutex mu_; + uint32_t trailers_intercepted_ = 0; }; TEST_F(ClientLbInterceptTrailingMetadataTest, Intercepts_retries_disabled) { const int kNumServers = 1; StartServers(kNumServers); - auto channel = BuildChannel(intercept_trailing_name); + auto channel = BuildChannel("intercept_trailing_metadata_lb"); auto stub = BuildStub(channel); std::vector ports; for (size_t i = 0; i < servers_.size(); ++i) { ports.emplace_back(servers_[i]->port_); } SetNextResolution(ports); - for (size_t i = 0; i < servers_.size(); ++i) { CheckRpcSendOk(stub, DEBUG_LOCATION); } - // All requests should have gone to a single server. - bool found = false; - for (size_t i = 0; i < servers_.size(); ++i) { - const int request_count = servers_[i]->service_.request_count(); - if (request_count == kNumServers) { - found = true; - } else { - EXPECT_EQ(0, request_count); - } - } - EXPECT_TRUE(found); // Check LB policy name for the channel. EXPECT_EQ( - intercept_trailing_name, + "intercept_trailing_metadata_lb", channel->GetLoadBalancingPolicyName()); + EXPECT_EQ(kNumServers, trailers_intercepted()); } } // namespace From 1e2d43315ed65b3fc94b2f2d8e57830a907bbc0b Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Thu, 25 Oct 2018 15:49:19 -0700 Subject: [PATCH 137/534] fix contract of pick->recv_trailing_metadata_ready --- src/core/ext/filters/client_channel/lb_policy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index fd8464dc08e..67a1b5363f4 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -75,7 +75,7 @@ class LoadBalancingPolicy grpc_closure* on_complete; // Callback set by lb policy to be notified of trailing metadata. - // The callback is scheduled on grpc_schedule_on_exec_ctx. + // The callback must be scheduled on grpc_schedule_on_exec_ctx. grpc_closure* recv_trailing_metadata_ready; // If this is not nullptr, then the client channel will point it to the // call's trailing metadata before invoking recv_trailing_metadata_ready. From f9d2510d8f655badea3dea14493b6d4d3882705a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 26 Oct 2018 11:15:16 -0700 Subject: [PATCH 138/534] Specify nullability in ProtoRPC --- src/objective-c/ProtoRPC/ProtoRPC.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 635ba0c90ee..b0f4ced99e8 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -134,10 +134,11 @@ __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC * addr and the port number, for example @"localhost:5050". */ - - (instancetype)initWithHost : (NSString *)host method - : (GRPCProtoMethod *)method requestsWriter : (GRXWriter *)requestsWriter responseClass - : (Class)responseClass responsesWriteable - : (id)responsesWriteable NS_DESIGNATED_INITIALIZER; + (instancetype _Null_unspecified)initWithHost : (NSString *_Null_unspecified)host method + : (GRPCProtoMethod *_Null_unspecified)method requestsWriter + : (GRXWriter *_Null_unspecified)requestsWriter responseClass + : (Class _Null_unspecified)responseClass responsesWriteable + : (id _Null_unspecified)responsesWriteable NS_DESIGNATED_INITIALIZER; - (void)start; @end From a8c4eb7d2742eb3ba370d9801cc1b83e35d551a9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 29 Oct 2018 14:15:26 -0700 Subject: [PATCH 139/534] Bug fix --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 85a2837336d..44432a120ac 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -782,7 +782,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = callOptions; } - NSAssert(_callOptions.authTokenProvider != nil || _callOptions.oauth2AccessToken != nil, + NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); if (_callOptions.authTokenProvider != nil) { @synchronized(self) { From abe4aae40049ca73fb29ccf325cc3734408d9aae Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 29 Oct 2018 15:21:05 -0700 Subject: [PATCH 140/534] Remove length check in GRPCCall for backwards compatibility --- src/objective-c/GRPCClient/GRPCCall.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 44432a120ac..ca2cdd6b312 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -391,7 +391,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; callSafety:(GRPCCallSafety)safety requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { - if (host.length == 0 || path.length == 0) { + // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. + if (!host || !path) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil or empty."]; } From aec84416a4308e547736569f2bc815a8bbd9c80f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 29 Oct 2018 15:48:16 -0700 Subject: [PATCH 141/534] Remove NS_UNAVAILABLE for backwards compatibility --- src/objective-c/ProtoRPC/ProtoService.h | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 3a16ab24026..2105de78a38 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -31,14 +31,9 @@ __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoServ : NSObject - - (instancetype)init NS_UNAVAILABLE; - -+ (instancetype) new NS_UNAVAILABLE; - -- (instancetype)initWithHost:(NSString *)host - packageName:(NSString *)packageName - serviceName:(NSString *)serviceName - callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; + (instancetype)initWithHost : (NSString *)host packageName + : (NSString *)packageName serviceName : (NSString *)serviceName callOptions + : (GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName From 40750ef4846847648a964d62a6cd1c87eff2f959 Mon Sep 17 00:00:00 2001 From: Daniel Joos Date: Mon, 29 Oct 2018 17:26:20 +0100 Subject: [PATCH 142/534] Enable compilation with OpenSSL 1.1 API This adds the possibility to compile the core library against OpenSSL 1.1 without backwards-compatible/deprecated API enabled. It also adds missing include statements in `jwt_verifier.cc` that are required to build with OpenSSL 1.1 (as the `BN_` and `RSA_` APIs are used there). --- .../lib/security/credentials/jwt/jwt_verifier.cc | 2 ++ src/core/tsi/ssl_transport_security.cc | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc index c7d1b36ff0a..cdef0f322a9 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc @@ -31,7 +31,9 @@ #include extern "C" { +#include #include +#include } #include "src/core/lib/gpr/string.h" diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index d6a72ada0d8..9243d845cb3 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -156,9 +156,13 @@ static unsigned long openssl_thread_id_cb(void) { #endif static void init_openssl(void) { +#if OPENSSL_API_COMPAT >= 0x10100000L + OPENSSL_init_ssl(0, NULL); +#else SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); +#endif #if OPENSSL_VERSION_NUMBER < 0x10100000 if (!CRYPTO_get_locking_callback()) { int num_locks = CRYPTO_num_locks(); @@ -1649,7 +1653,11 @@ tsi_result tsi_create_ssl_client_handshaker_factory_with_options( return TSI_INVALID_ARGUMENT; } +#if defined(OPENSSL_NO_TLS1_2_METHOD) || OPENSSL_API_COMPAT >= 0x10100000L + ssl_context = SSL_CTX_new(TLS_method()); +#else ssl_context = SSL_CTX_new(TLSv1_2_method()); +#endif if (ssl_context == nullptr) { gpr_log(GPR_ERROR, "Could not create ssl context."); return TSI_INVALID_ARGUMENT; @@ -1806,7 +1814,11 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options( for (i = 0; i < options->num_key_cert_pairs; i++) { do { +#if defined(OPENSSL_NO_TLS1_2_METHOD) || OPENSSL_API_COMPAT >= 0x10100000L + impl->ssl_contexts[i] = SSL_CTX_new(TLS_method()); +#else impl->ssl_contexts[i] = SSL_CTX_new(TLSv1_2_method()); +#endif if (impl->ssl_contexts[i] == nullptr) { gpr_log(GPR_ERROR, "Could not create ssl context."); result = TSI_OUT_OF_RESOURCES; From 0cabf27fa3e5afc4918a6aaf7d51825d7c0eb8e0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 31 Oct 2018 18:25:49 -0700 Subject: [PATCH 143/534] Clean codes --- src/objective-c/GRPCClient/GRPCCall.m | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index ca2cdd6b312..505d84a954c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -167,13 +167,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) { dispatch_async(self->_dispatchQueue, ^{ if (self->_handler) { - NSDictionary *headers = nil; if (!self->_initialMetadataPublished) { - headers = self->_call.responseHeaders; self->_initialMetadataPublished = YES; - } - if (headers) { - [self issueInitialMetadata:headers]; + [self issueInitialMetadata:self->_call.responseHeaders]; } if (value) { [self issueMessage:value]; @@ -184,13 +180,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; completionHandler:^(NSError *errorOrNil) { dispatch_async(self->_dispatchQueue, ^{ if (self->_handler) { - NSDictionary *headers = nil; if (!self->_initialMetadataPublished) { - headers = self->_call.responseHeaders; self->_initialMetadataPublished = YES; - } - if (headers) { - [self issueInitialMetadata:headers]; + [self issueInitialMetadata:self->_call.responseHeaders]; } [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; From a37ec5e3e6f7184458108bd5419ce6b832061975 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 31 Oct 2018 18:26:02 -0700 Subject: [PATCH 144/534] Polish error message --- src/objective-c/GRPCClient/GRPCCall.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 505d84a954c..5aeedba9a7d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -385,8 +385,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. if (!host || !path) { - [NSException raise:NSInvalidArgumentException - format:@"Neither host nor path can be nil or empty."]; + [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; } if (safety > GRPCCallSafetyCacheableRequest) { [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; From 16fd5a758c2418dcf0be3a0985e68b1e15582387 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 31 Oct 2018 18:26:39 -0700 Subject: [PATCH 145/534] Remove __block for synchronized blocks --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 5aeedba9a7d..8e7d5a5f94b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -564,7 +564,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } NSMutableDictionary *headers = _requestHeaders; - __block NSString *fetchedOauth2AccessToken; + NSString *fetchedOauth2AccessToken; @synchronized(self) { fetchedOauth2AccessToken = _fetchedOauth2AccessToken; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 56f76450b22..7aac077e773 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -190,7 +190,7 @@ extern const char *kCFStreamVarName; } - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration { - __block GRPCChannel *channel; + GRPCChannel *channel; @synchronized(self) { if ([_channelPool objectForKey:configuration]) { channel = _channelPool[configuration]; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index ab5b69cc4e9..480e4621845 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -141,7 +141,7 @@ static NSMutableDictionary *gHostCache; host = [hostURL.host stringByAppendingString:@":443"]; } - __block GRPCCallOptions *callOptions = nil; + GRPCCallOptions *callOptions = nil; @synchronized(gHostCache) { if ([gHostCache objectForKey:host]) { callOptions = [gHostCache[host] callOptions]; From 73251477bc4f7cb10bf40c9f56df8a65d58689f1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 09:03:23 -0700 Subject: [PATCH 146/534] clamp positive NSTimeInterval in initializer --- src/objective-c/GRPCClient/GRPCCallOptions.m | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 0977a4ccdbc..8bb2ad29fc6 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -146,7 +146,7 @@ static const NSUInteger kDefaultChannelID = 0; channelID:(NSUInteger)channelID { if ((self = [super init])) { _serverAuthority = [serverAuthority copy]; - _timeout = timeout; + _timeout = timeout < 0 ? 0 : timeout; _oauth2AccessToken = [oauth2AccessToken copy]; _authTokenProvider = authTokenProvider; _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; @@ -154,11 +154,11 @@ static const NSUInteger kDefaultChannelID = 0; _responseSizeLimit = responseSizeLimit; _compressionAlgorithm = compressionAlgorithm; _retryEnabled = retryEnabled; - _keepaliveInterval = keepaliveInterval; - _keepaliveTimeout = keepaliveTimeout; - _connectMinTimeout = connectMinTimeout; - _connectInitialBackoff = connectInitialBackoff; - _connectMaxBackoff = connectMaxBackoff; + _keepaliveInterval = keepaliveInterval < 0 ? 0 : keepaliveInterval; + _keepaliveTimeout = keepaliveTimeout < 0 ? 0 : keepaliveTimeout; + _connectMinTimeout = connectMinTimeout < 0 ? 0 : connectMinTimeout; + _connectInitialBackoff = connectInitialBackoff < 0 ? 0 : connectInitialBackoff; + _connectMaxBackoff = connectMaxBackoff < 0 ? 0 : connectMaxBackoff; _additionalChannelArgs = [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; _PEMRootCertificates = [PEMRootCertificates copy]; From 790adca8e397d78affef7589e1ddf94b80b052f1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 09:18:50 -0700 Subject: [PATCH 147/534] copy items in GRPCCallOptions:mutableCopy: --- src/objective-c/GRPCClient/GRPCCallOptions.m | 22 +++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 8bb2ad29fc6..c7096cf1cfb 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -203,12 +203,13 @@ static const NSUInteger kDefaultChannelID = 0; - (nonnull id)mutableCopyWithZone:(NSZone *)zone { GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] - initWithServerAuthority:_serverAuthority + initWithServerAuthority:[_serverAuthority copy] timeout:_timeout - oauth2AccessToken:_oauth2AccessToken + oauth2AccessToken:[_oauth2AccessToken copy] authTokenProvider:_authTokenProvider - initialMetadata:_initialMetadata - userAgentPrefix:_userAgentPrefix + initialMetadata:[[NSDictionary alloc] initWithDictionary:_initialMetadata + copyItems:YES] + userAgentPrefix:[_userAgentPrefix copy] responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm retryEnabled:_retryEnabled @@ -217,14 +218,15 @@ static const NSUInteger kDefaultChannelID = 0; connectMinTimeout:_connectMinTimeout connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff - additionalChannelArgs:[_additionalChannelArgs copy] - PEMRootCertificates:_PEMRootCertificates - PEMPrivateKey:_PEMPrivateKey - PEMCertChain:_PEMCertChain + additionalChannelArgs:[[NSDictionary alloc] initWithDictionary:_additionalChannelArgs + copyItems:YES] + PEMRootCertificates:[_PEMRootCertificates copy] + PEMPrivateKey:[_PEMPrivateKey copy] + PEMCertChain:[_PEMCertChain copy] transportType:_transportType - hostNameOverride:_hostNameOverride + hostNameOverride:[_hostNameOverride copy] logContext:_logContext - channelPoolDomain:_channelPoolDomain + channelPoolDomain:[_channelPoolDomain copy] channelID:_channelID]; return newOptions; } From ce53ba74746248ef914986bc5fe8a2f89f42ceda Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 09:27:40 -0700 Subject: [PATCH 148/534] kChannelDestroyDelay->_destroyDelay in GRPCChannelRef --- src/objective-c/GRPCClient/private/GRPCChannel.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 777cbab8092..67a3ac12749 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -109,7 +109,7 @@ static GRPCChannelPool *gChannelPool; if (self->_refCount == 0) { self->_lastDispatch = [NSDate date]; dispatch_time_t delay = - dispatch_time(DISPATCH_TIME_NOW, (int64_t)kChannelDestroyDelay * 1e9); + dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * 1e9); dispatch_after(delay, self->_timerQueue, ^{ [self timerFire]; }); @@ -132,7 +132,7 @@ static GRPCChannelPool *gChannelPool; - (void)timerFire { dispatch_async(_dispatchQueue, ^{ if (self->_disconnected || self->_lastDispatch == nil || - -[self->_lastDispatch timeIntervalSinceNow] < -kChannelDestroyDelay) { + -[self->_lastDispatch timeIntervalSinceNow] < -_destroyDelay) { return; } self->_lastDispatch = nil; From dc4fc1ce38f9060c10ae639173d106c5a7d2bece Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 09:29:15 -0700 Subject: [PATCH 149/534] Use NSEC_PER_SEC --- src/objective-c/GRPCClient/private/GRPCChannel.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 67a3ac12749..377900fd9e1 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -109,7 +109,7 @@ static GRPCChannelPool *gChannelPool; if (self->_refCount == 0) { self->_lastDispatch = [NSDate date]; dispatch_time_t delay = - dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * 1e9); + dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); dispatch_after(delay, self->_timerQueue, ^{ [self timerFire]; }); @@ -132,7 +132,7 @@ static GRPCChannelPool *gChannelPool; - (void)timerFire { dispatch_async(_dispatchQueue, ^{ if (self->_disconnected || self->_lastDispatch == nil || - -[self->_lastDispatch timeIntervalSinceNow] < -_destroyDelay) { + -[self->_lastDispatch timeIntervalSinceNow] < -self->_destroyDelay) { return; } self->_lastDispatch = nil; From 601475b57105f0aff3e96043e6399b621cfc5b84 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 11:43:09 -0700 Subject: [PATCH 150/534] Easier check if timer is canceled --- src/objective-c/GRPCClient/private/GRPCChannel.m | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 377900fd9e1..1d7fb421e5e 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -66,6 +66,12 @@ static GRPCChannelPool *gChannelPool; BOOL _disconnected; dispatch_queue_t _dispatchQueue; dispatch_queue_t _timerQueue; + + /** + * Date and time when last timer is scheduled. When a timer is fired, if + * _lastDispatch + _destroyDelay < now, it can be determined that another timer is scheduled after + * schedule of the current timer, hence the current one should be discarded. + */ NSDate *_lastDispatch; } @@ -107,11 +113,12 @@ static GRPCChannelPool *gChannelPool; if (!self->_disconnected) { self->_refCount--; if (self->_refCount == 0) { - self->_lastDispatch = [NSDate date]; + NSDate *now = [NSDate date]; + self->_lastDispatch = now; dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); dispatch_after(delay, self->_timerQueue, ^{ - [self timerFire]; + [self timerFireWithScheduleDate:now]; }); } } @@ -129,10 +136,9 @@ static GRPCChannelPool *gChannelPool; }); } -- (void)timerFire { +- (void)timerFireWithScheduleDate:(NSDate *)scheduleDate { dispatch_async(_dispatchQueue, ^{ - if (self->_disconnected || self->_lastDispatch == nil || - -[self->_lastDispatch timeIntervalSinceNow] < -self->_destroyDelay) { + if (self->_disconnected || self->_lastDispatch != scheduleDate) { return; } self->_lastDispatch = nil; From 29bf3864d1a3d00b2199adb0d56298c3a32178fb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 12:44:48 -0700 Subject: [PATCH 151/534] Remove object after finish iterating in loop --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 7aac077e773..56de8a0d6f5 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -147,7 +147,9 @@ extern const char *kCFStreamVarName; } - (BOOL)isEqual:(id)object { - NSAssert([object isKindOfClass:[GRPCChannelConfiguration class]], @"Illegal :isEqual"); + if (![object isKindOfClass:[GRPCChannelConfiguration class]]) { + return NO; + } GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; if (!(obj.host == _host || [obj.host isEqualToString:_host])) return NO; if (!(obj.callOptions == _callOptions || [obj.callOptions hasChannelOptionsEqualTo:_callOptions])) @@ -207,13 +209,16 @@ extern const char *kCFStreamVarName; - (void)removeChannel:(GRPCChannel *)channel { @synchronized(self) { + __block GRPCChannelConfiguration *keyToDelete = nil; [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, GRPCChannel *_Nonnull obj, BOOL *_Nonnull stop) { if (obj == channel) { - [self->_channelPool removeObjectForKey:key]; + keyToDelete = key; + *stop = YES; } }]; + [self->_channelPool removeObjectForKey:keyToDelete]; } } From 395fc1226f1225b267f912f4a860ad52ef6f4e0a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 12:54:38 -0700 Subject: [PATCH 152/534] Cleaner code using nil messaging --- src/objective-c/GRPCClient/private/GRPCHost.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 480e4621845..8a59bd43d74 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -143,9 +143,7 @@ static NSMutableDictionary *gHostCache; GRPCCallOptions *callOptions = nil; @synchronized(gHostCache) { - if ([gHostCache objectForKey:host]) { - callOptions = [gHostCache[host] callOptions]; - } + callOptions = [gHostCache[host] callOptions]; } if (callOptions == nil) { callOptions = [[GRPCCallOptions alloc] init]; From c827fbc1d044f31a1f925e52e07c843f88094a74 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 13:06:31 -0700 Subject: [PATCH 153/534] Log failures when unable to create call or channel --- src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 100d4cf2914..577002e7a85 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -257,8 +257,13 @@ // queue. Currently we use a singleton queue. _queue = [GRPCCompletionQueue completionQueue]; _channel = [GRPCChannel channelWithHost:host callOptions:callOptions]; + if (_channel == nil) { + NSLog(@"Failed to get a channel for the host."); + return nil; + } _call = [_channel unmanagedCallWithPath:path completionQueue:_queue callOptions:callOptions]; if (_call == NULL) { + NSLog(@"Failed to create a call."); return nil; } } From bc0ce06951b091e81e8bc1c71dc660dc3168e75f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 15:05:58 -0700 Subject: [PATCH 154/534] use _dispatchQueue for timer --- src/objective-c/GRPCClient/private/GRPCChannel.m | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 1d7fb421e5e..0ca2a359926 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -65,7 +65,6 @@ static GRPCChannelPool *gChannelPool; NSUInteger _refCount; BOOL _disconnected; dispatch_queue_t _dispatchQueue; - dispatch_queue_t _timerQueue; /** * Date and time when last timer is scheduled. When a timer is fired, if @@ -87,12 +86,8 @@ static GRPCChannelPool *gChannelPool; _dispatchQueue = dispatch_queue_create( NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); - _timerQueue = - dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class( - DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_DEFAULT, -1)); } else { _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - _timerQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); } _lastDispatch = nil; } @@ -117,7 +112,7 @@ static GRPCChannelPool *gChannelPool; self->_lastDispatch = now; dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); - dispatch_after(delay, self->_timerQueue, ^{ + dispatch_after(delay, self->_dispatchQueue, ^{ [self timerFireWithScheduleDate:now]; }); } From 17a67fdb0fb01fe34c75d2c6bf34e24214222a89 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 2 Nov 2018 14:48:56 -0700 Subject: [PATCH 155/534] Aggregate v2 api tests --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 482 ++++++++++++++++++ src/objective-c/tests/APIv2Tests/Info.plist | 22 + src/objective-c/tests/GRPCClientTests.m | 291 ----------- src/objective-c/tests/Podfile | 1 + .../tests/Tests.xcodeproj/project.pbxproj | 263 ++++++++++ .../xcschemes/APIv2Tests.xcscheme | 90 ++++ src/objective-c/tests/run_tests.sh | 10 + 9 files changed, 870 insertions(+), 293 deletions(-) create mode 100644 src/objective-c/tests/APIv2Tests/APIv2Tests.m create mode 100644 src/objective-c/tests/APIv2Tests/Info.plist create mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 8e7d5a5f94b..2abc0fe8f3b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -780,7 +780,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(self) { self.isWaitingForToken = YES; } - [self.tokenProvider getTokenWithHandler:^(NSString *token) { + [_callOptions.authTokenProvider getTokenWithHandler:^(NSString *token) { @synchronized(self) { if (self.isWaitingForToken) { if (token) { diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 9683bd3c638..77fde371bc0 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -64,7 +64,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)getTokenWithHandler:(void (^)(NSString *token))hander; +- (void)getTokenWithHandler:(void (^)(NSString *token))handler; @end @interface GRPCCallOptions : NSObject diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m new file mode 100644 index 00000000000..7fc353391f3 --- /dev/null +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -0,0 +1,482 @@ +/* + * + * 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. + * + */ + +#import +#import +#import +#import + +#include + +#import "../version.h" + +// The server address is derived from preprocessor macro, which is +// in turn derived from environment variable of the same name. +#define NSStringize_helper(x) #x +#define NSStringize(x) @NSStringize_helper(x) +static NSString *const kHostAddress = NSStringize(HOST_PORT_LOCAL); +static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); + +// Package and service name of test server +static NSString *const kPackage = @"grpc.testing"; +static NSString *const kService = @"TestService"; + +static GRPCProtoMethod *kInexistentMethod; +static GRPCProtoMethod *kEmptyCallMethod; +static GRPCProtoMethod *kUnaryCallMethod; +static GRPCProtoMethod *kFullDuplexCallMethod; + +static const int kSimpleDataLength = 100; + +static const NSTimeInterval kTestTimeout = 16; + +// Reveal the _class ivar for testing access +@interface GRPCCall2 () { + @public + GRPCCall *_call; +} + +@end + +// Convenience class to use blocks as callbacks +@interface ClientTestsBlockCallbacks : NSObject + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; + +@end + +@implementation ClientTestsBlockCallbacks { + void (^_initialMetadataCallback)(NSDictionary *); + void (^_messageCallback)(id); + void (^_closeCallback)(NSDictionary *, NSError *); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + if ((self = [super init])) { + _initialMetadataCallback = initialMetadataCallback; + _messageCallback = messageCallback; + _closeCallback = closeCallback; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { + dispatch_async(_dispatchQueue, ^{ + if (self->_initialMetadataCallback) { + self->_initialMetadataCallback(initialMetadata); + } + }); +} + +- (void)receivedRawMessage:(GPBMessage *_Nullable)message { + dispatch_async(_dispatchQueue, ^{ + if (self->_messageCallback) { + self->_messageCallback(message); + } + }); +} + +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error { + dispatch_async(_dispatchQueue, ^{ + if (self->_closeCallback) { + self->_closeCallback(trailingMetadata, error); + } + }); +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + +@interface CallAPIv2Tests : XCTestCase + +@end + +@implementation CallAPIv2Tests + +- (void)setUp { + // 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"]; +} + +- (void)testMetadata { + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.fillUsername = YES; + request.fillOauthScope = YES; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kRemoteSSLHost + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + __block NSDictionary *init_md; + __block NSDictionary *trailing_md; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.oauth2AccessToken = @"bogusToken"; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + init_md = initialMetadata; + } + messageCallback:^(id message) { + XCTFail(@"Received unexpected response."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + trailing_md = trailingMetadata; + if (error) { + XCTAssertEqual(error.code, 16, + @"Finished with unexpected error: %@", error); + XCTAssertEqualObjects(init_md, + error.userInfo[kGRPCHeadersKey]); + XCTAssertEqualObjects(trailing_md, + error.userInfo[kGRPCTrailersKey]); + NSString *challengeHeader = init_md[@"www-authenticate"]; + XCTAssertGreaterThan(challengeHeader.length, 0, + @"No challenge in response headers %@", + init_md); + [expectation fulfill]; + } + }] + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testUserAgentPrefix { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."]; + __weak XCTestExpectation *recvInitialMd = + [self expectationWithDescription:@"Did not receive initial md."]; + + GRPCRequestOptions *request = [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kEmptyCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + NSDictionary *headers = + [NSDictionary dictionaryWithObjectsAndKeys:@"", @"x-grpc-test-echo-useragent", nil]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.userAgentPrefix = @"Foo"; + options.initialMetadata = headers; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:request + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( + NSDictionary *initialMetadata) { + NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; + // 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:@")"]; + XCTAssertEqualObjects(userAgent, expectedUserAgent); + + NSError *error = nil; + // 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 = + [regex stringByReplacingMatchesInString:userAgent + options:0 + range:NSMakeRange(0, [userAgent length]) + withTemplate:@""]; + XCTAssertEqualObjects(customUserAgent, @"Foo"); + [recvInitialMd fulfill]; + } + messageCallback:^(id message) { + XCTAssertNotNil(message); + XCTAssertEqual([message length], 0, + @"Non-empty response received: %@", message); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + if (error) { + XCTFail(@"Finished with unexpected error: %@", error); + } else { + [completion fulfill]; + } + }] + callOptions:options]; + [call writeData:[NSData data]]; + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)getTokenWithHandler:(void (^)(NSString *token))handler { + dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + dispatch_sync(queue, ^{ + handler(@"test-access-token"); + }); +} + +- (void)testOAuthToken { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kEmptyCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.authTokenProvider = self; + __block GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + [completion fulfill]; + }] + callOptions:options]; + [call writeData:[NSData data]]; + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testResponseSizeLimitExceeded { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.responseSizeLimit = kSimpleDataLength; + options.transportType = GRPCTransportTypeInsecure; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.payload.body = [NSMutableData dataWithLength:options.responseSizeLimit]; + request.responseSize = (int32_t)(options.responseSizeLimit * 2); + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNotNil(error, + @"Expecting non-nil error"); + XCTAssertEqual(error.code, + GRPCErrorCodeResourceExhausted); + [completion fulfill]; + }] + callOptions:options]; + [call writeData:[request data]]; + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testIdempotentProtoRPC { + __weak XCTestExpectation *response = [self expectationWithDescription:@"Expected response."]; + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = kSimpleDataLength; + request.fillUsername = YES; + request.fillOauthScope = YES; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyIdempotentRequest]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + NSData *data = (NSData *)message; + XCTAssertNotNil(data, @"nil value received as response."); + XCTAssertGreaterThan(data.length, 0, + @"Empty response received."); + RMTSimpleResponse *responseProto = + [RMTSimpleResponse parseFromData:data error:NULL]; + // We expect empty strings, not nil: + XCTAssertNotNil(responseProto.username, + @"Response's username is nil."); + XCTAssertNotNil(responseProto.oauthScope, + @"Response's OAuth scope is nil."); + [response fulfill]; + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", + error); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testTimeout { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.timeout = 0.001; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler: + [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + XCTFail(@"Failure: response received; Expect: no response received."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Failure: no error received; Expect: receive " + @"deadline exceeded."); + XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testTimeoutBackoffWithTimeout:(double)timeout Backoff:(double)backoff { + const double maxConnectTime = timeout > backoff ? timeout : backoff; + const double kMargin = 0.1; + + __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; + NSString *const kDummyAddress = [NSString stringWithFormat:@"127.0.0.1:10000"]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kDummyAddress + path:@"/dummy/path" + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.connectMinTimeout = timeout; + options.connectInitialBackoff = backoff; + options.connectMaxBackoff = 0; + + NSDate *startTime = [NSDate date]; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + XCTFail(@"Received message. Should not reach here."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Finished with no error; expecting error"); + XCTAssertLessThan( + [[NSDate date] timeIntervalSinceDate:startTime], + maxConnectTime + kMargin); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testTimeoutBackoff1 { + [self testTimeoutBackoffWithTimeout:0.7 Backoff:0.4]; +} + +- (void)testTimeoutBackoff2 { + [self testTimeoutBackoffWithTimeout:0.3 Backoff:0.8]; +} + +- (void)testCompression { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.expectCompressed = [RMTBoolValue message]; + request.expectCompressed.value = YES; + request.responseCompressed = [RMTBoolValue message]; + request.expectCompressed.value = YES; + request.responseSize = kSimpleDataLength; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.compressionAlgorithm = GRPCCompressGzip; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler: [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + NSError *error; + RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:data error:&error]; + XCTAssertNil(error, @"Error when parsing response: %@", error); + XCTAssertEqual(response.payload.body.length, kSimpleDataLength); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Received failure: %@", error); + [completion fulfill]; + }] + + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +@end diff --git a/src/objective-c/tests/APIv2Tests/Info.plist b/src/objective-c/tests/APIv2Tests/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/APIv2Tests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index bbe81502dcf..727dc59ca11 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -86,65 +86,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; @end -// Convenience class to use blocks as callbacks -@interface ClientTestsBlockCallbacks : NSObject - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; - -@end - -@implementation ClientTestsBlockCallbacks { - void (^_initialMetadataCallback)(NSDictionary *); - void (^_messageCallback)(id); - void (^_closeCallback)(NSDictionary *, NSError *); - dispatch_queue_t _dispatchQueue; -} - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { - if ((self = [super init])) { - _initialMetadataCallback = initialMetadataCallback; - _messageCallback = messageCallback; - _closeCallback = closeCallback; - _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); - } - return self; -} - -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { - dispatch_async(_dispatchQueue, ^{ - if (_initialMetadataCallback) { - _initialMetadataCallback(initialMetadata); - } - }); -} - -- (void)receivedRawMessage:(GPBMessage *_Nullable)message { - dispatch_async(_dispatchQueue, ^{ - if (_messageCallback) { - _messageCallback(message); - } - }); -} - -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error { - dispatch_async(_dispatchQueue, ^{ - if (_closeCallback) { - _closeCallback(trailingMetadata, error); - } - }); -} - -- (dispatch_queue_t)dispatchQueue { - return _dispatchQueue; -} - -@end - #pragma mark Tests /** @@ -296,55 +237,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testMetadataWithV2API { - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."]; - - RMTSimpleRequest *request = [RMTSimpleRequest message]; - request.fillUsername = YES; - request.fillOauthScope = YES; - - GRPCRequestOptions *callRequest = - [[GRPCRequestOptions alloc] initWithHost:(NSString *)kRemoteSSLHost - path:kUnaryCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - __block NSDictionary *init_md; - __block NSDictionary *trailing_md; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.oauth2AccessToken = @"bogusToken"; - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:callRequest - responseHandler:[[ClientTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - init_md = initialMetadata; - } - messageCallback:^(id message) { - XCTFail(@"Received unexpected response."); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - trailing_md = trailingMetadata; - if (error) { - XCTAssertEqual(error.code, 16, - @"Finished with unexpected error: %@", error); - XCTAssertEqualObjects(init_md, - error.userInfo[kGRPCHeadersKey]); - XCTAssertEqualObjects(trailing_md, - error.userInfo[kGRPCTrailersKey]); - NSString *challengeHeader = init_md[@"www-authenticate"]; - XCTAssertGreaterThan(challengeHeader.length, 0, - @"No challenge in response headers %@", - init_md); - [expectation fulfill]; - } - }] - callOptions:options]; - - [call start]; - [call writeData:[request data]]; - [call finish]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (void)testResponseMetadataKVO { __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."]; @@ -437,75 +329,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testUserAgentPrefixWithV2API { - __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."]; - __weak XCTestExpectation *recvInitialMd = - [self expectationWithDescription:@"Did not receive initial md."]; - - GRPCRequestOptions *request = [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kEmptyCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - NSDictionary *headers = - [NSDictionary dictionaryWithObjectsAndKeys:@"", @"x-grpc-test-echo-useragent", nil]; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = GRPCTransportTypeInsecure; - options.userAgentPrefix = @"Foo"; - options.initialMetadata = headers; - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:request - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( - NSDictionary *initialMetadata) { - NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; - // 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:@")"]; - XCTAssertEqualObjects(userAgent, expectedUserAgent); - - NSError *error = nil; - // 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 = - [regex stringByReplacingMatchesInString:userAgent - options:0 - range:NSMakeRange(0, [userAgent length]) - withTemplate:@""]; - XCTAssertEqualObjects(customUserAgent, @"Foo"); - [recvInitialMd fulfill]; - } - messageCallback:^(id message) { - XCTAssertNotNil(message); - XCTAssertEqual([message length], 0, - @"Non-empty response received: %@", message); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - if (error) { - XCTFail(@"Finished with unexpected error: %@", error); - } else { - [completion fulfill]; - } - }] - callOptions:options]; - [call writeData:[NSData data]]; - [call start]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (void)testTrailers { __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."]; @@ -597,52 +420,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testIdempotentProtoRPCWithV2API { - __weak XCTestExpectation *response = [self expectationWithDescription:@"Expected response."]; - __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; - - RMTSimpleRequest *request = [RMTSimpleRequest message]; - request.responseSize = 100; - request.fillUsername = YES; - request.fillOauthScope = YES; - GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kUnaryCallMethod.HTTPPath - safety:GRPCCallSafetyIdempotentRequest]; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = GRPCTransportTypeInsecure; - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - NSData *data = (NSData *)message; - XCTAssertNotNil(data, @"nil value received as response."); - XCTAssertGreaterThan(data.length, 0, - @"Empty response received."); - RMTSimpleResponse *responseProto = - [RMTSimpleResponse parseFromData:data error:NULL]; - // We expect empty strings, not nil: - XCTAssertNotNil(responseProto.username, - @"Response's username is nil."); - XCTAssertNotNil(responseProto.oauthScope, - @"Response's OAuth scope is nil."); - [response fulfill]; - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error, @"Finished with unexpected error: %@", - error); - [completion fulfill]; - }] - callOptions:options]; - - [call start]; - [call writeData:[request data]]; - [call finish]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (void)testAlternateDispatchQueue { const int32_t kPayloadSize = 100; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -732,37 +509,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testTimeoutWithV2API { - __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.timeout = 0.001; - GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kFullDuplexCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler: - [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id data) { - XCTFail(@"Failure: response received; Expect: no response received."); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNotNil(error, - @"Failure: no error received; Expect: receive " - @"deadline exceeded."); - XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); - [completion fulfill]; - }] - callOptions:options]; - - [call start]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (int)findFreePort { struct sockaddr_in addr; unsigned int addr_len = sizeof(addr); @@ -834,43 +580,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testTimeoutBackoffWithOptionsWithTimeout:(double)timeout Backoff:(double)backoff { - const double maxConnectTime = timeout > backoff ? timeout : backoff; - const double kMargin = 0.1; - - __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; - NSString *const kDummyAddress = [NSString stringWithFormat:@"127.0.0.1:10000"]; - GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kDummyAddress - path:@"/dummy/path" - safety:GRPCCallSafetyDefault]; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.connectMinTimeout = timeout; - options.connectInitialBackoff = backoff; - options.connectMaxBackoff = 0; - - NSDate *startTime = [NSDate date]; - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id data) { - XCTFail(@"Received message. Should not reach here."); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNotNil(error, - @"Finished with no error; expecting error"); - XCTAssertLessThan( - [[NSDate date] timeIntervalSinceDate:startTime], - maxConnectTime + kMargin); - [completion fulfill]; - }] - callOptions:options]; - - [call start]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - // The numbers of the following three tests are selected to be smaller than the default values of // initial backoff (1s) and min_connect_timeout (20s), so that if they fail we know the default // values fail to be overridden by the channel args. diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index e87aba235ad..5df9d4e85bd 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -17,6 +17,7 @@ GRPC_LOCAL_SRC = '../../..' InteropTestsMultipleChannels InteropTestsCallOptions UnitTests + APIv2Tests ).each do |target_name| target target_name do pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 104fd0a4ea0..6d1932b0215 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 5E0282E9215AA697007AC99D /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; 5E0282EB215AA697007AC99D /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5E10F5AA218CB0D2008BAB68 /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */; }; 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */; }; 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; @@ -68,6 +69,7 @@ BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */; }; C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */; }; CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */; }; + E7F4C80FC8FC667B7447BFE7 /* libPods-APIv2Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */; }; F15EF7852DC70770EFDB1D2C /* libPods-AllTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */; }; /* End PBXBuildFile section */ @@ -176,7 +178,9 @@ 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartextCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.debug.xcconfig"; sourceTree = ""; }; + 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.debug.xcconfig"; sourceTree = ""; }; 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.cronet.xcconfig"; sourceTree = ""; }; + 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.release.xcconfig"; sourceTree = ""; }; 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.cronet.xcconfig"; sourceTree = ""; }; 1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.test.xcconfig"; sourceTree = ""; }; 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; sourceTree = ""; }; @@ -200,6 +204,7 @@ 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.release.xcconfig"; sourceTree = ""; }; 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.cronet.xcconfig"; sourceTree = ""; }; 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = ""; }; + 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.test.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.test.xcconfig"; sourceTree = ""; }; 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = ""; }; 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; sourceTree = ""; }; 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; sourceTree = ""; }; @@ -207,6 +212,9 @@ 5E0282E6215AA697007AC99D /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E0282E8215AA697007AC99D /* UnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnitTests.m; sourceTree = ""; }; 5E0282EA215AA697007AC99D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = APIv2Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = APIv2Tests.m; sourceTree = ""; }; + 5E10F5AB218CB0D2008BAB68 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsCallOptions.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsCallOptions.m; sourceTree = ""; }; 5E7D71B6210B9EC9001EA6BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -254,6 +262,7 @@ 7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.release.xcconfig"; sourceTree = ""; }; 7BA53C6D224288D5870FE6F3 /* Pods-InteropTestsLocalCleartextCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; sourceTree = ""; }; 8B498B05C6DA0818B2FA91D4 /* Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; sourceTree = ""; }; + 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.cronet.xcconfig"; sourceTree = ""; }; 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.cronet.xcconfig"; sourceTree = ""; }; 943138072A9605B5B8DC1FC0 /* Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; sourceTree = ""; }; 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.test.xcconfig"; sourceTree = ""; }; @@ -266,6 +275,7 @@ AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.release.xcconfig"; sourceTree = ""; }; AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsCallOptions.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.test.xcconfig"; sourceTree = ""; }; + B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-APIv2Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = ""; }; BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.test.xcconfig"; sourceTree = ""; }; C17F57E5BCB989AB1C2F1F25 /* Pods-InteropTestsRemoteCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.test.xcconfig"; sourceTree = ""; }; @@ -303,6 +313,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E10F5A4218CB0D1008BAB68 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E7F4C80FC8FC667B7447BFE7 /* libPods-APIv2Tests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E7D71AF210B9EC8001EA6BA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -456,6 +474,7 @@ 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */, AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */, 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */, + B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */, ); name = Frameworks; sourceTree = ""; @@ -525,6 +544,10 @@ 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */, E1E7660656D902104F728892 /* Pods-UnitTests.cronet.xcconfig */, EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */, + 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */, + 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */, + 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */, + 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -538,6 +561,15 @@ path = UnitTests; sourceTree = ""; }; + 5E10F5A8218CB0D1008BAB68 /* APIv2Tests */ = { + isa = PBXGroup; + children = ( + 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */, + 5E10F5AB218CB0D2008BAB68 /* Info.plist */, + ); + path = APIv2Tests; + sourceTree = ""; + }; 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */ = { isa = PBXGroup; children = ( @@ -604,6 +636,7 @@ 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */, 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */, 5E0282E7215AA697007AC99D /* UnitTests */, + 5E10F5A8218CB0D1008BAB68 /* APIv2Tests */, 635697C81B14FC11007A7283 /* Products */, 51E4650F34F854F41FF053B3 /* Pods */, 136D535E19727099B941D7B1 /* Frameworks */, @@ -629,6 +662,7 @@ 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */, 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */, 5E0282E6215AA697007AC99D /* UnitTests.xctest */, + 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */, ); name = Products; sourceTree = ""; @@ -681,6 +715,25 @@ productReference = 5E0282E6215AA697007AC99D /* UnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 5E10F5A6218CB0D1008BAB68 /* APIv2Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E10F5B0218CB0D2008BAB68 /* Build configuration list for PBXNativeTarget "APIv2Tests" */; + buildPhases = ( + 031ADD72298D6C6979CB06DB /* [CP] Check Pods Manifest.lock */, + 5E10F5A3218CB0D1008BAB68 /* Sources */, + 5E10F5A4218CB0D1008BAB68 /* Frameworks */, + 5E10F5A5218CB0D1008BAB68 /* Resources */, + FBB92A8B11C52512E67791E8 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = APIv2Tests; + productName = APIv2Tests; + productReference = 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */ = { isa = PBXNativeTarget; buildConfigurationList = 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */; @@ -990,6 +1043,10 @@ CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; }; + 5E10F5A6218CB0D1008BAB68 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; 5E7D71B1210B9EC8001EA6BA = { CreatedOnToolsVersion = 9.3; ProvisioningStyle = Automatic; @@ -1071,6 +1128,7 @@ 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */, 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */, 5E0282E5215AA697007AC99D /* UnitTests */, + 5E10F5A6218CB0D1008BAB68 /* APIv2Tests */, ); }; /* End PBXProject section */ @@ -1083,6 +1141,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E10F5A5218CB0D1008BAB68 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E7D71B0210B9EC8001EA6BA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1206,6 +1271,28 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + 031ADD72298D6C6979CB06DB /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-APIv2Tests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1764,6 +1851,28 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + FBB92A8B11C52512E67791E8 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1775,6 +1884,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E10F5A3218CB0D1008BAB68 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E10F5AA218CB0D2008BAB68 /* APIv2Tests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E7D71AE210B9EC8001EA6BA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2098,6 +2215,141 @@ }; name = Release; }; + 5E10F5AC218CB0D2008BAB68 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5E10F5AD218CB0D2008BAB68 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5E10F5AE218CB0D2008BAB68 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5E10F5AF218CB0D2008BAB68 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 5E1228981E4D400F00E8504F /* Test */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3648,6 +3900,17 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 5E10F5B0218CB0D2008BAB68 /* Build configuration list for PBXNativeTarget "APIv2Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E10F5AC218CB0D2008BAB68 /* Debug */, + 5E10F5AD218CB0D2008BAB68 /* Test */, + 5E10F5AE218CB0D2008BAB68 /* Cronet */, + 5E10F5AF218CB0D2008BAB68 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme new file mode 100644 index 00000000000..b444ddc2b67 --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index 118220ce4b1..e8c3e6ec2a4 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -183,4 +183,14 @@ xcodebuild \ | egrep -v '^$' \ | egrep -v "(GPBDictionary|GPBArray)" - +echo "TIME: $(date)" +xcodebuild \ + -workspace Tests.xcworkspace \ + -scheme APIv2Tests \ + -destination name="iPhone 8" \ + test \ + | egrep -v "$XCODEBUILD_FILTER" \ + | egrep -v '^$' \ + | egrep -v "(GPBDictionary|GPBArray)" - + exit 0 From 6b8f0ceae8f581cfd63b40c4e2ccab95783081ae Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 10:15:20 -0800 Subject: [PATCH 156/534] A few nits --- src/objective-c/GRPCClient/GRPCCall+OAuth2.h | 2 +- src/objective-c/GRPCClient/GRPCCall.h | 4 ++-- src/objective-c/GRPCClient/GRPCCall.m | 9 +++++++-- src/objective-c/ProtoRPC/ProtoRPC.h | 4 ++-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h index 3054bfc5a7a..60cdc50bfda 100644 --- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h +++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h @@ -24,7 +24,7 @@ @interface GRPCCall (OAuth2) @property(atomic, copy) NSString* oauth2AccessToken; -@property(atomic, readonly) NSString* oauth2ChallengeHeader; +@property(atomic, copy, readonly) NSString* oauth2ChallengeHeader; @property(atomic, strong) id tokenProvider; @end diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index a1f139fc186..4f0660d203e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -196,7 +196,7 @@ extern NSString *const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype) new NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; /** Initialize with all properties. */ - (instancetype)initWithHost:(NSString *)host @@ -224,7 +224,7 @@ extern NSString *const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype) new NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; /** * Designated initializer for a call. diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 2abc0fe8f3b..2f727e62be1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -67,6 +67,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @implementation GRPCRequestOptions - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { + NSAssert(host.length != 0 && path.length != 0, @"Host and Path cannot be empty"); if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -90,7 +91,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; /** The handler of responses. */ id _handler; - // Thread safety of ivars below are protected by _dispatcheQueue. + // Thread safety of ivars below are protected by _dispatchQueue. /** * Make use of legacy GRPCCall to make calls. Nullified when call is finished. @@ -121,7 +122,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; if ((self = [super init])) { _requestOptions = [requestOptions copy]; - _callOptions = [callOptions copy]; + if (callOptions == nil) { + _callOptions = [[GRPCCallOptions alloc] init]; + } else { + _callOptions = [callOptions copy]; + } _handler = responseHandler; _initialMetadataPublished = NO; _pipe = [GRXBufferedPipe pipe]; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index b0f4ced99e8..3d137a53ffc 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -66,7 +66,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -+ (instancetype) new NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; /** * Users should not use this initializer directly. Call objects will be created, initialized, and @@ -92,7 +92,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -+ (instancetype) new NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; /** * Users should not use this initializer directly. Call objects will be created, initialized, and From b496e3a2663824c22806b7ee7b1423c806ecc61a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 11:07:03 -0800 Subject: [PATCH 157/534] On finish, clean _handler and _call independently --- src/objective-c/GRPCClient/GRPCCall.m | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 2f727e62be1..af141935813 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -184,6 +184,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; } completionHandler:^(NSError *errorOrNil) { dispatch_async(self->_dispatchQueue, ^{ + if (self->_call) { + [self->_pipe writesFinishedWithError:nil]; + self->_call = nil; + self->_pipe = nil; + } if (self->_handler) { if (!self->_initialMetadataPublished) { self->_initialMetadataPublished = YES; @@ -193,12 +198,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; - - if (self->_call) { - [self->_pipe writesFinishedWithError:nil]; - self->_call = nil; - self->_pipe = nil; - } } }); }]; From 739760cdc8a6625fe93f4f0312d84305052b0d09 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 11:22:51 -0800 Subject: [PATCH 158/534] More comment --- src/objective-c/GRPCClient/GRPCCall.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index af141935813..9be0554ff98 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -185,6 +185,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; completionHandler:^(NSError *errorOrNil) { dispatch_async(self->_dispatchQueue, ^{ if (self->_call) { + // Clean up the request writers. This should have no effect to _call since its + // response writeable is already nullified. [self->_pipe writesFinishedWithError:nil]; self->_call = nil; self->_pipe = nil; From 24265b03ac5c6ace73916f3bc3a847abf1c64c33 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 11:31:48 -0800 Subject: [PATCH 159/534] Clarify cancel before call is started --- src/objective-c/GRPCClient/GRPCCall.h | 1 + src/objective-c/GRPCClient/GRPCCall.m | 1 + 2 files changed, 2 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 4f0660d203e..f713262b643 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -245,6 +245,7 @@ extern NSString *const kGRPCTrailersKey; /** * Starts the call. This function should only be called once; additional calls will be discarded. + * Invokes after calling cancel: are discarded. */ - (void)start; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9be0554ff98..5ce361300d6 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -209,6 +209,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { dispatch_async(_dispatchQueue, ^{ + self->_started = YES; if (self->_call) { [self->_call cancel]; self->_call = nil; From 9558618182aa817ad5aa9885f1fe12003ee1a93e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 11:37:41 -0800 Subject: [PATCH 160/534] Check if call is cancelled --- src/objective-c/GRPCClient/GRPCCall.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 5ce361300d6..1338c1edd60 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -237,7 +237,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(NSData *)data { dispatch_async(_dispatchQueue, ^{ - [self->_pipe writeValue:data]; + if (self->_call) { + [self->_pipe writeValue:data]; + } }); } From b3b98ba4a29f434541355e026765938998c22da4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 12:09:46 -0800 Subject: [PATCH 161/534] test fix --- src/objective-c/tests/GRPCClientTests.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 727dc59ca11..834bf6d661a 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -585,12 +585,10 @@ static GRPCProtoMethod *kFullDuplexCallMethod; // values fail to be overridden by the channel args. - (void)testTimeoutBackoff1 { [self testTimeoutBackoffWithTimeout:0.7 Backoff:0.3]; - [self testTimeoutBackoffWithOptionsWithTimeout:0.7 Backoff:0.4]; } - (void)testTimeoutBackoff2 { [self testTimeoutBackoffWithTimeout:0.3 Backoff:0.7]; - [self testTimeoutBackoffWithOptionsWithTimeout:0.3 Backoff:0.8]; } - (void)testErrorDebugInformation { From 1be316e5641db3192a3f7b276e3926d8da17c62a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 14:12:14 -0800 Subject: [PATCH 162/534] Remove check in cancel --- src/objective-c/GRPCClient/GRPCCall.h | 5 ++-- src/objective-c/GRPCClient/GRPCCall.m | 42 +++++++++++++++------------ 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index f713262b643..260305a989c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -244,8 +244,7 @@ extern NSString *const kGRPCTrailersKey; responseHandler:(id)responseHandler; /** - * Starts the call. This function should only be called once; additional calls will be discarded. - * Invokes after calling cancel: are discarded. + * Starts the call. This function must only be called once for each instance. */ - (void)start; @@ -263,7 +262,7 @@ extern NSString *const kGRPCTrailersKey; /** * Finish the RPC request and half-close the call. The server may still send messages and/or - * trailers to the client. + * trailers to the client. The method must only be called once and after start is called. */ - (void)finish; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 1338c1edd60..9f8339eb601 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -105,6 +105,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_queue_t _dispatchQueue; /** Flags whether call has started. */ BOOL _started; + /** Flags whether call has been canceled. */ + BOOL _canceled; + /** Flags whether call has been finished. */ } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -140,6 +143,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); _started = NO; + _canceled = NO; } return self; @@ -153,9 +157,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)start { dispatch_async(_dispatchQueue, ^{ - if (self->_started) { - return; - } + NSAssert(!self->_started, @"Call already started."); + NSAssert(!self->_canceled, @"Call already canceled."); self->_started = YES; if (!self->_callOptions) { self->_callOptions = [[GRPCCallOptions alloc] init]; @@ -184,13 +187,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; } completionHandler:^(NSError *errorOrNil) { dispatch_async(self->_dispatchQueue, ^{ - if (self->_call) { - // Clean up the request writers. This should have no effect to _call since its - // response writeable is already nullified. - [self->_pipe writesFinishedWithError:nil]; - self->_call = nil; - self->_pipe = nil; - } if (self->_handler) { if (!self->_initialMetadataPublished) { self->_initialMetadataPublished = YES; @@ -201,6 +197,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; } + // Clearing _call must happen *after* dispatching close in order to get trailing + // metadata from _call. + if (self->_call) { + // Clean up the request writers. This should have no effect to _call since its + // response writeable is already nullified. + [self->_pipe writesFinishedWithError:nil]; + self->_call = nil; + self->_pipe = nil; + } }); }]; [self->_call startWithWriteable:responseWriteable]; @@ -209,7 +214,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { dispatch_async(_dispatchQueue, ^{ - self->_started = YES; + NSAssert(!self->_canceled, @"Call already canceled."); if (self->_call) { [self->_call cancel]; self->_call = nil; @@ -237,6 +242,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(NSData *)data { dispatch_async(_dispatchQueue, ^{ + NSAssert(!self->_canceled, @"Call arleady canceled."); + NSAssert(!self->_finished, @"Call is half-closed before sending data."); if (self->_call) { [self->_pipe writeValue:data]; } @@ -245,6 +252,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)finish { dispatch_async(_dispatchQueue, ^{ + NSAssert(self->started, @"Call not started."); + NSAssert(!self->_canceled, @"Call arleady canceled."); + NSAssert(!self->_finished, @"Call already half-closed."); if (self->_call) { [self->_pipe writesFinishedWithError:nil]; } @@ -265,9 +275,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - NSDictionary *trailers = _call.responseTrailers; if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [_handler closedWithTrailingMetadata:trailers error:error]; + [_handler closedWithTrailingMetadata:_call.responseTrailers error:error]; } } @@ -464,11 +473,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { @synchronized(self) { - if (!self.isWaitingForToken) { - [self cancelCall]; - } else { - self.isWaitingForToken = NO; - } + [self cancelCall]; + self.isWaitingForToken = NO; } [self maybeFinishWithError:[NSError From 515941ae1899ca125e8da77c3031d3f0471488ff Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 16:04:56 -0800 Subject: [PATCH 163/534] copy _requestHeaders in GRPCCall --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9f8339eb601..c10fe7c1346 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -578,7 +578,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; break; } - NSMutableDictionary *headers = _requestHeaders; + NSMutableDictionary *headers = [_requestHeaders copy]; NSString *fetchedOauth2AccessToken; @synchronized(self) { fetchedOauth2AccessToken = _fetchedOauth2AccessToken; From d635d9f9f98bc374c0b3502bbcc8f707c27d7038 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 16:43:58 -0800 Subject: [PATCH 164/534] fix some threading issues --- src/objective-c/GRPCClient/GRPCCall.m | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index c10fe7c1346..b3bddf08a05 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -468,7 +468,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancelCall { // Can be called from any thread, any number of times. - [_wrappedCall cancel]; + @synchronized (self) { + [_wrappedCall cancel]; + } } - (void)cancel { @@ -730,17 +732,21 @@ const char *kCFStreamVarName = "grpc_cfstream"; _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; - if (_wrappedCall == nil) { + GRPCWrappedCall *wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; + if (wrappedCall == nil) { [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{ - NSLocalizedDescriptionKey : - @"Failed to create call or channel." - }]]; + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; return; } + @synchronized (self) { + _wrappedCall = wrappedCall; + } + [self sendHeaders]; [self invokeCall]; From d40e828d53cdb983255e0406261fed71710ba361 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 17:08:26 -0800 Subject: [PATCH 165/534] NSInteger->NSUInteger --- src/objective-c/GRPCClient/GRPCCallOptions.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 77fde371bc0..bb8a1d251a9 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -34,7 +34,7 @@ typedef NS_ENUM(NSUInteger, GRPCCallSafety) { }; // Compression algorithm to be used by a gRPC call -typedef NS_ENUM(NSInteger, GRPCCompressionAlgorithm) { +typedef NS_ENUM(NSUInteger, GRPCCompressionAlgorithm) { GRPCCompressNone = 0, GRPCCompressDeflate, GRPCCompressGzip, @@ -45,7 +45,7 @@ typedef NS_ENUM(NSInteger, GRPCCompressionAlgorithm) { typedef GRPCCompressionAlgorithm GRPCCompressAlgorithm; /** The transport to be used by a gRPC call */ -typedef NS_ENUM(NSInteger, GRPCTransportType) { +typedef NS_ENUM(NSUInteger, GRPCTransportType) { GRPCTransportTypeDefault = 0, /** gRPC internal HTTP/2 stack with BoringSSL */ GRPCTransportTypeChttp2BoringSSL = 0, From ae623ea5b65ff6060d0b8a63fdf3f26560118720 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 17:32:22 -0800 Subject: [PATCH 166/534] Polish isEqual of options --- src/objective-c/GRPCClient/GRPCCallOptions.m | 43 +++++++++---------- .../GRPCClient/private/GRPCChannelPool.m | 2 +- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index c7096cf1cfb..beea9ce46ec 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -44,6 +44,17 @@ static const id kDefaultLogContext = nil; static NSString *const kDefaultChannelPoolDomain = nil; static const NSUInteger kDefaultChannelID = 0; +// Check if two objects are equal. Returns YES if both are nil; +BOOL areObjectsEqual(id obj1, id obj2) { + if (obj1 == obj2) { + return YES; + } + if (obj1 == nil || obj2 == nil) { + return NO; + } + return [obj1 isEqual:obj2]; +} + @implementation GRPCCallOptions { @protected NSString *_serverAuthority; @@ -232,9 +243,8 @@ static const NSUInteger kDefaultChannelID = 0; } - (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions { - if (!(callOptions.userAgentPrefix == _userAgentPrefix || - [callOptions.userAgentPrefix isEqualToString:_userAgentPrefix])) - return NO; + if (callOptions == nil) return NO; + if (!areObjectsEqual(callOptions.userAgentPrefix, _userAgentPrefix)) return NO; if (!(callOptions.responseSizeLimit == _responseSizeLimit)) return NO; if (!(callOptions.compressionAlgorithm == _compressionAlgorithm)) return NO; if (!(callOptions.retryEnabled == _retryEnabled)) return NO; @@ -243,27 +253,14 @@ static const NSUInteger kDefaultChannelID = 0; if (!(callOptions.connectMinTimeout == _connectMinTimeout)) return NO; if (!(callOptions.connectInitialBackoff == _connectInitialBackoff)) return NO; if (!(callOptions.connectMaxBackoff == _connectMaxBackoff)) return NO; - if (!(callOptions.additionalChannelArgs == _additionalChannelArgs || - [callOptions.additionalChannelArgs isEqualToDictionary:_additionalChannelArgs])) - return NO; - if (!(callOptions.PEMRootCertificates == _PEMRootCertificates || - [callOptions.PEMRootCertificates isEqualToString:_PEMRootCertificates])) - return NO; - if (!(callOptions.PEMPrivateKey == _PEMPrivateKey || - [callOptions.PEMPrivateKey isEqualToString:_PEMPrivateKey])) - return NO; - if (!(callOptions.PEMCertChain == _PEMCertChain || - [callOptions.PEMCertChain isEqualToString:_PEMCertChain])) - return NO; - if (!(callOptions.hostNameOverride == _hostNameOverride || - [callOptions.hostNameOverride isEqualToString:_hostNameOverride])) - return NO; + if (!areObjectsEqual(callOptions.additionalChannelArgs, _additionalChannelArgs)) return NO; + if (!areObjectsEqual(callOptions.PEMRootCertificates, _PEMRootCertificates)) return NO; + if (!areObjectsEqual(callOptions.PEMPrivateKey, _PEMPrivateKey)) return NO; + if (!areObjectsEqual(callOptions.PEMCertChain, _PEMCertChain)) return NO; + if (!areObjectsEqual(callOptions.hostNameOverride, _hostNameOverride)) return NO; if (!(callOptions.transportType == _transportType)) return NO; - if (!(callOptions.logContext == _logContext || [callOptions.logContext isEqual:_logContext])) - return NO; - if (!(callOptions.channelPoolDomain == _channelPoolDomain || - [callOptions.channelPoolDomain isEqualToString:_channelPoolDomain])) - return NO; + if (!areObjectsEqual(callOptions.logContext, _logContext)) return NO; + if (!areObjectsEqual(callOptions.channelPoolDomain, _channelPoolDomain)) return NO; if (!(callOptions.channelID == _channelID)) return NO; return YES; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 56de8a0d6f5..627bbab3c01 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -151,7 +151,7 @@ extern const char *kCFStreamVarName; return NO; } GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; - if (!(obj.host == _host || [obj.host isEqualToString:_host])) return NO; + if (!(obj.host == _host || (_host != nil && [obj.host isEqualToString:_host]))) return NO; if (!(obj.callOptions == _callOptions || [obj.callOptions hasChannelOptionsEqualTo:_callOptions])) return NO; From bb5e55e86896ff353010db58bc6381436e11c4a5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 17:37:47 -0800 Subject: [PATCH 167/534] remove extra copy --- src/objective-c/GRPCClient/GRPCCallOptions.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index beea9ce46ec..696e81703ff 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -360,7 +360,7 @@ BOOL areObjectsEqual(id obj1, id obj2) { connectMinTimeout:_connectMinTimeout connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff - additionalChannelArgs:[_additionalChannelArgs copy] + additionalChannelArgs:_additionalChannelArgs PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey PEMCertChain:_PEMCertChain From d8e7a6c6f1269eedec3f7b175ac85ed89e6e490e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 17:38:21 -0800 Subject: [PATCH 168/534] hash: -> .hash --- src/objective-c/GRPCClient/GRPCCallOptions.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 696e81703ff..3e0dbbf7e42 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -283,7 +283,7 @@ BOOL areObjectsEqual(id obj1, id obj2) { result ^= _PEMCertChain.hash; result ^= _hostNameOverride.hash; result ^= _transportType; - result ^= [_logContext hash]; + result ^= _logContext.hash; result ^= _channelPoolDomain.hash; result ^= _channelID; From a0f5db15815d3ec5b2ad3b781cca5e2eb6468824 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 17:42:30 -0800 Subject: [PATCH 169/534] Rename GRPCCallOptions+internal->GRPCCallOptions+Internal --- gRPC.podspec | 2 +- .../{GRPCCallOptions+internal.h => GRPCCallOptions+Internal.h} | 0 templates/gRPC.podspec.template | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/objective-c/GRPCClient/internal/{GRPCCallOptions+internal.h => GRPCCallOptions+Internal.h} (100%) diff --git a/gRPC.podspec b/gRPC.podspec index 47a130d12d1..d8aa997e7cb 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -58,7 +58,7 @@ Pod::Spec.new do |s| ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}" ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}" - ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/GRPCCallOptions+Internal.h" + ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/*.h" ss.dependency 'gRPC-Core', version end diff --git a/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h b/src/objective-c/GRPCClient/internal/GRPCCallOptions+Internal.h similarity index 100% rename from src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h rename to src/objective-c/GRPCClient/internal/GRPCCallOptions+Internal.h diff --git a/templates/gRPC.podspec.template b/templates/gRPC.podspec.template index a3ed1d78584..593d277e5ba 100644 --- a/templates/gRPC.podspec.template +++ b/templates/gRPC.podspec.template @@ -60,7 +60,7 @@ ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}" ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}" - ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/GRPCCallOptions+Internal.h" + ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/*.h" ss.dependency 'gRPC-Core', version end From ab9510560781dd2f27608e694518f67b7d425d9a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 17:46:22 -0800 Subject: [PATCH 170/534] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 4 +-- src/objective-c/GRPCClient/GRPCCall.m | 13 +++---- src/objective-c/ProtoRPC/ProtoRPC.h | 4 +-- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 35 ++++++++++--------- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 260305a989c..bde69f01c52 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -196,7 +196,7 @@ extern NSString *const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** Initialize with all properties. */ - (instancetype)initWithHost:(NSString *)host @@ -224,7 +224,7 @@ extern NSString *const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Designated initializer for a call. diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index b3bddf08a05..321a0bd1bd7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -468,7 +468,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancelCall { // Can be called from any thread, any number of times. - @synchronized (self) { + @synchronized(self) { [_wrappedCall cancel]; } } @@ -732,18 +732,19 @@ const char *kCFStreamVarName = "grpc_cfstream"; _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - GRPCWrappedCall *wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; + GRPCWrappedCall *wrappedCall = + [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; if (wrappedCall == nil) { [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{ - NSLocalizedDescriptionKey : - @"Failed to create call or channel." - }]]; + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; return; } - @synchronized (self) { + @synchronized(self) { _wrappedCall = wrappedCall; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 3d137a53ffc..b0f4ced99e8 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -66,7 +66,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Users should not use this initializer directly. Call objects will be created, initialized, and @@ -92,7 +92,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Users should not use this initializer directly. Call objects will be created, initialized, and diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index 7fc353391f3..d681163419d 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -449,28 +449,29 @@ static const NSTimeInterval kTestTimeout = 16; request.responseSize = kSimpleDataLength; request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kUnaryCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = GRPCTransportTypeInsecure; options.compressionAlgorithm = GRPCCompressGzip; GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler: [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(NSData *data) { - NSError *error; - RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:data error:&error]; - XCTAssertNil(error, @"Error when parsing response: %@", error); - XCTAssertEqual(response.payload.body.length, kSimpleDataLength); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error, @"Received failure: %@", error); - [completion fulfill]; - }] - - callOptions:options]; + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + NSError *error; + RMTSimpleResponse *response = + [RMTSimpleResponse parseFromData:data error:&error]; + XCTAssertNil(error, @"Error when parsing response: %@", error); + XCTAssertEqual(response.payload.body.length, kSimpleDataLength); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Received failure: %@", error); + [completion fulfill]; + }] + + callOptions:options]; [call start]; [call writeData:[request data]]; From 9e5d7476ac48b82ee8ce7855c30d3aa5edab5280 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 7 Nov 2018 11:32:12 -0800 Subject: [PATCH 171/534] nit build fix --- src/objective-c/GRPCClient/GRPCCallOptions.m | 4 ++-- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 3e0dbbf7e42..ecb517762b3 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -17,7 +17,7 @@ */ #import "GRPCCallOptions.h" -#import "internal/GRPCCallOptions+internal.h" +#import "internal/GRPCCallOptions+Internal.h" // The default values for the call options. static NSString *const kDefaultServerAuthority = nil; @@ -77,7 +77,7 @@ BOOL areObjectsEqual(id obj1, id obj2) { NSString *_PEMCertChain; GRPCTransportType _transportType; NSString *_hostNameOverride; - id _logContext; + id _logContext; NSString *_channelPoolDomain; NSUInteger _channelID; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 627bbab3c01..b4a589ae838 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -18,7 +18,7 @@ #import -#import "../internal/GRPCCallOptions+internal.h" +#import "../internal/GRPCCallOptions+Internal.h" #import "GRPCChannel.h" #import "GRPCChannelFactory.h" #import "GRPCChannelPool.h" diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 8a59bd43d74..a67162c1014 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -25,7 +25,7 @@ #include #include -#import "../internal/GRPCCallOptions+internal.h" +#import "../internal/GRPCCallOptions+Internal.h" #import "GRPCChannelFactory.h" #import "GRPCCompletionQueue.h" #import "GRPCConnectivityMonitor.h" From c9c060c52da12cc55bbd383b1544260ad665dbab Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 7 Nov 2018 11:32:30 -0800 Subject: [PATCH 172/534] nit fixes in ChannelArgsUtil --- src/objective-c/GRPCClient/private/ChannelArgsUtil.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index b8342a79e79..d9e44b557d1 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -31,7 +31,7 @@ static void *copy_pointer_arg(void *p) { static void destroy_pointer_arg(void *p) { // Decrease ref count to the object when destroying - CFRelease((CFTreeRef)p); + CFRelease((CFTypeRef)p); } static int cmp_pointer_arg(void *p, void *q) { return p == q; } @@ -52,7 +52,7 @@ void GRPCFreeChannelArgs(grpc_channel_args *channel_args) { } grpc_channel_args *GRPCBuildChannelArgs(NSDictionary *dictionary) { - if (!dictionary) { + if (dictionary.count == 0) { return NULL; } From d72d5b2c8eaa8a434a7db4624fe6a45bc0d6bde4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 8 Nov 2018 15:33:27 -0800 Subject: [PATCH 173/534] Some nit fixes --- src/objective-c/GRPCClient/GRPCCall.m | 4 +++- .../GRPCClient/private/GRPCChannel.m | 21 +++++++++++-------- .../GRPCClient/private/GRPCChannelPool.h | 2 -- .../GRPCClient/private/GRPCChannelPool.m | 1 + 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 321a0bd1bd7..9b9b4f95471 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -108,6 +108,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; /** Flags whether call has been canceled. */ BOOL _canceled; /** Flags whether call has been finished. */ + BOOL _finished; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -144,6 +145,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); _started = NO; _canceled = NO; + _finished = YES; } return self; @@ -252,7 +254,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)finish { dispatch_async(_dispatchQueue, ^{ - NSAssert(self->started, @"Call not started."); + NSAssert(self->_started, @"Call not started."); NSAssert(!self->_canceled, @"Call arleady canceled."); NSAssert(!self->_finished, @"Call already half-closed."); if (self->_call) { diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 0ca2a359926..773f4261d75 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -53,7 +53,7 @@ static GRPCChannelPool *gChannelPool; /** Reduce call ref count to the channel and maybe set the timer. */ - (void)unrefChannel; -/** Disconnect the channel immediately. */ +/** Disconnect the channel. Any further ref/unref are discarded. */ - (void)disconnect; @end @@ -67,9 +67,8 @@ static GRPCChannelPool *gChannelPool; dispatch_queue_t _dispatchQueue; /** - * Date and time when last timer is scheduled. When a timer is fired, if - * _lastDispatch + _destroyDelay < now, it can be determined that another timer is scheduled after - * schedule of the current timer, hence the current one should be discarded. + * Date and time when last timer is scheduled. If a firing timer's scheduled date is different + * from this, it is discarded. */ NSDate *_lastDispatch; } @@ -113,7 +112,7 @@ static GRPCChannelPool *gChannelPool; dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); dispatch_after(delay, self->_dispatchQueue, ^{ - [self timerFireWithScheduleDate:now]; + [self timedDisconnectWithScheduleDate:now]; }); } } @@ -131,7 +130,7 @@ static GRPCChannelPool *gChannelPool; }); } -- (void)timerFireWithScheduleDate:(NSDate *)scheduleDate { +- (void)timedDisconnectWithScheduleDate:(NSDate *)scheduleDate { dispatch_async(_dispatchQueue, ^{ if (self->_disconnected || self->_lastDispatch != scheduleDate) { return; @@ -183,6 +182,8 @@ static GRPCChannelPool *gChannelPool; grpc_slice_unref(host_slice); } grpc_slice_unref(path_slice); + } else { + NSAssert(self->_unmanagedChannel != nil, @"Invalid channeg."); } }); return call; @@ -255,10 +256,9 @@ static GRPCChannelPool *gChannelPool; } + (nullable instancetype)createChannelWithConfiguration:(GRPCChannelConfiguration *)config { + NSAssert(config != nil, @"configuration cannot be empty"); NSString *host = config.host; - if (host.length == 0) { - return nil; - } + NSAssert(host.length != 0, @"host cannot be nil"); NSDictionary *channelArgs; if (config.callOptions.additionalChannelArgs.count != 0) { @@ -287,6 +287,9 @@ static GRPCChannelPool *gChannelPool; GRPCChannelConfiguration *channelConfig = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; + if (channelConfig == nil) { + return nil; + } return [gChannelPool channelWithConfiguration:channelConfig]; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 2244361df2c..f99c0ba4dc2 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -57,8 +57,6 @@ NS_ASSUME_NONNULL_BEGIN */ @interface GRPCChannelPool : NSObject -- (instancetype)init; - /** * Return a channel with a particular configuration. If the channel does not exist, execute \a * createChannel then add it in the pool. If the channel exists, increase its reference count. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index b4a589ae838..1bf2a5c5633 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -192,6 +192,7 @@ extern const char *kCFStreamVarName; } - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration { + NSAssert(configuration != nil, @"Must has a configuration"); GRPCChannel *channel; @synchronized(self) { if ([_channelPool objectForKey:configuration]) { From 37dbad80d5254f9bf17076d12b22b7a081e6e9dc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 8 Nov 2018 22:01:10 -0800 Subject: [PATCH 174/534] Refactor channel pool --- .../GRPCClient/GRPCCall+ChannelArg.m | 4 +- .../GRPCClient/private/GRPCChannel.h | 69 ++- .../GRPCClient/private/GRPCChannel.m | 397 ++++++++++-------- .../GRPCClient/private/GRPCChannelPool.h | 55 ++- .../GRPCClient/private/GRPCChannelPool.m | 215 ++-------- .../GRPCClient/private/GRPCWrappedCall.m | 24 +- .../tests/ChannelTests/ChannelPoolTest.m | 161 +++---- .../tests/ChannelTests/ChannelTests.m | 97 ++--- 8 files changed, 482 insertions(+), 540 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index d01d0c0d4fd..971c2803e29 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -18,7 +18,7 @@ #import "GRPCCall+ChannelArg.h" -#import "private/GRPCChannel.h" +#import "private/GRPCChannelPool.h" #import "private/GRPCHost.h" #import @@ -36,7 +36,7 @@ } + (void)closeOpenConnections { - [GRPCChannel closeOpenConnections]; + [GRPCChannelPool closeOpenConnections]; } + (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host { diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index e1bf8fb1af4..bbe0ba53904 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -20,11 +20,37 @@ #include +@protocol GRPCChannelFactory; + @class GRPCCompletionQueue; @class GRPCCallOptions; @class GRPCChannelConfiguration; struct grpc_channel_credentials; +NS_ASSUME_NONNULL_BEGIN + +/** Caching signature of a channel. */ +@interface GRPCChannelConfiguration : NSObject + +/** The host that this channel is connected to. */ +@property(copy, readonly) NSString *host; + +/** + * Options of the corresponding call. Note that only the channel-related options are of interest to + * this class. + */ +@property(strong, readonly) GRPCCallOptions *callOptions; + +/** Acquire the factory to generate a new channel with current configurations. */ +@property(readonly) id channelFactory; + +/** Acquire the dictionary of channel args with current configurations. */ +@property(copy, readonly) NSDictionary *channelArgs; + +- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; + +@end + /** * Each separate instance of this class represents at least one TCP connection to the provided host. */ @@ -35,40 +61,45 @@ struct grpc_channel_credentials; + (nullable instancetype) new NS_UNAVAILABLE; /** - * Returns a channel connecting to \a host with options as \a callOptions. The channel may be new - * or a cached channel that is already connected. + * Create a channel with remote \a host and signature \a channelConfigurations. Destroy delay is + * defaulted to 30 seconds. */ -+ (nullable instancetype)channelWithHost:(nonnull NSString *)host - callOptions:(nullable GRPCCallOptions *)callOptions; +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration; /** - * Create a channel object with the signature \a config. + * Create a channel with remote \a host, signature \a channelConfigurations, and destroy delay of + * \a destroyDelay. */ -+ (nullable instancetype)createChannelWithConfiguration:(nonnull GRPCChannelConfiguration *)config; +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay NS_DESIGNATED_INITIALIZER; /** - * Get a grpc core call object from this channel. + * Create a grpc core call object from this channel. The channel's refcount is added by 1. If no + * call is created, NULL is returned, and if the reason is because the channel is already + * disconnected, \a disconnected is set to YES. When the returned call is unreffed, the caller is + * obligated to call \a unref method once. \a disconnected may be null. */ -- (nullable grpc_call *)unmanagedCallWithPath:(nonnull NSString *)path - completionQueue:(nonnull GRPCCompletionQueue *)queue - callOptions:(nonnull GRPCCallOptions *)callOptions; +- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions + disconnected:(BOOL * _Nullable)disconnected; /** - * Increase the refcount of the channel. If the channel was timed to be destroyed, cancel the timer. + * Unref the channel when a call is done. It also decreases the channel's refcount. If the refcount + * of the channel decreases to 0, the channel is destroyed after the destroy delay. */ -- (void)ref; +- (void)unref; /** - * Decrease the refcount of the channel. If the refcount of the channel decrease to 0, the channel - * is destroyed after 30 seconds. + * Force the channel to be disconnected and destroyed. */ -- (void)unref; +- (void)disconnect; /** - * Force the channel to be disconnected and destroyed immediately. + * Return whether the channel is already disconnected. */ -- (void)disconnect; +@property(readonly) BOOL disconnected; -// TODO (mxyan): deprecate with GRPCCall:closeOpenConnections -+ (void)closeOpenConnections; @end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 773f4261d75..298b6605d1f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -28,141 +28,222 @@ #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "version.h" +#import "../internal/GRPCCallOptions+Internal.h" #import #import /** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ -NSTimeInterval kChannelDestroyDelay = 30; +NSTimeInterval kDefaultChannelDestroyDelay = 30; -/** Global instance of channel pool. */ -static GRPCChannelPool *gChannelPool; +@implementation GRPCChannelConfiguration -/** - * Time the channel destroy when the channel's calls are unreffed. If there's new call, reset the - * timer. - */ -@interface GRPCChannelRef : NSObject +- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { + NSAssert(host.length, @"Host must not be empty."); + NSAssert(callOptions, @"callOptions must not be empty."); + if ((self = [super init])) { + _host = [host copy]; + _callOptions = [callOptions copy]; + } + return self; +} -- (instancetype)initWithDestroyDelay:(NSTimeInterval)destroyDelay - destroyChannelCallback:(void (^)())destroyChannelCallback; +- (id)channelFactory { + NSError *error; + id factory; + GRPCTransportType type = _callOptions.transportType; + switch (type) { + case GRPCTransportTypeChttp2BoringSSL: + // TODO (mxyan): Remove when the API is deprecated +#ifdef GRPC_COMPILE_WITH_CRONET + if (![GRPCCall isUsingCronet]) { +#endif + factory = [GRPCSecureChannelFactory + factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates + privateKey:_callOptions.PEMPrivateKey + certChain:_callOptions.PEMCertChain + error:&error]; + if (factory == nil) { + NSLog(@"Error creating secure channel factory: %@", error); + } + return factory; +#ifdef GRPC_COMPILE_WITH_CRONET + } +#endif + // fallthrough + case GRPCTransportTypeCronet: + return [GRPCCronetChannelFactory sharedInstance]; + case GRPCTransportTypeInsecure: + return [GRPCInsecureChannelFactory sharedInstance]; + } +} -/** Add call ref count to the channel and maybe reset the timer. */ -- (void)refChannel; +- (NSDictionary *)channelArgs { + NSMutableDictionary *args = [NSMutableDictionary new]; -/** Reduce call ref count to the channel and maybe set the timer. */ -- (void)unrefChannel; + NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; + NSString *userAgentPrefix = _callOptions.userAgentPrefix; + if (userAgentPrefix) { + args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = + [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; + } else { + args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = userAgent; + } -/** Disconnect the channel. Any further ref/unref are discarded. */ -- (void)disconnect; + NSString *hostNameOverride = _callOptions.hostNameOverride; + if (hostNameOverride) { + args[@GRPC_SSL_TARGET_NAME_OVERRIDE_ARG] = hostNameOverride; + } -@end + if (_callOptions.responseSizeLimit) { + args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = + [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; + } -@implementation GRPCChannelRef { - NSTimeInterval _destroyDelay; - void (^_destroyChannelCallback)(); + if (_callOptions.compressionAlgorithm != GRPC_COMPRESS_NONE) { + args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = + [NSNumber numberWithInt:_callOptions.compressionAlgorithm]; + } - NSUInteger _refCount; - BOOL _disconnected; - dispatch_queue_t _dispatchQueue; + if (_callOptions.keepaliveInterval != 0) { + args[@GRPC_ARG_KEEPALIVE_TIME_MS] = + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; + args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; + } - /** - * Date and time when last timer is scheduled. If a firing timer's scheduled date is different - * from this, it is discarded. - */ - NSDate *_lastDispatch; -} + if (_callOptions.retryEnabled == NO) { + args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.retryEnabled]; + } -- (instancetype)initWithDestroyDelay:(NSTimeInterval)destroyDelay - destroyChannelCallback:(void (^)())destroyChannelCallback { - if ((self = [super init])) { - _destroyDelay = destroyDelay; - _destroyChannelCallback = destroyChannelCallback; + if (_callOptions.connectMinTimeout > 0) { + args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMinTimeout * 1000)]; + } + if (_callOptions.connectInitialBackoff > 0) { + args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber + numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectInitialBackoff * 1000)]; + } + if (_callOptions.connectMaxBackoff > 0) { + args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMaxBackoff * 1000)]; + } - _refCount = 1; - _disconnected = NO; - if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); - } else { - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } - _lastDispatch = nil; + if (_callOptions.logContext != nil) { + args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = _callOptions.logContext; } - return self; -} -- (void)refChannel { - dispatch_async(_dispatchQueue, ^{ - if (!self->_disconnected) { - self->_refCount++; - self->_lastDispatch = nil; - } - }); + if (_callOptions.channelPoolDomain.length != 0) { + args[@GRPC_ARG_CHANNEL_POOL_DOMAIN] = _callOptions.channelPoolDomain; + } + + [args addEntriesFromDictionary:_callOptions.additionalChannelArgs]; + + return args; } -- (void)unrefChannel { - dispatch_async(_dispatchQueue, ^{ - if (!self->_disconnected) { - self->_refCount--; - if (self->_refCount == 0) { - NSDate *now = [NSDate date]; - self->_lastDispatch = now; - dispatch_time_t delay = - dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); - dispatch_after(delay, self->_dispatchQueue, ^{ - [self timedDisconnectWithScheduleDate:now]; - }); - } - } - }); +- (nonnull id)copyWithZone:(nullable NSZone *)zone { + GRPCChannelConfiguration *newConfig = + [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; + + return newConfig; } -- (void)disconnect { - dispatch_async(_dispatchQueue, ^{ - if (!self->_disconnected) { - self->_lastDispatch = nil; - self->_disconnected = YES; - // Break retain loop - self->_destroyChannelCallback = nil; - } - }); +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[GRPCChannelConfiguration class]]) { + return NO; + } + GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; + if (!(obj.host == _host || (_host != nil && [obj.host isEqualToString:_host]))) return NO; + if (!(obj.callOptions == _callOptions || [obj.callOptions hasChannelOptionsEqualTo:_callOptions])) + return NO; + + return YES; } -- (void)timedDisconnectWithScheduleDate:(NSDate *)scheduleDate { - dispatch_async(_dispatchQueue, ^{ - if (self->_disconnected || self->_lastDispatch != scheduleDate) { - return; - } - self->_lastDispatch = nil; - self->_disconnected = YES; - self->_destroyChannelCallback(); - // Break retain loop - self->_destroyChannelCallback = nil; - }); +- (NSUInteger)hash { + NSUInteger result = 0; + result ^= _host.hash; + result ^= _callOptions.channelOptionsHash; + + return result; } @end + + @implementation GRPCChannel { GRPCChannelConfiguration *_configuration; - grpc_channel *_unmanagedChannel; - GRPCChannelRef *_channelRef; + dispatch_queue_t _dispatchQueue; + grpc_channel *_unmanagedChannel; + NSTimeInterval _destroyDelay; + + NSUInteger _refcount; + NSDate *_lastDispatch; +} +@synthesize disconnected = _disconnected; + +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { + return [self initWithChannelConfiguration:channelConfiguration + destroyDelay:kDefaultChannelDestroyDelay]; +} + +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay { + NSAssert(channelConfiguration, @"channelConfiguration must not be empty."); + NSAssert(destroyDelay > 0, @"destroyDelay must be greater than 0."); + if ((self = [super init])) { + _configuration = [channelConfiguration copy]; + if (@available(iOS 8.0, *)) { + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + } else { + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + + // Create gRPC core channel object. + NSString *host = channelConfiguration.host; + NSAssert(host.length != 0, @"host cannot be nil"); + NSDictionary *channelArgs; + if (channelConfiguration.callOptions.additionalChannelArgs.count != 0) { + NSMutableDictionary *args = [channelConfiguration.channelArgs mutableCopy]; + [args addEntriesFromDictionary:channelConfiguration.callOptions.additionalChannelArgs]; + channelArgs = args; + } else { + channelArgs = channelConfiguration.channelArgs; + } + id factory = channelConfiguration.channelFactory; + _unmanagedChannel = [factory createChannelWithHost:host channelArgs:channelArgs]; + if (_unmanagedChannel == NULL) { + NSLog(@"Unable to create channel."); + return nil; + } + _destroyDelay = destroyDelay; + _disconnected = NO; + } + return self; } - (grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions { + callOptions:(GRPCCallOptions *)callOptions + disconnected:(BOOL *)disconnected { NSAssert(path.length, @"path must not be empty."); NSAssert(queue, @"completionQueue must not be empty."); NSAssert(callOptions, @"callOptions must not be empty."); - __block grpc_call *call = nil; + __block BOOL isDisconnected = NO; + __block grpc_call *call = NULL; dispatch_sync(_dispatchQueue, ^{ - if (self->_unmanagedChannel) { + if (self->_disconnected) { + isDisconnected = YES; + } else { + NSAssert(self->_unmanagedChannel != NULL, @"Invalid channel."); + NSString *serverAuthority = - callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); grpc_slice host_slice = grpc_empty_slice(); @@ -171,10 +252,10 @@ static GRPCChannelPool *gChannelPool; } 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_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + 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)); call = grpc_channel_create_call(self->_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, serverAuthority ? &host_slice : NULL, deadline_ms, NULL); @@ -182,71 +263,64 @@ static GRPCChannelPool *gChannelPool; grpc_slice_unref(host_slice); } grpc_slice_unref(path_slice); - } else { - NSAssert(self->_unmanagedChannel != nil, @"Invalid channeg."); + if (call == NULL) { + NSLog(@"Unable to create call."); + } else { + // Ref the channel; + [self ref]; + } } }); + if (disconnected != nil) { + *disconnected = isDisconnected; + } return call; } +// This function should be called on _dispatchQueue. - (void)ref { - dispatch_async(_dispatchQueue, ^{ - if (self->_unmanagedChannel) { - [self->_channelRef refChannel]; - } - }); + _refcount++; + if (_refcount == 1 && _lastDispatch != nil) { + _lastDispatch = nil; + } } - (void)unref { dispatch_async(_dispatchQueue, ^{ - if (self->_unmanagedChannel) { - [self->_channelRef unrefChannel]; + self->_refcount--; + if (self->_refcount == 0 && !self->_disconnected) { + // Start timer. + dispatch_time_t delay = + dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); + NSDate *now = [NSDate date]; + self->_lastDispatch = now; + dispatch_after(delay, self->_dispatchQueue, ^{ + if (self->_lastDispatch == now) { + grpc_channel_destroy(self->_unmanagedChannel); + self->_unmanagedChannel = NULL; + self->_disconnected = YES; + } + }); } }); } - (void)disconnect { dispatch_async(_dispatchQueue, ^{ - if (self->_unmanagedChannel) { + if (!self->_disconnected) { grpc_channel_destroy(self->_unmanagedChannel); self->_unmanagedChannel = nil; - [self->_channelRef disconnect]; + self->_disconnected = YES; } }); } -- (void)destroyChannel { - dispatch_async(_dispatchQueue, ^{ - if (self->_unmanagedChannel) { - grpc_channel_destroy(self->_unmanagedChannel); - self->_unmanagedChannel = nil; - [gChannelPool removeChannel:self]; - } +- (BOOL)disconnected { + __block BOOL disconnected; + dispatch_sync(_dispatchQueue, ^{ + disconnected = self->_disconnected; }); -} - -- (nullable instancetype)initWithUnmanagedChannel:(grpc_channel *_Nullable)unmanagedChannel - configuration:(GRPCChannelConfiguration *)configuration { - NSAssert(configuration, @"Configuration must not be empty."); - if (!unmanagedChannel) { - return nil; - } - if ((self = [super init])) { - _unmanagedChannel = unmanagedChannel; - _configuration = [configuration copy]; - _channelRef = [[GRPCChannelRef alloc] initWithDestroyDelay:kChannelDestroyDelay - destroyChannelCallback:^{ - [self destroyChannel]; - }]; - if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); - } else { - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } - } - return self; + return disconnected; } - (void)dealloc { @@ -255,47 +329,4 @@ static GRPCChannelPool *gChannelPool; } } -+ (nullable instancetype)createChannelWithConfiguration:(GRPCChannelConfiguration *)config { - NSAssert(config != nil, @"configuration cannot be empty"); - NSString *host = config.host; - NSAssert(host.length != 0, @"host cannot be nil"); - - NSDictionary *channelArgs; - if (config.callOptions.additionalChannelArgs.count != 0) { - NSMutableDictionary *args = [config.channelArgs mutableCopy]; - [args addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; - channelArgs = args; - } else { - channelArgs = config.channelArgs; - } - id factory = config.channelFactory; - grpc_channel *unmanaged_channel = [factory createChannelWithHost:host channelArgs:channelArgs]; - return [[GRPCChannel alloc] initWithUnmanagedChannel:unmanaged_channel configuration:config]; -} - -+ (nullable instancetype)channelWithHost:(NSString *)host - callOptions:(GRPCCallOptions *)callOptions { - static dispatch_once_t initChannelPool; - dispatch_once(&initChannelPool, ^{ - gChannelPool = [[GRPCChannelPool alloc] init]; - }); - - NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:host]]; - if (hostURL.host && !hostURL.port) { - host = [hostURL.host stringByAppendingString:@":443"]; - } - - GRPCChannelConfiguration *channelConfig = - [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; - if (channelConfig == nil) { - return nil; - } - - return [gChannelPool channelWithConfiguration:channelConfig]; -} - -+ (void)closeOpenConnections { - [gChannelPool removeAndCloseAllChannels]; -} - @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index f99c0ba4dc2..24c0a8df115 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -29,48 +29,45 @@ NS_ASSUME_NONNULL_BEGIN @class GRPCChannel; -/** Caching signature of a channel. */ -@interface GRPCChannelConfiguration : NSObject - -/** The host that this channel is connected to. */ -@property(copy, readonly) NSString *host; - -/** - * Options of the corresponding call. Note that only the channel-related options are of interest to - * this class. - */ -@property(strong, readonly) GRPCCallOptions *callOptions; - -/** Acquire the factory to generate a new channel with current configurations. */ -@property(readonly) id channelFactory; - -/** Acquire the dictionary of channel args with current configurations. */ -@property(copy, readonly) NSDictionary *channelArgs; - -- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; - -@end - /** * Manage the pool of connected channels. When a channel is no longer referenced by any call, * destroy the channel after a certain period of time elapsed. */ @interface GRPCChannelPool : NSObject +/** + * Get the singleton instance + */ ++ (nullable instancetype)sharedInstance; + /** * Return a channel with a particular configuration. If the channel does not exist, execute \a * createChannel then add it in the pool. If the channel exists, increase its reference count. */ -- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration; +- (GRPCChannel *)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions; + +/** + * This method is deprecated. + * + * Destroy all open channels and close their connections. + */ ++ (void)closeOpenConnections; -/** Remove a channel from the pool. */ -- (void)removeChannel:(GRPCChannel *)channel; +// Test-only methods below -/** Clear all channels in the pool. */ -- (void)removeAllChannels; +/** + * Return a channel with a special destroy delay. If \a destroyDelay is 0, use the default destroy + * delay. + */ +- (GRPCChannel *)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions + destroyDelay:(NSTimeInterval)destroyDelay; -/** Clear all channels in the pool and destroy the channels. */ -- (void)removeAndCloseAllChannels; +/** + * Simulate a network transition event and destroy all channels. + */ +- (void)destroyAllChannels; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 1bf2a5c5633..98c1634bc8b 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -33,147 +33,23 @@ extern const char *kCFStreamVarName; -@implementation GRPCChannelConfiguration - -- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { - NSAssert(host.length, @"Host must not be empty."); - NSAssert(callOptions, @"callOptions must not be empty."); - if ((self = [super init])) { - _host = [host copy]; - _callOptions = [callOptions copy]; - } - return self; -} - -- (id)channelFactory { - NSError *error; - id factory; - GRPCTransportType type = _callOptions.transportType; - switch (type) { - case GRPCTransportTypeChttp2BoringSSL: - // TODO (mxyan): Remove when the API is deprecated -#ifdef GRPC_COMPILE_WITH_CRONET - if (![GRPCCall isUsingCronet]) { -#endif - factory = [GRPCSecureChannelFactory - factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates - privateKey:_callOptions.PEMPrivateKey - certChain:_callOptions.PEMCertChain - error:&error]; - if (factory == nil) { - NSLog(@"Error creating secure channel factory: %@", error); - } - return factory; -#ifdef GRPC_COMPILE_WITH_CRONET - } -#endif - // fallthrough - case GRPCTransportTypeCronet: - return [GRPCCronetChannelFactory sharedInstance]; - case GRPCTransportTypeInsecure: - return [GRPCInsecureChannelFactory sharedInstance]; - } -} - -- (NSDictionary *)channelArgs { - NSMutableDictionary *args = [NSMutableDictionary new]; - - NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; - NSString *userAgentPrefix = _callOptions.userAgentPrefix; - if (userAgentPrefix) { - args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = - [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; - } else { - args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = userAgent; - } - - NSString *hostNameOverride = _callOptions.hostNameOverride; - if (hostNameOverride) { - args[@GRPC_SSL_TARGET_NAME_OVERRIDE_ARG] = hostNameOverride; - } - - if (_callOptions.responseSizeLimit) { - args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = - [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; - } - - if (_callOptions.compressionAlgorithm != GRPC_COMPRESS_NONE) { - args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = - [NSNumber numberWithInt:_callOptions.compressionAlgorithm]; - } - - if (_callOptions.keepaliveInterval != 0) { - args[@GRPC_ARG_KEEPALIVE_TIME_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; - args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; - } - - if (_callOptions.retryEnabled == NO) { - args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.retryEnabled]; - } - - if (_callOptions.connectMinTimeout > 0) { - args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMinTimeout * 1000)]; - } - if (_callOptions.connectInitialBackoff > 0) { - args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber - numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectInitialBackoff * 1000)]; - } - if (_callOptions.connectMaxBackoff > 0) { - args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMaxBackoff * 1000)]; - } - - if (_callOptions.logContext != nil) { - args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = _callOptions.logContext; - } - - if (_callOptions.channelPoolDomain.length != 0) { - args[@GRPC_ARG_CHANNEL_POOL_DOMAIN] = _callOptions.channelPoolDomain; - } - - [args addEntriesFromDictionary:_callOptions.additionalChannelArgs]; - - return args; -} - -- (nonnull id)copyWithZone:(nullable NSZone *)zone { - GRPCChannelConfiguration *newConfig = - [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; - - return newConfig; -} - -- (BOOL)isEqual:(id)object { - if (![object isKindOfClass:[GRPCChannelConfiguration class]]) { - return NO; - } - GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; - if (!(obj.host == _host || (_host != nil && [obj.host isEqualToString:_host]))) return NO; - if (!(obj.callOptions == _callOptions || [obj.callOptions hasChannelOptionsEqualTo:_callOptions])) - return NO; - - return YES; -} - -- (NSUInteger)hash { - NSUInteger result = 0; - result ^= _host.hash; - result ^= _callOptions.channelOptionsHash; - - return result; -} - -@end - -#pragma mark GRPCChannelPool +static GRPCChannelPool *gChannelPool; +static dispatch_once_t gInitChannelPool; @implementation GRPCChannelPool { NSMutableDictionary *_channelPool; } ++ (nullable instancetype)sharedInstance { + dispatch_once(&gInitChannelPool, ^{ + gChannelPool = [[GRPCChannelPool alloc] init]; + if (gChannelPool == nil) { + [NSException raise:NSMallocException format:@"Cannot initialize global channel pool."]; + } + }); + return gChannelPool; +} + - (instancetype)init { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; @@ -187,61 +63,56 @@ extern const char *kCFStreamVarName; return self; } -- (void)dealloc { - [GRPCConnectivityMonitor unregisterObserver:self]; +- (GRPCChannel *)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions { + return [self channelWithHost:host + callOptions:callOptions + destroyDelay:0]; } -- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration { - NSAssert(configuration != nil, @"Must has a configuration"); +- (GRPCChannel *)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions + destroyDelay:(NSTimeInterval)destroyDelay { + NSAssert(host.length > 0, @"Host must not be empty."); + NSAssert(callOptions != nil, @"callOptions must not be empty."); GRPCChannel *channel; + GRPCChannelConfiguration *configuration = + [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; @synchronized(self) { - if ([_channelPool objectForKey:configuration]) { - channel = _channelPool[configuration]; - [channel ref]; - } else { - channel = [GRPCChannel createChannelWithConfiguration:configuration]; - if (channel != nil) { - _channelPool[configuration] = channel; + channel = _channelPool[configuration]; + if (channel == nil || channel.disconnected) { + if (destroyDelay == 0) { + channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration]; + } else { + channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:destroyDelay]; } + _channelPool[configuration] = channel; } } return channel; } -- (void)removeChannel:(GRPCChannel *)channel { - @synchronized(self) { - __block GRPCChannelConfiguration *keyToDelete = nil; - [_channelPool - enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, - GRPCChannel *_Nonnull obj, BOOL *_Nonnull stop) { - if (obj == channel) { - keyToDelete = key; - *stop = YES; - } - }]; - [self->_channelPool removeObjectForKey:keyToDelete]; - } -} -- (void)removeAllChannels { - @synchronized(self) { - _channelPool = [NSMutableDictionary dictionary]; - } + ++ (void)closeOpenConnections { + [[GRPCChannelPool sharedInstance] destroyAllChannels]; } -- (void)removeAndCloseAllChannels { +- (void)destroyAllChannels { @synchronized(self) { - [_channelPool - enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, - GRPCChannel *_Nonnull obj, BOOL *_Nonnull stop) { - [obj disconnect]; - }]; + for (id key in _channelPool) { + [_channelPool[key] disconnect]; + } _channelPool = [NSMutableDictionary dictionary]; } } - (void)connectivityChange:(NSNotification *)note { - [self removeAndCloseAllChannels]; + [self destroyAllChannels]; +} + +- (void)dealloc { + [GRPCConnectivityMonitor unregisterObserver:self]; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 577002e7a85..2358c7bb0a8 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -24,6 +24,7 @@ #include #import "GRPCChannel.h" +#import "GRPCChannelPool.h" #import "GRPCCompletionQueue.h" #import "GRPCHost.h" #import "NSData+GRPC.h" @@ -256,13 +257,21 @@ // consuming too many threads and having contention of multiple calls in a single completion // queue. Currently we use a singleton queue. _queue = [GRPCCompletionQueue completionQueue]; - _channel = [GRPCChannel channelWithHost:host callOptions:callOptions]; - if (_channel == nil) { - NSLog(@"Failed to get a channel for the host."); - return nil; - } - _call = [_channel unmanagedCallWithPath:path completionQueue:_queue callOptions:callOptions]; - if (_call == NULL) { + BOOL disconnected; + do { + _channel = [[GRPCChannelPool sharedInstance] channelWithHost:host callOptions:callOptions]; + if (_channel == nil) { + NSLog(@"Failed to get a channel for the host."); + return nil; + } + _call = [_channel unmanagedCallWithPath:path + completionQueue:_queue + callOptions:callOptions + disconnected:&disconnected]; + // Try create another channel if the current channel is disconnected (due to idleness or + // connectivity monitor disconnection). + } while (_call == NULL && disconnected); + if (_call == nil) { NSLog(@"Failed to create a call."); return nil; } @@ -317,6 +326,7 @@ - (void)dealloc { if (_call) { grpc_call_unref(_call); + [_channel unref]; } [_channel unref]; _channel = nil; diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index 5c3f0edba0b..d684db545e9 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -20,6 +20,7 @@ #import "../../GRPCClient/private/GRPCChannel.h" #import "../../GRPCClient/private/GRPCChannelPool.h" +#import "../../GRPCClient/private/GRPCCompletionQueue.h" #define TEST_TIMEOUT 32 @@ -35,92 +36,104 @@ NSString *kDummyHost = @"dummy.host"; grpc_init(); } -- (void)testCreateChannel { +- (void)testChannelPooling { NSString *kDummyHost = @"dummy.host"; + NSString *kDummyHost2 = @"dummy.host2"; + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeInsecure; GRPCCallOptions *options2 = [options1 copy]; - GRPCChannelConfiguration *config1 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelConfiguration *config2 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - - GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; + GRPCMutableCallOptions *options3 = [options2 mutableCopy]; + options3.transportType = GRPCTransportTypeInsecure; + + GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; + + GRPCChannel *channel1 = [pool channelWithHost:kDummyHost + callOptions:options1]; + GRPCChannel *channel2 = [pool channelWithHost:kDummyHost + callOptions:options2]; + GRPCChannel *channel3 = [pool channelWithHost:kDummyHost2 + callOptions:options1]; + GRPCChannel *channel4 = [pool channelWithHost:kDummyHost + callOptions:options3]; XCTAssertEqual(channel1, channel2); + XCTAssertNotEqual(channel1, channel3); + XCTAssertNotEqual(channel1, channel4); + XCTAssertNotEqual(channel3, channel4); } -- (void)testChannelRemove { - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeInsecure; - GRPCChannelConfiguration *config1 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - [pool removeChannel:channel1]; - GRPCChannel *channel2 = [pool channelWithConfiguration:config1]; - XCTAssertNotEqual(channel1, channel2); -} - -extern NSTimeInterval kChannelDestroyDelay; +- (void)testDestroyAllChannels { + NSString *kDummyHost = @"dummy.host"; -- (void)testChannelTimeoutCancel { - NSTimeInterval kOriginalInterval = kChannelDestroyDelay; - kChannelDestroyDelay = 3.0; - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeInsecure; - GRPCChannelConfiguration *config1 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - [channel1 unref]; - sleep(1); - GRPCChannel *channel2 = [pool channelWithConfiguration:config1]; - XCTAssertEqual(channel1, channel2); - sleep((int)kChannelDestroyDelay + 2); - GRPCChannel *channel3 = [pool channelWithConfiguration:config1]; - XCTAssertEqual(channel1, channel3); - kChannelDestroyDelay = kOriginalInterval; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; + GRPCChannel *channel = [pool channelWithHost:kDummyHost + callOptions:options]; + grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:nil]; + [pool destroyAllChannels]; + XCTAssertTrue(channel.disconnected); + GRPCChannel *channel2 = [pool channelWithHost:kDummyHost + callOptions:options]; + XCTAssertNotEqual(channel, channel2); + grpc_call_unref(call); } -- (void)testChannelDisconnect { +- (void)testGetChannelBeforeChannelTimedDisconnection { NSString *kDummyHost = @"dummy.host"; - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeInsecure; - GRPCCallOptions *options2 = [options1 copy]; - GRPCChannelConfiguration *config1 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelConfiguration *config2 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - - GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - [pool removeAndCloseAllChannels]; - GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; - XCTAssertNotEqual(channel1, channel2); + const NSTimeInterval kDestroyDelay = 1; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; + GRPCChannel *channel = [pool channelWithHost:kDummyHost + callOptions:options + destroyDelay:kDestroyDelay]; + grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:nil]; + grpc_call_unref(call); + [channel unref]; + + // Test that we can still get the channel at this time + GRPCChannel *channel2 = [pool channelWithHost:kDummyHost + callOptions:options + destroyDelay:kDestroyDelay]; + XCTAssertEqual(channel, channel2); + call = [channel2 unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:nil]; + + // Test that after the destroy delay, the channel is still alive + sleep(kDestroyDelay + 1); + XCTAssertFalse(channel.disconnected); } -- (void)testClearChannels { - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeInsecure; - GRPCMutableCallOptions *options2 = [[GRPCMutableCallOptions alloc] init]; - options2.transportType = GRPCTransportTypeChttp2BoringSSL; - GRPCChannelConfiguration *config1 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelConfiguration *config2 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - - GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; - XCTAssertNotEqual(channel1, channel2); - - [pool removeAndCloseAllChannels]; - GRPCChannel *channel3 = [pool channelWithConfiguration:config1]; - GRPCChannel *channel4 = [pool channelWithConfiguration:config2]; - XCTAssertNotEqual(channel1, channel3); - XCTAssertNotEqual(channel2, channel4); +- (void)testGetChannelAfterChannelTimedDisconnection { + NSString *kDummyHost = @"dummy.host"; + const NSTimeInterval kDestroyDelay = 1; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; + GRPCChannel *channel = [pool channelWithHost:kDummyHost + callOptions:options + destroyDelay:kDestroyDelay]; + grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:nil]; + grpc_call_unref(call); + [channel unref]; + + sleep(kDestroyDelay + 1); + + // Test that we get new channel to the same host and with the same callOptions + GRPCChannel *channel2 = [pool channelWithHost:kDummyHost + callOptions:options + destroyDelay:kDestroyDelay]; + XCTAssertNotEqual(channel, channel2); } @end diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 64c3356b13f..27e76d41799 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -20,6 +20,7 @@ #import "../../GRPCClient/GRPCCallOptions.h" #import "../../GRPCClient/private/GRPCChannel.h" +#import "../../GRPCClient/private/GRPCCompletionQueue.h" @interface ChannelTests : XCTestCase @@ -31,63 +32,51 @@ grpc_init(); } -- (void)testSameConfiguration { - NSString *host = @"grpc-test.sandbox.googleapis.com"; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.userAgentPrefix = @"TestUAPrefix"; - NSMutableDictionary *args = [NSMutableDictionary new]; - args[@"abc"] = @"xyz"; - options.additionalChannelArgs = [args copy]; - GRPCChannel *channel1 = [GRPCChannel channelWithHost:host callOptions:options]; - GRPCChannel *channel2 = [GRPCChannel channelWithHost:host callOptions:options]; - XCTAssertEqual(channel1, channel2); - GRPCMutableCallOptions *options2 = [options mutableCopy]; - options2.additionalChannelArgs = [args copy]; - GRPCChannel *channel3 = [GRPCChannel channelWithHost:host callOptions:options2]; - XCTAssertEqual(channel1, channel3); -} +- (void)testTimedDisconnection { + NSString * const kHost = @"grpc-test.sandbox.googleapis.com"; + const NSTimeInterval kDestroyDelay = 1; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; + GRPCChannel *channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration + destroyDelay:kDestroyDelay]; + BOOL disconnected; + grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:&disconnected]; + XCTAssertFalse(disconnected); + grpc_call_unref(call); + [channel unref]; + XCTAssertFalse(channel.disconnected, @"Channel is pre-maturely disconnected."); + sleep(kDestroyDelay + 1); + XCTAssertTrue(channel.disconnected, @"Channel is not disconnected after delay."); -- (void)testDifferentHost { - NSString *host1 = @"grpc-test.sandbox.googleapis.com"; - NSString *host2 = @"grpc-test2.sandbox.googleapis.com"; - NSString *host3 = @"http://grpc-test.sandbox.googleapis.com"; - NSString *host4 = @"dns://grpc-test.sandbox.googleapis.com"; - NSString *host5 = @"grpc-test.sandbox.googleapis.com:80"; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.userAgentPrefix = @"TestUAPrefix"; - NSMutableDictionary *args = [NSMutableDictionary new]; - args[@"abc"] = @"xyz"; - options.additionalChannelArgs = [args copy]; - GRPCChannel *channel1 = [GRPCChannel channelWithHost:host1 callOptions:options]; - GRPCChannel *channel2 = [GRPCChannel channelWithHost:host2 callOptions:options]; - GRPCChannel *channel3 = [GRPCChannel channelWithHost:host3 callOptions:options]; - GRPCChannel *channel4 = [GRPCChannel channelWithHost:host4 callOptions:options]; - GRPCChannel *channel5 = [GRPCChannel channelWithHost:host5 callOptions:options]; - XCTAssertNotEqual(channel1, channel2); - XCTAssertNotEqual(channel1, channel3); - XCTAssertNotEqual(channel1, channel4); - XCTAssertNotEqual(channel1, channel5); + // Check another call creation returns null and indicates disconnected. + call = [channel unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:&disconnected]; + XCTAssert(call == NULL); + XCTAssertTrue(disconnected); } -- (void)testDifferentChannelParameters { - NSString *host = @"grpc-test.sandbox.googleapis.com"; - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeChttp2BoringSSL; - NSMutableDictionary *args = [NSMutableDictionary new]; - args[@"abc"] = @"xyz"; - options1.additionalChannelArgs = [args copy]; - GRPCMutableCallOptions *options2 = [[GRPCMutableCallOptions alloc] init]; - options2.transportType = GRPCTransportTypeInsecure; - options2.additionalChannelArgs = [args copy]; - GRPCMutableCallOptions *options3 = [[GRPCMutableCallOptions alloc] init]; - options3.transportType = GRPCTransportTypeChttp2BoringSSL; - args[@"def"] = @"uvw"; - options3.additionalChannelArgs = [args copy]; - GRPCChannel *channel1 = [GRPCChannel channelWithHost:host callOptions:options1]; - GRPCChannel *channel2 = [GRPCChannel channelWithHost:host callOptions:options2]; - GRPCChannel *channel3 = [GRPCChannel channelWithHost:host callOptions:options3]; - XCTAssertNotEqual(channel1, channel2); - XCTAssertNotEqual(channel1, channel3); +- (void)testForceDisconnection { + NSString * const kHost = @"grpc-test.sandbox.googleapis.com"; + const NSTimeInterval kDestroyDelay = 1; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; + GRPCChannel *channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration + destroyDelay:kDestroyDelay]; + grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:nil]; + grpc_call_unref(call); + [channel disconnect]; + XCTAssertTrue(channel.disconnected, @"Channel is not disconnected."); + + // Test calling another unref here will not crash + [channel unref]; } @end From 861e7ce452866311ee2746d7b7a9fd1d11b84087 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 9 Nov 2018 07:51:38 -0800 Subject: [PATCH 175/534] nit fixes --- src/objective-c/GRPCClient/private/GRPCChannel.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 298b6605d1f..4f26b349b49 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -34,7 +34,7 @@ #import /** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ -NSTimeInterval kDefaultChannelDestroyDelay = 30; +static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannelConfiguration @@ -295,6 +295,7 @@ NSTimeInterval kDefaultChannelDestroyDelay = 30; NSDate *now = [NSDate date]; self->_lastDispatch = now; dispatch_after(delay, self->_dispatchQueue, ^{ + // Timed disconnection. if (self->_lastDispatch == now) { grpc_channel_destroy(self->_unmanagedChannel); self->_unmanagedChannel = NULL; From 33022c9172bd3cf52c9aa3416ce9c69d9f3c6494 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 9 Nov 2018 10:23:05 -0800 Subject: [PATCH 176/534] Introduce GRPCAssert --- src/objective-c/GRPCClient/GRPCCall.m | 47 +++++++------------ .../GRPCClient/private/GRPCChannel.m | 21 +++++---- .../GRPCClient/private/GRPCChannelPool.m | 9 ++-- src/objective-c/GRPCClient/private/GRPCHost.m | 3 +- .../private/GRPCSecureChannelFactory.m | 4 +- .../GRPCClient/private/utilities.h | 35 ++++++++++++++ 6 files changed, 72 insertions(+), 47 deletions(-) create mode 100644 src/objective-c/GRPCClient/private/utilities.h diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9b9b4f95471..3d06aa929bb 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -35,6 +35,7 @@ #import "private/NSData+GRPC.h" #import "private/NSDictionary+GRPC.h" #import "private/NSError+GRPC.h" +#import "private/utilities.h" // At most 6 ops can be in an op batch for a client: SEND_INITIAL_METADATA, // SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT, RECV_INITIAL_METADATA, RECV_MESSAGE, @@ -67,7 +68,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @implementation GRPCRequestOptions - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { - NSAssert(host.length != 0 && path.length != 0, @"Host and Path cannot be empty"); + GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, @"Host and Path cannot be empty"); if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -114,15 +115,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *_Nullable)callOptions { - if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { - [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; - } - if (requestOptions.safety > GRPCCallSafetyCacheableRequest) { - [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; - } - if (responseHandler == nil) { - [NSException raise:NSInvalidArgumentException format:@"Response handler required."]; - } + GRPCAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, NSInvalidArgumentException, @"Neither host nor path can be nil."); + GRPCAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, @"Invalid call safety value."); + GRPCAssert(responseHandler != nil, NSInvalidArgumentException, @"Response handler required."); if ((self = [super init])) { _requestOptions = [requestOptions copy]; @@ -159,8 +154,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)start { dispatch_async(_dispatchQueue, ^{ - NSAssert(!self->_started, @"Call already started."); - NSAssert(!self->_canceled, @"Call already canceled."); + GRPCAssert(!self->_started, NSInternalInconsistencyException, @"Call already started."); + GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call already canceled."); self->_started = YES; if (!self->_callOptions) { self->_callOptions = [[GRPCCallOptions alloc] init]; @@ -216,7 +211,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { dispatch_async(_dispatchQueue, ^{ - NSAssert(!self->_canceled, @"Call already canceled."); + GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call already canceled."); if (self->_call) { [self->_call cancel]; self->_call = nil; @@ -244,8 +239,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(NSData *)data { dispatch_async(_dispatchQueue, ^{ - NSAssert(!self->_canceled, @"Call arleady canceled."); - NSAssert(!self->_finished, @"Call is half-closed before sending data."); + GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); + GRPCAssert(!self->_finished, NSInternalInconsistencyException, @"Call is half-closed before sending data."); if (self->_call) { [self->_pipe writeValue:data]; } @@ -254,9 +249,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)finish { dispatch_async(_dispatchQueue, ^{ - NSAssert(self->_started, @"Call not started."); - NSAssert(!self->_canceled, @"Call arleady canceled."); - NSAssert(!self->_finished, @"Call already half-closed."); + GRPCAssert(self->_started, NSInternalInconsistencyException, @"Call not started."); + GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); + GRPCAssert(!self->_finished, NSInternalInconsistencyException, @"Call already half-closed."); if (self->_call) { [self->_pipe writesFinishedWithError:nil]; } @@ -404,16 +399,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. - if (!host || !path) { - [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; - } - if (safety > GRPCCallSafetyCacheableRequest) { - [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; - } - if (requestWriter.state != GRXWriterStateNotStarted) { - [NSException raise:NSInvalidArgumentException - format:@"The requests writer can't be already started."]; - } + GRPCAssert(host && path, NSInvalidArgumentException, @"Neither host nor path can be nil."); + GRPCAssert(safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, @"Invalid call safety value."); + GRPCAssert(requestWriter.state == GRXWriterStateNotStarted, NSInvalidArgumentException, @"The requests writer can't be already started."); if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -798,8 +786,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = callOptions; } - NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, - @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); + GRPCAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, NSInvalidArgumentException, @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); if (_callOptions.authTokenProvider != nil) { @synchronized(self) { self.isWaitingForToken = YES; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 4f26b349b49..7d0baa91ee6 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -28,6 +28,7 @@ #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "version.h" +#import "utilities.h" #import "../internal/GRPCCallOptions+Internal.h" #import @@ -39,8 +40,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannelConfiguration - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { - NSAssert(host.length, @"Host must not be empty."); - NSAssert(callOptions, @"callOptions must not be empty."); + GRPCAssert(host.length, NSInvalidArgumentException, @"Host must not be empty."); + GRPCAssert(callOptions != nil, NSInvalidArgumentException, @"callOptions must not be empty."); if ((self = [super init])) { _host = [host copy]; _callOptions = [callOptions copy]; @@ -192,8 +193,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay { - NSAssert(channelConfiguration, @"channelConfiguration must not be empty."); - NSAssert(destroyDelay > 0, @"destroyDelay must be greater than 0."); + GRPCAssert(channelConfiguration != nil, NSInvalidArgumentException, @"channelConfiguration must not be empty."); + GRPCAssert(destroyDelay > 0, NSInvalidArgumentException, @"destroyDelay must be greater than 0."); if ((self = [super init])) { _configuration = [channelConfiguration copy]; if (@available(iOS 8.0, *)) { @@ -206,7 +207,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; // Create gRPC core channel object. NSString *host = channelConfiguration.host; - NSAssert(host.length != 0, @"host cannot be nil"); + GRPCAssert(host.length != 0, NSInvalidArgumentException, @"host cannot be nil"); NSDictionary *channelArgs; if (channelConfiguration.callOptions.additionalChannelArgs.count != 0) { NSMutableDictionary *args = [channelConfiguration.channelArgs mutableCopy]; @@ -231,21 +232,21 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions disconnected:(BOOL *)disconnected { - NSAssert(path.length, @"path must not be empty."); - NSAssert(queue, @"completionQueue must not be empty."); - NSAssert(callOptions, @"callOptions must not be empty."); + GRPCAssert(path.length, NSInvalidArgumentException, @"path must not be empty."); + GRPCAssert(queue, NSInvalidArgumentException, @"completionQueue must not be empty."); + GRPCAssert(callOptions, NSInvalidArgumentException, @"callOptions must not be empty."); __block BOOL isDisconnected = NO; __block grpc_call *call = NULL; dispatch_sync(_dispatchQueue, ^{ if (self->_disconnected) { isDisconnected = YES; } else { - NSAssert(self->_unmanagedChannel != NULL, @"Invalid channel."); + GRPCAssert(self->_unmanagedChannel != NULL, NSInvalidArgumentException, @"Invalid channel."); NSString *serverAuthority = callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; - NSAssert(timeout >= 0, @"Invalid timeout"); + GRPCAssert(timeout >= 0, NSInvalidArgumentException, @"Invalid timeout"); grpc_slice host_slice = grpc_empty_slice(); if (serverAuthority) { host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 98c1634bc8b..8a3b5edfa12 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -27,6 +27,7 @@ #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "version.h" +#import "utilities.h" #import #include @@ -43,9 +44,7 @@ static dispatch_once_t gInitChannelPool; + (nullable instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ gChannelPool = [[GRPCChannelPool alloc] init]; - if (gChannelPool == nil) { - [NSException raise:NSMallocException format:@"Cannot initialize global channel pool."]; - } + GRPCAssert(gChannelPool != nil, NSMallocException, @"Cannot initialize global channel pool."); }); return gChannelPool; } @@ -73,8 +72,8 @@ static dispatch_once_t gInitChannelPool; - (GRPCChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions destroyDelay:(NSTimeInterval)destroyDelay { - NSAssert(host.length > 0, @"Host must not be empty."); - NSAssert(callOptions != nil, @"callOptions must not be empty."); + GRPCAssert(host.length > 0, NSInvalidArgumentException, @"Host must not be empty."); + GRPCAssert(callOptions != nil, NSInvalidArgumentException, @"callOptions must not be empty."); GRPCChannel *channel; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index a67162c1014..14d07e949b7 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -33,6 +33,7 @@ #import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" #import "version.h" +#import "utilities.h" NS_ASSUME_NONNULL_BEGIN @@ -121,7 +122,7 @@ static NSMutableDictionary *gHostCache; if (_transportType == GRPCTransportTypeInsecure) { options.transportType = GRPCTransportTypeInsecure; } else { - NSAssert(_transportType == GRPCTransportTypeDefault, @"Invalid transport type"); + GRPCAssert(_transportType == GRPCTransportTypeDefault, NSInvalidArgumentException, @"Invalid transport type"); options.transportType = GRPCTransportTypeCronet; } } else diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 1f6458c5247..3079394ed8a 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -22,6 +22,7 @@ #import "ChannelArgsUtil.h" #import "GRPCChannel.h" +#import "utilities.h" NS_ASSUME_NONNULL_BEGIN @@ -82,8 +83,9 @@ NS_ASSUME_NONNULL_BEGIN if (errorPtr) { *errorPtr = defaultRootsError; } - NSAssert( + GRPCAssertWithArgument( defaultRootsASCII, + NSObjectNotAvailableException, @"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 " diff --git a/src/objective-c/GRPCClient/private/utilities.h b/src/objective-c/GRPCClient/private/utilities.h new file mode 100644 index 00000000000..c664e8bf9df --- /dev/null +++ b/src/objective-c/GRPCClient/private/utilities.h @@ -0,0 +1,35 @@ +/* + * + * 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. + * + */ + +#import + +/** Raise exception when condition not met. Disregard NS_BLOCK_ASSERTIONS. */ +#define GRPCAssert(condition, errorType, errorString) \ +do { \ +if (!(condition)) { \ +[NSException raise:(errorType) format:(errorString)]; \ +} \ +} while (0) + +/** The same as GRPCAssert but allows arguments to be put in the raised string. */ +#define GRPCAssertWithArgument(condition, errorType, errorFormat, ...) \ + do { \ + if (!(condition)) { \ + [NSException raise:(errorType) format:(errorFormat), __VA_ARGS__]; \ + } \ + } while (0) From 2895ee9b6a63c19ebbd6c188ab475f0a6e7f0ba5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 9 Nov 2018 11:06:46 -0800 Subject: [PATCH 177/534] clang-format --- src/objective-c/GRPCClient/GRPCCall.m | 22 +++++--- .../GRPCClient/private/GRPCChannel.h | 11 ++-- .../GRPCClient/private/GRPCChannel.m | 55 ++++++++++--------- .../GRPCClient/private/GRPCChannelPool.h | 3 +- .../GRPCClient/private/GRPCChannelPool.m | 16 ++---- src/objective-c/GRPCClient/private/GRPCHost.m | 5 +- .../private/GRPCSecureChannelFactory.m | 3 +- .../GRPCClient/private/utilities.h | 27 ++++----- 8 files changed, 75 insertions(+), 67 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 3d06aa929bb..5e3491dafaa 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -68,7 +68,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; @implementation GRPCRequestOptions - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { - GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, @"Host and Path cannot be empty"); + GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, + @"Host and Path cannot be empty"); if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -115,8 +116,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *_Nullable)callOptions { - GRPCAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, NSInvalidArgumentException, @"Neither host nor path can be nil."); - GRPCAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, @"Invalid call safety value."); + GRPCAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, + NSInvalidArgumentException, @"Neither host nor path can be nil."); + GRPCAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, + @"Invalid call safety value."); GRPCAssert(responseHandler != nil, NSInvalidArgumentException, @"Response handler required."); if ((self = [super init])) { @@ -240,7 +243,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(NSData *)data { dispatch_async(_dispatchQueue, ^{ GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); - GRPCAssert(!self->_finished, NSInternalInconsistencyException, @"Call is half-closed before sending data."); + GRPCAssert(!self->_finished, NSInternalInconsistencyException, + @"Call is half-closed before sending data."); if (self->_call) { [self->_pipe writeValue:data]; } @@ -400,8 +404,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. GRPCAssert(host && path, NSInvalidArgumentException, @"Neither host nor path can be nil."); - GRPCAssert(safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, @"Invalid call safety value."); - GRPCAssert(requestWriter.state == GRXWriterStateNotStarted, NSInvalidArgumentException, @"The requests writer can't be already started."); + GRPCAssert(safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, + @"Invalid call safety value."); + GRPCAssert(requestWriter.state == GRXWriterStateNotStarted, NSInvalidArgumentException, + @"The requests writer can't be already started."); if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -786,7 +792,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = callOptions; } - GRPCAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, NSInvalidArgumentException, @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); + GRPCAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, + NSInvalidArgumentException, + @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); if (_callOptions.authTokenProvider != nil) { @synchronized(self) { self.isWaitingForToken = YES; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index bbe0ba53904..6c58f4f387f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -64,14 +64,17 @@ NS_ASSUME_NONNULL_BEGIN * Create a channel with remote \a host and signature \a channelConfigurations. Destroy delay is * defaulted to 30 seconds. */ -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration; +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration; /** * Create a channel with remote \a host, signature \a channelConfigurations, and destroy delay of * \a destroyDelay. */ -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration - destroyDelay:(NSTimeInterval)destroyDelay NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay + NS_DESIGNATED_INITIALIZER; /** * Create a grpc core call object from this channel. The channel's refcount is added by 1. If no @@ -82,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions - disconnected:(BOOL * _Nullable)disconnected; + disconnected:(BOOL *_Nullable)disconnected; /** * Unref the channel when a call is done. It also decreases the channel's refcount. If the refcount diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 7d0baa91ee6..fc0448bb962 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -20,6 +20,7 @@ #include +#import "../internal/GRPCCallOptions+Internal.h" #import "ChannelArgsUtil.h" #import "GRPCChannelFactory.h" #import "GRPCChannelPool.h" @@ -27,9 +28,8 @@ #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" -#import "version.h" #import "utilities.h" -#import "../internal/GRPCCallOptions+Internal.h" +#import "version.h" #import #import @@ -60,10 +60,10 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (![GRPCCall isUsingCronet]) { #endif factory = [GRPCSecureChannelFactory - factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates - privateKey:_callOptions.PEMPrivateKey - certChain:_callOptions.PEMCertChain - error:&error]; + factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates + privateKey:_callOptions.PEMPrivateKey + certChain:_callOptions.PEMCertChain + error:&error]; if (factory == nil) { NSLog(@"Error creating secure channel factory: %@", error); } @@ -86,7 +86,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSString *userAgentPrefix = _callOptions.userAgentPrefix; if (userAgentPrefix) { args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = - [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; + [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; } else { args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = userAgent; } @@ -98,19 +98,19 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (_callOptions.responseSizeLimit) { args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = - [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; + [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; } if (_callOptions.compressionAlgorithm != GRPC_COMPRESS_NONE) { args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = - [NSNumber numberWithInt:_callOptions.compressionAlgorithm]; + [NSNumber numberWithInt:_callOptions.compressionAlgorithm]; } if (_callOptions.keepaliveInterval != 0) { args[@GRPC_ARG_KEEPALIVE_TIME_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; } if (_callOptions.retryEnabled == NO) { @@ -119,15 +119,15 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (_callOptions.connectMinTimeout > 0) { args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMinTimeout * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMinTimeout * 1000)]; } if (_callOptions.connectInitialBackoff > 0) { args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber - numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectInitialBackoff * 1000)]; + numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectInitialBackoff * 1000)]; } if (_callOptions.connectMaxBackoff > 0) { args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMaxBackoff * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMaxBackoff * 1000)]; } if (_callOptions.logContext != nil) { @@ -145,7 +145,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (nonnull id)copyWithZone:(nullable NSZone *)zone { GRPCChannelConfiguration *newConfig = - [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; + [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; return newConfig; } @@ -172,8 +172,6 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @end - - @implementation GRPCChannel { GRPCChannelConfiguration *_configuration; @@ -186,21 +184,24 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } @synthesize disconnected = _disconnected; -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration { return [self initWithChannelConfiguration:channelConfiguration destroyDelay:kDefaultChannelDestroyDelay]; } -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay { - GRPCAssert(channelConfiguration != nil, NSInvalidArgumentException, @"channelConfiguration must not be empty."); + GRPCAssert(channelConfiguration != nil, NSInvalidArgumentException, + @"channelConfiguration must not be empty."); GRPCAssert(destroyDelay > 0, NSInvalidArgumentException, @"destroyDelay must be greater than 0."); if ((self = [super init])) { _configuration = [channelConfiguration copy]; if (@available(iOS 8.0, *)) { _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); } else { _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } @@ -244,7 +245,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; GRPCAssert(self->_unmanagedChannel != NULL, NSInvalidArgumentException, @"Invalid channel."); NSString *serverAuthority = - callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; GRPCAssert(timeout >= 0, NSInvalidArgumentException, @"Invalid timeout"); grpc_slice host_slice = grpc_empty_slice(); @@ -253,10 +254,10 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } 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_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + 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)); call = grpc_channel_create_call(self->_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, serverAuthority ? &host_slice : NULL, deadline_ms, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 24c0a8df115..48779c44497 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -44,8 +44,7 @@ NS_ASSUME_NONNULL_BEGIN * Return a channel with a particular configuration. If the channel does not exist, execute \a * createChannel then add it in the pool. If the channel exists, increase its reference count. */ -- (GRPCChannel *)channelWithHost:(NSString *)host - callOptions:(GRPCCallOptions *)callOptions; +- (GRPCChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; /** * This method is deprecated. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 8a3b5edfa12..85ca527277c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -26,8 +26,8 @@ #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" -#import "version.h" #import "utilities.h" +#import "version.h" #import #include @@ -62,11 +62,8 @@ static dispatch_once_t gInitChannelPool; return self; } -- (GRPCChannel *)channelWithHost:(NSString *)host - callOptions:(GRPCCallOptions *)callOptions { - return [self channelWithHost:host - callOptions:callOptions - destroyDelay:0]; +- (GRPCChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { + return [self channelWithHost:host callOptions:callOptions destroyDelay:0]; } - (GRPCChannel *)channelWithHost:(NSString *)host @@ -76,14 +73,15 @@ static dispatch_once_t gInitChannelPool; GRPCAssert(callOptions != nil, NSInvalidArgumentException, @"callOptions must not be empty."); GRPCChannel *channel; GRPCChannelConfiguration *configuration = - [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; + [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; @synchronized(self) { channel = _channelPool[configuration]; if (channel == nil || channel.disconnected) { if (destroyDelay == 0) { channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration]; } else { - channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:destroyDelay]; + channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration + destroyDelay:destroyDelay]; } _channelPool[configuration] = channel; } @@ -91,8 +89,6 @@ static dispatch_once_t gInitChannelPool; return channel; } - - + (void)closeOpenConnections { [[GRPCChannelPool sharedInstance] destroyAllChannels]; } diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 14d07e949b7..5fc7427b689 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -32,8 +32,8 @@ #import "GRPCCronetChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" -#import "version.h" #import "utilities.h" +#import "version.h" NS_ASSUME_NONNULL_BEGIN @@ -122,7 +122,8 @@ static NSMutableDictionary *gHostCache; if (_transportType == GRPCTransportTypeInsecure) { options.transportType = GRPCTransportTypeInsecure; } else { - GRPCAssert(_transportType == GRPCTransportTypeDefault, NSInvalidArgumentException, @"Invalid transport type"); + GRPCAssert(_transportType == GRPCTransportTypeDefault, NSInvalidArgumentException, + @"Invalid transport type"); options.transportType = GRPCTransportTypeCronet; } } else diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 3079394ed8a..57bd40d6787 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -84,8 +84,7 @@ NS_ASSUME_NONNULL_BEGIN *errorPtr = defaultRootsError; } GRPCAssertWithArgument( - defaultRootsASCII, - NSObjectNotAvailableException, + defaultRootsASCII, NSObjectNotAvailableException, @"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 " diff --git a/src/objective-c/GRPCClient/private/utilities.h b/src/objective-c/GRPCClient/private/utilities.h index c664e8bf9df..3e51730d637 100644 --- a/src/objective-c/GRPCClient/private/utilities.h +++ b/src/objective-c/GRPCClient/private/utilities.h @@ -19,17 +19,18 @@ #import /** Raise exception when condition not met. Disregard NS_BLOCK_ASSERTIONS. */ -#define GRPCAssert(condition, errorType, errorString) \ -do { \ -if (!(condition)) { \ -[NSException raise:(errorType) format:(errorString)]; \ -} \ -} while (0) +#define GRPCAssert(condition, errorType, errorString) \ + do { \ + if (!(condition)) { \ + [NSException raise:(errorType)format:(errorString)]; \ + } \ + } while (0) -/** The same as GRPCAssert but allows arguments to be put in the raised string. */ -#define GRPCAssertWithArgument(condition, errorType, errorFormat, ...) \ - do { \ - if (!(condition)) { \ - [NSException raise:(errorType) format:(errorFormat), __VA_ARGS__]; \ - } \ - } while (0) +/** The same as GRPCAssert but allows arguments to be put in the raised string. + */ +#define GRPCAssertWithArgument(condition, errorType, errorFormat, ...) \ + do { \ + if (!(condition)) { \ + [NSException raise:(errorType)format:(errorFormat), __VA_ARGS__]; \ + } \ + } while (0) From 699c10386d6f0cbed7364e5a94144f0794f469d5 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 9 Nov 2018 19:43:00 -0800 Subject: [PATCH 178/534] Add method to fail recv msg for hijacked rpcs --- include/grpcpp/impl/codegen/call_op_set.h | 4 +- include/grpcpp/impl/codegen/interceptor.h | 3 + .../grpcpp/impl/codegen/interceptor_common.h | 14 ++- .../grpcpp/impl/codegen/server_interface.h | 2 +- src/cpp/server/server_cc.cc | 4 +- .../client_interceptors_end2end_test.cc | 101 ++++++++++++++++++ 6 files changed, 122 insertions(+), 6 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index b4c34a01c9a..aae8b9d3e37 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -406,7 +406,7 @@ class CallOpRecvMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - interceptor_methods->SetRecvMessage(message_); + interceptor_methods->SetRecvMessage(message_, &got_message); } void SetFinishInterceptionHookPoint( @@ -501,7 +501,7 @@ class CallOpGenericRecvMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - interceptor_methods->SetRecvMessage(message_); + interceptor_methods->SetRecvMessage(message_, &got_message); } void SetFinishInterceptionHookPoint( diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index e449e44a23b..943376a5451 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -118,6 +118,9 @@ class InterceptorBatchMethods { // only interceptors after the current interceptor are created from the // factory objects registered with the channel. virtual std::unique_ptr GetInterceptedChannel() = 0; + + // On a hijacked RPC, an interceptor can decide to fail a RECV MESSAGE op. + virtual void FailHijackedRecvMessage() = 0; }; class Interceptor { diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index d0aa23cb0a0..4c881c783d3 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -134,7 +134,10 @@ class InterceptorBatchMethodsImpl send_trailing_metadata_ = metadata; } - void SetRecvMessage(void* message) { recv_message_ = message; } + void SetRecvMessage(void* message, bool* got_message) { + recv_message_ = message; + got_message_ = got_message; + } void SetRecvInitialMetadata(MetadataMap* map) { recv_initial_metadata_ = map; @@ -157,6 +160,8 @@ class InterceptorBatchMethodsImpl info->channel(), current_interceptor_index_ + 1)); } + void FailHijackedRecvMessage() override { *got_message_ = false; } + // Clears all state void ClearState() { reverse_ = false; @@ -345,6 +350,7 @@ class InterceptorBatchMethodsImpl std::multimap* send_trailing_metadata_ = nullptr; void* recv_message_ = nullptr; + bool* got_message_ = nullptr; MetadataMap* recv_initial_metadata_ = nullptr; @@ -451,6 +457,12 @@ class CancelInterceptorBatchMethods "method which has a Cancel notification"); return std::unique_ptr(nullptr); } + + void FailHijackedRecvMessage() override { + GPR_CODEGEN_ASSERT(false && + "It is illegal to call FailHijackedRecvMessage on a " + "method which has a Cancel notification"); + } }; } // namespace internal } // namespace grpc diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index 55c94f4d2fa..23d1f445b16 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -270,7 +270,7 @@ class ServerInterface : public internal::CallHook { /* Set interception point for recv message */ interceptor_methods_.AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); - interceptor_methods_.SetRecvMessage(request_); + interceptor_methods_.SetRecvMessage(request_, nullptr); return RegisteredAsyncRequest::FinalizeResult(tag, status); } diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 7a98bce507a..8b1658dd278 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -280,7 +280,7 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { request_payload_ = nullptr; interceptor_methods_.AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); - interceptor_methods_.SetRecvMessage(request_); + interceptor_methods_.SetRecvMessage(request_, nullptr); } if (interceptor_methods_.RunInterceptors( @@ -447,7 +447,7 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { req_->request_payload_ = nullptr; req_->interceptor_methods_.AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); - req_->interceptor_methods_.SetRecvMessage(req_->request_); + req_->interceptor_methods_.SetRecvMessage(req_->request_, nullptr); } if (req_->interceptor_methods_.RunInterceptors( diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 0b34ec93ae7..b94a3d752e8 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -269,6 +269,92 @@ class HijackingInterceptorMakesAnotherCallFactory } }; +class ServerStreamingRpcHijackingInterceptor + : public experimental::Interceptor { + public: + ServerStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) { + info_ = info; + } + + virtual void Intercept(experimental::InterceptorBatchMethods* methods) { + bool hijack = false; + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + auto* map = methods->GetSendInitialMetadata(); + // Check that we can see the test metadata + ASSERT_EQ(map->size(), static_cast(1)); + auto iterator = map->begin(); + EXPECT_EQ("testkey", iterator->first); + EXPECT_EQ("testvalue", iterator->second); + hijack = true; + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + EchoRequest req; + auto* buffer = methods->GetSendMessage(); + auto copied_buffer = *buffer; + EXPECT_TRUE( + SerializationTraits::Deserialize(&copied_buffer, &req) + .ok()); + EXPECT_EQ(req.message(), "Hello"); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { + // Got nothing to do here for now + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_STATUS)) { + auto* map = methods->GetRecvTrailingMetadata(); + bool found = false; + // Check that we received the metadata as an echo + for (const auto& pair : *map) { + found = pair.first.starts_with("testkey") && + pair.second.starts_with("testvalue"); + if (found) break; + } + EXPECT_EQ(found, true); + auto* status = methods->GetRecvStatus(); + EXPECT_EQ(status->ok(), true); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { + if (++count > 10) { + methods->FailHijackedRecvMessage(); + } + EchoResponse* resp = + static_cast(methods->GetRecvMessage()); + resp->set_message("Hello"); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { + auto* map = methods->GetRecvTrailingMetadata(); + // insert the metadata that we want + EXPECT_EQ(map->size(), static_cast(0)); + map->insert(std::make_pair("testkey", "testvalue")); + auto* status = methods->GetRecvStatus(); + *status = Status(StatusCode::OK, ""); + } + if (hijack) { + methods->Hijack(); + } else { + methods->Proceed(); + } + } + + private: + experimental::ClientRpcInfo* info_; + int count = 0; +}; + +class ServerStreamingRpcHijackingInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return new ServerStreamingRpcHijackingInterceptor(info); + } +}; + class LoggingInterceptor : public experimental::Interceptor { public: LoggingInterceptor(experimental::ClientRpcInfo* info) { info_ = info; } @@ -535,6 +621,21 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } +TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingHijackingTest) { + ChannelArguments args; + DummyInterceptor::Reset(); + auto creators = std::unique_ptr>>( + new std::vector< + std::unique_ptr>()); + creators->push_back( + std::unique_ptr( + new ServerStreamingRpcHijackingInterceptorFactory())); + auto channel = experimental::CreateCustomChannelWithInterceptors( + server_address_, InsecureChannelCredentials(), args, std::move(creators)); + MakeServerStreamingCall(channel); +} + TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); From 565edf529766e66b4394f59ff33a89211c92206a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 9 Nov 2018 19:51:11 -0800 Subject: [PATCH 179/534] Add safety checks --- include/grpcpp/impl/codegen/interceptor_common.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 4c881c783d3..d23b71f8a77 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -160,7 +160,11 @@ class InterceptorBatchMethodsImpl info->channel(), current_interceptor_index_ + 1)); } - void FailHijackedRecvMessage() override { *got_message_ = false; } + void FailHijackedRecvMessage() override { + GPR_CODEGEN_ASSERT(hooks_[static_cast( + experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)]); + *got_message_ = false; + } // Clears all state void ClearState() { From 94d220d32c0db708a3afa36a17aae25d93c2636b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 14:03:27 -0800 Subject: [PATCH 180/534] Rename variable --- .../cronet/client/secure/cronet_channel_create.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc index dffb61b082d..1cb38f25b6d 100644 --- a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc +++ b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc @@ -47,11 +47,11 @@ GRPCAPI grpc_channel* grpc_cronet_secure_channel_create( target); // Disable client authority filter when using Cronet - grpc_arg arg; - arg.key = const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); - arg.type = GRPC_ARG_INTEGER; - arg.value.integer = 1; - grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &arg, 1); + grpc_arg disable_client_authority_filter_arg; + disable_client_authority_filter_arg.key = const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); + disable_client_authority_filter_arg.type = GRPC_ARG_INTEGER; + disable_client_authority_filter_arg.value.integer = 1; + grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &disable_client_authority_filter_arg, 1); grpc_transport* ct = grpc_create_cronet_transport(engine, target, new_args, reserved); From 8d0cf9ec0aaa9e9efd23254d189d78fbaead2702 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 14:03:50 -0800 Subject: [PATCH 181/534] clang-format --- .../tests/ChannelTests/ChannelPoolTest.m | 38 +++++++------------ .../tests/ChannelTests/ChannelTests.m | 18 +++++---- 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index d684db545e9..b85e62feb5f 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -47,14 +47,10 @@ NSString *kDummyHost = @"dummy.host"; GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel1 = [pool channelWithHost:kDummyHost - callOptions:options1]; - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost - callOptions:options2]; - GRPCChannel *channel3 = [pool channelWithHost:kDummyHost2 - callOptions:options1]; - GRPCChannel *channel4 = [pool channelWithHost:kDummyHost - callOptions:options3]; + GRPCChannel *channel1 = [pool channelWithHost:kDummyHost callOptions:options1]; + GRPCChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options2]; + GRPCChannel *channel3 = [pool channelWithHost:kDummyHost2 callOptions:options1]; + GRPCChannel *channel4 = [pool channelWithHost:kDummyHost callOptions:options3]; XCTAssertEqual(channel1, channel2); XCTAssertNotEqual(channel1, channel3); XCTAssertNotEqual(channel1, channel4); @@ -66,16 +62,14 @@ NSString *kDummyHost = @"dummy.host"; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = [pool channelWithHost:kDummyHost - callOptions:options]; + GRPCChannel *channel = [pool channelWithHost:kDummyHost callOptions:options]; grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" completionQueue:[GRPCCompletionQueue completionQueue] callOptions:options disconnected:nil]; [pool destroyAllChannels]; XCTAssertTrue(channel.disconnected); - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost - callOptions:options]; + GRPCChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options]; XCTAssertNotEqual(channel, channel2); grpc_call_unref(call); } @@ -86,9 +80,8 @@ NSString *kDummyHost = @"dummy.host"; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = [pool channelWithHost:kDummyHost - callOptions:options - destroyDelay:kDestroyDelay]; + GRPCChannel *channel = + [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" completionQueue:[GRPCCompletionQueue completionQueue] callOptions:options @@ -97,9 +90,8 @@ NSString *kDummyHost = @"dummy.host"; [channel unref]; // Test that we can still get the channel at this time - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost - callOptions:options - destroyDelay:kDestroyDelay]; + GRPCChannel *channel2 = + [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; XCTAssertEqual(channel, channel2); call = [channel2 unmanagedCallWithPath:@"dummy.path" completionQueue:[GRPCCompletionQueue completionQueue] @@ -117,9 +109,8 @@ NSString *kDummyHost = @"dummy.host"; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = [pool channelWithHost:kDummyHost - callOptions:options - destroyDelay:kDestroyDelay]; + GRPCChannel *channel = + [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" completionQueue:[GRPCCompletionQueue completionQueue] callOptions:options @@ -130,9 +121,8 @@ NSString *kDummyHost = @"dummy.host"; sleep(kDestroyDelay + 1); // Test that we get new channel to the same host and with the same callOptions - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost - callOptions:options - destroyDelay:kDestroyDelay]; + GRPCChannel *channel2 = + [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; XCTAssertNotEqual(channel, channel2); } diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 27e76d41799..5daafcdf3f3 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -33,12 +33,13 @@ } - (void)testTimedDisconnection { - NSString * const kHost = @"grpc-test.sandbox.googleapis.com"; + NSString *const kHost = @"grpc-test.sandbox.googleapis.com"; const NSTimeInterval kDestroyDelay = 1; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; - GRPCChannel *channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration - destroyDelay:kDestroyDelay]; + GRPCChannelConfiguration *configuration = + [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; + GRPCChannel *channel = + [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:kDestroyDelay]; BOOL disconnected; grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" completionQueue:[GRPCCompletionQueue completionQueue] @@ -61,12 +62,13 @@ } - (void)testForceDisconnection { - NSString * const kHost = @"grpc-test.sandbox.googleapis.com"; + NSString *const kHost = @"grpc-test.sandbox.googleapis.com"; const NSTimeInterval kDestroyDelay = 1; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; - GRPCChannel *channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration - destroyDelay:kDestroyDelay]; + GRPCChannelConfiguration *configuration = + [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; + GRPCChannel *channel = + [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:kDestroyDelay]; grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" completionQueue:[GRPCCompletionQueue completionQueue] callOptions:options From b77203fdf59faa38e7be01f8796d3bc3e67db602 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 14:09:41 -0800 Subject: [PATCH 182/534] Move blocks into varibles for readability --- src/objective-c/GRPCClient/GRPCCall.m | 53 ++++++++++++++------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 5e3491dafaa..39681d2adfb 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -172,7 +172,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (self->_callOptions.initialMetadata) { [self->_call.requestHeaders addEntriesFromDictionary:self->_callOptions.initialMetadata]; } - id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) { + + void (^valueHandler)(id value) = ^(id value) { dispatch_async(self->_dispatchQueue, ^{ if (self->_handler) { if (!self->_initialMetadataPublished) { @@ -184,30 +185,32 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } }); - } - completionHandler:^(NSError *errorOrNil) { - dispatch_async(self->_dispatchQueue, ^{ - if (self->_handler) { - if (!self->_initialMetadataPublished) { - self->_initialMetadataPublished = YES; - [self issueInitialMetadata:self->_call.responseHeaders]; - } - [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; - - // Clean up _handler so that no more responses are reported to the handler. - self->_handler = nil; - } - // Clearing _call must happen *after* dispatching close in order to get trailing - // metadata from _call. - if (self->_call) { - // Clean up the request writers. This should have no effect to _call since its - // response writeable is already nullified. - [self->_pipe writesFinishedWithError:nil]; - self->_call = nil; - self->_pipe = nil; - } - }); - }]; + }; + void (^completionHandler)(NSError *errorOrNil) = ^(NSError *errorOrNil) { + dispatch_async(self->_dispatchQueue, ^{ + if (self->_handler) { + if (!self->_initialMetadataPublished) { + self->_initialMetadataPublished = YES; + [self issueInitialMetadata:self->_call.responseHeaders]; + } + [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + + // Clean up _handler so that no more responses are reported to the handler. + self->_handler = nil; + } + // Clearing _call must happen *after* dispatching close in order to get trailing + // metadata from _call. + if (self->_call) { + // Clean up the request writers. This should have no effect to _call since its + // response writeable is already nullified. + [self->_pipe writesFinishedWithError:nil]; + self->_call = nil; + self->_pipe = nil; + } + }); + }; + id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:valueHandler + completionHandler:completionHandler]; [self->_call startWithWriteable:responseWriteable]; }); } From 78c2176afcdf2267467c68f6f070fc6543673bd7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 14:40:44 -0800 Subject: [PATCH 183/534] Assign finished and canceled --- src/objective-c/GRPCClient/GRPCCall.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 39681d2adfb..9d81dcf6e6e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -143,7 +143,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); _started = NO; _canceled = NO; - _finished = YES; + _finished = NO; } return self; @@ -218,6 +218,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { dispatch_async(_dispatchQueue, ^{ GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call already canceled."); + self->_canceled = YES; if (self->_call) { [self->_call cancel]; self->_call = nil; @@ -263,6 +264,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self->_pipe writesFinishedWithError:nil]; } self->_pipe = nil; + self->_finished = YES; }); } From f4a77ce4926064e193787521081e835bd94f1e7d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 14:51:07 -0800 Subject: [PATCH 184/534] _call->_pipe --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9d81dcf6e6e..46cd5a4f227 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -260,7 +260,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRPCAssert(self->_started, NSInternalInconsistencyException, @"Call not started."); GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); GRPCAssert(!self->_finished, NSInternalInconsistencyException, @"Call already half-closed."); - if (self->_call) { + if (self->_pipe) { [self->_pipe writesFinishedWithError:nil]; } self->_pipe = nil; From c83ab56fe1d4bc6e5c3cebbc4943505eaf6ea74a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 14:51:25 -0800 Subject: [PATCH 185/534] copy->mutableCopy --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 46cd5a4f227..6de7bd8967b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -581,7 +581,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; break; } - NSMutableDictionary *headers = [_requestHeaders copy]; + NSMutableDictionary *headers = [_requestHeaders mutableCopy]; NSString *fetchedOauth2AccessToken; @synchronized(self) { fetchedOauth2AccessToken = _fetchedOauth2AccessToken; From b22120f69601450d4cbdc6957f661ba7ec29ca3a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 16:10:10 -0800 Subject: [PATCH 186/534] Test fix --- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index d681163419d..28f94cd8c77 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -277,6 +277,7 @@ static const NSTimeInterval kTestTimeout = 16; callOptions:options]; [call writeData:[NSData data]]; [call start]; + [call finish]; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } @@ -312,6 +313,7 @@ static const NSTimeInterval kTestTimeout = 16; callOptions:options]; [call writeData:[request data]]; [call start]; + [call finish]; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } From e023468e9a82a4338e30e57ab822c86406480b94 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 16:34:58 -0800 Subject: [PATCH 187/534] some nit fixes --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannel.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 6de7bd8967b..2a56514bdc9 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -282,7 +282,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [_handler closedWithTrailingMetadata:_call.responseTrailers error:error]; + [_handler closedWithTrailingMetadata:trailingMetadata error:error]; } } diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index ecb517762b3..9a36ee547cd 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -45,7 +45,7 @@ static NSString *const kDefaultChannelPoolDomain = nil; static const NSUInteger kDefaultChannelID = 0; // Check if two objects are equal. Returns YES if both are nil; -BOOL areObjectsEqual(id obj1, id obj2) { +static BOOL areObjectsEqual(id obj1, id obj2) { if (obj1 == obj2) { return YES; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 6c58f4f387f..32e68bb2625 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -39,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN * Options of the corresponding call. Note that only the channel-related options are of interest to * this class. */ -@property(strong, readonly) GRPCCallOptions *callOptions; +@property(readonly) GRPCCallOptions *callOptions; /** Acquire the factory to generate a new channel with current configurations. */ @property(readonly) id channelFactory; From 5d7d6c0fbdcac75ea482e1fde3e128cd0c1646c1 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 14 Nov 2018 17:35:26 -0800 Subject: [PATCH 188/534] Add method to fail hijacked send messages --- include/grpcpp/impl/codegen/call_op_set.h | 10 ++- include/grpcpp/impl/codegen/interceptor.h | 4 + .../grpcpp/impl/codegen/interceptor_common.h | 18 ++++- .../client_interceptors_end2end_test.cc | 73 +++++++++++++++++++ 4 files changed, 102 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index b4c34a01c9a..1f2b88e9e14 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -314,14 +314,19 @@ class CallOpSendMessage { // Flags are per-message: clear them after use. write_options_.Clear(); } - void FinishOp(bool* status) { send_buf_.Clear(); } + void FinishOp(bool* status) { + send_buf_.Clear(); + if (hijacked_ && failed_send_) { + *status = false; + } + } void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { if (!send_buf_.Valid()) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE); - interceptor_methods->SetSendMessage(&send_buf_); + interceptor_methods->SetSendMessage(&send_buf_, &failed_send_); } void SetFinishInterceptionHookPoint( @@ -333,6 +338,7 @@ class CallOpSendMessage { private: bool hijacked_ = false; + bool failed_send_ = false; ByteBuffer send_buf_; WriteOptions write_options_; }; diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index e449e44a23b..47239332c86 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -118,6 +118,10 @@ class InterceptorBatchMethods { // only interceptors after the current interceptor are created from the // factory objects registered with the channel. virtual std::unique_ptr GetInterceptedChannel() = 0; + + // On a hijacked RPC/ to-be hijacked RPC, this can be called to fail a SEND + // MESSAGE op + virtual void FailHijackedSendMessage() = 0; }; class Interceptor { diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index d0aa23cb0a0..601a929afe6 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -110,12 +110,21 @@ class InterceptorBatchMethodsImpl Status* GetRecvStatus() override { return recv_status_; } + void FailHijackedSendMessage() override { + GPR_CODEGEN_ASSERT(hooks_[static_cast( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)]); + *fail_send_message_ = true; + } + std::multimap* GetRecvTrailingMetadata() override { return recv_trailing_metadata_->map(); } - void SetSendMessage(ByteBuffer* buf) { send_message_ = buf; } + void SetSendMessage(ByteBuffer* buf, bool* fail_send_message) { + send_message_ = buf; + fail_send_message_ = fail_send_message; + } void SetSendInitialMetadata( std::multimap* metadata) { @@ -334,6 +343,7 @@ class InterceptorBatchMethodsImpl std::function callback_; ByteBuffer* send_message_ = nullptr; + bool* fail_send_message_ = nullptr; std::multimap* send_initial_metadata_; @@ -451,6 +461,12 @@ class CancelInterceptorBatchMethods "method which has a Cancel notification"); return std::unique_ptr(nullptr); } + + void FailHijackedSendMessage() override { + GPR_CODEGEN_ASSERT(false && + "It is illegal to call FailHijackedSendMessage on a " + "method which has a Cancel notification"); + } }; } // namespace internal } // namespace grpc diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 0b34ec93ae7..81efd154525 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -269,6 +269,49 @@ class HijackingInterceptorMakesAnotherCallFactory } }; +class ClientStreamingRpcHijackingInterceptor + : public experimental::Interceptor { + public: + ClientStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) { + info_ = info; + } + virtual void Intercept(experimental::InterceptorBatchMethods* methods) { + bool hijack = false; + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + hijack = true; + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + if (++count_ > 10) { + methods->FailHijackedSendMessage(); + } + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { + auto* status = methods->GetRecvStatus(); + *status = Status(StatusCode::UNAVAILABLE, "Done sending 10 messages"); + } + if (hijack) { + methods->Hijack(); + } else { + methods->Proceed(); + } + } + + private: + experimental::ClientRpcInfo* info_; + int count_ = 0; +}; +class ClientStreamingRpcHijackingInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return new ClientStreamingRpcHijackingInterceptor(info); + } +}; + class LoggingInterceptor : public experimental::Interceptor { public: LoggingInterceptor(experimental::ClientRpcInfo* info) { info_ = info; } @@ -535,6 +578,36 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } +TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingHijackingTest) { + ChannelArguments args; + auto creators = std::unique_ptr>>( + new std::vector< + std::unique_ptr>()); + creators->push_back( + std::unique_ptr( + new ClientStreamingRpcHijackingInterceptorFactory())); + auto channel = experimental::CreateCustomChannelWithInterceptors( + server_address_, InsecureChannelCredentials(), args, std::move(creators)); + + auto stub = grpc::testing::EchoTestService::NewStub(channel); + ClientContext ctx; + EchoRequest req; + EchoResponse resp; + req.mutable_param()->set_echo_metadata(true); + req.set_message("Hello"); + string expected_resp = ""; + auto writer = stub->RequestStream(&ctx, &resp); + for (int i = 0; i < 10; i++) { + EXPECT_TRUE(writer->Write(req)); + expected_resp += "Hello"; + } + // Expect that the interceptor will reject the 11th message + EXPECT_FALSE(writer->Write(req)); + Status s = writer->Finish(); + EXPECT_EQ(s.ok(), false); +} + TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); From 2bd38f29df16b874bea254e001e3c40d6945c28c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 17:59:30 -0800 Subject: [PATCH 189/534] Batch fixes --- .../GRPCClient/private/GRPCChannel.m | 17 ++++++++++------- .../GRPCClient/private/GRPCWrappedCall.m | 7 +++---- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index fc0448bb962..52dacad9f50 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -84,7 +84,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; NSString *userAgentPrefix = _callOptions.userAgentPrefix; - if (userAgentPrefix) { + if (userAgentPrefix.length != 0) { args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; } else { @@ -242,7 +242,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (self->_disconnected) { isDisconnected = YES; } else { - GRPCAssert(self->_unmanagedChannel != NULL, NSInvalidArgumentException, @"Invalid channel."); + GRPCAssert(self->_unmanagedChannel != NULL, NSInternalInconsistencyException, @"Channel should have valid unmanaged channel."); NSString *serverAuthority = callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; @@ -281,14 +281,17 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; // This function should be called on _dispatchQueue. - (void)ref { - _refcount++; - if (_refcount == 1 && _lastDispatch != nil) { - _lastDispatch = nil; - } + dispatch_sync(_dispatchQueue, ^{ + self->_refcount++; + if (self->_refcount == 1 && self->_lastDispatch != nil) { + self->_lastDispatch = nil; + } + }); } - (void)unref { dispatch_async(_dispatchQueue, ^{ + GRPCAssert(self->_refcount > 0, NSInternalInconsistencyException, @"Illegal reference count."); self->_refcount--; if (self->_refcount == 0 && !self->_disconnected) { // Start timer. @@ -298,7 +301,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; self->_lastDispatch = now; dispatch_after(delay, self->_dispatchQueue, ^{ // Timed disconnection. - if (self->_lastDispatch == now) { + if (!self->_disconnected && self->_lastDispatch == now) { grpc_channel_destroy(self->_unmanagedChannel); self->_unmanagedChannel = NULL; self->_disconnected = YES; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 2358c7bb0a8..f3fe8bac455 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -30,6 +30,7 @@ #import "NSData+GRPC.h" #import "NSDictionary+GRPC.h" #import "NSError+GRPC.h" +#import "utilities.h" #import "GRPCOpBatchLog.h" @@ -248,16 +249,14 @@ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path callOptions:(GRPCCallOptions *)callOptions { - if (host.length == 0 || path.length == 0) { - [NSException raise:NSInvalidArgumentException format:@"path and host cannot be nil."]; - } + GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, @"path and host cannot be nil."); if ((self = [super init])) { // Each completion queue consumes one thread. There's a trade to be made between creating and // consuming too many threads and having contention of multiple calls in a single completion // queue. Currently we use a singleton queue. _queue = [GRPCCompletionQueue completionQueue]; - BOOL disconnected; + BOOL disconnected = NO; do { _channel = [[GRPCChannelPool sharedInstance] channelWithHost:host callOptions:callOptions]; if (_channel == nil) { From ceeb28a360d48389edb8c1c91a1efac46e24a9b7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 14 Nov 2018 18:02:54 -0800 Subject: [PATCH 190/534] s/count/count_/ --- test/cpp/end2end/client_interceptors_end2end_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index b94a3d752e8..459788ba519 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -318,7 +318,7 @@ class ServerStreamingRpcHijackingInterceptor } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { - if (++count > 10) { + if (++count_ > 10) { methods->FailHijackedRecvMessage(); } EchoResponse* resp = @@ -343,7 +343,7 @@ class ServerStreamingRpcHijackingInterceptor private: experimental::ClientRpcInfo* info_; - int count = 0; + int count_ = 0; }; class ServerStreamingRpcHijackingInterceptorFactory From b5434c05aaaacfba9d6ef6882b6c1f3285a304e2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 18:48:09 -0800 Subject: [PATCH 191/534] Make tests pass --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannel.m | 11 +++++------ src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 2a56514bdc9..1ba55a7744d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -249,7 +249,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); GRPCAssert(!self->_finished, NSInternalInconsistencyException, @"Call is half-closed before sending data."); - if (self->_call) { + if (self->_pipe) { [self->_pipe writeValue:data]; } }); diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 52dacad9f50..f63157c9743 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -281,15 +281,14 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; // This function should be called on _dispatchQueue. - (void)ref { - dispatch_sync(_dispatchQueue, ^{ - self->_refcount++; - if (self->_refcount == 1 && self->_lastDispatch != nil) { - self->_lastDispatch = nil; - } - }); + _refcount++; + if (_refcount == 1 && _lastDispatch != nil) { + _lastDispatch = nil; + } } - (void)unref { + NSLog(@"unref"); dispatch_async(_dispatchQueue, ^{ GRPCAssert(self->_refcount > 0, NSInternalInconsistencyException, @"Illegal reference count."); self->_refcount--; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index f3fe8bac455..905719f4642 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -325,7 +325,6 @@ - (void)dealloc { if (_call) { grpc_call_unref(_call); - [_channel unref]; } [_channel unref]; _channel = nil; From e14ec44b0ac1512bc3def0f2094be883d1b53c5f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 18:52:35 -0800 Subject: [PATCH 192/534] clang-format --- src/objective-c/GRPCClient/GRPCCall.m | 5 +++-- src/objective-c/GRPCClient/private/GRPCChannel.m | 3 ++- src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 1ba55a7744d..4068c3b4608 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -209,8 +209,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; } }); }; - id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:valueHandler - completionHandler:completionHandler]; + id responseWriteable = + [[GRXWriteable alloc] initWithValueHandler:valueHandler + completionHandler:completionHandler]; [self->_call startWithWriteable:responseWriteable]; }); } diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index f63157c9743..2933ca7044a 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -242,7 +242,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (self->_disconnected) { isDisconnected = YES; } else { - GRPCAssert(self->_unmanagedChannel != NULL, NSInternalInconsistencyException, @"Channel should have valid unmanaged channel."); + GRPCAssert(self->_unmanagedChannel != NULL, NSInternalInconsistencyException, + @"Channel should have valid unmanaged channel."); NSString *serverAuthority = callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 905719f4642..aa7d60786ea 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -249,7 +249,8 @@ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path callOptions:(GRPCCallOptions *)callOptions { - GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, @"path and host cannot be nil."); + GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, + @"path and host cannot be nil."); if ((self = [super init])) { // Each completion queue consumes one thread. There's a trade to be made between creating and From 7500528b15b3a47343a6483c1b71857cbe00244a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 09:45:12 -0800 Subject: [PATCH 193/534] clang-format --- .../transport/cronet/client/secure/cronet_channel_create.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc index 1cb38f25b6d..6e08d27b21d 100644 --- a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc +++ b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc @@ -48,10 +48,12 @@ GRPCAPI grpc_channel* grpc_cronet_secure_channel_create( // Disable client authority filter when using Cronet grpc_arg disable_client_authority_filter_arg; - disable_client_authority_filter_arg.key = const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); + disable_client_authority_filter_arg.key = + const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); disable_client_authority_filter_arg.type = GRPC_ARG_INTEGER; disable_client_authority_filter_arg.value.integer = 1; - grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &disable_client_authority_filter_arg, 1); + grpc_channel_args* new_args = grpc_channel_args_copy_and_add( + args, &disable_client_authority_filter_arg, 1); grpc_transport* ct = grpc_create_cronet_transport(engine, target, new_args, reserved); From 6b6ab2bdc9d03ffe85398451342a140320aac1dd Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 12:22:38 -0800 Subject: [PATCH 194/534] Back to NSAssert --- src/objective-c/GRPCClient/GRPCCall.m | 37 +++++++++---------- .../GRPCClient/private/GRPCChannel.m | 22 +++++------ .../GRPCClient/private/GRPCChannelPool.m | 6 +-- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- .../private/GRPCSecureChannelFactory.m | 2 +- .../GRPCClient/private/GRPCWrappedCall.m | 4 +- .../GRPCClient/private/utilities.h | 19 ++-------- 7 files changed, 39 insertions(+), 53 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 4068c3b4608..788afeb6c3c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -68,8 +68,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @implementation GRPCRequestOptions - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { - GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, - @"Host and Path cannot be empty"); + NSAssert(host.length != 0 && path.length != 0, @"Host and Path cannot be empty"); if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -116,11 +115,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *_Nullable)callOptions { - GRPCAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, - NSInvalidArgumentException, @"Neither host nor path can be nil."); - GRPCAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, + NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, + @"Neither host nor path can be nil."); + NSAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); - GRPCAssert(responseHandler != nil, NSInvalidArgumentException, @"Response handler required."); + NSAssert(responseHandler != nil, @"Response handler required."); if ((self = [super init])) { _requestOptions = [requestOptions copy]; @@ -157,8 +156,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)start { dispatch_async(_dispatchQueue, ^{ - GRPCAssert(!self->_started, NSInternalInconsistencyException, @"Call already started."); - GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call already canceled."); + NSAssert(!self->_started, @"Call already started."); + NSAssert(!self->_canceled, @"Call already canceled."); self->_started = YES; if (!self->_callOptions) { self->_callOptions = [[GRPCCallOptions alloc] init]; @@ -218,7 +217,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { dispatch_async(_dispatchQueue, ^{ - GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call already canceled."); + NSAssert(!self->_canceled, @"Call already canceled."); self->_canceled = YES; if (self->_call) { [self->_call cancel]; @@ -247,9 +246,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(NSData *)data { dispatch_async(_dispatchQueue, ^{ - GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); - GRPCAssert(!self->_finished, NSInternalInconsistencyException, - @"Call is half-closed before sending data."); + NSAssert(!self->_canceled, @"Call arleady canceled."); + NSAssert(!self->_finished, @"Call is half-closed before sending data."); if (self->_pipe) { [self->_pipe writeValue:data]; } @@ -258,9 +256,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)finish { dispatch_async(_dispatchQueue, ^{ - GRPCAssert(self->_started, NSInternalInconsistencyException, @"Call not started."); - GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); - GRPCAssert(!self->_finished, NSInternalInconsistencyException, @"Call already half-closed."); + NSAssert(self->_started, @"Call not started."); + NSAssert(!self->_canceled, @"Call arleady canceled."); + NSAssert(!self->_finished, @"Call already half-closed."); if (self->_pipe) { [self->_pipe writesFinishedWithError:nil]; } @@ -409,10 +407,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. - GRPCAssert(host && path, NSInvalidArgumentException, @"Neither host nor path can be nil."); - GRPCAssert(safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, + NSAssert(host && path, @"Neither host nor path can be nil."); + NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); - GRPCAssert(requestWriter.state == GRXWriterStateNotStarted, NSInvalidArgumentException, + NSAssert(requestWriter.state == GRXWriterStateNotStarted, @"The requests writer can't be already started."); if ((self = [super init])) { _host = [host copy]; @@ -798,8 +796,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = callOptions; } - GRPCAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, - NSInvalidArgumentException, + NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); if (_callOptions.authTokenProvider != nil) { @synchronized(self) { diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 2933ca7044a..ab084fba480 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -40,8 +40,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannelConfiguration - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { - GRPCAssert(host.length, NSInvalidArgumentException, @"Host must not be empty."); - GRPCAssert(callOptions != nil, NSInvalidArgumentException, @"callOptions must not be empty."); + NSAssert(host.length, @"Host must not be empty."); + NSAssert(callOptions != nil, @"callOptions must not be empty."); if ((self = [super init])) { _host = [host copy]; _callOptions = [callOptions copy]; @@ -193,9 +193,9 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (nullable instancetype)initWithChannelConfiguration: (GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay { - GRPCAssert(channelConfiguration != nil, NSInvalidArgumentException, + NSAssert(channelConfiguration != nil, @"channelConfiguration must not be empty."); - GRPCAssert(destroyDelay > 0, NSInvalidArgumentException, @"destroyDelay must be greater than 0."); + NSAssert(destroyDelay > 0, @"destroyDelay must be greater than 0."); if ((self = [super init])) { _configuration = [channelConfiguration copy]; if (@available(iOS 8.0, *)) { @@ -208,7 +208,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; // Create gRPC core channel object. NSString *host = channelConfiguration.host; - GRPCAssert(host.length != 0, NSInvalidArgumentException, @"host cannot be nil"); + NSAssert(host.length != 0, @"host cannot be nil"); NSDictionary *channelArgs; if (channelConfiguration.callOptions.additionalChannelArgs.count != 0) { NSMutableDictionary *args = [channelConfiguration.channelArgs mutableCopy]; @@ -233,22 +233,22 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions disconnected:(BOOL *)disconnected { - GRPCAssert(path.length, NSInvalidArgumentException, @"path must not be empty."); - GRPCAssert(queue, NSInvalidArgumentException, @"completionQueue must not be empty."); - GRPCAssert(callOptions, NSInvalidArgumentException, @"callOptions must not be empty."); + NSAssert(path.length, @"path must not be empty."); + NSAssert(queue, @"completionQueue must not be empty."); + NSAssert(callOptions, @"callOptions must not be empty."); __block BOOL isDisconnected = NO; __block grpc_call *call = NULL; dispatch_sync(_dispatchQueue, ^{ if (self->_disconnected) { isDisconnected = YES; } else { - GRPCAssert(self->_unmanagedChannel != NULL, NSInternalInconsistencyException, + NSAssert(self->_unmanagedChannel != NULL, @"Channel should have valid unmanaged channel."); NSString *serverAuthority = callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; - GRPCAssert(timeout >= 0, NSInvalidArgumentException, @"Invalid timeout"); + NSAssert(timeout >= 0, @"Invalid timeout"); grpc_slice host_slice = grpc_empty_slice(); if (serverAuthority) { host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); @@ -291,7 +291,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (void)unref { NSLog(@"unref"); dispatch_async(_dispatchQueue, ^{ - GRPCAssert(self->_refcount > 0, NSInternalInconsistencyException, @"Illegal reference count."); + NSAssert(self->_refcount > 0, @"Illegal reference count."); self->_refcount--; if (self->_refcount == 0 && !self->_disconnected) { // Start timer. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 85ca527277c..6745010bd49 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -44,7 +44,7 @@ static dispatch_once_t gInitChannelPool; + (nullable instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ gChannelPool = [[GRPCChannelPool alloc] init]; - GRPCAssert(gChannelPool != nil, NSMallocException, @"Cannot initialize global channel pool."); + NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; } @@ -69,8 +69,8 @@ static dispatch_once_t gInitChannelPool; - (GRPCChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions destroyDelay:(NSTimeInterval)destroyDelay { - GRPCAssert(host.length > 0, NSInvalidArgumentException, @"Host must not be empty."); - GRPCAssert(callOptions != nil, NSInvalidArgumentException, @"callOptions must not be empty."); + NSAssert(host.length > 0, @"Host must not be empty."); + NSAssert(callOptions != nil, @"callOptions must not be empty."); GRPCChannel *channel; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 5fc7427b689..b693b926bad 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -122,7 +122,7 @@ static NSMutableDictionary *gHostCache; if (_transportType == GRPCTransportTypeInsecure) { options.transportType = GRPCTransportTypeInsecure; } else { - GRPCAssert(_transportType == GRPCTransportTypeDefault, NSInvalidArgumentException, + NSAssert(_transportType == GRPCTransportTypeDefault, @"Invalid transport type"); options.transportType = GRPCTransportTypeCronet; } diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 57bd40d6787..f5e7a2b9e20 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -83,7 +83,7 @@ NS_ASSUME_NONNULL_BEGIN if (errorPtr) { *errorPtr = defaultRootsError; } - GRPCAssertWithArgument( + NSAssert( defaultRootsASCII, NSObjectNotAvailableException, @"Could not read gRPCCertificates.bundle/roots.pem. This file, " "with the root certificates, is needed to establish secure (TLS) connections. " diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index aa7d60786ea..ae7f07f1192 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -249,7 +249,7 @@ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path callOptions:(GRPCCallOptions *)callOptions { - GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, + NSAssert(host.length != 0 && path.length != 0, @"path and host cannot be nil."); if ((self = [super init])) { @@ -261,6 +261,7 @@ do { _channel = [[GRPCChannelPool sharedInstance] channelWithHost:host callOptions:callOptions]; if (_channel == nil) { + NSAssert(_channel != nil, @"Failed to get a channel for the host."); NSLog(@"Failed to get a channel for the host."); return nil; } @@ -272,6 +273,7 @@ // connectivity monitor disconnection). } while (_call == NULL && disconnected); if (_call == nil) { + NSAssert(_channel != nil, @"Failed to get a channel for the host."); NSLog(@"Failed to create a call."); return nil; } diff --git a/src/objective-c/GRPCClient/private/utilities.h b/src/objective-c/GRPCClient/private/utilities.h index 3e51730d637..8f6baadcf7b 100644 --- a/src/objective-c/GRPCClient/private/utilities.h +++ b/src/objective-c/GRPCClient/private/utilities.h @@ -18,19 +18,6 @@ #import -/** Raise exception when condition not met. Disregard NS_BLOCK_ASSERTIONS. */ -#define GRPCAssert(condition, errorType, errorString) \ - do { \ - if (!(condition)) { \ - [NSException raise:(errorType)format:(errorString)]; \ - } \ - } while (0) - -/** The same as GRPCAssert but allows arguments to be put in the raised string. - */ -#define GRPCAssertWithArgument(condition, errorType, errorFormat, ...) \ - do { \ - if (!(condition)) { \ - [NSException raise:(errorType)format:(errorFormat), __VA_ARGS__]; \ - } \ - } while (0) +/** Raise exception when condition not met. */ +#define GRPCAssert(condition, errorString) \ + NSAssert(condition, errorString) From 8a762d447813db1b1c3fe52b24e638581235460e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 12:56:08 -0800 Subject: [PATCH 195/534] Polish nullability + something else --- src/objective-c/GRPCClient/GRPCCall.h | 28 +++++------ src/objective-c/GRPCClient/GRPCCall.m | 4 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 46 +++++++++---------- .../GRPCClient/private/GRPCChannel.h | 2 +- .../GRPCClient/private/GRPCChannel.m | 10 ++-- .../GRPCClient/private/GRPCChannelFactory.h | 4 +- .../GRPCClient/private/GRPCChannelPool.m | 2 +- .../private/GRPCConnectivityMonitor.m | 4 +- .../private/GRPCCronetChannelFactory.m | 22 +++------ .../private/GRPCInsecureChannelFactory.m | 10 ++-- .../private/GRPCSecureChannelFactory.m | 22 ++++----- src/objective-c/ProtoRPC/ProtoRPC.h | 12 ++--- src/objective-c/ProtoRPC/ProtoRPC.m | 14 +++--- src/objective-c/tests/InteropTests.m | 8 ++-- 14 files changed, 86 insertions(+), 102 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index bde69f01c52..fcda4dc8acd 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -159,14 +159,14 @@ extern NSString *const kGRPCTrailersKey; * Issued when initial metadata is received from the server. The task must be scheduled onto the * dispatch queue in property \a dispatchQueue. */ -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; +- (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; /** * Issued when a message is received from the server. The message is the raw data received from the * server, with decompression and without proto deserialization. The task must be scheduled onto the * dispatch queue in property \a dispatchQueue. */ -- (void)receivedRawMessage:(NSData *_Nullable)message; +- (void)receivedRawMessage:(nullable NSData *)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -175,8 +175,8 @@ extern NSString *const kGRPCTrailersKey; * error descriptions. The task must be scheduled onto the dispatch queue in property * \a dispatchQueue. */ -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error; +- (void)closedWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata + error:(nullable NSError *)error; @required @@ -234,7 +234,7 @@ extern NSString *const kGRPCTrailersKey; */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler - callOptions:(GRPCCallOptions *_Nullable)callOptions + callOptions:(nullable GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; /** * Convenience initializer for a call that uses default call options (see GRPCCallOptions.m for @@ -342,9 +342,9 @@ NS_ASSUME_NONNULL_END * 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 _Null_unspecified)initWithHost:(NSString *_Null_unspecified)host - path:(NSString *_Null_unspecified)path - requestsWriter:(GRXWriter *_Null_unspecified)requestWriter; +- (null_unspecified instancetype)initWithHost:(null_unspecified NSString *)host + path:(null_unspecified NSString *)path + requestsWriter:(null_unspecified GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -356,11 +356,11 @@ NS_ASSUME_NONNULL_END * The following methods are deprecated. */ + (void)setCallSafety:(GRPCCallSafety)callSafety - host:(NSString *_Null_unspecified)host - path:(NSString *_Null_unspecified)path; + host:(null_unspecified NSString *)host + path:(null_unspecified NSString *)path; @property(null_unspecified, atomic, copy, readwrite) NSString *serverName; @property NSTimeInterval timeout; -- (void)setResponseDispatchQueue:(dispatch_queue_t _Null_unspecified)queue; +- (void)setResponseDispatchQueue:(null_unspecified dispatch_queue_t)queue; @end @@ -371,11 +371,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (id _Null_unspecified)objectForKeyedSubscript:(id _Null_unspecified)key; -- (void)setObject:(id _Null_unspecified)obj forKeyedSubscript:(id _Null_unspecified)key; +- (null_unspecified id)objectForKeyedSubscript:(null_unspecified id)key; +- (void)setObject:(null_unspecified id)obj forKeyedSubscript:(null_unspecified id)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(id _Null_unspecified)key; +- (void)removeObjectForKey:(null_unspecified id)key; @end #pragma clang diagnostic push diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 788afeb6c3c..68b51d8c846 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -114,7 +114,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler - callOptions:(GRPCCallOptions *_Nullable)callOptions { + callOptions:(GRPCCallOptions *)callOptions { NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, @"Neither host nor path can be nil."); NSAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, @@ -134,7 +134,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (@available(iOS 8.0, *)) { _dispatchQueue = dispatch_queue_create( NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { // Fallback on earlier versions _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index bb8a1d251a9..61d85642863 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -78,7 +78,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * :authority header field of the call and performs an extra check that server's certificate * matches the :authority header. */ -@property(copy, readonly) NSString *serverAuthority; +@property(copy, readonly, nullable) NSString *serverAuthority; /** * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to @@ -94,18 +94,18 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * request's "authorization" header field. This parameter should not be used simultaneously with * \a authTokenProvider. */ -@property(copy, readonly) NSString *oauth2AccessToken; +@property(copy, readonly, nullable) NSString *oauth2AccessToken; /** * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. */ -@property(readonly) id authTokenProvider; +@property(readonly, nullable) id authTokenProvider; /** * Initial metadata key-value pairs that should be included in the request. */ -@property(copy, readonly) NSDictionary *initialMetadata; +@property(copy, readonly, nullable) NSDictionary *initialMetadata; // Channel parameters; take into account of channel signature. @@ -113,7 +113,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * Custom string that is prefixed to a request's user-agent header field before gRPC's internal * user-agent string. */ -@property(copy, readonly) NSString *userAgentPrefix; +@property(copy, readonly, nullable) NSString *userAgentPrefix; /** * The size limit for the response received from server. If it is exceeded, an error with status @@ -152,7 +152,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * Specify channel args to be used for this call. For a list of channel args available, see * grpc/grpc_types.h */ -@property(copy, readonly) NSDictionary *additionalChannelArgs; +@property(copy, readonly, nullable) NSDictionary *additionalChannelArgs; // Parameters for SSL authentication. @@ -160,17 +160,17 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default * root certificates. */ -@property(copy, readonly) NSString *PEMRootCertificates; +@property(copy, readonly, nullable) NSString *PEMRootCertificates; /** * PEM format private key for client authentication, if required by the server. */ -@property(copy, readonly) NSString *PEMPrivateKey; +@property(copy, readonly, nullable) NSString *PEMPrivateKey; /** * PEM format certificate chain for client authentication, if required by the server. */ -@property(copy, readonly) NSString *PEMCertChain; +@property(copy, readonly, nullable) NSString *PEMCertChain; /** * Select the transport type to be used for this call. @@ -180,13 +180,13 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Override the hostname during the TLS hostname validation process. */ -@property(copy, readonly) NSString *hostNameOverride; +@property(copy, readonly, nullable) NSString *hostNameOverride; /** * A string that specify the domain where channel is being cached. Channels with different domains * will not get cached to the same connection. */ -@property(copy, readonly) NSString *channelPoolDomain; +@property(copy, readonly, nullable) NSString *channelPoolDomain; /** * Channel id allows control of channel caching within a channelPoolDomain. A call with a unique @@ -199,7 +199,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Return if the channel options are equal to another object. */ -- (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; +- (BOOL)hasChannelOptionsEqualTo:(nonnull GRPCCallOptions *)callOptions; /** * Hash for channel options. @@ -219,7 +219,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * :authority header field of the call and performs an extra check that server's certificate * matches the :authority header. */ -@property(copy, readwrite) NSString *serverAuthority; +@property(copy, readwrite, nullable) NSString *serverAuthority; /** * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to @@ -236,18 +236,18 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * request's "authorization" header field. This parameter should not be used simultaneously with * \a authTokenProvider. */ -@property(copy, readwrite) NSString *oauth2AccessToken; +@property(copy, readwrite, nullable) NSString *oauth2AccessToken; /** * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. */ -@property(readwrite) id authTokenProvider; +@property(readwrite, nullable) id authTokenProvider; /** * Initial metadata key-value pairs that should be included in the request. */ -@property(copy, readwrite) NSDictionary *initialMetadata; +@property(copy, readwrite, nullable) NSDictionary *initialMetadata; // Channel parameters; take into account of channel signature. @@ -255,7 +255,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * Custom string that is prefixed to a request's user-agent header field before gRPC's internal * user-agent string. */ -@property(copy, readwrite) NSString *userAgentPrefix; +@property(copy, readwrite, nullable) NSString *userAgentPrefix; /** * The size limit for the response received from server. If it is exceeded, an error with status @@ -296,7 +296,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * Specify channel args to be used for this call. For a list of channel args available, see * grpc/grpc_types.h */ -@property(copy, readwrite) NSDictionary *additionalChannelArgs; +@property(copy, readwrite, nullable) NSDictionary *additionalChannelArgs; // Parameters for SSL authentication. @@ -304,17 +304,17 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default * root certificates. */ -@property(copy, readwrite) NSString *PEMRootCertificates; +@property(copy, readwrite, nullable) NSString *PEMRootCertificates; /** * PEM format private key for client authentication, if required by the server. */ -@property(copy, readwrite) NSString *PEMPrivateKey; +@property(copy, readwrite, nullable) NSString *PEMPrivateKey; /** * PEM format certificate chain for client authentication, if required by the server. */ -@property(copy, readwrite) NSString *PEMCertChain; +@property(copy, readwrite, nullable) NSString *PEMCertChain; /** * Select the transport type to be used for this call. @@ -324,7 +324,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Override the hostname during the TLS hostname validation process. */ -@property(copy, readwrite) NSString *hostNameOverride; +@property(copy, readwrite, nullable) NSString *hostNameOverride; /** * A string that specify the domain where channel is being cached. Channels with different domains @@ -332,7 +332,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * domain 'io.grpc.example' so that its calls do not reuse the channel created by other modules in * the same process. */ -@property(copy, readwrite) NSString *channelPoolDomain; +@property(copy, readwrite, nullable) NSString *channelPoolDomain; /** * Channel id allows a call to force creating a new channel (connection) rather than using a cached diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 32e68bb2625..4dbe0c276ce 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -85,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions - disconnected:(BOOL *_Nullable)disconnected; + disconnected:(nullable BOOL *)disconnected; /** * Unref the channel when a call is done. It also decreases the channel's refcount. If the refcount diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index ab084fba480..de3302598ef 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -39,7 +39,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannelConfiguration -- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { +- (instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { NSAssert(host.length, @"Host must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); if ((self = [super init])) { @@ -143,7 +143,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; return args; } -- (nonnull id)copyWithZone:(nullable NSZone *)zone { +- (id)copyWithZone:(NSZone *)zone { GRPCChannelConfiguration *newConfig = [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; @@ -184,13 +184,13 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } @synthesize disconnected = _disconnected; -- (nullable instancetype)initWithChannelConfiguration: +- (instancetype)initWithChannelConfiguration: (GRPCChannelConfiguration *)channelConfiguration { return [self initWithChannelConfiguration:channelConfiguration destroyDelay:kDefaultChannelDestroyDelay]; } -- (nullable instancetype)initWithChannelConfiguration: +- (instancetype)initWithChannelConfiguration: (GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay { NSAssert(channelConfiguration != nil, @@ -201,7 +201,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (@available(iOS 8.0, *)) { _dispatchQueue = dispatch_queue_create( NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h index 3a3500fc95e..a934e966e9d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -26,8 +26,8 @@ NS_ASSUME_NONNULL_BEGIN @protocol GRPCChannelFactory /** Create a channel with specific channel args to a specific host. */ -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args; +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSDictionary *)args; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 6745010bd49..72554ca6dc8 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -41,7 +41,7 @@ static dispatch_once_t gInitChannelPool; NSMutableDictionary *_channelPool; } -+ (nullable instancetype)sharedInstance { ++ (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ gChannelPool = [[GRPCChannelPool alloc] init]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m index a36788b35aa..bb8618ff335 100644 --- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m +++ b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m @@ -76,14 +76,14 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach } } -+ (void)registerObserver:(_Nonnull id)observer selector:(SEL)selector { ++ (void)registerObserver:(id)observer selector:(SEL)selector { [[NSNotificationCenter defaultCenter] addObserver:observer selector:selector name:kGRPCConnectivityNotification object:nil]; } -+ (void)unregisterObserver:(_Nonnull id)observer { ++ (void)unregisterObserver:(id)observer { [[NSNotificationCenter defaultCenter] removeObserver:observer]; } diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 781881d211b..74ea9723b3d 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -26,13 +26,11 @@ #import #include -NS_ASSUME_NONNULL_BEGIN - @implementation GRPCCronetChannelFactory { stream_engine *_cronetEngine; } -+ (instancetype _Nullable)sharedInstance { ++ (instancetype)sharedInstance { static GRPCCronetChannelFactory *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -41,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN return instance; } -- (instancetype _Nullable)initWithEngine:(stream_engine *)engine { +- (instancetype)initWithEngine:(stream_engine *)engine { if (!engine) { [NSException raise:NSInvalidArgumentException format:@"Cronet engine is NULL. Set it first."]; return nil; @@ -52,8 +50,8 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *)args { grpc_channel_args *channelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); @@ -63,22 +61,18 @@ NS_ASSUME_NONNULL_BEGIN @end -NS_ASSUME_NONNULL_END - #else -NS_ASSUME_NONNULL_BEGIN - @implementation GRPCCronetChannelFactory -+ (instancetype _Nullable)sharedInstance { ++ (instancetype)sharedInstance { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return nil; } -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *)args { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return NULL; @@ -86,6 +80,4 @@ NS_ASSUME_NONNULL_BEGIN @end -NS_ASSUME_NONNULL_END - #endif diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index 99698877124..3e9ebe7ae02 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -21,11 +21,9 @@ #import "ChannelArgsUtil.h" #import "GRPCChannel.h" -NS_ASSUME_NONNULL_BEGIN - @implementation GRPCInsecureChannelFactory -+ (instancetype _Nullable)sharedInstance { ++ (instancetype)sharedInstance { static GRPCInsecureChannelFactory *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -34,8 +32,8 @@ NS_ASSUME_NONNULL_BEGIN return instance; } -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); @@ -44,5 +42,3 @@ NS_ASSUME_NONNULL_BEGIN } @end - -NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index f5e7a2b9e20..2e7f1a0dbe2 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -24,15 +24,13 @@ #import "GRPCChannel.h" #import "utilities.h" -NS_ASSUME_NONNULL_BEGIN - @implementation GRPCSecureChannelFactory { grpc_channel_credentials *_channelCreds; } -+ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString *_Nullable)rootCerts - privateKey:(NSString *_Nullable)privateKey - certChain:(NSString *_Nullable)certChain ++ (instancetype)factoryWithPEMRootCertificates:(NSString *)rootCerts + privateKey:(NSString *)privateKey + certChain:(NSString *)certChain error:(NSError **)errorPtr { return [[self alloc] initWithPEMRootCerts:rootCerts privateKey:privateKey @@ -40,7 +38,7 @@ NS_ASSUME_NONNULL_BEGIN error:errorPtr]; } -- (NSData *_Nullable)nullTerminatedDataWithString:(NSString *_Nullable)string { +- (NSData *)nullTerminatedDataWithString:(NSString *)string { // dataUsingEncoding: does not return a null-terminated string. NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; if (data == nil) { @@ -51,9 +49,9 @@ NS_ASSUME_NONNULL_BEGIN return nullTerminated; } -- (instancetype _Nullable)initWithPEMRootCerts:(NSString *_Nullable)rootCerts - privateKey:(NSString *_Nullable)privateKey - certChain:(NSString *_Nullable)certChain +- (instancetype)initWithPEMRootCerts:(NSString *)rootCerts + privateKey:(NSString *)privateKey + certChain:(NSString *)certChain error:(NSError **)errorPtr { static NSData *defaultRootsASCII; static NSError *defaultRootsError; @@ -117,8 +115,8 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); @@ -133,5 +131,3 @@ NS_ASSUME_NONNULL_BEGIN } @end - -NS_ASSUME_NONNULL_END diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index b0f4ced99e8..dc776368a8f 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -33,13 +33,13 @@ NS_ASSUME_NONNULL_BEGIN /** * Issued when initial metadata is received from the server. The task must be scheduled onto the * dispatch queue in property \a dispatchQueue. */ -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; +- (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; /** * Issued when a message is received from the server. The message is the deserialized proto object. * The task must be scheduled onto the dispatch queue in property \a dispatchQueue. */ -- (void)receivedProtoMessage:(GPBMessage *_Nullable)message; +- (void)receivedProtoMessage:(nullable GPBMessage *)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -48,8 +48,8 @@ NS_ASSUME_NONNULL_BEGIN * error descriptions. The task must be scheduled onto the dispatch queue in property * \a dispatchQueue. */ -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error; +- (void)closedWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata + error:(nullable NSError *)error; @required @@ -75,7 +75,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message responseHandler:(id)handler - callOptions:(GRPCCallOptions *_Nullable)callOptions + callOptions:(nullable GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** @@ -100,7 +100,7 @@ NS_ASSUME_NONNULL_BEGIN */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler - callOptions:(GRPCCallOptions *_Nullable)callOptions + callOptions:(nullable GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 34891e8953b..f99da45fef9 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -52,7 +52,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message responseHandler:(id)handler - callOptions:(GRPCCallOptions *_Nullable)callOptions + callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { if ((self = [super init])) { _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions @@ -88,7 +88,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler - callOptions:(GRPCCallOptions *_Nullable)callOptions + callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; @@ -108,7 +108,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing if (@available(iOS 8.0, *)) { _dispatchQueue = dispatch_queue_create( NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } @@ -171,7 +171,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing }); } -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { dispatch_async(_dispatchQueue, ^{ if (initialMetadata != nil && [self->_handler respondsToSelector:@selector(initialMetadata:)]) { [self->_handler receivedInitialMetadata:initialMetadata]; @@ -179,7 +179,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing }); } -- (void)receivedRawMessage:(NSData *_Nullable)message { +- (void)receivedRawMessage:(NSData *)message { dispatch_async(_dispatchQueue, ^{ if (self->_handler && message != nil) { NSError *error = nil; @@ -202,8 +202,8 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing }); } -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error { +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata + error:(NSError *)error { dispatch_async(_dispatchQueue, ^{ if ([self->_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { [self->_handler closedWithTrailingMetadata:trailingMetadata error:error]; diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index c42718f15ee..dcc8f1b589a 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -102,7 +102,7 @@ BOOL isRemoteInteropTest(NSString *host) { return self; } -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { dispatch_async(_dispatchQueue, ^{ if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); @@ -110,7 +110,7 @@ BOOL isRemoteInteropTest(NSString *host) { }); } -- (void)receivedProtoMessage:(GPBMessage *_Nullable)message { +- (void)receivedProtoMessage:(GPBMessage *)message { dispatch_async(_dispatchQueue, ^{ if (_messageCallback) { _messageCallback(message); @@ -118,8 +118,8 @@ BOOL isRemoteInteropTest(NSString *host) { }); } -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error { +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata + error:(NSError *)error { dispatch_async(_dispatchQueue, ^{ if (_closeCallback) { _closeCallback(trailingMetadata, error); From 0911e489e3fe22e2ca5d7c927dac83358f2f05b7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 15 Nov 2018 13:55:56 -0800 Subject: [PATCH 196/534] Add a method to check whether the message was received successfully --- include/grpcpp/impl/codegen/call_op_set.h | 6 ++++-- include/grpcpp/impl/codegen/interceptor.h | 3 +++ include/grpcpp/impl/codegen/interceptor_common.h | 10 ++++++++++ test/cpp/end2end/client_interceptors_end2end_test.cc | 12 ++++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index aae8b9d3e37..3699ec94f2f 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -406,12 +406,13 @@ class CallOpRecvMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { + if (message_ == nullptr) return; interceptor_methods->SetRecvMessage(message_, &got_message); } void SetFinishInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - if (!got_message) return; + if (message_ == nullptr) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); } @@ -501,12 +502,13 @@ class CallOpGenericRecvMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { + if (!deserialize_) return; interceptor_methods->SetRecvMessage(message_, &got_message); } void SetFinishInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - if (!got_message) return; + if (!deserialize_) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); } diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 943376a5451..b977c350166 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -103,6 +103,9 @@ class InterceptorBatchMethods { // is already deserialized virtual void* GetRecvMessage() = 0; + // Checks whether the RECV MESSAGE op completed successfully + virtual bool GetRecvMessageStatus() = 0; + // Returns a modifiable multimap of the received initial metadata virtual std::multimap* GetRecvInitialMetadata() = 0; diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index d23b71f8a77..b2e92dd6f3d 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -103,6 +103,8 @@ class InterceptorBatchMethodsImpl void* GetRecvMessage() override { return recv_message_; } + bool GetRecvMessageStatus() override { return *got_message_; } + std::multimap* GetRecvInitialMetadata() override { return recv_initial_metadata_->map(); @@ -432,6 +434,14 @@ class CancelInterceptorBatchMethods return nullptr; } + bool GetRecvMessageStatus() override { + GPR_CODEGEN_ASSERT( + false && + "It is illegal to call GetRecvMessageStatus on a method which " + "has a Cancel notification"); + return false; + } + std::multimap* GetRecvInitialMetadata() override { GPR_CODEGEN_ASSERT(false && diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 459788ba519..4d4760a6524 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -325,6 +325,12 @@ class ServerStreamingRpcHijackingInterceptor static_cast(methods->GetRecvMessage()); resp->set_message("Hello"); } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { + // Only the last message will be a failure + EXPECT_FALSE(got_failed_message_); + got_failed_message_ = !methods->GetRecvMessageStatus(); + } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { auto* map = methods->GetRecvTrailingMetadata(); @@ -341,11 +347,16 @@ class ServerStreamingRpcHijackingInterceptor } } + static bool GotFailedMessage() { return got_failed_message_; } + private: experimental::ClientRpcInfo* info_; + static bool got_failed_message_; int count_ = 0; }; +bool ServerStreamingRpcHijackingInterceptor::got_failed_message_ = false; + class ServerStreamingRpcHijackingInterceptorFactory : public experimental::ClientInterceptorFactoryInterface { public: @@ -634,6 +645,7 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingHijackingTest) { auto channel = experimental::CreateCustomChannelWithInterceptors( server_address_, InsecureChannelCredentials(), args, std::move(creators)); MakeServerStreamingCall(channel); + EXPECT_TRUE(ServerStreamingRpcHijackingInterceptor::GotFailedMessage()); } TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { From 57464321214a5ce34e5de1868ce4eb3624ebdebb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 14:00:51 -0800 Subject: [PATCH 197/534] Fix handler release - Part 1 --- src/objective-c/GRPCClient/GRPCCall.h | 9 +++---- src/objective-c/ProtoRPC/ProtoRPC.h | 7 ++---- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 24 +++++++------------ src/objective-c/tests/InteropTests.m | 24 +++++++------------ 4 files changed, 23 insertions(+), 41 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index fcda4dc8acd..7f80c17f1f3 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -156,15 +156,13 @@ extern NSString *const kGRPCTrailersKey; @optional /** - * Issued when initial metadata is received from the server. The task must be scheduled onto the - * dispatch queue in property \a dispatchQueue. + * Issued when initial metadata is received from the server. */ - (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; /** * Issued when a message is received from the server. The message is the raw data received from the - * server, with decompression and without proto deserialization. The task must be scheduled onto the - * dispatch queue in property \a dispatchQueue. + * server, with decompression and without proto deserialization. */ - (void)receivedRawMessage:(nullable NSData *)message; @@ -172,8 +170,7 @@ extern NSString *const kGRPCTrailersKey; * Issued when a call finished. If the call finished successfully, \a error is nil and \a * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error * is non-nil and contains the corresponding error information, including gRPC error codes and - * error descriptions. The task must be scheduled onto the dispatch queue in property - * \a dispatchQueue. + * error descriptions. */ - (void)closedWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index dc776368a8f..569aaa79e4d 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -31,13 +31,11 @@ NS_ASSUME_NONNULL_BEGIN @optional /** - * Issued when initial metadata is received from the server. The task must be scheduled onto the - * dispatch queue in property \a dispatchQueue. */ + * Issued when initial metadata is received from the server. - (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; /** * Issued when a message is received from the server. The message is the deserialized proto object. - * The task must be scheduled onto the dispatch queue in property \a dispatchQueue. */ - (void)receivedProtoMessage:(nullable GPBMessage *)message; @@ -45,8 +43,7 @@ NS_ASSUME_NONNULL_BEGIN * Issued when a call finished. If the call finished successfully, \a error is nil and \a * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error * is non-nil and contains the corresponding error information, including gRPC error codes and - * error descriptions. The task must be scheduled onto the dispatch queue in property - * \a dispatchQueue. + * error descriptions. */ - (void)closedWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index 28f94cd8c77..e49f58ae9d3 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -82,28 +82,22 @@ static const NSTimeInterval kTestTimeout = 16; } - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { - dispatch_async(_dispatchQueue, ^{ - if (self->_initialMetadataCallback) { - self->_initialMetadataCallback(initialMetadata); - } - }); + if (self->_initialMetadataCallback) { + self->_initialMetadataCallback(initialMetadata); + } } - (void)receivedRawMessage:(GPBMessage *_Nullable)message { - dispatch_async(_dispatchQueue, ^{ - if (self->_messageCallback) { - self->_messageCallback(message); - } - }); + if (self->_messageCallback) { + self->_messageCallback(message); + } } - (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata error:(NSError *_Nullable)error { - dispatch_async(_dispatchQueue, ^{ - if (self->_closeCallback) { - self->_closeCallback(trailingMetadata, error); - } - }); + if (self->_closeCallback) { + self->_closeCallback(trailingMetadata, error); + } } - (dispatch_queue_t)dispatchQueue { diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index dcc8f1b589a..8754bd5ccaf 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -103,28 +103,22 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { - dispatch_async(_dispatchQueue, ^{ - if (_initialMetadataCallback) { - _initialMetadataCallback(initialMetadata); - } - }); + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } } - (void)receivedProtoMessage:(GPBMessage *)message { - dispatch_async(_dispatchQueue, ^{ - if (_messageCallback) { - _messageCallback(message); - } - }); + if (_messageCallback) { + _messageCallback(message); + } } - (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - dispatch_async(_dispatchQueue, ^{ - if (_closeCallback) { - _closeCallback(trailingMetadata, error); - } - }); + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } } - (dispatch_queue_t)dispatchQueue { From ffeb0e682393e5b76d732e0b034c71f3837b9e57 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 14:56:50 -0800 Subject: [PATCH 198/534] Add *if* after assert --- src/objective-c/GRPCClient/GRPCCall.m | 54 +++++++++++++++++++ .../GRPCClient/private/GRPCChannel.m | 25 +++++++-- .../GRPCClient/private/GRPCChannelPool.m | 3 ++ 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 68b51d8c846..f340e2bd8c2 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -69,6 +69,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { NSAssert(host.length != 0 && path.length != 0, @"Host and Path cannot be empty"); + if (host.length == 0) { + host = [NSString string]; + } + if (path.length == 0) { + path = [NSString string]; + } if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -120,6 +126,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; NSAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); NSAssert(responseHandler != nil, @"Response handler required."); + if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { + return nil; + } + if (requestOptions.safety > GRPCCallSafetyCacheableRequest) { + return nil; + } + if (responseHandler == nil) { + return nil; + } + if ((self = [super init])) { _requestOptions = [requestOptions copy]; @@ -158,6 +174,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_async(_dispatchQueue, ^{ NSAssert(!self->_started, @"Call already started."); NSAssert(!self->_canceled, @"Call already canceled."); + if (self->_started) { + return; + } + if (self->_canceled) { + return; + } + self->_started = YES; if (!self->_callOptions) { self->_callOptions = [[GRPCCallOptions alloc] init]; @@ -218,6 +241,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { dispatch_async(_dispatchQueue, ^{ NSAssert(!self->_canceled, @"Call already canceled."); + if (self->_canceled) { + return; + } + self->_canceled = YES; if (self->_call) { [self->_call cancel]; @@ -248,6 +275,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_async(_dispatchQueue, ^{ NSAssert(!self->_canceled, @"Call arleady canceled."); NSAssert(!self->_finished, @"Call is half-closed before sending data."); + if (self->_canceled) { + return; + } + if (self->_finished) { + return; + } + if (self->_pipe) { [self->_pipe writeValue:data]; } @@ -259,6 +293,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; NSAssert(self->_started, @"Call not started."); NSAssert(!self->_canceled, @"Call arleady canceled."); NSAssert(!self->_finished, @"Call already half-closed."); + if (!self->_started) { + return; + } + if (self->_canceled) { + return; + } + if (self->_finished) { + return; + } + if (self->_pipe) { [self->_pipe writesFinishedWithError:nil]; } @@ -412,6 +456,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; @"Invalid call safety value."); NSAssert(requestWriter.state == GRXWriterStateNotStarted, @"The requests writer can't be already started."); + if (!host || !path) { + return nil; + } + if (safety > GRPCCallSafetyCacheableRequest) { + return nil; + } + if (requestWriter.state != GRXWriterStateNotStarted) { + return nil; + } + if ((self = [super init])) { _host = [host copy]; _path = [path copy]; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index de3302598ef..a19802b0106 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -40,8 +40,11 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannelConfiguration - (instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { - NSAssert(host.length, @"Host must not be empty."); + NSAssert(host.length > 0, @"Host must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); + if (host.length == 0) return nil; + if (callOptions == nil) return nil; + if ((self = [super init])) { _host = [host copy]; _callOptions = [callOptions copy]; @@ -196,6 +199,9 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSAssert(channelConfiguration != nil, @"channelConfiguration must not be empty."); NSAssert(destroyDelay > 0, @"destroyDelay must be greater than 0."); + if (channelConfiguration == nil) return nil; + if (destroyDelay <= 0) return nil; + if ((self = [super init])) { _configuration = [channelConfiguration copy]; if (@available(iOS 8.0, *)) { @@ -219,6 +225,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } id factory = channelConfiguration.channelFactory; _unmanagedChannel = [factory createChannelWithHost:host channelArgs:channelArgs]; + NSAssert(_unmanagedChannel != NULL, @"Failed to create channel"); if (_unmanagedChannel == NULL) { NSLog(@"Unable to create channel."); return nil; @@ -233,9 +240,13 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions disconnected:(BOOL *)disconnected { - NSAssert(path.length, @"path must not be empty."); - NSAssert(queue, @"completionQueue must not be empty."); - NSAssert(callOptions, @"callOptions must not be empty."); + NSAssert(path.length > 0, @"path must not be empty."); + NSAssert(queue != nil, @"completionQueue must not be empty."); + NSAssert(callOptions != nil, @"callOptions must not be empty."); + if (path.length == 0) return nil; + if (queue == nil) return nil; + if (callOptions == nil) return nil; + __block BOOL isDisconnected = NO; __block grpc_call *call = NULL; dispatch_sync(_dispatchQueue, ^{ @@ -244,11 +255,13 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } else { NSAssert(self->_unmanagedChannel != NULL, @"Channel should have valid unmanaged channel."); + if (self->_unmanagedChannel == NULL) return; NSString *serverAuthority = callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); + if (timeout < 0) return; grpc_slice host_slice = grpc_empty_slice(); if (serverAuthority) { host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); @@ -292,6 +305,10 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSLog(@"unref"); dispatch_async(_dispatchQueue, ^{ NSAssert(self->_refcount > 0, @"Illegal reference count."); + if (self->_refcount == 0) { + NSLog(@"Illegal reference count."); + return; + } self->_refcount--; if (self->_refcount == 0 && !self->_disconnected) { // Start timer. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 72554ca6dc8..5e2e9bcfebb 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -71,6 +71,9 @@ static dispatch_once_t gInitChannelPool; destroyDelay:(NSTimeInterval)destroyDelay { NSAssert(host.length > 0, @"Host must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); + if (host.length == 0) return nil; + if (callOptions == nil) return nil; + GRPCChannel *channel; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; From d4ebd30eb2eb94f77ac9b52c44880e3d70c6aef0 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 15 Nov 2018 15:57:43 -0800 Subject: [PATCH 199/534] Add method to get status of send message op on POST_SEND_MESSAGE --- include/grpcpp/impl/codegen/call_op_set.h | 18 ++++++++++++++++-- include/grpcpp/impl/codegen/interceptor.h | 6 +++++- .../grpcpp/impl/codegen/interceptor_common.h | 10 ++++++++++ .../client_interceptors_end2end_test.cc | 18 ++++++++++++++++-- 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 1f2b88e9e14..f330679ffc9 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -315,9 +315,16 @@ class CallOpSendMessage { write_options_.Clear(); } void FinishOp(bool* status) { - send_buf_.Clear(); + if (!send_buf_.Valid()) { + return; + } if (hijacked_ && failed_send_) { + // Hijacking interceptor failed this Op *status = false; + } else if (!*status) { + // This Op was passed down to core and the Op failed + gpr_log(GPR_ERROR, "failure status"); + failed_send_ = true; } } @@ -330,7 +337,14 @@ class CallOpSendMessage { } void SetFinishInterceptionHookPoint( - InterceptorBatchMethodsImpl* interceptor_methods) {} + InterceptorBatchMethodsImpl* interceptor_methods) { + if (send_buf_.Valid()) { + interceptor_methods->AddInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_SEND_MESSAGE); + // We had already registered failed_send_ earlier. No need to do it again. + } + send_buf_.Clear(); + } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { hijacked_ = true; diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 47239332c86..154172dd814 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -41,9 +41,10 @@ class InterceptedMessage { }; enum class InterceptionHookPoints { - /* The first two in this list are for clients and servers */ + /* The first three in this list are for clients and servers */ PRE_SEND_INITIAL_METADATA, PRE_SEND_MESSAGE, + POST_SEND_MESSAGE, PRE_SEND_STATUS /* server only */, PRE_SEND_CLOSE /* client only */, /* The following three are for hijacked clients only and can only be @@ -85,6 +86,9 @@ class InterceptorBatchMethods { // sent virtual ByteBuffer* GetSendMessage() = 0; + // Checks whether the SEND MESSAGE op succeeded + virtual bool GetSendMessageStatus() = 0; + // Returns a modifiable multimap of the initial metadata to be sent virtual std::multimap* GetSendInitialMetadata() = 0; diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 601a929afe6..21326df73be 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -81,6 +81,8 @@ class InterceptorBatchMethodsImpl ByteBuffer* GetSendMessage() override { return send_message_; } + bool GetSendMessageStatus() override { return !*fail_send_message_; } + std::multimap* GetSendInitialMetadata() override { return send_initial_metadata_; } @@ -113,6 +115,7 @@ class InterceptorBatchMethodsImpl void FailHijackedSendMessage() override { GPR_CODEGEN_ASSERT(hooks_[static_cast( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)]); + gpr_log(GPR_ERROR, "failing"); *fail_send_message_ = true; } @@ -396,6 +399,13 @@ class CancelInterceptorBatchMethods return nullptr; } + bool GetSendMessageStatus() override { + GPR_CODEGEN_ASSERT( + false && + "It is illegal to call GetSendMessageStatus on a method which " + "has a Cancel notification"); + } + std::multimap* GetSendInitialMetadata() override { GPR_CODEGEN_ASSERT(false && "It is illegal to call GetSendInitialMetadata on a " diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 81efd154525..97947e73931 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -287,6 +287,13 @@ class ClientStreamingRpcHijackingInterceptor methods->FailHijackedSendMessage(); } } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_SEND_MESSAGE)) { + EXPECT_FALSE(got_failed_send_); + gpr_log(GPR_ERROR, "%d", got_failed_send_); + got_failed_send_ = !methods->GetSendMessageStatus(); + gpr_log(GPR_ERROR, "%d", got_failed_send_); + } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { auto* status = methods->GetRecvStatus(); @@ -299,10 +306,16 @@ class ClientStreamingRpcHijackingInterceptor } } + static bool GotFailedSend() { return got_failed_send_; } + private: experimental::ClientRpcInfo* info_; int count_ = 0; + static bool got_failed_send_; }; + +bool ClientStreamingRpcHijackingInterceptor::got_failed_send_ = false; + class ClientStreamingRpcHijackingInterceptorFactory : public experimental::ClientInterceptorFactoryInterface { public: @@ -602,10 +615,11 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingHijackingTest) { EXPECT_TRUE(writer->Write(req)); expected_resp += "Hello"; } - // Expect that the interceptor will reject the 11th message - EXPECT_FALSE(writer->Write(req)); + // The interceptor will reject the 11th message + writer->Write(req); Status s = writer->Finish(); EXPECT_EQ(s.ok(), false); + EXPECT_TRUE(ClientStreamingRpcHijackingInterceptor::GotFailedSend()); } TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { From 00c9c40004d011f01c72d253a530edb3364992bf Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 15 Nov 2018 16:00:33 -0800 Subject: [PATCH 200/534] Remove extraneous logging statements --- include/grpcpp/impl/codegen/call_op_set.h | 1 - include/grpcpp/impl/codegen/interceptor_common.h | 1 - test/cpp/end2end/client_interceptors_end2end_test.cc | 2 -- 3 files changed, 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index f330679ffc9..ac3ba17bd9d 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -323,7 +323,6 @@ class CallOpSendMessage { *status = false; } else if (!*status) { // This Op was passed down to core and the Op failed - gpr_log(GPR_ERROR, "failure status"); failed_send_ = true; } } diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 21326df73be..321691236be 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -115,7 +115,6 @@ class InterceptorBatchMethodsImpl void FailHijackedSendMessage() override { GPR_CODEGEN_ASSERT(hooks_[static_cast( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)]); - gpr_log(GPR_ERROR, "failing"); *fail_send_message_ = true; } diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 97947e73931..3708c11235a 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -290,9 +290,7 @@ class ClientStreamingRpcHijackingInterceptor if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::POST_SEND_MESSAGE)) { EXPECT_FALSE(got_failed_send_); - gpr_log(GPR_ERROR, "%d", got_failed_send_); got_failed_send_ = !methods->GetSendMessageStatus(); - gpr_log(GPR_ERROR, "%d", got_failed_send_); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { From 512c01bc574ab09129608bc501d80f06503c79a3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 16:59:31 -0800 Subject: [PATCH 201/534] Polish threading + something else --- src/objective-c/GRPCClient/GRPCCall.m | 241 ++++++++++-------- .../GRPCClient/private/GRPCChannel.m | 1 - src/objective-c/ProtoRPC/ProtoRPC.h | 1 + src/objective-c/ProtoRPC/ProtoRPC.m | 123 +++++---- 4 files changed, 209 insertions(+), 157 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index f340e2bd8c2..ede16b42e8c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -155,7 +155,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Fallback on earlier versions _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } - dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); + dispatch_set_target_queue(_dispatchQueue ,responseHandler.dispatchQueue); _started = NO; _canceled = NO; _finished = NO; @@ -171,161 +171,194 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)start { - dispatch_async(_dispatchQueue, ^{ - NSAssert(!self->_started, @"Call already started."); - NSAssert(!self->_canceled, @"Call already canceled."); - if (self->_started) { + GRPCCall *call = nil; + @synchronized (self) { + NSAssert(!_started, @"Call already started."); + NSAssert(!_canceled, @"Call already canceled."); + if (_started) { return; } - if (self->_canceled) { + if (_canceled) { return; } - self->_started = YES; - if (!self->_callOptions) { - self->_callOptions = [[GRPCCallOptions alloc] init]; + _started = YES; + if (!_callOptions) { + _callOptions = [[GRPCCallOptions alloc] init]; } - self->_call = [[GRPCCall alloc] initWithHost:self->_requestOptions.host - path:self->_requestOptions.path - callSafety:self->_requestOptions.safety - requestsWriter:self->_pipe - callOptions:self->_callOptions]; - if (self->_callOptions.initialMetadata) { - [self->_call.requestHeaders addEntriesFromDictionary:self->_callOptions.initialMetadata]; + _call = [[GRPCCall alloc] initWithHost:_requestOptions.host + path:_requestOptions.path + callSafety:_requestOptions.safety + requestsWriter:_pipe + callOptions:_callOptions]; + if (_callOptions.initialMetadata) { + [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; } + call = _call; + } - void (^valueHandler)(id value) = ^(id value) { - dispatch_async(self->_dispatchQueue, ^{ - if (self->_handler) { - if (!self->_initialMetadataPublished) { - self->_initialMetadataPublished = YES; - [self issueInitialMetadata:self->_call.responseHeaders]; - } - if (value) { - [self issueMessage:value]; - } + void (^valueHandler)(id value) = ^(id value) { + @synchronized (self) { + if (self->_handler) { + if (!self->_initialMetadataPublished) { + self->_initialMetadataPublished = YES; + [self issueInitialMetadata:self->_call.responseHeaders]; } - }); - }; - void (^completionHandler)(NSError *errorOrNil) = ^(NSError *errorOrNil) { - dispatch_async(self->_dispatchQueue, ^{ - if (self->_handler) { - if (!self->_initialMetadataPublished) { - self->_initialMetadataPublished = YES; - [self issueInitialMetadata:self->_call.responseHeaders]; - } - [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; - - // Clean up _handler so that no more responses are reported to the handler. - self->_handler = nil; + if (value) { + [self issueMessage:value]; } - // Clearing _call must happen *after* dispatching close in order to get trailing - // metadata from _call. - if (self->_call) { - // Clean up the request writers. This should have no effect to _call since its - // response writeable is already nullified. - [self->_pipe writesFinishedWithError:nil]; - self->_call = nil; - self->_pipe = nil; + } + } + }; + void (^completionHandler)(NSError *errorOrNil) = ^(NSError *errorOrNil) { + @synchronized(self) { + if (self->_handler) { + if (!self->_initialMetadataPublished) { + self->_initialMetadataPublished = YES; + [self issueInitialMetadata:self->_call.responseHeaders]; } - }); - }; - id responseWriteable = - [[GRXWriteable alloc] initWithValueHandler:valueHandler - completionHandler:completionHandler]; - [self->_call startWithWriteable:responseWriteable]; - }); + [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + + } + // Clearing _call must happen *after* dispatching close in order to get trailing + // metadata from _call. + if (self->_call) { + // Clean up the request writers. This should have no effect to _call since its + // response writeable is already nullified. + [self->_pipe writesFinishedWithError:nil]; + self->_call = nil; + self->_pipe = nil; + } + } + }; + id responseWriteable = + [[GRXWriteable alloc] initWithValueHandler:valueHandler + completionHandler:completionHandler]; + [call startWithWriteable:responseWriteable]; } - (void)cancel { - dispatch_async(_dispatchQueue, ^{ - NSAssert(!self->_canceled, @"Call already canceled."); - if (self->_canceled) { + GRPCCall *call = nil; + @synchronized (self) { + if (_canceled) { return; } - self->_canceled = YES; - if (self->_call) { - [self->_call cancel]; - self->_call = nil; - self->_pipe = nil; - } - if (self->_handler) { - id handler = self->_handler; - dispatch_async(handler.dispatchQueue, ^{ - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [handler closedWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + _canceled = YES; + + call = _call; + _call = nil; + _pipe = nil; + + if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(_dispatchQueue, ^{ + // Copy to local so that block is freed after cancellation completes. + id copiedHandler = nil; + @synchronized (self) { + copiedHandler = self->_handler; + self->_handler = nil; } - }); - // Clean up _handler so that no more responses are reported to the handler. - self->_handler = nil; + [copiedHandler closedWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); } - }); + } + [call cancel]; } - (void)writeData:(NSData *)data { - dispatch_async(_dispatchQueue, ^{ - NSAssert(!self->_canceled, @"Call arleady canceled."); - NSAssert(!self->_finished, @"Call is half-closed before sending data."); - if (self->_canceled) { + GRXBufferedPipe *pipe = nil; + @synchronized(self) { + NSAssert(!_canceled, @"Call arleady canceled."); + NSAssert(!_finished, @"Call is half-closed before sending data."); + if (_canceled) { return; } - if (self->_finished) { + if (_finished) { return; } - if (self->_pipe) { - [self->_pipe writeValue:data]; + if (_pipe) { + pipe = _pipe; } - }); + } + [pipe writeValue:data]; } - (void)finish { - dispatch_async(_dispatchQueue, ^{ - NSAssert(self->_started, @"Call not started."); - NSAssert(!self->_canceled, @"Call arleady canceled."); - NSAssert(!self->_finished, @"Call already half-closed."); - if (!self->_started) { + GRXBufferedPipe *pipe = nil; + @synchronized(self) { + NSAssert(_started, @"Call not started."); + NSAssert(!_canceled, @"Call arleady canceled."); + NSAssert(!_finished, @"Call already half-closed."); + if (!_started) { return; } - if (self->_canceled) { + if (_canceled) { return; } - if (self->_finished) { + if (_finished) { return; } - if (self->_pipe) { - [self->_pipe writesFinishedWithError:nil]; + if (_pipe) { + pipe = _pipe; + _pipe = nil; } - self->_pipe = nil; - self->_finished = YES; - }); + _finished = YES; + } + [pipe writesFinishedWithError:nil]; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - if (initialMetadata != nil && [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { - [_handler receivedInitialMetadata:initialMetadata]; + @synchronized (self) { + if (initialMetadata != nil && [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; + } + [handler receivedInitialMetadata:initialMetadata]; + }); + } } } - (void)issueMessage:(id)message { - if (message != nil && [_handler respondsToSelector:@selector(receivedRawMessage:)]) { - [_handler receivedRawMessage:message]; + @synchronized (self) { + if (message != nil && [_handler respondsToSelector:@selector(receivedRawMessage:)]) { + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; + } + [handler receivedRawMessage:message]; + }); + } } } - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [_handler closedWithTrailingMetadata:trailingMetadata error:error]; + @synchronized (self) { + if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; + // Clean up _handler so that no more responses are reported to the handler. + self->_handler = nil; + } + [handler closedWithTrailingMetadata:trailingMetadata + error:error]; + }); + } } } diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index a19802b0106..997d1ff663c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -302,7 +302,6 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (void)unref { - NSLog(@"unref"); dispatch_async(_dispatchQueue, ^{ NSAssert(self->_refcount > 0, @"Illegal reference count."); if (self->_refcount == 0) { diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 569aaa79e4d..98b60c3f727 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN /** * Issued when initial metadata is received from the server. + */ - (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; /** diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index f99da45fef9..9f45bdfcd46 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -112,7 +112,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } else { _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } - dispatch_set_target_queue(handler.dispatchQueue, _dispatchQueue); + dispatch_set_target_queue(_dispatchQueue, handler.dispatchQueue); [self start]; } @@ -127,15 +127,17 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)cancel { - dispatch_async(_dispatchQueue, ^{ - if (_call) { - [_call cancel]; - _call = nil; - } - if (_handler) { - id handler = _handler; - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(handler.dispatchQueue, ^{ + GRPCCall2 *call; + @synchronized(self) { + call = _call; + _call = nil; + if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(_handler.dispatchQueue, ^{ + id handler = nil; + @synchronized(self) { + handler = self->_handler; + self->_handler = nil; + } [handler closedWithTrailingMetadata:nil error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled @@ -145,9 +147,8 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing }]]; }); } - _handler = nil; - } - }); + } + [call cancel]; } - (void)writeMessage:(GPBMessage *)message { @@ -155,63 +156,81 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing [NSException raise:NSInvalidArgumentException format:@"Data must be a valid protobuf type."]; } - dispatch_async(_dispatchQueue, ^{ - if (_call) { - [_call writeData:[message data]]; - } - }); + GRPCCall2 *call; + @synchronized(self) { + call = _call; + } + [call writeData:[message data]]; } - (void)finish { - dispatch_async(_dispatchQueue, ^{ - if (_call) { - [_call finish]; - _call = nil; - } - }); + GRPCCall2 *call; + @synchronized(self) { + call = _call; + _call = nil; + } + [call finish]; } - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { - dispatch_async(_dispatchQueue, ^{ - if (initialMetadata != nil && [self->_handler respondsToSelector:@selector(initialMetadata:)]) { - [self->_handler receivedInitialMetadata:initialMetadata]; + @synchronized (self) { + if (initialMetadata != nil && [_handler respondsToSelector:@selector(initialMetadata:)]) { + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; + } + [handler receivedInitialMetadata:initialMetadata]; + }); } - }); + } } - (void)receivedRawMessage:(NSData *)message { - dispatch_async(_dispatchQueue, ^{ - if (self->_handler && message != nil) { - NSError *error = nil; - GPBMessage *parsed = [self->_responseClass parseFromData:message error:&error]; - if (parsed) { - if ([self->_handler respondsToSelector:@selector(receivedProtoMessage:)]) { - [self->_handler receivedProtoMessage:parsed]; + if (message == nil) return; + + NSError *error = nil; + GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; + @synchronized (self) { + if (parsed && [_handler respondsToSelector:@selector(receivedProtoMessage:)]) { + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; } - } else { - if ([self->_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [self->_handler - closedWithTrailingMetadata:nil - error:ErrorForBadProto(message, _responseClass, error)]; + [handler receivedProtoMessage:parsed]; + }); + } else if (!parsed && [_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]){ + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; + self->_handler = nil; } - self->_handler = nil; - [self->_call cancel]; - self->_call = nil; - } + [handler closedWithTrailingMetadata:nil + error:ErrorForBadProto(message, _responseClass, error)]; + }); + [_call cancel]; + _call = nil; } - }); + } } - (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - dispatch_async(_dispatchQueue, ^{ - if ([self->_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [self->_handler closedWithTrailingMetadata:trailingMetadata error:error]; + @synchronized (self) { + if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; + self->_handler = nil; + } + [handler closedWithTrailingMetadata:trailingMetadata error:error]; + }); } - self->_handler = nil; - [self->_call cancel]; - self->_call = nil; - }); + _call = nil; + } } - (dispatch_queue_t)dispatchQueue { From 87abab45c99ab4b40718557cbc1c25dcd7f5a418 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 17:44:26 -0800 Subject: [PATCH 202/534] Fix version availability --- src/objective-c/GRPCClient/GRPCCall.m | 8 ++++++-- src/objective-c/GRPCClient/private/GRPCChannel.m | 7 +++++-- src/objective-c/ProtoRPC/ProtoRPC.m | 8 +++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index ede16b42e8c..19de004cbcd 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -147,12 +147,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; _handler = responseHandler; _initialMetadataPublished = NO; _pipe = [GRXBufferedPipe pipe]; - if (@available(iOS 8.0, *)) { + // Set queue QoS only when iOS version is 8.0 or above and Xcode version is 9.0 or above +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { _dispatchQueue = dispatch_queue_create( NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { - // Fallback on earlier versions +#else + { +#endif _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } dispatch_set_target_queue(_dispatchQueue ,responseHandler.dispatchQueue); diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 997d1ff663c..0220141db04 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -204,14 +204,17 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if ((self = [super init])) { _configuration = [channelConfiguration copy]; - if (@available(iOS 8.0, *)) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED < 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED < 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { _dispatchQueue = dispatch_queue_create( NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { +#else + { +#endif _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } - // Create gRPC core channel object. NSString *host = channelConfiguration.host; NSAssert(host.length != 0, @"host cannot be nil"); diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 9f45bdfcd46..9164f2320bf 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -105,11 +105,17 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing _handler = handler; _callOptions = [callOptions copy]; _responseClass = responseClass; - if (@available(iOS 8.0, *)) { + + // Set queue QoS only when iOS version is 8.0 or above and Xcode version is 9.0 or above +#if __IPHONE_OS_VERSION_MAX_ALLOWED < 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED < 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { _dispatchQueue = dispatch_queue_create( NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { +#else + { +#endif _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } dispatch_set_target_queue(_dispatchQueue, handler.dispatchQueue); From f0cbcde73195b8e17130538c3479d4c0e3bcd2a2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 18 Nov 2018 22:47:35 -0800 Subject: [PATCH 203/534] New channel pool design --- .../GRPCClient/GRPCCall+ChannelArg.m | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 2 +- .../GRPCClient/private/GRPCChannel.h | 36 +-- .../GRPCClient/private/GRPCChannel.m | 169 +++-------- .../GRPCClient/private/GRPCChannelPool.h | 74 ++++- .../GRPCClient/private/GRPCChannelPool.m | 263 ++++++++++++++++-- .../GRPCClient/private/GRPCWrappedCall.m | 31 +-- .../tests/ChannelTests/ChannelPoolTest.m | 222 +++++++++------ .../tests/ChannelTests/ChannelTests.m | 126 +++++---- 9 files changed, 573 insertions(+), 352 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index 971c2803e29..703cff63bb0 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -36,7 +36,7 @@ } + (void)closeOpenConnections { - [GRPCChannelPool closeOpenConnections]; + [[GRPCChannelPool sharedInstance] closeOpenConnections]; } + (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host { diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 19de004cbcd..6f4b1647a5a 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -488,7 +488,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. - NSAssert(host && path, @"Neither host nor path can be nil."); + NSAssert(host != nil && path != nil, @"Neither host nor path can be nil."); NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); NSAssert(requestWriter.state == GRXWriterStateNotStarted, diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 4dbe0c276ce..de6d1bf4a24 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -61,47 +61,19 @@ NS_ASSUME_NONNULL_BEGIN + (nullable instancetype) new NS_UNAVAILABLE; /** - * Create a channel with remote \a host and signature \a channelConfigurations. Destroy delay is - * defaulted to 30 seconds. - */ -- (nullable instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration; - -/** - * Create a channel with remote \a host, signature \a channelConfigurations, and destroy delay of - * \a destroyDelay. + * Create a channel with remote \a host and signature \a channelConfigurations. */ - (nullable instancetype)initWithChannelConfiguration: (GRPCChannelConfiguration *)channelConfiguration - destroyDelay:(NSTimeInterval)destroyDelay NS_DESIGNATED_INITIALIZER; /** - * Create a grpc core call object from this channel. The channel's refcount is added by 1. If no - * call is created, NULL is returned, and if the reason is because the channel is already - * disconnected, \a disconnected is set to YES. When the returned call is unreffed, the caller is - * obligated to call \a unref method once. \a disconnected may be null. + * Create a grpc core call object (grpc_call) from this channel. If no call is created, NULL is + * returned. */ - (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions - disconnected:(nullable BOOL *)disconnected; - -/** - * Unref the channel when a call is done. It also decreases the channel's refcount. If the refcount - * of the channel decreases to 0, the channel is destroyed after the destroy delay. - */ -- (void)unref; - -/** - * Force the channel to be disconnected and destroyed. - */ -- (void)disconnect; - -/** - * Return whether the channel is already disconnected. - */ -@property(readonly) BOOL disconnected; + callOptions:(GRPCCallOptions *)callOptions; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 0220141db04..81e53d48e34 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -34,9 +34,6 @@ #import #import -/** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ -static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - @implementation GRPCChannelConfiguration - (instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { @@ -178,43 +175,18 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannel { GRPCChannelConfiguration *_configuration; - dispatch_queue_t _dispatchQueue; grpc_channel *_unmanagedChannel; - NSTimeInterval _destroyDelay; - - NSUInteger _refcount; - NSDate *_lastDispatch; -} -@synthesize disconnected = _disconnected; - -- (instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration { - return [self initWithChannelConfiguration:channelConfiguration - destroyDelay:kDefaultChannelDestroyDelay]; } - (instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration - destroyDelay:(NSTimeInterval)destroyDelay { + (GRPCChannelConfiguration *)channelConfiguration { NSAssert(channelConfiguration != nil, @"channelConfiguration must not be empty."); - NSAssert(destroyDelay > 0, @"destroyDelay must be greater than 0."); if (channelConfiguration == nil) return nil; - if (destroyDelay <= 0) return nil; if ((self = [super init])) { _configuration = [channelConfiguration copy]; -#if __IPHONE_OS_VERSION_MAX_ALLOWED < 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED < 101300 - if (@available(iOS 8.0, macOS 10.10, *)) { - _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); - } else { -#else - { -#endif - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } + // Create gRPC core channel object. NSString *host = channelConfiguration.host; NSAssert(host.length != 0, @"host cannot be nil"); @@ -233,119 +205,54 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSLog(@"Unable to create channel."); return nil; } - _destroyDelay = destroyDelay; - _disconnected = NO; } return self; } - (grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions - disconnected:(BOOL *)disconnected { + callOptions:(GRPCCallOptions *)callOptions { NSAssert(path.length > 0, @"path must not be empty."); NSAssert(queue != nil, @"completionQueue must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); - if (path.length == 0) return nil; - if (queue == nil) return nil; - if (callOptions == nil) return nil; - - __block BOOL isDisconnected = NO; - __block grpc_call *call = NULL; - dispatch_sync(_dispatchQueue, ^{ - if (self->_disconnected) { - isDisconnected = YES; - } else { - NSAssert(self->_unmanagedChannel != NULL, - @"Channel should have valid unmanaged channel."); - if (self->_unmanagedChannel == NULL) return; - - NSString *serverAuthority = - callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; - NSTimeInterval timeout = callOptions.timeout; - NSAssert(timeout >= 0, @"Invalid timeout"); - if (timeout < 0) return; - grpc_slice host_slice = grpc_empty_slice(); - if (serverAuthority) { - host_slice = grpc_slice_from_copied_string(serverAuthority.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_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); - call = grpc_channel_create_call(self->_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, - queue.unmanagedQueue, path_slice, - serverAuthority ? &host_slice : NULL, deadline_ms, NULL); - if (serverAuthority) { - grpc_slice_unref(host_slice); - } - grpc_slice_unref(path_slice); - if (call == NULL) { - NSLog(@"Unable to create call."); - } else { - // Ref the channel; - [self ref]; - } + if (path.length == 0) return NULL; + if (queue == nil) return NULL; + if (callOptions == nil) return NULL; + + grpc_call *call = NULL; + @synchronized(self) { + NSAssert(_unmanagedChannel != NULL, + @"Channel should have valid unmanaged channel."); + if (_unmanagedChannel == NULL) return NULL; + + NSString *serverAuthority = + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + NSTimeInterval timeout = callOptions.timeout; + NSAssert(timeout >= 0, @"Invalid timeout"); + if (timeout < 0) return NULL; + grpc_slice host_slice = grpc_empty_slice(); + if (serverAuthority) { + host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); } - }); - if (disconnected != nil) { - *disconnected = isDisconnected; - } - return call; -} - -// This function should be called on _dispatchQueue. -- (void)ref { - _refcount++; - if (_refcount == 1 && _lastDispatch != nil) { - _lastDispatch = nil; - } -} - -- (void)unref { - dispatch_async(_dispatchQueue, ^{ - NSAssert(self->_refcount > 0, @"Illegal reference count."); - if (self->_refcount == 0) { - NSLog(@"Illegal reference count."); - return; + 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_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, + queue.unmanagedQueue, path_slice, + serverAuthority ? &host_slice : NULL, deadline_ms, NULL); + if (serverAuthority) { + grpc_slice_unref(host_slice); } - self->_refcount--; - if (self->_refcount == 0 && !self->_disconnected) { - // Start timer. - dispatch_time_t delay = - dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); - NSDate *now = [NSDate date]; - self->_lastDispatch = now; - dispatch_after(delay, self->_dispatchQueue, ^{ - // Timed disconnection. - if (!self->_disconnected && self->_lastDispatch == now) { - grpc_channel_destroy(self->_unmanagedChannel); - self->_unmanagedChannel = NULL; - self->_disconnected = YES; - } - }); + grpc_slice_unref(path_slice); + NSAssert(call != nil, @"Unable to create call."); + if (call == NULL) { + NSLog(@"Unable to create call."); } - }); -} - -- (void)disconnect { - dispatch_async(_dispatchQueue, ^{ - if (!self->_disconnected) { - grpc_channel_destroy(self->_unmanagedChannel); - self->_unmanagedChannel = nil; - self->_disconnected = YES; - } - }); -} - -- (BOOL)disconnected { - __block BOOL disconnected; - dispatch_sync(_dispatchQueue, ^{ - disconnected = self->_disconnected; - }); - return disconnected; + } + return call; } - (void)dealloc { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 48779c44497..887bd5f89f7 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -27,7 +27,53 @@ NS_ASSUME_NONNULL_BEGIN +@protocol GRPCChannel; @class GRPCChannel; +@class GRPCChannelPool; +@class GRPCCompletionQueue; +@class GRPCChannelConfiguration; + +/** + * Channel proxy that can be retained and automatically reestablish connection when the channel is + * disconnected. + */ +@interface GRPCPooledChannel : NSObject + +/** + * Initialize with an actual channel object \a channel and a reference to the channel pool. + */ +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration + channelPool:(GRPCChannelPool *)channelPool; + + +/** + * Create a grpc core call object (grpc_call) from this channel. If channel is disconnected, get a + * new channel object from the channel pool. + */ +- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions; + +/** + * Return ownership and destroy the grpc_call object created by + * \a unmanagedCallWithPath:completionQueue:callOptions: and decrease channel refcount. If refcount + * of the channel becomes 0, return the channel object to channel pool. + */ +- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall; + +/** + * Force the channel to disconnect immediately. + */ +- (void)disconnect; + +// The following methods and properties are for test only + +/** + * Return the pointer to the real channel wrapped by the proxy. + */ +@property(atomic, readonly) GRPCChannel *wrappedChannel; + +@end /** * Manage the pool of connected channels. When a channel is no longer referenced by any call, @@ -36,37 +82,41 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCChannelPool : NSObject /** - * Get the singleton instance + * Get the global channel pool. */ + (nullable instancetype)sharedInstance; /** - * Return a channel with a particular configuration. If the channel does not exist, execute \a - * createChannel then add it in the pool. If the channel exists, increase its reference count. + * Return a channel with a particular configuration. The channel may be a cached channel. */ -- (GRPCChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; +- (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; /** * This method is deprecated. * * Destroy all open channels and close their connections. */ -+ (void)closeOpenConnections; +- (void)closeOpenConnections; // Test-only methods below /** - * Return a channel with a special destroy delay. If \a destroyDelay is 0, use the default destroy - * delay. + * Get an instance of pool isolated from the global shared pool. This method is for test only. + * Global pool should be used in production. + */ +- (nullable instancetype)init; + +/** + * Simulate a network transition event and destroy all channels. This method is for internal and + * test only. */ -- (GRPCChannel *)channelWithHost:(NSString *)host - callOptions:(GRPCCallOptions *)callOptions - destroyDelay:(NSTimeInterval)destroyDelay; +- (void)disconnectAllChannels; /** - * Simulate a network transition event and destroy all channels. + * Set the destroy delay of channels. A channel should be destroyed if it stayed idle (no active + * call on it) for this period of time. This property is for test only. */ -- (void)destroyAllChannels; +@property(atomic) NSTimeInterval destroyDelay; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 5e2e9bcfebb..92dd4c86aee 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -37,8 +37,150 @@ extern const char *kCFStreamVarName; static GRPCChannelPool *gChannelPool; static dispatch_once_t gInitChannelPool; +/** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ +static const NSTimeInterval kDefaultChannelDestroyDelay = 30; + +@interface GRPCChannelPool() + +- (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; + +- (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; + +@end + +@implementation GRPCPooledChannel { + __weak GRPCChannelPool *_channelPool; + GRPCChannelConfiguration *_channelConfiguration; + NSMutableSet *_unmanagedCalls; +} + +@synthesize wrappedChannel = _wrappedChannel; + +- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration + channelPool:(GRPCChannelPool *)channelPool { + NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); + NSAssert(channelPool != nil, @"channelPool cannot be empty."); + if (channelPool == nil || channelConfiguration == nil) { + return nil; + } + + if ((self = [super init])) { + _channelPool = channelPool; + _channelConfiguration = channelConfiguration; + _unmanagedCalls = [NSMutableSet set]; + } + + return self; +} + +- (grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions { + NSAssert(path.length > 0, @"path must not be empty."); + NSAssert(queue != nil, @"completionQueue must not be empty."); + NSAssert(callOptions, @"callOptions must not be empty."); + if (path.length == 0 || queue == nil || callOptions == nil) return NULL; + + grpc_call *call = NULL; + @synchronized(self) { + if (_wrappedChannel == nil) { + __strong GRPCChannelPool *strongPool = _channelPool; + if (strongPool) { + _wrappedChannel = [strongPool refChannelWithConfiguration:_channelConfiguration]; + } + NSAssert(_wrappedChannel != nil, @"Unable to get a raw channel for proxy."); + } + call = [_wrappedChannel unmanagedCallWithPath:path completionQueue:queue callOptions:callOptions]; + if (call != NULL) { + [_unmanagedCalls addObject:[NSValue valueWithPointer:call]]; + } + } + return call; +} + +- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall { + if (unmanagedCall == nil) return; + + grpc_call_unref(unmanagedCall); + BOOL timedDestroy = NO; + @synchronized(self) { + if ([_unmanagedCalls containsObject:[NSValue valueWithPointer:unmanagedCall]]) { + [_unmanagedCalls removeObject:[NSValue valueWithPointer:unmanagedCall]]; + if ([_unmanagedCalls count] == 0) { + timedDestroy = YES; + } + } + } + if (timedDestroy) { + [self timedDestroy]; + } +} + +- (void)disconnect { + @synchronized(self) { + _wrappedChannel = nil; + [_unmanagedCalls removeAllObjects]; + } +} + +- (GRPCChannel *)wrappedChannel { + GRPCChannel *channel = nil; + @synchronized (self) { + channel = _wrappedChannel; + } + return channel; +} + +- (void)timedDestroy { + __strong GRPCChannelPool *pool = nil; + @synchronized(self) { + // Check if we still want to destroy the channel. + if ([_unmanagedCalls count] == 0) { + pool = _channelPool; + _wrappedChannel = nil; + } + } + [pool unrefChannelWithConfiguration:_channelConfiguration]; +} + +@end + +/** + * A convenience value type for cached channel. + */ +@interface GRPCChannelRecord : NSObject + +/** Pointer to the raw channel. May be nil when the channel has been destroyed. */ +@property GRPCChannel *channel; + +/** Channel proxy corresponding to this channel configuration. */ +@property GRPCPooledChannel *proxy; + +/** Last time when a timed destroy is initiated on the channel. */ +@property NSDate *timedDestroyDate; + +/** Reference count of the proxy to the channel. */ +@property NSUInteger refcount; + +@end + +@implementation GRPCChannelRecord + +- (id)copyWithZone:(NSZone *)zone { + GRPCChannelRecord *newRecord = [[GRPCChannelRecord allocWithZone:zone] init]; + newRecord.channel = _channel; + newRecord.proxy = _proxy; + newRecord.timedDestroyDate = _timedDestroyDate; + newRecord.refcount = _refcount; + + return newRecord; +} + +@end + @implementation GRPCChannelPool { - NSMutableDictionary *_channelPool; + NSMutableDictionary *_channelPool; + dispatch_queue_t _dispatchQueue; } + (instancetype)sharedInstance { @@ -52,6 +194,18 @@ static dispatch_once_t gInitChannelPool; - (instancetype)init { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + } else { +#else + { +#endif + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + _destroyDelay = kDefaultChannelDestroyDelay; // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); @@ -62,51 +216,106 @@ static dispatch_once_t gInitChannelPool; return self; } -- (GRPCChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { - return [self channelWithHost:host callOptions:callOptions destroyDelay:0]; -} - -- (GRPCChannel *)channelWithHost:(NSString *)host - callOptions:(GRPCCallOptions *)callOptions - destroyDelay:(NSTimeInterval)destroyDelay { +- (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { NSAssert(host.length > 0, @"Host must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); if (host.length == 0) return nil; if (callOptions == nil) return nil; - GRPCChannel *channel; + GRPCPooledChannel *channelProxy = nil; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; @synchronized(self) { - channel = _channelPool[configuration]; - if (channel == nil || channel.disconnected) { - if (destroyDelay == 0) { - channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration]; - } else { - channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration - destroyDelay:destroyDelay]; - } - _channelPool[configuration] = channel; + GRPCChannelRecord *record = _channelPool[configuration]; + if (record == nil) { + record = [[GRPCChannelRecord alloc] init]; + record.proxy = [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration + channelPool:self]; + record.timedDestroyDate = nil; + _channelPool[configuration] = record; + channelProxy = record.proxy; + } else { + channelProxy = record.proxy; } } - return channel; + return channelProxy; } -+ (void)closeOpenConnections { - [[GRPCChannelPool sharedInstance] destroyAllChannels]; +- (void)closeOpenConnections { + [self disconnectAllChannels]; } -- (void)destroyAllChannels { - @synchronized(self) { - for (id key in _channelPool) { - [_channelPool[key] disconnect]; +- (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { + GRPCChannel *ret = nil; + @synchronized (self) { + NSAssert(configuration != nil, @"configuration cannot be empty."); + if (configuration == nil) return nil; + + GRPCChannelRecord *record = _channelPool[configuration]; + NSAssert(record != nil, @"No record corresponding to a proxy."); + if (record == nil) return nil; + + if (record.channel == nil) { + // Channel is already destroyed; + record.channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration]; + record.timedDestroyDate = nil; + record.refcount = 1; + ret = record.channel; + } else { + ret = record.channel; + record.timedDestroyDate = nil; + record.refcount++; } - _channelPool = [NSMutableDictionary dictionary]; } + return ret; +} + +- (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { + @synchronized (self) { + GRPCChannelRecord *record = _channelPool[configuration]; + NSAssert(record != nil, @"No record corresponding to a proxy."); + if (record == nil) return; + NSAssert(record.refcount > 0, @"Inconsistent channel refcount."); + if (record.refcount > 0) { + record.refcount--; + if (record.refcount == 0) { + NSDate *now = [NSDate date]; + record.timedDestroyDate = now; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_destroyDelay * NSEC_PER_SEC)), + _dispatchQueue, + ^{ + @synchronized (self) { + if (now == record.timedDestroyDate) { + // Destroy the raw channel and reset related records. + record.timedDestroyDate = nil; + record.refcount = 0; + record.channel = nil; + } + } + }); + } + } + } +} + +- (void)disconnectAllChannels { + NSMutableSet *proxySet = [NSMutableSet set]; + @synchronized (self) { + [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannelRecord * _Nonnull obj, BOOL * _Nonnull stop) { + obj.channel = nil; + obj.timedDestroyDate = nil; + obj.refcount = 0; + [proxySet addObject:obj.proxy]; + }]; + } + // Disconnect proxies + [proxySet enumerateObjectsUsingBlock:^(GRPCPooledChannel * _Nonnull obj, BOOL * _Nonnull stop) { + [obj disconnect]; + }]; } - (void)connectivityChange:(NSNotification *)note { - [self destroyAllChannels]; + [self disconnectAllChannels]; } - (void)dealloc { diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index ae7f07f1192..5c402250ccf 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -238,7 +238,7 @@ @implementation GRPCWrappedCall { GRPCCompletionQueue *_queue; - GRPCChannel *_channel; + GRPCPooledChannel *_channel; grpc_call *_call; } @@ -257,21 +257,15 @@ // consuming too many threads and having contention of multiple calls in a single completion // queue. Currently we use a singleton queue. _queue = [GRPCCompletionQueue completionQueue]; - BOOL disconnected = NO; - do { - _channel = [[GRPCChannelPool sharedInstance] channelWithHost:host callOptions:callOptions]; - if (_channel == nil) { - NSAssert(_channel != nil, @"Failed to get a channel for the host."); - NSLog(@"Failed to get a channel for the host."); - return nil; - } - _call = [_channel unmanagedCallWithPath:path - completionQueue:_queue - callOptions:callOptions - disconnected:&disconnected]; - // Try create another channel if the current channel is disconnected (due to idleness or - // connectivity monitor disconnection). - } while (_call == NULL && disconnected); + _channel = [[GRPCChannelPool sharedInstance] channelWithHost:host callOptions:callOptions]; + if (_channel == nil) { + NSAssert(_channel != nil, @"Failed to get a channel for the host."); + NSLog(@"Failed to get a channel for the host."); + return nil; + } + _call = [_channel unmanagedCallWithPath:path + completionQueue:_queue + callOptions:callOptions]; if (_call == nil) { NSAssert(_channel != nil, @"Failed to get a channel for the host."); NSLog(@"Failed to create a call."); @@ -326,10 +320,7 @@ } - (void)dealloc { - if (_call) { - grpc_call_unref(_call); - } - [_channel unref]; + [_channel unrefUnmanagedCall:_call]; _channel = nil; } diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index b85e62feb5f..51819b12c2f 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -25,6 +25,8 @@ #define TEST_TIMEOUT 32 NSString *kDummyHost = @"dummy.host"; +NSString *kDummyHost2 = @"dummy.host.2"; +NSString *kDummyPath = @"/dummy/path"; @interface ChannelPoolTest : XCTestCase @@ -36,94 +38,156 @@ NSString *kDummyHost = @"dummy.host"; grpc_init(); } -- (void)testChannelPooling { - NSString *kDummyHost = @"dummy.host"; - NSString *kDummyHost2 = @"dummy.host2"; +- (void)testCreateChannelAndCall { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + XCTAssertNil(channel.wrappedChannel); + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + grpc_call *call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq callOptions:options]; + XCTAssert(call != NULL); + XCTAssertNotNil(channel.wrappedChannel); + [channel unrefUnmanagedCall:call]; + XCTAssertNil(channel.wrappedChannel); +} - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; +- (void)testCacheChannel { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCCallOptions *options1 = [[GRPCCallOptions alloc] init]; GRPCCallOptions *options2 = [options1 copy]; - GRPCMutableCallOptions *options3 = [options2 mutableCopy]; + GRPCMutableCallOptions *options3 = [options1 mutableCopy]; options3.transportType = GRPCTransportTypeInsecure; - - GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - - GRPCChannel *channel1 = [pool channelWithHost:kDummyHost callOptions:options1]; - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options2]; - GRPCChannel *channel3 = [pool channelWithHost:kDummyHost2 callOptions:options1]; - GRPCChannel *channel4 = [pool channelWithHost:kDummyHost callOptions:options3]; - XCTAssertEqual(channel1, channel2); - XCTAssertNotEqual(channel1, channel3); - XCTAssertNotEqual(channel1, channel4); - XCTAssertNotEqual(channel3, channel4); -} - -- (void)testDestroyAllChannels { - NSString *kDummyHost = @"dummy.host"; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = [pool channelWithHost:kDummyHost callOptions:options]; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - [pool destroyAllChannels]; - XCTAssertTrue(channel.disconnected); - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options]; - XCTAssertNotEqual(channel, channel2); - grpc_call_unref(call); + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + GRPCPooledChannel *channel1 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options1]; + grpc_call *call1 = [channel1 unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options1]; + GRPCPooledChannel *channel2 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options2]; + grpc_call *call2 = [channel2 unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options2]; + GRPCPooledChannel *channel3 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options3]; + grpc_call *call3 = [channel3 unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options3]; + GRPCPooledChannel *channel4 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost2 + callOptions:options1]; + grpc_call *call4 = [channel4 unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options1]; + XCTAssertEqual(channel1.wrappedChannel, channel2.wrappedChannel); + XCTAssertNotEqual(channel1.wrappedChannel, channel3.wrappedChannel); + XCTAssertNotEqual(channel1.wrappedChannel, channel4.wrappedChannel); + XCTAssertNotEqual(channel3.wrappedChannel, channel4.wrappedChannel); + [channel1 unrefUnmanagedCall:call1]; + [channel2 unrefUnmanagedCall:call2]; + [channel3 unrefUnmanagedCall:call3]; + [channel4 unrefUnmanagedCall:call4]; } -- (void)testGetChannelBeforeChannelTimedDisconnection { - NSString *kDummyHost = @"dummy.host"; - const NSTimeInterval kDestroyDelay = 1; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = - [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - grpc_call_unref(call); - [channel unref]; - - // Test that we can still get the channel at this time - GRPCChannel *channel2 = - [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; - XCTAssertEqual(channel, channel2); - call = [channel2 unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - - // Test that after the destroy delay, the channel is still alive +- (void)testTimedDestroyChannel { + const NSTimeInterval kDestroyDelay = 1.0; + + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + pool.destroyDelay = kDestroyDelay; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + grpc_call *call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq callOptions:options]; + GRPCChannel *wrappedChannel = channel.wrappedChannel; + + [channel unrefUnmanagedCall:call]; + // Confirm channel is not destroyed at this time + call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertEqual(wrappedChannel, channel.wrappedChannel); + + [channel unrefUnmanagedCall:call]; sleep(kDestroyDelay + 1); - XCTAssertFalse(channel.disconnected); + // Confirm channel is new at this time + call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); + + // Confirm the new channel can create call + call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssert(call != NULL); + [channel unrefUnmanagedCall:call]; } -- (void)testGetChannelAfterChannelTimedDisconnection { - NSString *kDummyHost = @"dummy.host"; - const NSTimeInterval kDestroyDelay = 1; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = - [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - grpc_call_unref(call); - [channel unref]; - - sleep(kDestroyDelay + 1); +- (void)testPoolDisconnection { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + grpc_call *call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + GRPCChannel *wrappedChannel = channel.wrappedChannel; + + // Test a new channel is created by requesting a channel from pool + [pool disconnectAllChannels]; + channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); + wrappedChannel = channel.wrappedChannel; + + // Test a new channel is created by requesting a new call from the previous proxy + [pool disconnectAllChannels]; + grpc_call *call2 = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); + [channel unrefUnmanagedCall:call]; + [channel unrefUnmanagedCall:call2]; +} - // Test that we get new channel to the same host and with the same callOptions - GRPCChannel *channel2 = - [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; - XCTAssertNotEqual(channel, channel2); +- (void)testUnrefCallFromStaleChannel { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + grpc_call *call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + + [pool disconnectAllChannels]; + channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + + grpc_call *call2 = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + // Test unref the call of a stale channel will not cause the current channel going into timed + // destroy state + XCTAssertNotNil(channel.wrappedChannel); + GRPCChannel *wrappedChannel = channel.wrappedChannel; + [channel unrefUnmanagedCall:call]; + XCTAssertNotNil(channel.wrappedChannel); + XCTAssertEqual(wrappedChannel, channel.wrappedChannel); + // Test unref the call of the current channel will cause the channel going into timed destroy + // state + [channel unrefUnmanagedCall:call2]; + XCTAssertNil(channel.wrappedChannel); } @end diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 5daafcdf3f3..212db2f653a 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -20,65 +20,93 @@ #import "../../GRPCClient/GRPCCallOptions.h" #import "../../GRPCClient/private/GRPCChannel.h" +#import "../../GRPCClient/private/GRPCChannelPool.h" #import "../../GRPCClient/private/GRPCCompletionQueue.h" -@interface ChannelTests : XCTestCase +/* +#define TEST_TIMEOUT 8 + +@interface GRPCChannelFake : NSObject + +- (instancetype)initWithCreateExpectation:(XCTestExpectation *)createExpectation + unrefExpectation:(XCTestExpectation *)unrefExpectation; + +- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions; + +- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall; @end -@implementation ChannelTests +@implementation GRPCChannelFake { + __weak XCTestExpectation *_createExpectation; + __weak XCTestExpectation *_unrefExpectation; + long _grpcCallCounter; +} -+ (void)setUp { - grpc_init(); +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { + return nil; } -- (void)testTimedDisconnection { - NSString *const kHost = @"grpc-test.sandbox.googleapis.com"; - const NSTimeInterval kDestroyDelay = 1; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *configuration = - [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; - GRPCChannel *channel = - [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:kDestroyDelay]; - BOOL disconnected; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:&disconnected]; - XCTAssertFalse(disconnected); - grpc_call_unref(call); - [channel unref]; - XCTAssertFalse(channel.disconnected, @"Channel is pre-maturely disconnected."); - sleep(kDestroyDelay + 1); - XCTAssertTrue(channel.disconnected, @"Channel is not disconnected after delay."); - - // Check another call creation returns null and indicates disconnected. - call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:&disconnected]; - XCTAssert(call == NULL); - XCTAssertTrue(disconnected); +- (instancetype)initWithCreateExpectation:(XCTestExpectation *)createExpectation + unrefExpectation:(XCTestExpectation *)unrefExpectation { + if ((self = [super init])) { + _createExpectation = createExpectation; + _unrefExpectation = unrefExpectation; + _grpcCallCounter = 0; + } + return self; } -- (void)testForceDisconnection { - NSString *const kHost = @"grpc-test.sandbox.googleapis.com"; - const NSTimeInterval kDestroyDelay = 1; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *configuration = - [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; - GRPCChannel *channel = - [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:kDestroyDelay]; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - grpc_call_unref(call); - [channel disconnect]; - XCTAssertTrue(channel.disconnected, @"Channel is not disconnected."); - - // Test calling another unref here will not crash - [channel unref]; +- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions { + if (_createExpectation) [_createExpectation fulfill]; + return (grpc_call *)(++_grpcCallCounter); +} + +- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall { + if (_unrefExpectation) [_unrefExpectation fulfill]; +} + +@end + +@interface GRPCChannelPoolFake : NSObject + +- (instancetype)initWithDelayedDestroyExpectation:(XCTestExpectation *)delayedDestroyExpectation; + +- (GRPCChannel *)rawChannelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; + +- (void)delayedDestroyChannel; + +@end + +@implementation GRPCChannelPoolFake { + __weak XCTestExpectation *_delayedDestroyExpectation; +} + +- (instancetype)initWithDelayedDestroyExpectation:(XCTestExpectation *)delayedDestroyExpectation { + if ((self = [super init])) { + _delayedDestroyExpectation = delayedDestroyExpectation; + } + return self; +} + +- (void)delayedDestroyChannel { + if (_delayedDestroyExpectation) [_delayedDestroyExpectation fulfill]; +} + +@end */ + +@interface ChannelTests : XCTestCase + +@end + +@implementation ChannelTests + ++ (void)setUp { + grpc_init(); } @end From 680b53f7ad7c93947003dcf8d377f2b33c7623e9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 18 Nov 2018 23:00:08 -0800 Subject: [PATCH 204/534] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 4 +- src/objective-c/GRPCClient/GRPCCall.m | 59 +++++----- .../GRPCClient/private/GRPCChannel.h | 3 +- .../GRPCClient/private/GRPCChannel.m | 18 ++-- .../GRPCClient/private/GRPCChannelPool.h | 4 +- .../GRPCClient/private/GRPCChannelPool.m | 58 +++++----- .../private/GRPCCronetChannelFactory.m | 6 +- src/objective-c/GRPCClient/private/GRPCHost.m | 3 +- .../private/GRPCInsecureChannelFactory.m | 3 +- .../private/GRPCSecureChannelFactory.m | 15 ++- .../GRPCClient/private/GRPCWrappedCall.m | 7 +- .../GRPCClient/private/utilities.h | 3 +- src/objective-c/ProtoRPC/ProtoRPC.m | 50 ++++----- .../tests/ChannelTests/ChannelPoolTest.m | 102 ++++++++---------- .../tests/ChannelTests/ChannelTests.m | 4 +- src/objective-c/tests/InteropTests.m | 3 +- 16 files changed, 153 insertions(+), 189 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 7f80c17f1f3..4c8c11eded2 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -340,8 +340,8 @@ NS_ASSUME_NONNULL_END * and the port number, for example @"localhost:5050". */ - (null_unspecified instancetype)initWithHost:(null_unspecified NSString *)host - path:(null_unspecified NSString *)path - requestsWriter:(null_unspecified GRXWriter *)requestWriter; + path:(null_unspecified NSString *)path + requestsWriter:(null_unspecified GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 6f4b1647a5a..94e470d4ed9 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -122,9 +122,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *)callOptions { NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, - @"Neither host nor path can be nil."); - NSAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, - @"Invalid call safety value."); + @"Neither host nor path can be nil."); + NSAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); NSAssert(responseHandler != nil, @"Response handler required."); if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { return nil; @@ -136,7 +135,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; return nil; } - if ((self = [super init])) { _requestOptions = [requestOptions copy]; if (callOptions == nil) { @@ -159,7 +157,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; #endif _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } - dispatch_set_target_queue(_dispatchQueue ,responseHandler.dispatchQueue); + dispatch_set_target_queue(_dispatchQueue, responseHandler.dispatchQueue); _started = NO; _canceled = NO; _finished = NO; @@ -176,7 +174,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)start { GRPCCall *call = nil; - @synchronized (self) { + @synchronized(self) { NSAssert(!_started, @"Call already started."); NSAssert(!_canceled, @"Call already canceled."); if (_started) { @@ -192,10 +190,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; } _call = [[GRPCCall alloc] initWithHost:_requestOptions.host - path:_requestOptions.path - callSafety:_requestOptions.safety - requestsWriter:_pipe - callOptions:_callOptions]; + path:_requestOptions.path + callSafety:_requestOptions.safety + requestsWriter:_pipe + callOptions:_callOptions]; if (_callOptions.initialMetadata) { [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; } @@ -203,7 +201,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } void (^valueHandler)(id value) = ^(id value) { - @synchronized (self) { + @synchronized(self) { if (self->_handler) { if (!self->_initialMetadataPublished) { self->_initialMetadataPublished = YES; @@ -223,7 +221,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self issueInitialMetadata:self->_call.responseHeaders]; } [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; - } // Clearing _call must happen *after* dispatching close in order to get trailing // metadata from _call. @@ -237,14 +234,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; } }; id responseWriteable = - [[GRXWriteable alloc] initWithValueHandler:valueHandler - completionHandler:completionHandler]; + [[GRXWriteable alloc] initWithValueHandler:valueHandler completionHandler:completionHandler]; [call startWithWriteable:responseWriteable]; } - (void)cancel { GRPCCall *call = nil; - @synchronized (self) { + @synchronized(self) { if (_canceled) { return; } @@ -259,7 +255,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_async(_dispatchQueue, ^{ // Copy to local so that block is freed after cancellation completes. id copiedHandler = nil; - @synchronized (self) { + @synchronized(self) { copiedHandler = self->_handler; self->_handler = nil; } @@ -268,9 +264,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; }); } } @@ -322,11 +318,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - @synchronized (self) { - if (initialMetadata != nil && [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + @synchronized(self) { + if (initialMetadata != nil && + [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; } [handler receivedInitialMetadata:initialMetadata]; @@ -336,11 +333,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueMessage:(id)message { - @synchronized (self) { + @synchronized(self) { if (message != nil && [_handler respondsToSelector:@selector(receivedRawMessage:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; } [handler receivedRawMessage:message]; @@ -350,17 +347,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - @synchronized (self) { + @synchronized(self) { if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; } - [handler closedWithTrailingMetadata:trailingMetadata - error:error]; + [handler closedWithTrailingMetadata:trailingMetadata error:error]; }); } } @@ -489,10 +485,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. NSAssert(host != nil && path != nil, @"Neither host nor path can be nil."); - NSAssert(safety <= GRPCCallSafetyCacheableRequest, - @"Invalid call safety value."); + NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); NSAssert(requestWriter.state == GRXWriterStateNotStarted, - @"The requests writer can't be already started."); + @"The requests writer can't be already started."); if (!host || !path) { return nil; } @@ -888,7 +883,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, - @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); + @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); if (_callOptions.authTokenProvider != nil) { @synchronized(self) { self.isWaitingForToken = YES; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index de6d1bf4a24..5426b28d758 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -64,8 +64,7 @@ NS_ASSUME_NONNULL_BEGIN * Create a channel with remote \a host and signature \a channelConfigurations. */ - (nullable instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration - NS_DESIGNATED_INITIALIZER; + (GRPCChannelConfiguration *)channelConfiguration NS_DESIGNATED_INITIALIZER; /** * Create a grpc core call object (grpc_call) from this channel. If no call is created, NULL is diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 81e53d48e34..e4cefc338c6 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -178,10 +178,8 @@ grpc_channel *_unmanagedChannel; } -- (instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration { - NSAssert(channelConfiguration != nil, - @"channelConfiguration must not be empty."); +- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { + NSAssert(channelConfiguration != nil, @"channelConfiguration must not be empty."); if (channelConfiguration == nil) return nil; if ((self = [super init])) { @@ -221,12 +219,11 @@ grpc_call *call = NULL; @synchronized(self) { - NSAssert(_unmanagedChannel != NULL, - @"Channel should have valid unmanaged channel."); + NSAssert(_unmanagedChannel != NULL, @"Channel should have valid unmanaged channel."); if (_unmanagedChannel == NULL) return NULL; NSString *serverAuthority = - callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); if (timeout < 0) return NULL; @@ -236,10 +233,9 @@ } 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_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + 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)); call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, serverAuthority ? &host_slice : NULL, deadline_ms, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 887bd5f89f7..1e3c1d7d976 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -42,10 +42,10 @@ NS_ASSUME_NONNULL_BEGIN /** * Initialize with an actual channel object \a channel and a reference to the channel pool. */ -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration channelPool:(GRPCChannelPool *)channelPool; - /** * Create a grpc core call object (grpc_call) from this channel. If channel is disconnected, get a * new channel object from the channel pool. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 92dd4c86aee..7c139b37176 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -40,7 +40,7 @@ static dispatch_once_t gInitChannelPool; /** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; -@interface GRPCChannelPool() +@interface GRPCChannelPool () - (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; @@ -74,7 +74,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (grpc_call *)unmanagedCallWithPath:(NSString *)path - completionQueue:(GRPCCompletionQueue *)queue + completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions { NSAssert(path.length > 0, @"path must not be empty."); NSAssert(queue != nil, @"completionQueue must not be empty."); @@ -90,7 +90,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } NSAssert(_wrappedChannel != nil, @"Unable to get a raw channel for proxy."); } - call = [_wrappedChannel unmanagedCallWithPath:path completionQueue:queue callOptions:callOptions]; + call = + [_wrappedChannel unmanagedCallWithPath:path completionQueue:queue callOptions:callOptions]; if (call != NULL) { [_unmanagedCalls addObject:[NSValue valueWithPointer:call]]; } @@ -100,7 +101,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall { if (unmanagedCall == nil) return; - + grpc_call_unref(unmanagedCall); BOOL timedDestroy = NO; @synchronized(self) { @@ -125,7 +126,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (GRPCChannel *)wrappedChannel { GRPCChannel *channel = nil; - @synchronized (self) { + @synchronized(self) { channel = _wrappedChannel; } return channel; @@ -148,7 +149,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; /** * A convenience value type for cached channel. */ -@interface GRPCChannelRecord : NSObject +@interface GRPCChannelRecord : NSObject /** Pointer to the raw channel. May be nil when the channel has been destroyed. */ @property GRPCChannel *channel; @@ -197,14 +198,14 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 if (@available(iOS 8.0, macOS 10.10, *)) { _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { #else - { + { #endif - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } _destroyDelay = kDefaultChannelDestroyDelay; // Connectivity monitor is not required for CFStream @@ -221,7 +222,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSAssert(callOptions != nil, @"callOptions must not be empty."); if (host.length == 0) return nil; if (callOptions == nil) return nil; - + GRPCPooledChannel *channelProxy = nil; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; @@ -229,8 +230,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; GRPCChannelRecord *record = _channelPool[configuration]; if (record == nil) { record = [[GRPCChannelRecord alloc] init]; - record.proxy = [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration - channelPool:self]; + record.proxy = + [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration channelPool:self]; record.timedDestroyDate = nil; _channelPool[configuration] = record; channelProxy = record.proxy; @@ -247,7 +248,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { GRPCChannel *ret = nil; - @synchronized (self) { + @synchronized(self) { NSAssert(configuration != nil, @"configuration cannot be empty."); if (configuration == nil) return nil; @@ -271,7 +272,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { - @synchronized (self) { + @synchronized(self) { GRPCChannelRecord *record = _channelPool[configuration]; NSAssert(record != nil, @"No record corresponding to a proxy."); if (record == nil) return; @@ -282,9 +283,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSDate *now = [NSDate date]; record.timedDestroyDate = now; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_destroyDelay * NSEC_PER_SEC)), - _dispatchQueue, - ^{ - @synchronized (self) { + _dispatchQueue, ^{ + @synchronized(self) { if (now == record.timedDestroyDate) { // Destroy the raw channel and reset related records. record.timedDestroyDate = nil; @@ -292,7 +292,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; record.channel = nil; } } - }); + }); } } } @@ -300,16 +300,18 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (void)disconnectAllChannels { NSMutableSet *proxySet = [NSMutableSet set]; - @synchronized (self) { - [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannelRecord * _Nonnull obj, BOOL * _Nonnull stop) { - obj.channel = nil; - obj.timedDestroyDate = nil; - obj.refcount = 0; - [proxySet addObject:obj.proxy]; - }]; + @synchronized(self) { + [_channelPool + enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, + GRPCChannelRecord *_Nonnull obj, BOOL *_Nonnull stop) { + obj.channel = nil; + obj.timedDestroyDate = nil; + obj.refcount = 0; + [proxySet addObject:obj.proxy]; + }]; } // Disconnect proxies - [proxySet enumerateObjectsUsingBlock:^(GRPCPooledChannel * _Nonnull obj, BOOL * _Nonnull stop) { + [proxySet enumerateObjectsUsingBlock:^(GRPCPooledChannel *_Nonnull obj, BOOL *_Nonnull stop) { [obj disconnect]; }]; } diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 74ea9723b3d..0aeb67b1426 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -50,8 +50,7 @@ return self; } -- (grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { grpc_channel_args *channelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); @@ -71,8 +70,7 @@ return nil; } -- (grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return NULL; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index b693b926bad..0f2281ede85 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -122,8 +122,7 @@ static NSMutableDictionary *gHostCache; if (_transportType == GRPCTransportTypeInsecure) { options.transportType = GRPCTransportTypeInsecure; } else { - NSAssert(_transportType == GRPCTransportTypeDefault, - @"Invalid transport type"); + NSAssert(_transportType == GRPCTransportTypeDefault, @"Invalid transport type"); options.transportType = GRPCTransportTypeCronet; } } else diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index 3e9ebe7ae02..b802137c13a 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -32,8 +32,7 @@ return instance; } -- (grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 2e7f1a0dbe2..69f70de17d1 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -29,9 +29,9 @@ } + (instancetype)factoryWithPEMRootCertificates:(NSString *)rootCerts - privateKey:(NSString *)privateKey - certChain:(NSString *)certChain - error:(NSError **)errorPtr { + privateKey:(NSString *)privateKey + certChain:(NSString *)certChain + error:(NSError **)errorPtr { return [[self alloc] initWithPEMRootCerts:rootCerts privateKey:privateKey certChain:certChain @@ -50,9 +50,9 @@ } - (instancetype)initWithPEMRootCerts:(NSString *)rootCerts - privateKey:(NSString *)privateKey - certChain:(NSString *)certChain - error:(NSError **)errorPtr { + privateKey:(NSString *)privateKey + certChain:(NSString *)certChain + error:(NSError **)errorPtr { static NSData *defaultRootsASCII; static NSError *defaultRootsError; static dispatch_once_t loading; @@ -115,8 +115,7 @@ return self; } -- (grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 5c402250ccf..615dfc85569 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -249,8 +249,7 @@ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path callOptions:(GRPCCallOptions *)callOptions { - NSAssert(host.length != 0 && path.length != 0, - @"path and host cannot be nil."); + NSAssert(host.length != 0 && path.length != 0, @"path and host cannot be nil."); if ((self = [super init])) { // Each completion queue consumes one thread. There's a trade to be made between creating and @@ -263,9 +262,7 @@ NSLog(@"Failed to get a channel for the host."); return nil; } - _call = [_channel unmanagedCallWithPath:path - completionQueue:_queue - callOptions:callOptions]; + _call = [_channel unmanagedCallWithPath:path completionQueue:_queue callOptions:callOptions]; if (_call == nil) { NSAssert(_channel != nil, @"Failed to get a channel for the host."); NSLog(@"Failed to create a call."); diff --git a/src/objective-c/GRPCClient/private/utilities.h b/src/objective-c/GRPCClient/private/utilities.h index 8f6baadcf7b..8e3dd793586 100644 --- a/src/objective-c/GRPCClient/private/utilities.h +++ b/src/objective-c/GRPCClient/private/utilities.h @@ -19,5 +19,4 @@ #import /** Raise exception when condition not met. */ -#define GRPCAssert(condition, errorString) \ - NSAssert(condition, errorString) +#define GRPCAssert(condition, errorString) NSAssert(condition, errorString) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 9164f2320bf..2de2932072a 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -138,21 +138,21 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing call = _call; _call = nil; if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(_handler.dispatchQueue, ^{ - id handler = nil; - @synchronized(self) { - handler = self->_handler; - self->_handler = nil; - } - [handler closedWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; - }); - } + dispatch_async(_handler.dispatchQueue, ^{ + id handler = nil; + @synchronized(self) { + handler = self->_handler; + self->_handler = nil; + } + [handler closedWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); + } } [call cancel]; } @@ -179,11 +179,11 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { - @synchronized (self) { + @synchronized(self) { if (initialMetadata != nil && [_handler respondsToSelector:@selector(initialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; } [handler receivedInitialMetadata:initialMetadata]; @@ -197,19 +197,20 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing NSError *error = nil; GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; - @synchronized (self) { + @synchronized(self) { if (parsed && [_handler respondsToSelector:@selector(receivedProtoMessage:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; } [handler receivedProtoMessage:parsed]; }); - } else if (!parsed && [_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]){ + } else if (!parsed && + [_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; self->_handler = nil; } @@ -222,13 +223,12 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata - error:(NSError *)error { - @synchronized (self) { +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + @synchronized(self) { if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; self->_handler = nil; } diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index 51819b12c2f..4424801c110 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -41,12 +41,12 @@ NSString *kDummyPath = @"/dummy/path"; - (void)testCreateChannelAndCall { GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options]; + GRPCPooledChannel *channel = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; XCTAssertNil(channel.wrappedChannel); GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq callOptions:options]; + grpc_call *call = + [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssert(call != NULL); XCTAssertNotNil(channel.wrappedChannel); [channel unrefUnmanagedCall:call]; @@ -60,26 +60,22 @@ NSString *kDummyPath = @"/dummy/path"; GRPCMutableCallOptions *options3 = [options1 mutableCopy]; options3.transportType = GRPCTransportTypeInsecure; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - GRPCPooledChannel *channel1 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options1]; - grpc_call *call1 = [channel1 unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options1]; - GRPCPooledChannel *channel2 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options2]; - grpc_call *call2 = [channel2 unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options2]; - GRPCPooledChannel *channel3 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options3]; - grpc_call *call3 = [channel3 unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options3]; - GRPCPooledChannel *channel4 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost2 - callOptions:options1]; - grpc_call *call4 = [channel4 unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options1]; + GRPCPooledChannel *channel1 = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options1]; + grpc_call *call1 = + [channel1 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options1]; + GRPCPooledChannel *channel2 = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options2]; + grpc_call *call2 = + [channel2 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options2]; + GRPCPooledChannel *channel3 = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options3]; + grpc_call *call3 = + [channel3 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options3]; + GRPCPooledChannel *channel4 = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost2 callOptions:options1]; + grpc_call *call4 = + [channel4 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options1]; XCTAssertEqual(channel1.wrappedChannel, channel2.wrappedChannel); XCTAssertNotEqual(channel1.wrappedChannel, channel3.wrappedChannel); XCTAssertNotEqual(channel1.wrappedChannel, channel4.wrappedChannel); @@ -96,32 +92,26 @@ NSString *kDummyPath = @"/dummy/path"; GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; pool.destroyDelay = kDestroyDelay; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options]; + GRPCPooledChannel *channel = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq callOptions:options]; + grpc_call *call = + [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; GRPCChannel *wrappedChannel = channel.wrappedChannel; [channel unrefUnmanagedCall:call]; // Confirm channel is not destroyed at this time - call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertEqual(wrappedChannel, channel.wrappedChannel); [channel unrefUnmanagedCall:call]; sleep(kDestroyDelay + 1); // Confirm channel is new at this time - call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); // Confirm the new channel can create call - call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssert(call != NULL); [channel unrefUnmanagedCall:call]; } @@ -129,31 +119,26 @@ NSString *kDummyPath = @"/dummy/path"; - (void)testPoolDisconnection { GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options]; + GRPCPooledChannel *channel = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + grpc_call *call = + [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); GRPCChannel *wrappedChannel = channel.wrappedChannel; // Test a new channel is created by requesting a channel from pool [pool disconnectAllChannels]; - channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options]; - call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; + call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); wrappedChannel = channel.wrappedChannel; // Test a new channel is created by requesting a new call from the previous proxy [pool disconnectAllChannels]; - grpc_call *call2 = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + grpc_call *call2 = + [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); [channel unrefUnmanagedCall:call]; @@ -163,20 +148,17 @@ NSString *kDummyPath = @"/dummy/path"; - (void)testUnrefCallFromStaleChannel { GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options]; + GRPCPooledChannel *channel = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + grpc_call *call = + [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; [pool disconnectAllChannels]; - channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options]; + channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - grpc_call *call2 = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + grpc_call *call2 = + [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; // Test unref the call of a stale channel will not cause the current channel going into timed // destroy state XCTAssertNotNil(channel.wrappedChannel); diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 212db2f653a..c07c8e69834 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -45,8 +45,8 @@ long _grpcCallCounter; } -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { - return nil; +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration +*)channelConfiguration { return nil; } - (instancetype)initWithCreateExpectation:(XCTestExpectation *)createExpectation diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 8754bd5ccaf..a9f33aab6f1 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -114,8 +114,7 @@ BOOL isRemoteInteropTest(NSString *host) { } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata - error:(NSError *)error { +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { if (_closeCallback) { _closeCallback(trailingMetadata, error); } From 00ff5805a3c00e9d29cb71dfd5365c36dd5bf96c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 09:43:24 -0800 Subject: [PATCH 205/534] null_unspecified -> nullable --- src/objective-c/GRPCClient/GRPCCall.h | 26 +++++++++++++------------- src/objective-c/ProtoRPC/ProtoRPC.h | 10 +++++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 4c8c11eded2..214969af230 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -306,7 +306,7 @@ NS_ASSUME_NONNULL_END * * The property is initialized to an empty NSMutableDictionary. */ -@property(null_unspecified, atomic, readonly) NSMutableDictionary *requestHeaders; +@property(nullable, atomic, readonly) NSMutableDictionary *requestHeaders; /** * This dictionary is populated with the HTTP headers received from the server. This happens before @@ -317,7 +317,7 @@ NS_ASSUME_NONNULL_END * The value of this property is nil until all response headers are received, and will change before * any of -writeValue: or -writesFinishedWithError: are sent to the writeable. */ -@property(null_unspecified, atomic, readonly) NSDictionary *responseHeaders; +@property(nullable, atomic, readonly) NSDictionary *responseHeaders; /** * Same as responseHeaders, but populated with the HTTP trailers received from the server before the @@ -326,7 +326,7 @@ NS_ASSUME_NONNULL_END * The value of this property is nil until all response trailers are received, and will change * before -writesFinishedWithError: is sent to the writeable. */ -@property(null_unspecified, atomic, readonly) NSDictionary *responseTrailers; +@property(nullable, atomic, readonly) NSDictionary *responseTrailers; /** * The request writer has to write NSData objects into the provided Writeable. The server will @@ -339,9 +339,9 @@ NS_ASSUME_NONNULL_END * host parameter should not contain the scheme (http:// or https://), only the name or IP addr * and the port number, for example @"localhost:5050". */ -- (null_unspecified instancetype)initWithHost:(null_unspecified NSString *)host - path:(null_unspecified NSString *)path - requestsWriter:(null_unspecified GRXWriter *)requestWriter; +- (nullable instancetype)initWithHost:(nullable NSString *)host + path:(nullable NSString *)path + requestsWriter:(nullable GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -353,11 +353,11 @@ NS_ASSUME_NONNULL_END * The following methods are deprecated. */ + (void)setCallSafety:(GRPCCallSafety)callSafety - host:(null_unspecified NSString *)host - path:(null_unspecified NSString *)path; -@property(null_unspecified, atomic, copy, readwrite) NSString *serverName; + host:(nullable NSString *)host + path:(nullable NSString *)path; +@property(nullable, atomic, copy, readwrite) NSString *serverName; @property NSTimeInterval timeout; -- (void)setResponseDispatchQueue:(null_unspecified dispatch_queue_t)queue; +- (void)setResponseDispatchQueue:(nullable dispatch_queue_t)queue; @end @@ -368,11 +368,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (null_unspecified id)objectForKeyedSubscript:(null_unspecified id)key; -- (void)setObject:(null_unspecified id)obj forKeyedSubscript:(null_unspecified id)key; +- (nullable id)objectForKeyedSubscript:(nullable id)key; +- (void)setObject:(nullable id)obj forKeyedSubscript:(nullable id)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(null_unspecified id)key; +- (void)removeObjectForKey:(nullable id)key; @end #pragma clang diagnostic push diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 98b60c3f727..2623aecb82f 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -132,11 +132,11 @@ __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC * addr and the port number, for example @"localhost:5050". */ - - (instancetype _Null_unspecified)initWithHost : (NSString *_Null_unspecified)host method - : (GRPCProtoMethod *_Null_unspecified)method requestsWriter - : (GRXWriter *_Null_unspecified)requestsWriter responseClass - : (Class _Null_unspecified)responseClass responsesWriteable - : (id _Null_unspecified)responsesWriteable NS_DESIGNATED_INITIALIZER; + (nullable instancetype)initWithHost : (nullable NSString *)host method + : (nullable GRPCProtoMethod *)method requestsWriter + : (nullable GRXWriter *)requestsWriter responseClass + : (nullable Class)responseClass responsesWriteable + : (nullable id)responsesWriteable NS_DESIGNATED_INITIALIZER; - (void)start; @end From 29e1591904539fcb6d92ba49e69ed27ee9d3349d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 09:52:29 -0800 Subject: [PATCH 206/534] _Nullable -> nullable --- .../GRPCClient/private/GRPCCronetChannelFactory.h | 8 ++++---- .../GRPCClient/private/GRPCInsecureChannelFactory.h | 8 ++++---- .../GRPCClient/private/GRPCSecureChannelFactory.h | 12 ++++++------ src/objective-c/tests/APIv2Tests/APIv2Tests.m | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h index 5e35576ea10..738dfdb7370 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h @@ -24,12 +24,12 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCCronetChannelFactory : NSObject -+ (instancetype _Nullable)sharedInstance; ++ (nullable instancetype)sharedInstance; -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args; +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSDictionary *)args; -- (instancetype _Nullable)init NS_UNAVAILABLE; +- (nullable instancetype)init NS_UNAVAILABLE; @end diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h index 98a985fe84d..2d471aebed6 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h @@ -23,12 +23,12 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCInsecureChannelFactory : NSObject -+ (instancetype _Nullable)sharedInstance; ++ (nullable instancetype)sharedInstance; -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args; +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSDictionary *)args; -- (instancetype _Nullable)init NS_UNAVAILABLE; +- (nullable instancetype)init NS_UNAVAILABLE; @end diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index 02e7052996d..5dc5a973120 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -23,15 +23,15 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCSecureChannelFactory : NSObject -+ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString *_Nullable)rootCerts - privateKey:(NSString *_Nullable)privateKey - certChain:(NSString *_Nullable)certChain ++ (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain error:(NSError **)errorPtr; -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args; +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSDictionary *)args; -- (instancetype _Nullable)init NS_UNAVAILABLE; +- (nullable instancetype)init NS_UNAVAILABLE; @end diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index e49f58ae9d3..1b14043af92 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -81,20 +81,20 @@ static const NSTimeInterval kTestTimeout = 16; return self; } -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { if (self->_initialMetadataCallback) { self->_initialMetadataCallback(initialMetadata); } } -- (void)receivedRawMessage:(GPBMessage *_Nullable)message { +- (void)receivedRawMessage:(GPBMessage *)message { if (self->_messageCallback) { self->_messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error { +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata + error:(NSError *)error { if (self->_closeCallback) { self->_closeCallback(trailingMetadata, error); } From d806ce71d762a1a2fc03e41cc186d002ee604316 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 10:08:23 -0800 Subject: [PATCH 207/534] more nullability --- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- .../GRPCClient/private/GRPCSecureChannelFactory.h | 6 +++--- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 61d85642863..e88e28109cf 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -64,7 +64,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)getTokenWithHandler:(void (^)(NSString *token))handler; +- (void)getTokenWithHandler:(void (^)(NSString * _Nullable token))handler; @end @interface GRPCCallOptions : NSObject diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index 5dc5a973120..588239b7064 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -24,9 +24,9 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCSecureChannelFactory : NSObject + (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts - privateKey:(nullable NSString *)privateKey - certChain:(nullable NSString *)certChain - error:(NSError **)errorPtr; + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr; - (nullable grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(nullable NSDictionary *)args; diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index 1b14043af92..32f2122f79b 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -93,8 +93,7 @@ static const NSTimeInterval kTestTimeout = 16; } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata - error:(NSError *)error { +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { if (self->_closeCallback) { self->_closeCallback(trailingMetadata, error); } From 1d8550c4c27ca357195946759f161942a6e07589 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 11:26:24 -0800 Subject: [PATCH 208/534] nit nullability fix --- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index e88e28109cf..48bb11aeeb0 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -64,7 +64,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)getTokenWithHandler:(void (^)(NSString * _Nullable token))handler; +- (void)getTokenWithHandler:(void (^ _Nullable)(NSString * _Nullable token))handler; @end @interface GRPCCallOptions : NSObject From 195c042d3231d0ebbb1c2684ce32457b879062ef Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 17:35:21 -0800 Subject: [PATCH 209/534] Replace PB_FIELD_16BIT with PB_FIELD_32BIT --- CMakeLists.txt | 2 +- gRPC-Core.podspec | 2 +- setup.py | 2 +- .../lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c | 4 ++-- src/core/tsi/alts/handshaker/altscontext.pb.c | 4 ++-- src/core/tsi/alts/handshaker/handshaker.pb.c | 4 ++-- src/core/tsi/alts/handshaker/transport_security_common.pb.c | 4 ++-- templates/CMakeLists.txt.template | 2 +- templates/gRPC-Core.podspec.template | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c2ba2048c0..f1bcb7b9f99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,7 +94,7 @@ endif() set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) -add_definitions(-DPB_FIELD_16BIT) +add_definitions(-DPB_FIELD_32BIT) if (MSVC) include(cmake/msvc_static_runtime.cmake) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f0a715cb585..bd48ea3825a 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -93,7 +93,7 @@ Pod::Spec.new do |s| } s.default_subspecs = 'Interface', 'Implementation' - s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_16BIT' + s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_32BIT' s.libraries = 'c++' # Like many other C libraries, gRPC-Core has its public headers under `include//` and its diff --git a/setup.py b/setup.py index ae86e6c9fb7..c3aae1696b9 100644 --- a/setup.py +++ b/setup.py @@ -144,7 +144,7 @@ if EXTRA_ENV_COMPILE_ARGS is None: EXTRA_ENV_COMPILE_ARGS += ' -std=gnu99 -fvisibility=hidden -fno-wrapv -fno-exceptions' elif "darwin" in sys.platform: EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden -fno-wrapv -fno-exceptions' -EXTRA_ENV_COMPILE_ARGS += ' -DPB_FIELD_16BIT' +EXTRA_ENV_COMPILE_ARGS += ' -DPB_FIELD_32BIT' if EXTRA_ENV_LINK_ARGS is None: EXTRA_ENV_LINK_ARGS = '' diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c index f6538e1349f..a7b072420ec 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c @@ -75,14 +75,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_16BIT +/* If you get an error here, it means that you need to define PB_FIELD_32BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server) +PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server) #endif diff --git a/src/core/tsi/alts/handshaker/altscontext.pb.c b/src/core/tsi/alts/handshaker/altscontext.pb.c index 5fb152a558e..2320edb1eff 100644 --- a/src/core/tsi/alts/handshaker/altscontext.pb.c +++ b/src/core/tsi/alts/handshaker/altscontext.pb.c @@ -33,14 +33,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 65536 #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_16BIT +/* If you get an error here, it means that you need to define PB_FIELD_32BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_AltsContext) +PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_AltsContext) #endif diff --git a/src/core/tsi/alts/handshaker/handshaker.pb.c b/src/core/tsi/alts/handshaker/handshaker.pb.c index 5450b1602d4..8eda290e123 100644 --- a/src/core/tsi/alts/handshaker/handshaker.pb.c +++ b/src/core/tsi/alts/handshaker/handshaker.pb.c @@ -108,14 +108,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identit #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_16BIT +/* If you get an error here, it means that you need to define PB_FIELD_32BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identities) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_identity) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_ServerHandshakeParameters, local_identities) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, handshake_parameters[0]) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry, value) < 256 && pb_membersize(grpc_gcp_HandshakerReq, client_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, server_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, next) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, local_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_rpc_versions) < 256 && pb_membersize(grpc_gcp_HandshakerResp, result) < 256 && pb_membersize(grpc_gcp_HandshakerResp, status) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_Endpoint_grpc_gcp_Identity_grpc_gcp_StartClientHandshakeReq_grpc_gcp_ServerHandshakeParameters_grpc_gcp_StartServerHandshakeReq_grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_grpc_gcp_NextHandshakeMessageReq_grpc_gcp_HandshakerReq_grpc_gcp_HandshakerResult_grpc_gcp_HandshakerStatus_grpc_gcp_HandshakerResp) +PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identities) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_identity) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_ServerHandshakeParameters, local_identities) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, handshake_parameters[0]) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry, value) < 256 && pb_membersize(grpc_gcp_HandshakerReq, client_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, server_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, next) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, local_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_rpc_versions) < 256 && pb_membersize(grpc_gcp_HandshakerResp, result) < 256 && pb_membersize(grpc_gcp_HandshakerResp, status) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_Endpoint_grpc_gcp_Identity_grpc_gcp_StartClientHandshakeReq_grpc_gcp_ServerHandshakeParameters_grpc_gcp_StartServerHandshakeReq_grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_grpc_gcp_NextHandshakeMessageReq_grpc_gcp_HandshakerReq_grpc_gcp_HandshakerResult_grpc_gcp_HandshakerStatus_grpc_gcp_HandshakerResp) #endif diff --git a/src/core/tsi/alts/handshaker/transport_security_common.pb.c b/src/core/tsi/alts/handshaker/transport_security_common.pb.c index 326b1b10ab7..aac699314e7 100644 --- a/src/core/tsi/alts/handshaker/transport_security_common.pb.c +++ b/src/core/tsi/alts/handshaker/transport_security_common.pb.c @@ -35,14 +35,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_16BIT +/* If you get an error here, it means that you need to define PB_FIELD_32BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < 256 && pb_membersize(grpc_gcp_RpcProtocolVersions, min_rpc_version) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_RpcProtocolVersions_grpc_gcp_RpcProtocolVersions_Version) +PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < 256 && pb_membersize(grpc_gcp_RpcProtocolVersions, min_rpc_version) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_RpcProtocolVersions_grpc_gcp_RpcProtocolVersions_Version) #endif diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 1628493d000..f33d980cd00 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -143,7 +143,7 @@ ## Some libraries are shared even with BUILD_SHARED_LIBRARIES=OFF set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) - add_definitions(-DPB_FIELD_16BIT) + add_definitions(-DPB_FIELD_32BIT) if (MSVC) include(cmake/msvc_static_runtime.cmake) diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 98b6344a4bf..17178af4195 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -152,7 +152,7 @@ } s.default_subspecs = 'Interface', 'Implementation' - s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_16BIT' + s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_32BIT' s.libraries = 'c++' # Like many other C libraries, gRPC-Core has its public headers under `include//` and its From f62323aea28260d4233487dc84834dd26c48845c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 20 Nov 2018 13:21:07 -0800 Subject: [PATCH 210/534] Tests project fixes --- src/objective-c/tests/Tests.xcodeproj/project.pbxproj | 8 -------- .../xcshareddata/xcschemes/ChannelTests.xcscheme | 7 +++++-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 6d1932b0215..6f24d3512f8 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -1276,15 +1276,11 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); outputPaths = ( "$(DERIVED_FILE_DIR)/Pods-APIv2Tests-checkManifestLockResult.txt", ); @@ -1856,15 +1852,11 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - ); outputPaths = ( "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", ); diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme index 16ae481123b..8c8623d7b21 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme @@ -26,7 +26,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -47,7 +51,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" From 726f044932c2ae096d05f4f6cac2850ae2be3f83 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 21 Nov 2018 14:24:22 -0800 Subject: [PATCH 211/534] Include linux/version.h for manylinux --- include/grpc/impl/codegen/port_platform.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index b2028a63053..6795f05a6d9 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -121,6 +121,7 @@ #else /* _LP64 */ #define GPR_ARCH_32 1 #endif /* _LP64 */ +#include #elif defined(ANDROID) || defined(__ANDROID__) #define GPR_PLATFORM_STRING "android" #define GPR_ANDROID 1 From 03c73e92f1dedb1de4bba0269e7c614b47cf8035 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 21 Nov 2018 15:31:10 -0800 Subject: [PATCH 212/534] Fix test failure due to NSAssert --- src/objective-c/tests/Podfile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 5df9d4e85bd..12112f95e14 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -148,5 +148,14 @@ post_install do |installer| end end end + + # Enable NSAssert on gRPC + if target.name == 'gRPC' || target.name == 'ProtoRPC' || target.name == 'RxLibrary' + target.build_configurations.each do |config| + if config.name != 'Release' + config.build_settings['ENABLE_NS_ASSERTIONS'] = 'YES' + end + end + end end end From 5ae61f5a5a267f5975248d4262133a740e09a66b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 26 Nov 2018 17:17:09 -0800 Subject: [PATCH 213/534] Multiple fixes --- .../GRPCClient/GRPCCall+ChannelArg.m | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 53 +++---- .../GRPCClient/private/ChannelArgsUtil.m | 21 ++- .../GRPCClient/private/GRPCChannel.h | 6 +- .../GRPCClient/private/GRPCChannel.m | 66 ++++---- .../GRPCClient/private/GRPCChannelPool.h | 49 +++--- .../GRPCClient/private/GRPCChannelPool.m | 145 +++++++++--------- .../GRPCClient/private/GRPCWrappedCall.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.m | 38 ++--- .../tests/ChannelTests/ChannelPoolTest.m | 40 +++-- .../tests/ChannelTests/ChannelTests.m | 4 +- src/objective-c/tests/GRPCClientTests.m | 7 +- 12 files changed, 221 insertions(+), 212 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index 703cff63bb0..ae60d6208e1 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -36,7 +36,7 @@ } + (void)closeOpenConnections { - [[GRPCChannelPool sharedInstance] closeOpenConnections]; + [[GRPCChannelPool sharedInstance] disconnectAllChannels]; } + (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host { diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 94e470d4ed9..bf9441c27eb 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -69,11 +69,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { NSAssert(host.length != 0 && path.length != 0, @"Host and Path cannot be empty"); - if (host.length == 0) { - host = [NSString string]; - } - if (path.length == 0) { - path = [NSString string]; + if (host.length == 0 || path.length == 0) { + return nil; } if ((self = [super init])) { _host = [host copy]; @@ -173,7 +170,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)start { - GRPCCall *call = nil; + GRPCCall *copiedCall = nil; @synchronized(self) { NSAssert(!_started, @"Call already started."); NSAssert(!_canceled, @"Call already canceled."); @@ -197,7 +194,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (_callOptions.initialMetadata) { [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; } - call = _call; + copiedCall = _call; } void (^valueHandler)(id value) = ^(id value) { @@ -235,11 +232,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; }; id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:valueHandler completionHandler:completionHandler]; - [call startWithWriteable:responseWriteable]; + [copiedCall startWithWriteable:responseWriteable]; } - (void)cancel { - GRPCCall *call = nil; + GRPCCall *copiedCall = nil; @synchronized(self) { if (_canceled) { return; @@ -247,7 +244,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _canceled = YES; - call = _call; + copiedCall = _call; _call = nil; _pipe = nil; @@ -268,13 +265,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; @"Canceled by app" }]]; }); + } else { + _handler = nil; } } - [call cancel]; + [copiedCall cancel]; } - (void)writeData:(NSData *)data { - GRXBufferedPipe *pipe = nil; + GRXBufferedPipe *copiedPipe = nil; @synchronized(self) { NSAssert(!_canceled, @"Call arleady canceled."); NSAssert(!_finished, @"Call is half-closed before sending data."); @@ -286,14 +285,14 @@ const char *kCFStreamVarName = "grpc_cfstream"; } if (_pipe) { - pipe = _pipe; + copiedPipe = _pipe; } } - [pipe writeValue:data]; + [copiedPipe writeValue:data]; } - (void)finish { - GRXBufferedPipe *pipe = nil; + GRXBufferedPipe *copiedPipe = nil; @synchronized(self) { NSAssert(_started, @"Call not started."); NSAssert(!_canceled, @"Call arleady canceled."); @@ -309,12 +308,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; } if (_pipe) { - pipe = _pipe; + copiedPipe = _pipe; _pipe = nil; } _finished = YES; } - [pipe writesFinishedWithError:nil]; + [copiedPipe writesFinishedWithError:nil]; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { @@ -322,11 +321,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (initialMetadata != nil && [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; } - [handler receivedInitialMetadata:initialMetadata]; + [copiedHandler receivedInitialMetadata:initialMetadata]; }); } } @@ -336,11 +335,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(self) { if (message != nil && [_handler respondsToSelector:@selector(receivedRawMessage:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; } - [handler receivedRawMessage:message]; + [copiedHandler receivedRawMessage:message]; }); } } @@ -350,14 +349,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(self) { if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; } - [handler closedWithTrailingMetadata:trailingMetadata error:error]; + [copiedHandler closedWithTrailingMetadata:trailingMetadata error:error]; }); + } else { + _handler = nil; } } } diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index d9e44b557d1..3135fcff028 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -60,36 +60,35 @@ grpc_channel_args *GRPCBuildChannelArgs(NSDictionary *dictionary) { NSUInteger argCount = [keys count]; grpc_channel_args *channelArgs = gpr_malloc(sizeof(grpc_channel_args)); - channelArgs->num_args = argCount; channelArgs->args = gpr_malloc(argCount * sizeof(grpc_arg)); // TODO(kriswuollett) Check that keys adhere to GRPC core library requirements + NSUInteger j = 0; for (NSUInteger i = 0; i < argCount; ++i) { - grpc_arg *arg = &channelArgs->args[i]; + grpc_arg *arg = &channelArgs->args[j]; arg->key = gpr_strdup([keys[i] UTF8String]); id value = dictionary[keys[i]]; if ([value respondsToSelector:@selector(UTF8String)]) { arg->type = GRPC_ARG_STRING; arg->value.string = gpr_strdup([value UTF8String]); + j++; } else if ([value respondsToSelector:@selector(intValue)]) { - if ([value compare:[NSNumber numberWithInteger:INT_MAX]] == NSOrderedDescending || - [value compare:[NSNumber numberWithInteger:INT_MIN]] == NSOrderedAscending) { - [NSException raise:NSInvalidArgumentException - format:@"Out of range for a value-typed channel argument: %@", value]; + int64_t value64 = [value longLongValue]; + if (value64 <= INT_MAX || value64 >= INT_MIN) { + arg->type = GRPC_ARG_INTEGER; + arg->value.integer = [value intValue]; + j++; } - arg->type = GRPC_ARG_INTEGER; - arg->value.integer = [value intValue]; } else if (value != nil) { arg->type = GRPC_ARG_POINTER; arg->value.pointer.p = (__bridge_retained void *)value; arg->value.pointer.vtable = &objc_arg_vtable; - } else { - [NSException raise:NSInvalidArgumentException - format:@"Invalid channel argument type: %@", [value class]]; + j++; } } + channelArgs->num_args = j; return channelArgs; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 5426b28d758..147015bed10 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -32,6 +32,10 @@ NS_ASSUME_NONNULL_BEGIN /** Caching signature of a channel. */ @interface GRPCChannelConfiguration : NSObject +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype) new NS_UNAVAILABLE; + /** The host that this channel is connected to. */ @property(copy, readonly) NSString *host; @@ -47,7 +51,7 @@ NS_ASSUME_NONNULL_BEGIN /** Acquire the dictionary of channel args with current configurations. */ @property(copy, readonly) NSDictionary *channelArgs; -- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; +- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index e4cefc338c6..24cf670d1b5 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -39,8 +39,9 @@ - (instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { NSAssert(host.length > 0, @"Host must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); - if (host.length == 0) return nil; - if (callOptions == nil) return nil; + if (host.length == 0 || callOptions == nil) { + return nil; + } if ((self = [super init])) { _host = [host copy]; @@ -180,7 +181,9 @@ - (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { NSAssert(channelConfiguration != nil, @"channelConfiguration must not be empty."); - if (channelConfiguration == nil) return nil; + if (channelConfiguration == nil) { + return nil; + } if ((self = [super init])) { _configuration = [channelConfiguration copy]; @@ -218,35 +221,34 @@ if (callOptions == nil) return NULL; grpc_call *call = NULL; - @synchronized(self) { - NSAssert(_unmanagedChannel != NULL, @"Channel should have valid unmanaged channel."); - if (_unmanagedChannel == NULL) return NULL; - - NSString *serverAuthority = - callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; - NSTimeInterval timeout = callOptions.timeout; - NSAssert(timeout >= 0, @"Invalid timeout"); - if (timeout < 0) return NULL; - grpc_slice host_slice = grpc_empty_slice(); - if (serverAuthority) { - host_slice = grpc_slice_from_copied_string(serverAuthority.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_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); - call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, - queue.unmanagedQueue, path_slice, - serverAuthority ? &host_slice : NULL, deadline_ms, NULL); - if (serverAuthority) { - grpc_slice_unref(host_slice); - } - grpc_slice_unref(path_slice); - NSAssert(call != nil, @"Unable to create call."); - if (call == NULL) { - NSLog(@"Unable to create call."); - } + // No need to lock here since _unmanagedChannel is only changed in _dealloc + NSAssert(_unmanagedChannel != NULL, @"Channel should have valid unmanaged channel."); + if (_unmanagedChannel == NULL) return NULL; + + NSString *serverAuthority = + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + NSTimeInterval timeout = callOptions.timeout; + NSAssert(timeout >= 0, @"Invalid timeout"); + if (timeout < 0) return NULL; + grpc_slice host_slice = grpc_empty_slice(); + if (serverAuthority) { + host_slice = grpc_slice_from_copied_string(serverAuthority.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_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, + queue.unmanagedQueue, path_slice, + serverAuthority ? &host_slice : NULL, deadline_ms, NULL); + if (serverAuthority) { + grpc_slice_unref(host_slice); + } + grpc_slice_unref(path_slice); + NSAssert(call != nil, @"Unable to create call."); + if (call == NULL) { + NSLog(@"Unable to create call."); } return call; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 1e3c1d7d976..26600ef3a96 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -39,12 +39,16 @@ NS_ASSUME_NONNULL_BEGIN */ @interface GRPCPooledChannel : NSObject +- (nullable instancetype)init NS_UNAVAILABLE; + ++ (nullable instancetype)new NS_UNAVAILABLE; + /** * Initialize with an actual channel object \a channel and a reference to the channel pool. */ - (nullable instancetype)initWithChannelConfiguration: (GRPCChannelConfiguration *)channelConfiguration - channelPool:(GRPCChannelPool *)channelPool; + channelPool:(GRPCChannelPool *)channelPool NS_DESIGNATED_INITIALIZER; /** * Create a grpc core call object (grpc_call) from this channel. If channel is disconnected, get a @@ -59,17 +63,21 @@ NS_ASSUME_NONNULL_BEGIN * \a unmanagedCallWithPath:completionQueue:callOptions: and decrease channel refcount. If refcount * of the channel becomes 0, return the channel object to channel pool. */ -- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall; +- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall; /** - * Force the channel to disconnect immediately. + * Force the channel to disconnect immediately. Subsequent calls to unmanagedCallWithPath: will + * attempt to reconnect to the remote channel. */ - (void)disconnect; -// The following methods and properties are for test only +@end + +/** Test-only interface for \a GRPCPooledChannel. */ +@interface GRPCPooledChannel (Test) /** - * Return the pointer to the real channel wrapped by the proxy. + * Return the pointer to the raw channel wrapped. */ @property(atomic, readonly) GRPCChannel *wrappedChannel; @@ -81,6 +89,10 @@ NS_ASSUME_NONNULL_BEGIN */ @interface GRPCChannelPool : NSObject +- (nullable instancetype)init NS_UNAVAILABLE; + ++ (nullable instancetype)new NS_UNAVAILABLE; + /** * Get the global channel pool. */ @@ -92,31 +104,20 @@ NS_ASSUME_NONNULL_BEGIN - (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; /** - * This method is deprecated. - * - * Destroy all open channels and close their connections. + * Disconnect all channels in this pool. */ -- (void)closeOpenConnections; - -// Test-only methods below +- (void)disconnectAllChannels; -/** - * Get an instance of pool isolated from the global shared pool. This method is for test only. - * Global pool should be used in production. - */ -- (nullable instancetype)init; +@end -/** - * Simulate a network transition event and destroy all channels. This method is for internal and - * test only. - */ -- (void)disconnectAllChannels; +/** Test-only interface for \a GRPCChannelPool. */ +@interface GRPCChannelPool (Test) /** - * Set the destroy delay of channels. A channel should be destroyed if it stayed idle (no active - * call on it) for this period of time. This property is for test only. + * Get an instance of pool isolated from the global shared pool with channels' destroy delay being + * \a destroyDelay. */ -@property(atomic) NSTimeInterval destroyDelay; +- (nullable instancetype)initTestPoolWithDestroyDelay:(NSTimeInterval)destroyDelay; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 7c139b37176..f6615b58405 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -52,10 +52,9 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; __weak GRPCChannelPool *_channelPool; GRPCChannelConfiguration *_channelConfiguration; NSMutableSet *_unmanagedCalls; + GRPCChannel *_wrappedChannel; } -@synthesize wrappedChannel = _wrappedChannel; - - (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration channelPool:(GRPCChannelPool *)channelPool { NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); @@ -68,11 +67,17 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; _channelPool = channelPool; _channelConfiguration = channelConfiguration; _unmanagedCalls = [NSMutableSet set]; + _wrappedChannel = nil; } return self; } +- (void)dealloc { + NSAssert([_unmanagedCalls count] == 0 && _wrappedChannel == nil, @"Pooled channel should only be" + "destroyed after the wrapped channel is destroyed"); +} + - (grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions { @@ -99,31 +104,38 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; return call; } -- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall { - if (unmanagedCall == nil) return; +- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall { + if (unmanagedCall == NULL) { + return; + } grpc_call_unref(unmanagedCall); - BOOL timedDestroy = NO; @synchronized(self) { - if ([_unmanagedCalls containsObject:[NSValue valueWithPointer:unmanagedCall]]) { - [_unmanagedCalls removeObject:[NSValue valueWithPointer:unmanagedCall]]; - if ([_unmanagedCalls count] == 0) { - timedDestroy = YES; - } + NSValue *removedCall = [NSValue valueWithPointer:unmanagedCall]; + [_unmanagedCalls removeObject:removedCall]; + if ([_unmanagedCalls count] == 0) { + _wrappedChannel = nil; + GRPCChannelPool *strongPool = _channelPool; + [strongPool unrefChannelWithConfiguration:_channelConfiguration]; } } - if (timedDestroy) { - [self timedDestroy]; - } } - (void)disconnect { @synchronized(self) { - _wrappedChannel = nil; - [_unmanagedCalls removeAllObjects]; + if (_wrappedChannel != nil) { + _wrappedChannel = nil; + [_unmanagedCalls removeAllObjects]; + GRPCChannelPool *strongPool = _channelPool; + [strongPool unrefChannelWithConfiguration:_channelConfiguration]; + } } } +@end + +@implementation GRPCPooledChannel (Test) + - (GRPCChannel *)wrappedChannel { GRPCChannel *channel = nil; @synchronized(self) { @@ -132,67 +144,52 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; return channel; } -- (void)timedDestroy { - __strong GRPCChannelPool *pool = nil; - @synchronized(self) { - // Check if we still want to destroy the channel. - if ([_unmanagedCalls count] == 0) { - pool = _channelPool; - _wrappedChannel = nil; - } - } - [pool unrefChannelWithConfiguration:_channelConfiguration]; -} - @end /** * A convenience value type for cached channel. */ -@interface GRPCChannelRecord : NSObject +@interface GRPCChannelRecord : NSObject /** Pointer to the raw channel. May be nil when the channel has been destroyed. */ @property GRPCChannel *channel; /** Channel proxy corresponding to this channel configuration. */ -@property GRPCPooledChannel *proxy; +@property GRPCPooledChannel *pooledChannel; /** Last time when a timed destroy is initiated on the channel. */ @property NSDate *timedDestroyDate; /** Reference count of the proxy to the channel. */ -@property NSUInteger refcount; +@property NSUInteger refCount; @end @implementation GRPCChannelRecord -- (id)copyWithZone:(NSZone *)zone { - GRPCChannelRecord *newRecord = [[GRPCChannelRecord allocWithZone:zone] init]; - newRecord.channel = _channel; - newRecord.proxy = _proxy; - newRecord.timedDestroyDate = _timedDestroyDate; - newRecord.refcount = _refcount; +@end - return newRecord; -} +@interface GRPCChannelPool () + +- (instancetype)initInstanceWithDestroyDelay:(NSTimeInterval)destroyDelay NS_DESIGNATED_INITIALIZER; @end @implementation GRPCChannelPool { NSMutableDictionary *_channelPool; dispatch_queue_t _dispatchQueue; + NSTimeInterval _destroyDelay; } + (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ - gChannelPool = [[GRPCChannelPool alloc] init]; + gChannelPool = [[GRPCChannelPool alloc] initInstanceWithDestroyDelay:kDefaultChannelDestroyDelay]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; } -- (instancetype)init { +- (instancetype)initInstanceWithDestroyDelay:(NSTimeInterval)destroyDelay { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 @@ -206,7 +203,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; #endif _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } - _destroyDelay = kDefaultChannelDestroyDelay; + _destroyDelay = destroyDelay; // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); @@ -217,56 +214,56 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; return self; } +- (void)dealloc { + [GRPCConnectivityMonitor unregisterObserver:self]; +} + - (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { NSAssert(host.length > 0, @"Host must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); - if (host.length == 0) return nil; - if (callOptions == nil) return nil; + if (host.length == 0 || callOptions == nil) { + return nil; + } - GRPCPooledChannel *channelProxy = nil; + GRPCPooledChannel *pooledChannel = nil; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; @synchronized(self) { GRPCChannelRecord *record = _channelPool[configuration]; if (record == nil) { record = [[GRPCChannelRecord alloc] init]; - record.proxy = + record.pooledChannel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration channelPool:self]; - record.timedDestroyDate = nil; _channelPool[configuration] = record; - channelProxy = record.proxy; + pooledChannel = record.pooledChannel; } else { - channelProxy = record.proxy; + pooledChannel = record.pooledChannel; } } - return channelProxy; -} - -- (void)closeOpenConnections { - [self disconnectAllChannels]; + return pooledChannel; } - (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { GRPCChannel *ret = nil; @synchronized(self) { NSAssert(configuration != nil, @"configuration cannot be empty."); - if (configuration == nil) return nil; + if (configuration == nil) { + return nil; + } GRPCChannelRecord *record = _channelPool[configuration]; NSAssert(record != nil, @"No record corresponding to a proxy."); - if (record == nil) return nil; + if (record == nil) { + return nil; + } + record.refCount++; + record.timedDestroyDate = nil; if (record.channel == nil) { // Channel is already destroyed; record.channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration]; - record.timedDestroyDate = nil; - record.refcount = 1; - ret = record.channel; - } else { - ret = record.channel; - record.timedDestroyDate = nil; - record.refcount++; } + ret = record.channel; } return ret; } @@ -275,11 +272,13 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @synchronized(self) { GRPCChannelRecord *record = _channelPool[configuration]; NSAssert(record != nil, @"No record corresponding to a proxy."); - if (record == nil) return; - NSAssert(record.refcount > 0, @"Inconsistent channel refcount."); - if (record.refcount > 0) { - record.refcount--; - if (record.refcount == 0) { + if (record == nil) { + return; + } + NSAssert(record.refCount > 0, @"Inconsistent channel refcount."); + if (record.refCount > 0) { + record.refCount--; + if (record.refCount == 0) { NSDate *now = [NSDate date]; record.timedDestroyDate = now; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_destroyDelay * NSEC_PER_SEC)), @@ -288,7 +287,6 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (now == record.timedDestroyDate) { // Destroy the raw channel and reset related records. record.timedDestroyDate = nil; - record.refcount = 0; record.channel = nil; } } @@ -306,8 +304,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; GRPCChannelRecord *_Nonnull obj, BOOL *_Nonnull stop) { obj.channel = nil; obj.timedDestroyDate = nil; - obj.refcount = 0; - [proxySet addObject:obj.proxy]; + [proxySet addObject:obj.pooledChannel]; }]; } // Disconnect proxies @@ -320,8 +317,12 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; [self disconnectAllChannels]; } -- (void)dealloc { - [GRPCConnectivityMonitor unregisterObserver:self]; +@end + +@implementation GRPCChannelPool (Test) + +- (instancetype)initTestPoolWithDestroyDelay:(NSTimeInterval)destroyDelay { + return [self initInstanceWithDestroyDelay:destroyDelay]; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 615dfc85569..5788d0a003f 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -317,7 +317,7 @@ } - (void)dealloc { - [_channel unrefUnmanagedCall:_call]; + [_channel destroyUnmanagedCall:_call]; _channel = nil; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 2de2932072a..dff88b8591f 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -133,18 +133,18 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)cancel { - GRPCCall2 *call; + GRPCCall2 *copiedCall; @synchronized(self) { - call = _call; + copiedCall = _call; _call = nil; if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_handler.dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; self->_handler = nil; } - [handler closedWithTrailingMetadata:nil + [copiedHandler closedWithTrailingMetadata:nil error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ @@ -152,9 +152,11 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @"Canceled by app" }]]; }); + } else { + _handler = nil; } } - [call cancel]; + [copiedCall cancel]; } - (void)writeMessage:(GPBMessage *)message { @@ -182,11 +184,11 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @synchronized(self) { if (initialMetadata != nil && [_handler respondsToSelector:@selector(initialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; } - [handler receivedInitialMetadata:initialMetadata]; + [copiedHandler receivedInitialMetadata:initialMetadata]; }); } } @@ -200,21 +202,21 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @synchronized(self) { if (parsed && [_handler respondsToSelector:@selector(receivedProtoMessage:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; } - [handler receivedProtoMessage:parsed]; + [copiedHandler receivedProtoMessage:parsed]; }); } else if (!parsed && [_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; self->_handler = nil; } - [handler closedWithTrailingMetadata:nil + [copiedHandler closedWithTrailingMetadata:nil error:ErrorForBadProto(message, _responseClass, error)]; }); [_call cancel]; @@ -227,12 +229,12 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @synchronized(self) { if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; self->_handler = nil; } - [handler closedWithTrailingMetadata:trailingMetadata error:error]; + [copiedHandler closedWithTrailingMetadata:trailingMetadata error:error]; }); } _call = nil; diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index 4424801c110..9461945560a 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -28,6 +28,8 @@ NSString *kDummyHost = @"dummy.host"; NSString *kDummyHost2 = @"dummy.host.2"; NSString *kDummyPath = @"/dummy/path"; +const NSTimeInterval kDestroyDelay = 1.0; + @interface ChannelPoolTest : XCTestCase @end @@ -39,7 +41,7 @@ NSString *kDummyPath = @"/dummy/path"; } - (void)testCreateChannelAndCall { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; @@ -49,12 +51,12 @@ NSString *kDummyPath = @"/dummy/path"; [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssert(call != NULL); XCTAssertNotNil(channel.wrappedChannel); - [channel unrefUnmanagedCall:call]; + [channel destroyUnmanagedCall:call]; XCTAssertNil(channel.wrappedChannel); } - (void)testCacheChannel { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; GRPCCallOptions *options1 = [[GRPCCallOptions alloc] init]; GRPCCallOptions *options2 = [options1 copy]; GRPCMutableCallOptions *options3 = [options1 mutableCopy]; @@ -80,17 +82,14 @@ NSString *kDummyPath = @"/dummy/path"; XCTAssertNotEqual(channel1.wrappedChannel, channel3.wrappedChannel); XCTAssertNotEqual(channel1.wrappedChannel, channel4.wrappedChannel); XCTAssertNotEqual(channel3.wrappedChannel, channel4.wrappedChannel); - [channel1 unrefUnmanagedCall:call1]; - [channel2 unrefUnmanagedCall:call2]; - [channel3 unrefUnmanagedCall:call3]; - [channel4 unrefUnmanagedCall:call4]; + [channel1 destroyUnmanagedCall:call1]; + [channel2 destroyUnmanagedCall:call2]; + [channel3 destroyUnmanagedCall:call3]; + [channel4 destroyUnmanagedCall:call4]; } - (void)testTimedDestroyChannel { - const NSTimeInterval kDestroyDelay = 1.0; - - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - pool.destroyDelay = kDestroyDelay; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; @@ -99,25 +98,24 @@ NSString *kDummyPath = @"/dummy/path"; [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; GRPCChannel *wrappedChannel = channel.wrappedChannel; - [channel unrefUnmanagedCall:call]; + [channel destroyUnmanagedCall:call]; // Confirm channel is not destroyed at this time call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertEqual(wrappedChannel, channel.wrappedChannel); - [channel unrefUnmanagedCall:call]; + [channel destroyUnmanagedCall:call]; sleep(kDestroyDelay + 1); // Confirm channel is new at this time call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); // Confirm the new channel can create call - call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssert(call != NULL); - [channel unrefUnmanagedCall:call]; + [channel destroyUnmanagedCall:call]; } - (void)testPoolDisconnection { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; @@ -141,12 +139,12 @@ NSString *kDummyPath = @"/dummy/path"; [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); - [channel unrefUnmanagedCall:call]; - [channel unrefUnmanagedCall:call2]; + [channel destroyUnmanagedCall:call]; + [channel destroyUnmanagedCall:call2]; } - (void)testUnrefCallFromStaleChannel { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; @@ -163,12 +161,12 @@ NSString *kDummyPath = @"/dummy/path"; // destroy state XCTAssertNotNil(channel.wrappedChannel); GRPCChannel *wrappedChannel = channel.wrappedChannel; - [channel unrefUnmanagedCall:call]; + [channel destroyUnmanagedCall:call]; XCTAssertNotNil(channel.wrappedChannel); XCTAssertEqual(wrappedChannel, channel.wrappedChannel); // Test unref the call of the current channel will cause the channel going into timed destroy // state - [channel unrefUnmanagedCall:call2]; + [channel destroyUnmanagedCall:call2]; XCTAssertNil(channel.wrappedChannel); } diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index c07c8e69834..55474490926 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -35,7 +35,7 @@ completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions; -- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall; +- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall; @end @@ -66,7 +66,7 @@ return (grpc_call *)(++_grpcCallCounter); } -- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall { +- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall { if (_unrefExpectation) [_unrefExpectation fulfill]; } diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 834bf6d661a..2cfdd1a003b 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -554,13 +554,14 @@ static GRPCProtoMethod *kFullDuplexCallMethod; __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; NSString *const kDummyAddress = [NSString stringWithFormat:@"8.8.8.8:1"]; - GRPCCall *call = [[GRPCCall alloc] initWithHost:kDummyAddress - path:@"/dummyPath" - requestsWriter:[GRXWriter writerWithValue:[NSData data]]]; + [GRPCCall useInsecureConnectionsForHost:kDummyAddress]; [GRPCCall setMinConnectTimeout:timeout * 1000 initialBackoff:backoff * 1000 maxBackoff:0 forHost:kDummyAddress]; + GRPCCall *call = [[GRPCCall alloc] initWithHost:kDummyAddress + path:@"/dummyPath" + requestsWriter:[GRXWriter writerWithValue:[NSData data]]]; NSDate *startTime = [NSDate date]; id responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) { XCTAssert(NO, @"Received message. Should not reach here"); From fdf4b8f2f76cf13f9d41c24775b78727de3c994b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 26 Nov 2018 17:42:56 -0800 Subject: [PATCH 214/534] clang-format --- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- src/objective-c/GRPCClient/private/GRPCChannel.h | 3 ++- src/objective-c/GRPCClient/private/GRPCChannel.m | 8 ++++---- .../GRPCClient/private/GRPCChannelPool.h | 7 ++++--- .../GRPCClient/private/GRPCChannelPool.m | 8 +++++--- src/objective-c/ProtoRPC/ProtoRPC.m | 14 +++++++------- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 48bb11aeeb0..158a4745d23 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -64,7 +64,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)getTokenWithHandler:(void (^ _Nullable)(NSString * _Nullable token))handler; +- (void)getTokenWithHandler:(void (^_Nullable)(NSString *_Nullable token))handler; @end @interface GRPCCallOptions : NSObject diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 147015bed10..c01aeccf81f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -51,7 +51,8 @@ NS_ASSUME_NONNULL_BEGIN /** Acquire the dictionary of channel args with current configurations. */ @property(copy, readonly) NSDictionary *channelArgs; -- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 24cf670d1b5..9432e7ab397 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -226,7 +226,7 @@ if (_unmanagedChannel == NULL) return NULL; NSString *serverAuthority = - callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); if (timeout < 0) return NULL; @@ -236,9 +236,9 @@ } 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_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + 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)); call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, serverAuthority ? &host_slice : NULL, deadline_ms, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 26600ef3a96..7f8ee19fe59 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -41,14 +41,15 @@ NS_ASSUME_NONNULL_BEGIN - (nullable instancetype)init NS_UNAVAILABLE; -+ (nullable instancetype)new NS_UNAVAILABLE; ++ (nullable instancetype) new NS_UNAVAILABLE; /** * Initialize with an actual channel object \a channel and a reference to the channel pool. */ - (nullable instancetype)initWithChannelConfiguration: (GRPCChannelConfiguration *)channelConfiguration - channelPool:(GRPCChannelPool *)channelPool NS_DESIGNATED_INITIALIZER; + channelPool:(GRPCChannelPool *)channelPool + NS_DESIGNATED_INITIALIZER; /** * Create a grpc core call object (grpc_call) from this channel. If channel is disconnected, get a @@ -91,7 +92,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable instancetype)init NS_UNAVAILABLE; -+ (nullable instancetype)new NS_UNAVAILABLE; ++ (nullable instancetype) new NS_UNAVAILABLE; /** * Get the global channel pool. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index f6615b58405..646f1e4b86e 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -74,8 +74,9 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (void)dealloc { - NSAssert([_unmanagedCalls count] == 0 && _wrappedChannel == nil, @"Pooled channel should only be" - "destroyed after the wrapped channel is destroyed"); + NSAssert([_unmanagedCalls count] == 0 && _wrappedChannel == nil, + @"Pooled channel should only be" + "destroyed after the wrapped channel is destroyed"); } - (grpc_call *)unmanagedCallWithPath:(NSString *)path @@ -183,7 +184,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; + (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ - gChannelPool = [[GRPCChannelPool alloc] initInstanceWithDestroyDelay:kDefaultChannelDestroyDelay]; + gChannelPool = + [[GRPCChannelPool alloc] initInstanceWithDestroyDelay:kDefaultChannelDestroyDelay]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index dff88b8591f..1db04894d5e 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -145,12 +145,12 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing self->_handler = nil; } [copiedHandler closedWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; }); } else { _handler = nil; @@ -217,7 +217,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing self->_handler = nil; } [copiedHandler closedWithTrailingMetadata:nil - error:ErrorForBadProto(message, _responseClass, error)]; + error:ErrorForBadProto(message, _responseClass, error)]; }); [_call cancel]; _call = nil; From fd69f74b2091ae66b609ec7592905d9b20dddf88 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 27 Nov 2018 17:48:55 -0800 Subject: [PATCH 215/534] use value64 --- src/objective-c/GRPCClient/private/ChannelArgsUtil.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index 3135fcff028..c1c65c33841 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -78,7 +78,7 @@ grpc_channel_args *GRPCBuildChannelArgs(NSDictionary *dictionary) { int64_t value64 = [value longLongValue]; if (value64 <= INT_MAX || value64 >= INT_MIN) { arg->type = GRPC_ARG_INTEGER; - arg->value.integer = [value intValue]; + arg->value.integer = (int)value64; j++; } } else if (value != nil) { From a7c41346d8470e7eb5f10234daa08d09a48fa779 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 28 Nov 2018 11:22:33 -0800 Subject: [PATCH 216/534] Add one more cancel test --- src/objective-c/tests/InteropTests.m | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index a9f33aab6f1..2492718046f 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -655,6 +655,37 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testCancelAfterFirstRequestWithV2API { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *completionExpectation = + [self expectationWithDescription:@"Call completed."]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = self.class.transportType; + options.PEMRootCertificates = self.class.PEMRootCertificates; + options.hostNameOverride = [[self class] hostNameOverride]; + + id request = + [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTFail(@"Received unexpected response."); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + [completionExpectation fulfill]; + }] + callOptions:options]; + + [call writeMessage:request]; + [call cancel]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testRPCAfterClosingOpenConnections { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = From de0249ecaf362ed04f1351c57a7c7be9be79bdf8 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 29 Nov 2018 16:08:52 -0800 Subject: [PATCH 217/534] Fallback instead of failing for cases where are not able to set the socket options --- src/core/lib/iomgr/tcp_posix.cc | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 606bfce6e73..6f66551a7ee 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -589,7 +589,7 @@ ssize_t tcp_send(int fd, const struct msghdr* msg) { */ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, - ssize_t* sent_length, grpc_error** error); + ssize_t* sent_length); /** The callback function to be invoked when we get an error on the socket. */ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error); @@ -597,13 +597,11 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error); #ifdef GRPC_LINUX_ERRQUEUE static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, - ssize_t* sent_length, - grpc_error** error) { + ssize_t* sent_length) { if (!tcp->socket_ts_enabled) { uint32_t opt = grpc_core::kTimestampingSocketOptions; if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, static_cast(&opt), sizeof(opt)) != 0) { - *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "setsockopt"), tcp); grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_ERROR, "Failed to set timestamping options on the socket."); @@ -781,8 +779,7 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { #else /* GRPC_LINUX_ERRQUEUE */ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, - ssize_t* sent_length, - grpc_error** error) { + ssize_t* sent_length) { gpr_log(GPR_ERROR, "Write with timestamps not supported for this platform"); GPR_ASSERT(0); return false; @@ -801,7 +798,7 @@ void tcp_shutdown_buffer_list(grpc_tcp* tcp) { gpr_mu_lock(&tcp->tb_mu); grpc_core::TracedBuffer::Shutdown( &tcp->tb_head, tcp->outgoing_buffer_arg, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed")); + GRPC_ERROR_CREATE_FROM_STATIC_STRING("TracedBuffer list shutdown")); gpr_mu_unlock(&tcp->tb_mu); tcp->outgoing_buffer_arg = nullptr; } @@ -852,13 +849,17 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { msg.msg_iov = iov; msg.msg_iovlen = iov_size; msg.msg_flags = 0; + bool tried_sending_message = false; if (tcp->outgoing_buffer_arg != nullptr) { - if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length, - error)) { + if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length)) { + /* We could not set socket options to collect Fathom timestamps. + * Fallback on writing without timestamps. */ tcp_shutdown_buffer_list(tcp); - return true; /* something went wrong with timestamps */ + } else { + tried_sending_message = true; } - } else { + } + if (!tried_sending_message) { msg.msg_control = nullptr; msg.msg_controllen = 0; From 95f71d8d7fb25c4ca948b0ac58f00c565c95e27e Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 29 Nov 2018 17:36:00 -0800 Subject: [PATCH 218/534] Cache result of failing to set timestamping options --- src/core/lib/iomgr/tcp_posix.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 6f66551a7ee..90827033bd1 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -126,6 +126,7 @@ struct grpc_tcp { int bytes_counter; bool socket_ts_enabled; /* True if timestamping options are set on the socket */ + bool ts_capable; /* Cache whether we can set timestamping options */ gpr_atm stop_error_notification; /* Set to 1 if we do not want to be notified on errors anymore */ @@ -851,9 +852,11 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { msg.msg_flags = 0; bool tried_sending_message = false; if (tcp->outgoing_buffer_arg != nullptr) { - if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length)) { + if (!tcp->ts_capable || + !tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length)) { /* We could not set socket options to collect Fathom timestamps. * Fallback on writing without timestamps. */ + tcp->ts_capable = false; tcp_shutdown_buffer_list(tcp); } else { tried_sending_message = true; @@ -1115,6 +1118,7 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->is_first_read = true; tcp->bytes_counter = -1; tcp->socket_ts_enabled = false; + tcp->ts_capable = true; tcp->outgoing_buffer_arg = nullptr; /* paired with unref in grpc_tcp_destroy */ gpr_ref_init(&tcp->refcount, 1); From 459da578db5ae9bd95f91be2888236c4870a7314 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 30 Nov 2018 13:43:56 -0800 Subject: [PATCH 219/534] Refactor channel pool --- src/objective-c/GRPCClient/GRPCCall.m | 15 +- .../GRPCClient/private/GRPCChannelPool.h | 35 ++- .../GRPCClient/private/GRPCChannelPool.m | 276 +++++++----------- .../GRPCClient/private/GRPCWrappedCall.h | 13 +- .../GRPCClient/private/GRPCWrappedCall.m | 117 ++++---- .../tests/ChannelTests/ChannelPoolTest.m | 146 ++------- .../tests/ChannelTests/ChannelTests.m | 152 +++++----- .../xcschemes/ChannelTests.xcscheme | 5 - 8 files changed, 306 insertions(+), 453 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index bf9441c27eb..dad8594a264 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -36,6 +36,8 @@ #import "private/NSDictionary+GRPC.h" #import "private/NSError+GRPC.h" #import "private/utilities.h" +#import "private/GRPCChannelPool.h" +#import "private/GRPCCompletionQueue.h" // At most 6 ops can be in an op batch for a client: SEND_INITIAL_METADATA, // SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT, RECV_INITIAL_METADATA, RECV_MESSAGE, @@ -819,8 +821,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - GRPCWrappedCall *wrappedCall = - [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; + GRPCPooledChannel *channel = [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; + GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:_path + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:_callOptions]; + if (wrappedCall == nil) { [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable @@ -837,12 +842,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self sendHeaders]; [self invokeCall]; - - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; - } } - (void)startWithWriteable:(id)writeable { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 7f8ee19fe59..338b6e440f3 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -32,10 +32,13 @@ NS_ASSUME_NONNULL_BEGIN @class GRPCChannelPool; @class GRPCCompletionQueue; @class GRPCChannelConfiguration; +@class GRPCWrappedCall; /** - * Channel proxy that can be retained and automatically reestablish connection when the channel is - * disconnected. + * A proxied channel object that can be retained and creates GRPCWrappedCall object from. If a + * raw channel is not present (i.e. no tcp connection to the server) when a GRPCWrappedCall object + * is requested, it issues a connection/reconnection. The behavior of this object is to mimic that + * of gRPC core's channel object. */ @interface GRPCPooledChannel : NSObject @@ -47,24 +50,21 @@ NS_ASSUME_NONNULL_BEGIN * Initialize with an actual channel object \a channel and a reference to the channel pool. */ - (nullable instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration - channelPool:(GRPCChannelPool *)channelPool - NS_DESIGNATED_INITIALIZER; + (GRPCChannelConfiguration *)channelConfiguration; /** - * Create a grpc core call object (grpc_call) from this channel. If channel is disconnected, get a + * Create a GRPCWrappedCall object (grpc_call) from this channel. If channel is disconnected, get a * new channel object from the channel pool. */ -- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path - completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions; +- (nullable GRPCWrappedCall *)wrappedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions; /** - * Return ownership and destroy the grpc_call object created by - * \a unmanagedCallWithPath:completionQueue:callOptions: and decrease channel refcount. If refcount - * of the channel becomes 0, return the channel object to channel pool. + * Notify the pooled channel that a wrapped call object is no longer referenced and will be + * dealloc'ed. */ -- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall; +- (void)notifyWrappedCallDealloc:(GRPCWrappedCall *)wrappedCall; /** * Force the channel to disconnect immediately. Subsequent calls to unmanagedCallWithPath: will @@ -77,6 +77,13 @@ NS_ASSUME_NONNULL_BEGIN /** Test-only interface for \a GRPCPooledChannel. */ @interface GRPCPooledChannel (Test) +/** + * Initialize a pooled channel with non-default destroy delay for testing purpose. + */ +- (nullable instancetype)initWithChannelConfiguration: +(GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay; + /** * Return the pointer to the raw channel wrapped. */ @@ -118,7 +125,7 @@ NS_ASSUME_NONNULL_BEGIN * Get an instance of pool isolated from the global shared pool with channels' destroy delay being * \a destroyDelay. */ -- (nullable instancetype)initTestPoolWithDestroyDelay:(NSTimeInterval)destroyDelay; +- (nullable instancetype)initTestPool; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 646f1e4b86e..488766c0edc 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -28,6 +28,8 @@ #import "GRPCSecureChannelFactory.h" #import "utilities.h" #import "version.h" +#import "GRPCWrappedCall.h" +#import "GRPCCompletionQueue.h" #import #include @@ -40,103 +42,139 @@ static dispatch_once_t gInitChannelPool; /** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; -@interface GRPCChannelPool () - -- (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; - -- (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; - -@end - @implementation GRPCPooledChannel { - __weak GRPCChannelPool *_channelPool; GRPCChannelConfiguration *_channelConfiguration; - NSMutableSet *_unmanagedCalls; + NSTimeInterval _destroyDelay; + + NSHashTable *_wrappedCalls; GRPCChannel *_wrappedChannel; + NSDate *_lastTimedDestroy; + dispatch_queue_t _timerQueue; } -- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration - channelPool:(GRPCChannelPool *)channelPool { - NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); - NSAssert(channelPool != nil, @"channelPool cannot be empty."); - if (channelPool == nil || channelConfiguration == nil) { - return nil; - } - - if ((self = [super init])) { - _channelPool = channelPool; - _channelConfiguration = channelConfiguration; - _unmanagedCalls = [NSMutableSet set]; - _wrappedChannel = nil; - } - - return self; +- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { + return [self initWithChannelConfiguration:channelConfiguration destroyDelay:kDefaultChannelDestroyDelay]; } - (void)dealloc { - NSAssert([_unmanagedCalls count] == 0 && _wrappedChannel == nil, - @"Pooled channel should only be" - "destroyed after the wrapped channel is destroyed"); + if ([_wrappedCalls objectEnumerator].allObjects.count != 0) { + NSEnumerator *enumerator = [_wrappedCalls objectEnumerator]; + GRPCWrappedCall *wrappedCall; + while ((wrappedCall = [enumerator nextObject])) { + [wrappedCall channelDisconnected]; + }; + } } -- (grpc_call *)unmanagedCallWithPath:(NSString *)path - completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions { +- (GRPCWrappedCall *)wrappedCallWithPath:(NSString *)path +completionQueue:(GRPCCompletionQueue *)queue +callOptions:(GRPCCallOptions *)callOptions { NSAssert(path.length > 0, @"path must not be empty."); NSAssert(queue != nil, @"completionQueue must not be empty."); NSAssert(callOptions, @"callOptions must not be empty."); if (path.length == 0 || queue == nil || callOptions == nil) return NULL; - grpc_call *call = NULL; + GRPCWrappedCall *call = nil; + @synchronized(self) { if (_wrappedChannel == nil) { - __strong GRPCChannelPool *strongPool = _channelPool; - if (strongPool) { - _wrappedChannel = [strongPool refChannelWithConfiguration:_channelConfiguration]; + _wrappedChannel = [[GRPCChannel alloc] initWithChannelConfiguration:_channelConfiguration]; + if (_wrappedChannel == nil) { + NSAssert(_wrappedChannel != nil, @"Unable to get a raw channel for proxy."); + return nil; } - NSAssert(_wrappedChannel != nil, @"Unable to get a raw channel for proxy."); } - call = - [_wrappedChannel unmanagedCallWithPath:path completionQueue:queue callOptions:callOptions]; - if (call != NULL) { - [_unmanagedCalls addObject:[NSValue valueWithPointer:call]]; + _lastTimedDestroy = nil; + + grpc_call *unmanagedCall = [_wrappedChannel unmanagedCallWithPath:path + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:callOptions]; + if (unmanagedCall == NULL) { + NSAssert(unmanagedCall != NULL, @"Unable to create grpc_call object"); + return nil; + } + + call = [[GRPCWrappedCall alloc] initWithUnmanagedCall:unmanagedCall pooledChannel:self]; + if (call == nil) { + NSAssert(call != nil, @"Unable to create GRPCWrappedCall object"); + return nil; } + + [_wrappedCalls addObject:call]; } return call; } -- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall { - if (unmanagedCall == NULL) { +- (void)notifyWrappedCallDealloc:(GRPCWrappedCall *)wrappedCall { + NSAssert(wrappedCall != nil, @"wrappedCall cannot be empty."); + if (wrappedCall == nil) { return; } - - grpc_call_unref(unmanagedCall); @synchronized(self) { - NSValue *removedCall = [NSValue valueWithPointer:unmanagedCall]; - [_unmanagedCalls removeObject:removedCall]; - if ([_unmanagedCalls count] == 0) { - _wrappedChannel = nil; - GRPCChannelPool *strongPool = _channelPool; - [strongPool unrefChannelWithConfiguration:_channelConfiguration]; + if ([_wrappedCalls objectEnumerator].allObjects.count == 0) { + NSDate *now = [NSDate date]; + _lastTimedDestroy = now; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * NSEC_PER_SEC), + _timerQueue, ^{ + @synchronized(self) { + if (self->_lastTimedDestroy == now) { + self->_wrappedChannel = nil; + self->_lastTimedDestroy = nil; + } + } + }); } } } - (void)disconnect { + NSHashTable *copiedWrappedCalls = nil; @synchronized(self) { if (_wrappedChannel != nil) { _wrappedChannel = nil; - [_unmanagedCalls removeAllObjects]; - GRPCChannelPool *strongPool = _channelPool; - [strongPool unrefChannelWithConfiguration:_channelConfiguration]; + copiedWrappedCalls = [_wrappedCalls copy]; + [_wrappedCalls removeAllObjects]; } } + NSEnumerator *enumerator = [copiedWrappedCalls objectEnumerator]; + GRPCWrappedCall *wrappedCall; + while ((wrappedCall = [enumerator nextObject])) { + [wrappedCall channelDisconnected]; + } } @end @implementation GRPCPooledChannel (Test) +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay { + NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); + if (channelConfiguration == nil) { + return nil; + } + + if ((self = [super init])) { + _channelConfiguration = channelConfiguration; + _destroyDelay = destroyDelay; + _wrappedCalls = [[NSHashTable alloc] initWithOptions:NSHashTableWeakMemory capacity:1]; + _wrappedChannel = nil; + _lastTimedDestroy = nil; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { + _timerQueue = dispatch_queue_create(NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + } else { +#else + { +#endif + _timerQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + } + + return self; +} + - (GRPCChannel *)wrappedChannel { GRPCChannel *channel = nil; @synchronized(self) { @@ -147,65 +185,28 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @end -/** - * A convenience value type for cached channel. - */ -@interface GRPCChannelRecord : NSObject - -/** Pointer to the raw channel. May be nil when the channel has been destroyed. */ -@property GRPCChannel *channel; - -/** Channel proxy corresponding to this channel configuration. */ -@property GRPCPooledChannel *pooledChannel; - -/** Last time when a timed destroy is initiated on the channel. */ -@property NSDate *timedDestroyDate; - -/** Reference count of the proxy to the channel. */ -@property NSUInteger refCount; - -@end - -@implementation GRPCChannelRecord - -@end - @interface GRPCChannelPool () -- (instancetype)initInstanceWithDestroyDelay:(NSTimeInterval)destroyDelay NS_DESIGNATED_INITIALIZER; +- (instancetype)initInstance NS_DESIGNATED_INITIALIZER; @end @implementation GRPCChannelPool { - NSMutableDictionary *_channelPool; - dispatch_queue_t _dispatchQueue; - NSTimeInterval _destroyDelay; + NSMutableDictionary *_channelPool; } + (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ gChannelPool = - [[GRPCChannelPool alloc] initInstanceWithDestroyDelay:kDefaultChannelDestroyDelay]; + [[GRPCChannelPool alloc] initInstance]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; } -- (instancetype)initInstanceWithDestroyDelay:(NSTimeInterval)destroyDelay { +- (instancetype)initInstance { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 - if (@available(iOS 8.0, macOS 10.10, *)) { - _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); - } else { -#else - { -#endif - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } - _destroyDelay = destroyDelay; // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); @@ -231,86 +232,23 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; @synchronized(self) { - GRPCChannelRecord *record = _channelPool[configuration]; - if (record == nil) { - record = [[GRPCChannelRecord alloc] init]; - record.pooledChannel = - [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration channelPool:self]; - _channelPool[configuration] = record; - pooledChannel = record.pooledChannel; - } else { - pooledChannel = record.pooledChannel; + pooledChannel = _channelPool[configuration]; + if (pooledChannel == nil) { + pooledChannel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration]; + _channelPool[configuration] = pooledChannel; } } return pooledChannel; } -- (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { - GRPCChannel *ret = nil; - @synchronized(self) { - NSAssert(configuration != nil, @"configuration cannot be empty."); - if (configuration == nil) { - return nil; - } - - GRPCChannelRecord *record = _channelPool[configuration]; - NSAssert(record != nil, @"No record corresponding to a proxy."); - if (record == nil) { - return nil; - } - - record.refCount++; - record.timedDestroyDate = nil; - if (record.channel == nil) { - // Channel is already destroyed; - record.channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration]; - } - ret = record.channel; - } - return ret; -} - -- (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { - @synchronized(self) { - GRPCChannelRecord *record = _channelPool[configuration]; - NSAssert(record != nil, @"No record corresponding to a proxy."); - if (record == nil) { - return; - } - NSAssert(record.refCount > 0, @"Inconsistent channel refcount."); - if (record.refCount > 0) { - record.refCount--; - if (record.refCount == 0) { - NSDate *now = [NSDate date]; - record.timedDestroyDate = now; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_destroyDelay * NSEC_PER_SEC)), - _dispatchQueue, ^{ - @synchronized(self) { - if (now == record.timedDestroyDate) { - // Destroy the raw channel and reset related records. - record.timedDestroyDate = nil; - record.channel = nil; - } - } - }); - } - } - } -} - - (void)disconnectAllChannels { - NSMutableSet *proxySet = [NSMutableSet set]; + NSDictionary *copiedPooledChannels; @synchronized(self) { - [_channelPool - enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, - GRPCChannelRecord *_Nonnull obj, BOOL *_Nonnull stop) { - obj.channel = nil; - obj.timedDestroyDate = nil; - [proxySet addObject:obj.pooledChannel]; - }]; + copiedPooledChannels = [NSDictionary dictionaryWithDictionary:_channelPool]; } - // Disconnect proxies - [proxySet enumerateObjectsUsingBlock:^(GRPCPooledChannel *_Nonnull obj, BOOL *_Nonnull stop) { + + // Disconnect pooled channels. + [copiedPooledChannels enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { [obj disconnect]; }]; } @@ -323,8 +261,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannelPool (Test) -- (instancetype)initTestPoolWithDestroyDelay:(NSTimeInterval)destroyDelay { - return [self initInstanceWithDestroyDelay:destroyDelay]; +- (instancetype)initTestPool { + return [self initInstance]; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h index 19aa5367c77..0432190528f 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h @@ -71,11 +71,16 @@ #pragma mark GRPCWrappedCall +@class GRPCPooledChannel; + @interface GRPCWrappedCall : NSObject -- (instancetype)initWithHost:(NSString *)host - path:(NSString *)path - callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + +- (instancetype)initWithUnmanagedCall:(grpc_call *)unmanagedCall + pooledChannel:(GRPCPooledChannel *)pooledChannel NS_DESIGNATED_INITIALIZER; - (void)startBatchWithOperations:(NSArray *)ops errorHandler:(void (^)(void))errorHandler; @@ -83,4 +88,6 @@ - (void)cancel; +- (void)channelDisconnected; + @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 5788d0a003f..7e2d9d3c6d3 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -237,37 +237,21 @@ #pragma mark GRPCWrappedCall @implementation GRPCWrappedCall { - GRPCCompletionQueue *_queue; - GRPCPooledChannel *_channel; + __weak GRPCPooledChannel *_channel; grpc_call *_call; } -- (instancetype)init { - return [self initWithHost:nil path:nil callOptions:[[GRPCCallOptions alloc] init]]; -} - -- (instancetype)initWithHost:(NSString *)host - path:(NSString *)path - callOptions:(GRPCCallOptions *)callOptions { - NSAssert(host.length != 0 && path.length != 0, @"path and host cannot be nil."); +- (instancetype)initWithUnmanagedCall:(grpc_call *)unmanagedCall + pooledChannel:(GRPCPooledChannel *)pooledChannel { + NSAssert(unmanagedCall != NULL, @"unmanagedCall cannot be empty."); + NSAssert(pooledChannel != nil, @"pooledChannel cannot be empty."); + if (unmanagedCall == NULL || pooledChannel == nil) { + return nil; + } if ((self = [super init])) { - // Each completion queue consumes one thread. There's a trade to be made between creating and - // consuming too many threads and having contention of multiple calls in a single completion - // queue. Currently we use a singleton queue. - _queue = [GRPCCompletionQueue completionQueue]; - _channel = [[GRPCChannelPool sharedInstance] channelWithHost:host callOptions:callOptions]; - if (_channel == nil) { - NSAssert(_channel != nil, @"Failed to get a channel for the host."); - NSLog(@"Failed to get a channel for the host."); - return nil; - } - _call = [_channel unmanagedCallWithPath:path completionQueue:_queue callOptions:callOptions]; - if (_call == nil) { - NSAssert(_channel != nil, @"Failed to get a channel for the host."); - NSLog(@"Failed to create a call."); - return nil; - } + _call = unmanagedCall; + _channel = pooledChannel; } return self; } @@ -283,42 +267,67 @@ [GRPCOpBatchLog addOpBatchToLog:operations]; #endif - size_t nops = operations.count; - grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op)); - size_t i = 0; - 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) { - if (!success) { - if (errorHandler) { - errorHandler(); - } else { - return; - } - } - for (GRPCOperation *operation in operations) { - [operation finish]; - } - }), - NULL); - gpr_free(ops_array); - - if (error != GRPC_CALL_OK) { - [NSException + @synchronized (self) { + if (_call != NULL) { + size_t nops = operations.count; + grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op)); + size_t i = 0; + for (GRPCOperation *operation in operations) { + ops_array[i++] = operation.op; + } + grpc_call_error error; + error = grpc_call_start_batch(_call, ops_array, nops, (__bridge_retained void *)(^(bool success) { + if (!success) { + if (errorHandler) { + errorHandler(); + } else { + return; + } + } + for (GRPCOperation *operation in operations) { + [operation finish]; + } + }), + 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]; + format:@"A precondition for calling grpc_call_start_batch wasn't met. Error %i", error]; + } + } } } - (void)cancel { - grpc_call_cancel(_call, NULL); + @synchronized (self) { + if (_call != NULL) { + grpc_call_cancel(_call, NULL); + } + } +} + +- (void)channelDisconnected { + @synchronized (self) { + if (_call != NULL) { + grpc_call_unref(_call); + _call = NULL; + } + } } - (void)dealloc { - [_channel destroyUnmanagedCall:_call]; - _channel = nil; + @synchronized (self) { + if (_call != NULL) { + grpc_call_unref(_call); + _call = NULL; + } + } + __strong GRPCPooledChannel *channel = _channel; + if (channel != nil) { + [channel notifyWrappedCallDealloc:self]; + } } @end diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index 9461945560a..dc42d7c341d 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -24,11 +24,9 @@ #define TEST_TIMEOUT 32 -NSString *kDummyHost = @"dummy.host"; -NSString *kDummyHost2 = @"dummy.host.2"; -NSString *kDummyPath = @"/dummy/path"; - -const NSTimeInterval kDestroyDelay = 1.0; +static NSString *kDummyHost = @"dummy.host"; +static NSString *kDummyHost2 = @"dummy.host.2"; +static NSString *kDummyPath = @"/dummy/path"; @interface ChannelPoolTest : XCTestCase @@ -40,134 +38,26 @@ const NSTimeInterval kDestroyDelay = 1.0; grpc_init(); } -- (void)testCreateChannelAndCall { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - XCTAssertNil(channel.wrappedChannel); - GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = - [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - XCTAssert(call != NULL); - XCTAssertNotNil(channel.wrappedChannel); - [channel destroyUnmanagedCall:call]; - XCTAssertNil(channel.wrappedChannel); -} - -- (void)testCacheChannel { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; +- (void)testCreateAndCacheChannel { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPool]; GRPCCallOptions *options1 = [[GRPCCallOptions alloc] init]; GRPCCallOptions *options2 = [options1 copy]; GRPCMutableCallOptions *options3 = [options1 mutableCopy]; options3.transportType = GRPCTransportTypeInsecure; - GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - GRPCPooledChannel *channel1 = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options1]; - grpc_call *call1 = - [channel1 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options1]; - GRPCPooledChannel *channel2 = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options2]; - grpc_call *call2 = - [channel2 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options2]; - GRPCPooledChannel *channel3 = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options3]; - grpc_call *call3 = - [channel3 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options3]; - GRPCPooledChannel *channel4 = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost2 callOptions:options1]; - grpc_call *call4 = - [channel4 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options1]; - XCTAssertEqual(channel1.wrappedChannel, channel2.wrappedChannel); - XCTAssertNotEqual(channel1.wrappedChannel, channel3.wrappedChannel); - XCTAssertNotEqual(channel1.wrappedChannel, channel4.wrappedChannel); - XCTAssertNotEqual(channel3.wrappedChannel, channel4.wrappedChannel); - [channel1 destroyUnmanagedCall:call1]; - [channel2 destroyUnmanagedCall:call2]; - [channel3 destroyUnmanagedCall:call3]; - [channel4 destroyUnmanagedCall:call4]; -} - -- (void)testTimedDestroyChannel { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = - [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - GRPCChannel *wrappedChannel = channel.wrappedChannel; - - [channel destroyUnmanagedCall:call]; - // Confirm channel is not destroyed at this time - call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - XCTAssertEqual(wrappedChannel, channel.wrappedChannel); - - [channel destroyUnmanagedCall:call]; - sleep(kDestroyDelay + 1); - // Confirm channel is new at this time - call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); - - // Confirm the new channel can create call - XCTAssert(call != NULL); - [channel destroyUnmanagedCall:call]; -} - -- (void)testPoolDisconnection { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = - [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - XCTAssertNotNil(channel.wrappedChannel); - GRPCChannel *wrappedChannel = channel.wrappedChannel; - - // Test a new channel is created by requesting a channel from pool - [pool disconnectAllChannels]; - channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - XCTAssertNotNil(channel.wrappedChannel); - XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); - wrappedChannel = channel.wrappedChannel; - - // Test a new channel is created by requesting a new call from the previous proxy - [pool disconnectAllChannels]; - grpc_call *call2 = - [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - XCTAssertNotNil(channel.wrappedChannel); - XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); - [channel destroyUnmanagedCall:call]; - [channel destroyUnmanagedCall:call2]; -} - -- (void)testUnrefCallFromStaleChannel { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = - [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - - [pool disconnectAllChannels]; - channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - grpc_call *call2 = - [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - // Test unref the call of a stale channel will not cause the current channel going into timed - // destroy state - XCTAssertNotNil(channel.wrappedChannel); - GRPCChannel *wrappedChannel = channel.wrappedChannel; - [channel destroyUnmanagedCall:call]; - XCTAssertNotNil(channel.wrappedChannel); - XCTAssertEqual(wrappedChannel, channel.wrappedChannel); - // Test unref the call of the current channel will cause the channel going into timed destroy - // state - [channel destroyUnmanagedCall:call2]; - XCTAssertNil(channel.wrappedChannel); + GRPCPooledChannel *channel1 = [pool channelWithHost:kDummyHost callOptions:options1]; + GRPCPooledChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options2]; + GRPCPooledChannel *channel3 = [pool channelWithHost:kDummyHost callOptions:options3]; + GRPCPooledChannel *channel4 = [pool channelWithHost:kDummyHost2 callOptions:options1]; + + XCTAssertNotNil(channel1); + XCTAssertNotNil(channel2); + XCTAssertNotNil(channel3); + XCTAssertNotNil(channel4); + XCTAssertEqual(channel1, channel2); + XCTAssertNotEqual(channel1, channel3); + XCTAssertNotEqual(channel1, channel4); + XCTAssertNotEqual(channel3, channel4); } @end diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 55474490926..ee7f8b6fddb 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -22,91 +22,99 @@ #import "../../GRPCClient/private/GRPCChannel.h" #import "../../GRPCClient/private/GRPCChannelPool.h" #import "../../GRPCClient/private/GRPCCompletionQueue.h" +#import "../../GRPCClient/private/GRPCWrappedCall.h" -/* -#define TEST_TIMEOUT 8 - -@interface GRPCChannelFake : NSObject - -- (instancetype)initWithCreateExpectation:(XCTestExpectation *)createExpectation - unrefExpectation:(XCTestExpectation *)unrefExpectation; +static NSString *kDummyHost = @"dummy.host"; +static NSString *kDummyPath = @"/dummy/path"; -- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path - completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions; - -- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall; +@interface ChannelTests : XCTestCase @end -@implementation GRPCChannelFake { - __weak XCTestExpectation *_createExpectation; - __weak XCTestExpectation *_unrefExpectation; - long _grpcCallCounter; -} - -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration -*)channelConfiguration { return nil; -} - -- (instancetype)initWithCreateExpectation:(XCTestExpectation *)createExpectation - unrefExpectation:(XCTestExpectation *)unrefExpectation { - if ((self = [super init])) { - _createExpectation = createExpectation; - _unrefExpectation = unrefExpectation; - _grpcCallCounter = 0; - } - return self; -} +@implementation ChannelTests -- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path - completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions { - if (_createExpectation) [_createExpectation fulfill]; - return (grpc_call *)(++_grpcCallCounter); ++ (void)setUp { + grpc_init(); } -- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall { - if (_unrefExpectation) [_unrefExpectation fulfill]; +- (void)testPooledChannelCreatingChannel { + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost + callOptions:options]; + GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + (void)wrappedCall; } -@end - -@interface GRPCChannelPoolFake : NSObject - -- (instancetype)initWithDelayedDestroyExpectation:(XCTestExpectation *)delayedDestroyExpectation; - -- (GRPCChannel *)rawChannelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; - -- (void)delayedDestroyChannel; - -@end - -@implementation GRPCChannelPoolFake { - __weak XCTestExpectation *_delayedDestroyExpectation; -} - -- (instancetype)initWithDelayedDestroyExpectation:(XCTestExpectation *)delayedDestroyExpectation { - if ((self = [super init])) { - _delayedDestroyExpectation = delayedDestroyExpectation; +- (void)testTimedDestroyChannel { + const NSTimeInterval kDestroyDelay = 1.0; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost + callOptions:options]; + GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config + destroyDelay:kDestroyDelay]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + GRPCWrappedCall *wrappedCall; + GRPCChannel *wrappedChannel; + @autoreleasepool { + wrappedCall = [channel wrappedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + + // Unref and ref channel immediately; expect using the same raw channel. + wrappedChannel = channel.wrappedChannel; + + wrappedCall = nil; + wrappedCall = [channel wrappedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertEqual(channel.wrappedChannel, wrappedChannel); + + // Unref and ref channel after destroy delay; expect a new raw channel. + wrappedCall = nil; } - return self; -} - -- (void)delayedDestroyChannel { - if (_delayedDestroyExpectation) [_delayedDestroyExpectation fulfill]; + sleep(kDestroyDelay + 1); + XCTAssertNil(channel.wrappedChannel); + wrappedCall = [channel wrappedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); } -@end */ - -@interface ChannelTests : XCTestCase - -@end - -@implementation ChannelTests - -+ (void)setUp { - grpc_init(); +- (void)testDisconnect { + const NSTimeInterval kDestroyDelay = 1.0; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost + callOptions:options]; + GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config + destroyDelay:kDestroyDelay]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + + // Disconnect; expect wrapped channel to be dropped + [channel disconnect]; + XCTAssertNil(channel.wrappedChannel); + + // Create a new call and unref the old call; confirm that destroy of the old call does not make + // the channel disconnect, even after the destroy delay. + GRPCWrappedCall *wrappedCall2 = [channel wrappedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + GRPCChannel *wrappedChannel = channel.wrappedChannel; + wrappedCall = nil; + sleep(kDestroyDelay + 1); + XCTAssertNotNil(channel.wrappedChannel); + XCTAssertEqual(wrappedChannel, channel.wrappedChannel); + (void)wrappedCall2; } @end diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme index 8c8623d7b21..acae965bed0 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme @@ -37,11 +37,6 @@ BlueprintName = "ChannelTests" ReferencedContainer = "container:Tests.xcodeproj"> - - - - From d42c56788c31547f8ed99833e10f77d6af2c1732 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 4 Dec 2018 13:48:01 -0800 Subject: [PATCH 220/534] More debug timers to record root cause --- src/core/lib/gpr/sync_posix.cc | 92 ++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 5 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 69bd6094850..813a03c34bc 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -30,11 +30,16 @@ // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER +#include void (*g_grpc_debug_timer_manager_stats)( int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, int64_t fork_count, int64_t timer_wait_err, int64_t timer_cv_value, int64_t timer_mu_value, int64_t abstime_sec_value, - int64_t abstime_nsec_value) = nullptr; + int64_t abstime_nsec_value, int64_t abs_deadline_sec_value, int64_t abs_deadline_nsec_value, int64_t now1_sec_value, + int64_t now1_nsec_value, int64_t now2_sec_value, + int64_t now2_nsec_value, int64_t add_result_sec_value, + int64_t add_result_nsec_value, int64_t sub_result_sec_value, + int64_t sub_result_nsec_value) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; @@ -43,6 +48,16 @@ int64_t g_timer_cv_value = 0; int64_t g_timer_mu_value = 0; int64_t g_abstime_sec_value = -1; int64_t g_abstime_nsec_value = -1; +int64_t g_abs_deadline_sec_value = -1; +int64_t g_abs_deadline_nsec_value = -1; +int64_t g_now1_sec_value = -1; +int64_t g_now1_nsec_value = -1; +int64_t g_now2_sec_value = -1; +int64_t g_now2_nsec_value = -1; +int64_t g_add_result_sec_value = -1; +int64_t g_add_result_nsec_value = -1; +int64_t g_sub_result_sec_value = -1; +int64_t g_sub_result_nsec_value = -1; #endif // GRPC_DEBUG_TIMER_MANAGER #ifdef GPR_LOW_LEVEL_COUNTERS @@ -90,17 +105,70 @@ void gpr_cv_init(gpr_cv* cv) { void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); } +// For debug of the timer manager crash only. +// TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER +static gpr_timespec gpr_convert_clock_type_debug_timespec(gpr_timespec t, + gpr_clock_type clock_type, + gpr_timespec &now1, + gpr_timespec &now2, + gpr_timespec &add_result, + gpr_timespec &sub_result) { + if (t.clock_type == clock_type) { + return t; + } + + if (t.tv_sec == INT64_MAX || t.tv_sec == INT64_MIN) { + t.clock_type = clock_type; + return t; + } + + if (clock_type == GPR_TIMESPAN) { + return gpr_time_sub(t, gpr_now(t.clock_type)); + } + + if (t.clock_type == GPR_TIMESPAN) { + return gpr_time_add(gpr_now(clock_type), t); + } + + now1 = gpr_now(t.clock_type); + sub_result = gpr_time_sub(t, now1); + now2 = gpr_now(clock_type); + add_result = gpr_time_add(now2, sub_result); + return add_result; +} + +#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, sub_result) gpr_convert_clock_type_debug_timespec((t), (clock_type), (now1), (now2), (add_result), (sub_result)) +#else +#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, sub_result) gpr_convert_clock_type((t), (clock_type)) +#endif + int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { int err = 0; +#ifdef GRPC_DEBUG_TIMER_MANAGER + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. + gpr_timespec abs_deadline_copy; + abs_deadline_copy.tv_sec = abs_deadline.tv_sec; + abs_deadline_copy.tv_nsec = abs_deadline.tv_nsec; + gpr_timespec now1; + gpr_timespec now2; + gpr_timespec add_result; + gpr_timespec sub_result; + memset(&now1, 0, sizeof(now1)); + memset(&now2, 0, sizeof(now2)); + memset(&add_result, 0, sizeof(add_result)); + memset(&sub_result, 0, sizeof(sub_result)); +#endif if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) == 0) { err = pthread_cond_wait(cv, mu); } else { struct timespec abs_deadline_ts; #if GPR_LINUX - abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_MONOTONIC); + abs_deadline = gpr_convert_clock_type_debug(abs_deadline, GPR_CLOCK_MONOTONIC, now1, now2, add_result, sub_result); #else - abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME); + abs_deadline = gpr_convert_clock_type_debug(abs_deadline, GPR_CLOCK_REALTIME, now1, now2, add_result, sub_result); #endif // GPR_LINUX abs_deadline_ts.tv_sec = static_cast(abs_deadline.tv_sec); abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; @@ -123,11 +191,25 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { g_timer_wait_err = err; g_timer_cv_value = (int64_t)cv; g_timer_mu_value = (int64_t)mu; + g_abs_deadline_sec_value = abs_deadline_copy.tv_sec; + g_abs_deadline_nsec_value = abs_deadline_copy.tv_nsec; + g_now1_sec_value = now1.tv_sec; + g_now1_nsec_value = now1.tv_nsec; + g_now2_sec_value = now2.tv_sec; + g_now2_nsec_value = now2.tv_nsec; + g_add_result_sec_value = add_result.tv_sec; + g_add_result_nsec_value = add_result.tv_nsec; + g_sub_result_sec_value = sub_result.tv_sec; + g_sub_result_nsec_value = sub_result.tv_nsec; g_grpc_debug_timer_manager_stats( g_timer_manager_init_count, g_timer_manager_shutdown_count, g_fork_count, g_timer_wait_err, g_timer_cv_value, g_timer_mu_value, - g_abstime_sec_value, g_abstime_nsec_value); - } + g_abstime_sec_value, g_abstime_nsec_value, g_abs_deadline_sec_value, + g_abs_deadline_nsec_value, g_now1_sec_value, g_now1_nsec_value, + g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value, + g_add_result_nsec_value, g_sub_result_sec_value, + g_sub_result_nsec_value); + } } #endif GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); From 5ebbba543c5be26412eb5ba9493ee242eee2e0ac Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 4 Dec 2018 14:20:56 -0800 Subject: [PATCH 221/534] clang-format --- src/core/lib/gpr/sync_posix.cc | 36 +++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 813a03c34bc..4ded03055c8 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -35,11 +35,11 @@ void (*g_grpc_debug_timer_manager_stats)( int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, int64_t fork_count, int64_t timer_wait_err, int64_t timer_cv_value, int64_t timer_mu_value, int64_t abstime_sec_value, - int64_t abstime_nsec_value, int64_t abs_deadline_sec_value, int64_t abs_deadline_nsec_value, int64_t now1_sec_value, - int64_t now1_nsec_value, int64_t now2_sec_value, - int64_t now2_nsec_value, int64_t add_result_sec_value, - int64_t add_result_nsec_value, int64_t sub_result_sec_value, - int64_t sub_result_nsec_value) = nullptr; + int64_t abstime_nsec_value, int64_t abs_deadline_sec_value, + int64_t abs_deadline_nsec_value, int64_t now1_sec_value, + int64_t now1_nsec_value, int64_t now2_sec_value, int64_t now2_nsec_value, + int64_t add_result_sec_value, int64_t add_result_nsec_value, + int64_t sub_result_sec_value, int64_t sub_result_nsec_value) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; @@ -108,12 +108,9 @@ void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); } // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER -static gpr_timespec gpr_convert_clock_type_debug_timespec(gpr_timespec t, - gpr_clock_type clock_type, - gpr_timespec &now1, - gpr_timespec &now2, - gpr_timespec &add_result, - gpr_timespec &sub_result) { +static gpr_timespec gpr_convert_clock_type_debug_timespec( + gpr_timespec t, gpr_clock_type clock_type, gpr_timespec& now1, + gpr_timespec& now2, gpr_timespec& add_result, gpr_timespec& sub_result) { if (t.clock_type == clock_type) { return t; } @@ -138,9 +135,14 @@ static gpr_timespec gpr_convert_clock_type_debug_timespec(gpr_timespec t, return add_result; } -#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, sub_result) gpr_convert_clock_type_debug_timespec((t), (clock_type), (now1), (now2), (add_result), (sub_result)) +#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \ + sub_result) \ + gpr_convert_clock_type_debug_timespec((t), (clock_type), (now1), (now2), \ + (add_result), (sub_result)) #else -#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, sub_result) gpr_convert_clock_type((t), (clock_type)) +#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \ + sub_result) \ + gpr_convert_clock_type((t), (clock_type)) #endif int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { @@ -166,9 +168,11 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { } else { struct timespec abs_deadline_ts; #if GPR_LINUX - abs_deadline = gpr_convert_clock_type_debug(abs_deadline, GPR_CLOCK_MONOTONIC, now1, now2, add_result, sub_result); + abs_deadline = gpr_convert_clock_type_debug( + abs_deadline, GPR_CLOCK_MONOTONIC, now1, now2, add_result, sub_result); #else - abs_deadline = gpr_convert_clock_type_debug(abs_deadline, GPR_CLOCK_REALTIME, now1, now2, add_result, sub_result); + abs_deadline = gpr_convert_clock_type_debug( + abs_deadline, GPR_CLOCK_REALTIME, now1, now2, add_result, sub_result); #endif // GPR_LINUX abs_deadline_ts.tv_sec = static_cast(abs_deadline.tv_sec); abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; @@ -209,7 +213,7 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value, g_add_result_nsec_value, g_sub_result_sec_value, g_sub_result_nsec_value); - } + } } #endif GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); From 750e80ea1c12315ce987ed7b5c38595f698cf355 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Wed, 5 Dec 2018 10:27:01 -0800 Subject: [PATCH 222/534] bring back original network test for metadata server detection --- .../google_default_credentials.cc | 134 +++++++++++++++--- test/core/security/credentials_test.cc | 76 +++++++++- 2 files changed, 188 insertions(+), 22 deletions(-) diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc index fcab2529592..7474380c051 100644 --- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc +++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc @@ -49,9 +49,11 @@ /* -- Default credentials. -- */ -static int g_compute_engine_detection_done = 0; -static int g_need_compute_engine_creds = 0; +static int g_metadata_server_detection_done = 0; +static int g_metadata_server_available = 0; +static int g_is_on_gce = 0; static gpr_mu g_state_mu; +static gpr_mu* g_polling_mu; static gpr_once g_once = GPR_ONCE_INIT; static grpc_core::internal::grpc_gce_tenancy_checker g_gce_tenancy_checker = grpc_alts_is_running_on_gcp; @@ -89,15 +91,20 @@ static grpc_security_status google_default_create_security_connector( bool use_alts = is_grpclb_load_balancer || is_backend_from_grpclb_load_balancer; grpc_security_status status = GRPC_SECURITY_ERROR; + /* Return failure if ALTS is selected but not running on GCE. */ + if (use_alts && !g_is_on_gce) { + goto end; + } status = use_alts ? c->alts_creds->vtable->create_security_connector( c->alts_creds, call_creds, target, args, sc, new_args) : c->ssl_creds->vtable->create_security_connector( c->ssl_creds, call_creds, target, args, sc, new_args); - /* grpclb-specific channel args are removed from the channel args set - * to ensure backends and fallback adresses will have the same set of channel - * args. By doing that, it guarantees the connections to backends will not be - * torn down and re-connected when switching in and out of fallback mode. - */ +/* grpclb-specific channel args are removed from the channel args set + * to ensure backends and fallback adresses will have the same set of channel + * args. By doing that, it guarantees the connections to backends will not be + * torn down and re-connected when switching in and out of fallback mode. + */ +end: if (use_alts) { static const char* args_to_remove[] = { GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER, @@ -113,6 +120,93 @@ static grpc_channel_credentials_vtable google_default_credentials_vtable = { google_default_credentials_destruct, google_default_create_security_connector, nullptr}; +static void on_metadata_server_detection_http_response(void* user_data, + grpc_error* error) { + compute_engine_detector* detector = + static_cast(user_data); + if (error == GRPC_ERROR_NONE && detector->response.status == 200 && + detector->response.hdr_count > 0) { + /* Internet providers can return a generic response to all requests, so + it is necessary to check that metadata header is present also. */ + size_t i; + for (i = 0; i < detector->response.hdr_count; i++) { + grpc_http_header* header = &detector->response.hdrs[i]; + if (strcmp(header->key, "Metadata-Flavor") == 0 && + strcmp(header->value, "Google") == 0) { + detector->success = 1; + break; + } + } + } + gpr_mu_lock(g_polling_mu); + detector->is_done = 1; + GRPC_LOG_IF_ERROR( + "Pollset kick", + grpc_pollset_kick(grpc_polling_entity_pollset(&detector->pollent), + nullptr)); + gpr_mu_unlock(g_polling_mu); +} + +static void destroy_pollset(void* p, grpc_error* e) { + grpc_pollset_destroy(static_cast(p)); +} + +static int is_metadata_server_reachable() { + compute_engine_detector detector; + grpc_httpcli_request request; + grpc_httpcli_context context; + grpc_closure destroy_closure; + /* The http call is local. If it takes more than one sec, it is for sure not + on compute engine. */ + grpc_millis max_detection_delay = GPR_MS_PER_SEC; + grpc_pollset* pollset = + static_cast(gpr_zalloc(grpc_pollset_size())); + grpc_pollset_init(pollset, &g_polling_mu); + detector.pollent = grpc_polling_entity_create_from_pollset(pollset); + detector.is_done = 0; + detector.success = 0; + memset(&detector.response, 0, sizeof(detector.response)); + memset(&request, 0, sizeof(grpc_httpcli_request)); + request.host = (char*)GRPC_COMPUTE_ENGINE_DETECTION_HOST; + request.http.path = (char*)"/"; + grpc_httpcli_context_init(&context); + grpc_resource_quota* resource_quota = + grpc_resource_quota_create("google_default_credentials"); + grpc_httpcli_get( + &context, &detector.pollent, resource_quota, &request, + grpc_core::ExecCtx::Get()->Now() + max_detection_delay, + GRPC_CLOSURE_CREATE(on_metadata_server_detection_http_response, &detector, + grpc_schedule_on_exec_ctx), + &detector.response); + grpc_resource_quota_unref_internal(resource_quota); + grpc_core::ExecCtx::Get()->Flush(); + /* Block until we get the response. This is not ideal but this should only be + called once for the lifetime of the process by the default credentials. */ + gpr_mu_lock(g_polling_mu); + while (!detector.is_done) { + grpc_pollset_worker* worker = nullptr; + if (!GRPC_LOG_IF_ERROR( + "pollset_work", + grpc_pollset_work(grpc_polling_entity_pollset(&detector.pollent), + &worker, GRPC_MILLIS_INF_FUTURE))) { + detector.is_done = 1; + detector.success = 0; + } + } + gpr_mu_unlock(g_polling_mu); + grpc_httpcli_context_destroy(&context); + GRPC_CLOSURE_INIT(&destroy_closure, destroy_pollset, + grpc_polling_entity_pollset(&detector.pollent), + grpc_schedule_on_exec_ctx); + grpc_pollset_shutdown(grpc_polling_entity_pollset(&detector.pollent), + &destroy_closure); + g_polling_mu = nullptr; + grpc_core::ExecCtx::Get()->Flush(); + gpr_free(grpc_polling_entity_pollset(&detector.pollent)); + grpc_http_response_destroy(&detector.response); + return detector.success; +} + /* Takes ownership of creds_path if not NULL. */ static grpc_error* create_default_creds_from_path( char* creds_path, grpc_call_credentials** creds) { @@ -182,7 +276,6 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) { grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Failed to create Google credentials"); grpc_error* err; - int need_compute_engine_creds = 0; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ()); @@ -202,16 +295,25 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) { error = grpc_error_add_child(error, err); gpr_mu_lock(&g_state_mu); - /* At last try to see if we're on compute engine (do the detection only once - since it requires a network test). */ - if (!g_compute_engine_detection_done) { - g_need_compute_engine_creds = g_gce_tenancy_checker(); - g_compute_engine_detection_done = 1; + + /* Try a platform-provided hint for GCE. */ + if (!g_metadata_server_detection_done) { + g_is_on_gce = g_gce_tenancy_checker(); + g_metadata_server_detection_done = g_is_on_gce; + g_metadata_server_available = g_is_on_gce; + } + /* TODO: Add a platform-provided hint for GAE. */ + + /* Do a network test for metadata server. */ + if (!g_metadata_server_detection_done) { + bool detected = is_metadata_server_reachable(); + /* Do not cache detecion result if netowrk test returns false. */ + g_metadata_server_detection_done = detected; + g_metadata_server_available = detected; } - need_compute_engine_creds = g_need_compute_engine_creds; gpr_mu_unlock(&g_state_mu); - if (need_compute_engine_creds) { + if (g_metadata_server_available) { call_creds = grpc_google_compute_engine_credentials_create(nullptr); if (call_creds == nullptr) { error = grpc_error_add_child( @@ -259,7 +361,7 @@ void grpc_flush_cached_google_default_credentials(void) { grpc_core::ExecCtx exec_ctx; gpr_once_init(&g_once, init_default_credentials); gpr_mu_lock(&g_state_mu); - g_compute_engine_detection_done = 0; + g_metadata_server_detection_done = 0; gpr_mu_unlock(&g_state_mu); } diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index b3e3c3c7415..a7a6050ec0a 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -919,6 +919,22 @@ static void test_google_default_creds_refresh_token(void) { gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ } +static int default_creds_metadata_server_detection_httpcli_get_success_override( + const grpc_httpcli_request* request, grpc_millis deadline, + grpc_closure* on_done, grpc_httpcli_response* response) { + *response = http_response(200, ""); + grpc_http_header* headers = + static_cast(gpr_malloc(sizeof(*headers) * 1)); + headers[0].key = gpr_strdup("Metadata-Flavor"); + headers[0].value = gpr_strdup("Google"); + response->hdr_count = 1; + response->hdrs = headers; + GPR_ASSERT(strcmp(request->http.path, "/") == 0); + GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); + GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + return 1; +} + static char* null_well_known_creds_path_getter(void) { return nullptr; } static bool test_gce_tenancy_checker(void) { @@ -963,26 +979,73 @@ static void test_google_default_creds_gce(void) { grpc_override_well_known_credentials_path_getter(nullptr); } -static void test_no_google_default_creds(void) { +static void test_google_default_creds_non_gce(void) { + grpc_core::ExecCtx exec_ctx; + expected_md emd[] = { + {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}}; + request_metadata_state* state = + make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd)); + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, + nullptr, nullptr}; grpc_flush_cached_google_default_credentials(); gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ grpc_override_well_known_credentials_path_getter( null_well_known_creds_path_getter); - set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker); g_test_gce_tenancy_checker_called = false; g_test_is_on_gce = false; + /* Simulate a successful detection of metadata server. */ + grpc_httpcli_set_override( + default_creds_metadata_server_detection_httpcli_get_success_override, + httpcli_post_should_not_be_called); + grpc_composite_channel_credentials* creds = + reinterpret_cast( + grpc_google_default_credentials_create()); + /* Verify that the default creds actually embeds a GCE creds. */ + GPR_ASSERT(creds != nullptr); + GPR_ASSERT(creds->call_creds != nullptr); + grpc_httpcli_set_override(compute_engine_httpcli_get_success_override, + httpcli_post_should_not_be_called); + run_request_metadata_test(creds->call_creds, auth_md_ctx, state); + grpc_core::ExecCtx::Get()->Flush(); + GPR_ASSERT(g_test_gce_tenancy_checker_called == true); + /* Cleanup. */ + grpc_channel_credentials_unref(&creds->base); + grpc_httpcli_set_override(nullptr, nullptr); + grpc_override_well_known_credentials_path_getter(nullptr); +} + +static int default_creds_gce_detection_httpcli_get_failure_override( + const grpc_httpcli_request* request, grpc_millis deadline, + grpc_closure* on_done, grpc_httpcli_response* response) { + /* No magic header. */ + GPR_ASSERT(strcmp(request->http.path, "/") == 0); + GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); + *response = http_response(200, ""); + GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + return 1; +} +static void test_no_google_default_creds(void) { + grpc_flush_cached_google_default_credentials(); + gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ + grpc_override_well_known_credentials_path_getter( + null_well_known_creds_path_getter); + set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker); + g_test_gce_tenancy_checker_called = false; + g_test_is_on_gce = false; + grpc_httpcli_set_override( + default_creds_gce_detection_httpcli_get_failure_override, + httpcli_post_should_not_be_called); /* Simulate a successful detection of GCE. */ GPR_ASSERT(grpc_google_default_credentials_create() == nullptr); - - /* Try a second one. GCE detection should not occur anymore. */ + /* Try a second one. GCE detection should occur again. */ g_test_gce_tenancy_checker_called = false; GPR_ASSERT(grpc_google_default_credentials_create() == nullptr); - GPR_ASSERT(g_test_gce_tenancy_checker_called == false); - + GPR_ASSERT(g_test_gce_tenancy_checker_called == true); /* Cleanup. */ grpc_override_well_known_credentials_path_getter(nullptr); + grpc_httpcli_set_override(nullptr, nullptr); } typedef enum { @@ -1233,6 +1296,7 @@ int main(int argc, char** argv) { test_google_default_creds_auth_key(); test_google_default_creds_refresh_token(); test_google_default_creds_gce(); + test_google_default_creds_non_gce(); test_no_google_default_creds(); test_metadata_plugin_success(); test_metadata_plugin_failure(); From 734be6c7890670ea3c651aecbba74420a6601db3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 5 Dec 2018 18:28:43 -0800 Subject: [PATCH 223/534] Update doc to clarify serial queue requirement --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index e0ef8b1391f..e687a65da7d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -253,7 +253,7 @@ extern id const kGRPCTrailersKey; + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path; /** - * Set the dispatch queue to be used for callbacks. + * Set the dispatch queue to be used for callbacks. Current implementation requires \a queue to be a serial queue. * * This configuration is only effective before the call starts. */ From dfec57a9a9ebfbe92709498074eb184527ef599e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 5 Dec 2018 22:52:12 -0800 Subject: [PATCH 224/534] Channel pool polishments --- .../GRPCClient/private/GRPCChannelPool.h | 5 ++- .../GRPCClient/private/GRPCChannelPool.m | 41 ++++++++++--------- .../GRPCClient/private/GRPCWrappedCall.m | 10 ++--- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 338b6e440f3..7c6f2b3bbfa 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -67,8 +67,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)notifyWrappedCallDealloc:(GRPCWrappedCall *)wrappedCall; /** - * Force the channel to disconnect immediately. Subsequent calls to unmanagedCallWithPath: will - * attempt to reconnect to the remote channel. + * Force the channel to disconnect immediately. GRPCWrappedCall objects previously created with + * \a wrappedCallWithPath are failed if not already finished. Subsequent calls to + * unmanagedCallWithPath: will attempt to reconnect to the remote channel. */ - (void)disconnect; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 488766c0edc..391022efd19 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -57,7 +57,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (void)dealloc { - if ([_wrappedCalls objectEnumerator].allObjects.count != 0) { + // Disconnect GRPCWrappedCall objects created but not yet removed + if (_wrappedCalls.allObjects.count != 0) { NSEnumerator *enumerator = [_wrappedCalls objectEnumerator]; GRPCWrappedCall *wrappedCall; while ((wrappedCall = [enumerator nextObject])) { @@ -111,13 +112,17 @@ callOptions:(GRPCCallOptions *)callOptions { return; } @synchronized(self) { - if ([_wrappedCalls objectEnumerator].allObjects.count == 0) { + // Detect if all objects weakly referenced in _wrappedCalls are (implicitly) removed. In such + // case the channel is no longer referenced by a grpc_call object and can be destroyed after + // a certain delay. + if (_wrappedCalls.allObjects.count == 0) { NSDate *now = [NSDate date]; + NSAssert(now != nil, @"Unable to create NSDate object 'now'."); _lastTimedDestroy = now; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * NSEC_PER_SEC), _timerQueue, ^{ @synchronized(self) { - if (self->_lastTimedDestroy == now) { + if (now != nil && self->_lastTimedDestroy == now) { self->_wrappedChannel = nil; self->_lastTimedDestroy = nil; } @@ -128,17 +133,15 @@ callOptions:(GRPCCallOptions *)callOptions { } - (void)disconnect { - NSHashTable *copiedWrappedCalls = nil; + NSArray *copiedWrappedCalls = nil; @synchronized(self) { if (_wrappedChannel != nil) { _wrappedChannel = nil; - copiedWrappedCalls = [_wrappedCalls copy]; + copiedWrappedCalls = _wrappedCalls.allObjects; [_wrappedCalls removeAllObjects]; } } - NSEnumerator *enumerator = [copiedWrappedCalls objectEnumerator]; - GRPCWrappedCall *wrappedCall; - while ((wrappedCall = [enumerator nextObject])) { + for (GRPCWrappedCall *wrappedCall in copiedWrappedCalls) { [wrappedCall channelDisconnected]; } } @@ -155,9 +158,9 @@ callOptions:(GRPCCallOptions *)callOptions { } if ((self = [super init])) { - _channelConfiguration = channelConfiguration; + _channelConfiguration = [channelConfiguration copy]; _destroyDelay = destroyDelay; - _wrappedCalls = [[NSHashTable alloc] initWithOptions:NSHashTableWeakMemory capacity:1]; + _wrappedCalls = [NSHashTable weakObjectsHashTable]; _wrappedChannel = nil; _lastTimedDestroy = nil; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 @@ -187,7 +190,7 @@ callOptions:(GRPCCallOptions *)callOptions { @interface GRPCChannelPool () -- (instancetype)initInstance NS_DESIGNATED_INITIALIZER; +- (instancetype)initPrivate NS_DESIGNATED_INITIALIZER; @end @@ -198,13 +201,13 @@ callOptions:(GRPCCallOptions *)callOptions { + (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ gChannelPool = - [[GRPCChannelPool alloc] initInstance]; + [[GRPCChannelPool alloc] initPrivate]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; } -- (instancetype)initInstance { +- (instancetype)initPrivate { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; @@ -242,15 +245,15 @@ callOptions:(GRPCCallOptions *)callOptions { } - (void)disconnectAllChannels { - NSDictionary *copiedPooledChannels; + NSArray *copiedPooledChannels; @synchronized(self) { - copiedPooledChannels = [NSDictionary dictionaryWithDictionary:_channelPool]; + copiedPooledChannels = _channelPool.allValues; } // Disconnect pooled channels. - [copiedPooledChannels enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - [obj disconnect]; - }]; + for (GRPCPooledChannel *pooledChannel in copiedPooledChannels) { + [pooledChannel disconnect]; + } } - (void)connectivityChange:(NSNotification *)note { @@ -262,7 +265,7 @@ callOptions:(GRPCCallOptions *)callOptions { @implementation GRPCChannelPool (Test) - (instancetype)initTestPool { - return [self initInstance]; + return [self initPrivate]; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 7e2d9d3c6d3..727c9e0a88e 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -237,7 +237,7 @@ #pragma mark GRPCWrappedCall @implementation GRPCWrappedCall { - __weak GRPCPooledChannel *_channel; + GRPCPooledChannel *_pooledChannel; grpc_call *_call; } @@ -251,7 +251,7 @@ if ((self = [super init])) { _call = unmanagedCall; - _channel = pooledChannel; + _pooledChannel = pooledChannel; } return self; } @@ -324,10 +324,8 @@ _call = NULL; } } - __strong GRPCPooledChannel *channel = _channel; - if (channel != nil) { - [channel notifyWrappedCallDealloc:self]; - } + __strong GRPCPooledChannel *channel = _pooledChannel; + [channel notifyWrappedCallDealloc:self]; } @end From 0a3a99d84e2a12a68568ee45cf4496a2d9ef5bf7 Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Thu, 6 Dec 2018 09:33:53 -0800 Subject: [PATCH 225/534] Bump version to v1.17.1-pre1 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index eeb1a2fa620..fb87e824bec 100644 --- a/BUILD +++ b/BUILD @@ -68,7 +68,7 @@ g_stands_for = "gizmo" core_version = "7.0.0" -version = "1.17.0" +version = "1.17.1-pre1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 62e07f64e42..df1fd85e050 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gizmo - version: 1.17.0 + version: 1.17.1-pre1 filegroups: - name: alts_proto headers: From 9eaebf116d0651b314e186c454b26565347e5ede Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Thu, 6 Dec 2018 09:38:39 -0800 Subject: [PATCH 226/534] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 8 ++++---- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 4 ++-- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 29 files changed, 36 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58525d6c6f1..8c199696a9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.17.0") +set(PACKAGE_VERSION "1.17.1-pre1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 02273df21d1..18f49301d76 100644 --- a/Makefile +++ b/Makefile @@ -438,8 +438,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.17.0 -CSHARP_VERSION = 1.17.0 +CPP_VERSION = 1.17.1-pre1 +CSHARP_VERSION = 1.17.1-pre1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 73c87942430..ba26e3979d6 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.17.0' - version = '0.0.6' + # version = '1.17.1-pre1' + version = '0.0.6-pre1' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.17.0' + grpc_version = '1.17.1-pre1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index ff4d79426fe..4b499208f5c 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.17.0' + version = '1.17.1-pre1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index d7050906e43..5d5bd6c47f5 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.17.0' + version = '1.17.1-pre1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 955f3682f67..9c453f0b192 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.17.0' + version = '1.17.1-pre1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index fb46ab46704..83c7fceef1a 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.17.0' + version = '1.17.1-pre1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index bd2fffcc555..3e3d0c354c3 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.17.0 - 1.17.0 + 1.17.1RC1 + 1.17.1RC1 - stable - stable + beta + beta Apache 2.0 diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 0a3fd804fe5..af717f9934f 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.17.0"; } +grpc::string Version() { return "1.17.1-pre1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 4741e08cf53..1935ab77e4f 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.17.0 + 1.17.1-pre1 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index aa881867ec5..1209c509d03 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.17.0.0"; + public const string CurrentAssemblyFileVersion = "1.17.1.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.17.0"; + public const string CurrentVersion = "1.17.1-pre1"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 1b860c95380..996700b3e1e 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.17.0 +set VERSION=1.17.1-pre1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index b9f9cf4dbb8..2fec12ddf89 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.17.0 +set VERSION=1.17.1-pre1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index c72751d1c6f..65524edad29 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.17.0' + v = '1.17.1-pre1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index fa5b04612ce..02d2c58a7d0 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.17.0" +#define GRPC_OBJC_VERSION_STRING @"1.17.1-pre1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 1cfbf6f705d..8c3e0da603f 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.17.0" +#define GRPC_OBJC_VERSION_STRING @"1.17.1-pre1" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index d54db91b5fb..be72fc059e9 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "Apache-2.0", - "version": "1.17.0", + "version": "1.17.1", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index e529c749dbd..9e79442157f 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.17.0" +#define PHP_GRPC_VERSION "1.17.1RC1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 0677d1b9cf5..63e56efa6b1 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.17.0""" +__version__ = """1.17.1rc1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 8cbd5b24f25..03f7db3b2fe 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.17.0' +VERSION = '1.17.1rc1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 222d77aab18..c0817d51dce 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.17.0' +VERSION = '1.17.1rc1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index daa8a84edb3..445513c6045 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.17.0' +VERSION = '1.17.1rc1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index af9ab31aa13..0c89e08dfbf 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.17.0' +VERSION = '1.17.1rc1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 887f8c105bc..5b861bc0c83 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.17.0' +VERSION = '1.17.1rc1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 6b09d61c0b4..3af5e94a7d0 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.17.0' + VERSION = '1.17.1.pre1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 9ae2162335d..e27237158e0 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.17.0' + VERSION = '1.17.1.pre1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 4070200384b..628315ad26e 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.17.0' +VERSION = '1.17.1rc1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 88bfada6917..c32e6b34519 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.17.0 +PROJECT_NUMBER = 1.17.1-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 31f90cf1b66..d62f540ce84 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.17.0 +PROJECT_NUMBER = 1.17.1-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 6638279564f64e14e033865fc2191c60679b389d Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Thu, 6 Dec 2018 10:01:48 -0800 Subject: [PATCH 227/534] revision 1 --- .../google_default_credentials.cc | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc index 7474380c051..cf6eb83758c 100644 --- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc +++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc @@ -49,11 +49,16 @@ /* -- Default credentials. -- */ -static int g_metadata_server_detection_done = 0; +/* A sticky bit that will be set only if the result of metadata server detection + * is positive. We do not set the bit if the result is negative. Because it + * means the detection is done via network test that is unreliable and the + * unreliable result should not be referred by successive calls. */ static int g_metadata_server_available = 0; static int g_is_on_gce = 0; static gpr_mu g_state_mu; -static gpr_mu* g_polling_mu; +/* Protect a metadata_server_detector instance that can be modified by more than + * one gRPC threads */ +.static gpr_mu* g_polling_mu; static gpr_once g_once = GPR_ONCE_INIT; static grpc_core::internal::grpc_gce_tenancy_checker g_gce_tenancy_checker = grpc_alts_is_running_on_gcp; @@ -65,7 +70,7 @@ typedef struct { int is_done; int success; grpc_http_response response; -} compute_engine_detector; +} metadata_server_detector; static void google_default_credentials_destruct( grpc_channel_credentials* creds) { @@ -93,7 +98,7 @@ static grpc_security_status google_default_create_security_connector( grpc_security_status status = GRPC_SECURITY_ERROR; /* Return failure if ALTS is selected but not running on GCE. */ if (use_alts && !g_is_on_gce) { - goto end; + gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE.") goto end; } status = use_alts ? c->alts_creds->vtable->create_security_connector( c->alts_creds, call_creds, target, args, sc, new_args) @@ -122,8 +127,8 @@ static grpc_channel_credentials_vtable google_default_credentials_vtable = { static void on_metadata_server_detection_http_response(void* user_data, grpc_error* error) { - compute_engine_detector* detector = - static_cast(user_data); + metadata_server_detector* detector = + static_cast(user_data); if (error == GRPC_ERROR_NONE && detector->response.status == 200 && detector->response.hdr_count > 0) { /* Internet providers can return a generic response to all requests, so @@ -152,7 +157,7 @@ static void destroy_pollset(void* p, grpc_error* e) { } static int is_metadata_server_reachable() { - compute_engine_detector detector; + metadata_server_detector detector; grpc_httpcli_request request; grpc_httpcli_context context; grpc_closure destroy_closure; @@ -297,19 +302,15 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) { gpr_mu_lock(&g_state_mu); /* Try a platform-provided hint for GCE. */ - if (!g_metadata_server_detection_done) { + if (!g_metadata_server_available) { g_is_on_gce = g_gce_tenancy_checker(); - g_metadata_server_detection_done = g_is_on_gce; g_metadata_server_available = g_is_on_gce; } /* TODO: Add a platform-provided hint for GAE. */ /* Do a network test for metadata server. */ - if (!g_metadata_server_detection_done) { - bool detected = is_metadata_server_reachable(); - /* Do not cache detecion result if netowrk test returns false. */ - g_metadata_server_detection_done = detected; - g_metadata_server_available = detected; + if (!g_metadata_server_available) { + g_metadata_server_available = is_metadata_server_reachable(); } gpr_mu_unlock(&g_state_mu); @@ -361,7 +362,7 @@ void grpc_flush_cached_google_default_credentials(void) { grpc_core::ExecCtx exec_ctx; gpr_once_init(&g_once, init_default_credentials); gpr_mu_lock(&g_state_mu); - g_metadata_server_detection_done = 0; + g_metadata_server_available = 0; gpr_mu_unlock(&g_state_mu); } From c449da58339d4618ca1af447607033fab81de101 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Thu, 6 Dec 2018 10:09:54 -0800 Subject: [PATCH 228/534] fix a compilation error --- .../credentials/google_default/google_default_credentials.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc index cf6eb83758c..0674540d01c 100644 --- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc +++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc @@ -58,7 +58,7 @@ static int g_is_on_gce = 0; static gpr_mu g_state_mu; /* Protect a metadata_server_detector instance that can be modified by more than * one gRPC threads */ -.static gpr_mu* g_polling_mu; +static gpr_mu* g_polling_mu; static gpr_once g_once = GPR_ONCE_INIT; static grpc_core::internal::grpc_gce_tenancy_checker g_gce_tenancy_checker = grpc_alts_is_running_on_gcp; @@ -98,7 +98,8 @@ static grpc_security_status google_default_create_security_connector( grpc_security_status status = GRPC_SECURITY_ERROR; /* Return failure if ALTS is selected but not running on GCE. */ if (use_alts && !g_is_on_gce) { - gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE.") goto end; + gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE."); + goto end; } status = use_alts ? c->alts_creds->vtable->create_security_connector( c->alts_creds, call_creds, target, args, sc, new_args) From 70f34521deaeaf0d783f30d121fd26787135ac04 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 12:08:43 -0800 Subject: [PATCH 229/534] isolate start: function from proto calls --- src/objective-c/ProtoRPC/ProtoRPC.h | 10 ++++++ src/objective-c/ProtoRPC/ProtoRPC.m | 19 ++++++---- src/objective-c/tests/InteropTests.m | 53 ++++++++++++++++++++++++---- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 2623aecb82f..949f52d1b53 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -76,6 +76,11 @@ NS_ASSUME_NONNULL_BEGIN callOptions:(nullable GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; +/** + * Start the call. This function must only be called once for each instance. + */ +- (void)start; + /** * Cancel the request of this call at best effort. It attempts to notify the server that the RPC * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code @@ -101,6 +106,11 @@ NS_ASSUME_NONNULL_BEGIN callOptions:(nullable GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; +/** + * Start the call. This function must only be called once for each instance. + */ +- (void)start; + /** * Cancel the request of this call at best effort. It attempts to notify the server that the RPC * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 1db04894d5e..09f8d03af6f 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -47,6 +47,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @implementation GRPCUnaryProtoCall { GRPCStreamingProtoCall *_call; + GPBMessage *_message; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -54,17 +55,24 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { + NSAssert(message != nil, @"message cannot be empty."); + NSAssert(responseClass != nil, @"responseClass cannot be empty."); if ((self = [super init])) { _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions responseHandler:handler callOptions:callOptions responseClass:responseClass]; - [_call writeMessage:message]; - [_call finish]; + _message = [message copy]; } return self; } +- (void)start { + [_call start]; + [_call writeMessage:_message]; + [_call finish]; +} + - (void)cancel { [_call cancel]; _call = nil; @@ -120,15 +128,14 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } dispatch_set_target_queue(_dispatchQueue, handler.dispatchQueue); - [self start]; + _call = [[GRPCCall2 alloc] initWithRequestOptions:_requestOptions + responseHandler:self + callOptions:_callOptions]; } return self; } - (void)start { - _call = [[GRPCCall2 alloc] initWithRequestOptions:_requestOptions - responseHandler:self - callOptions:_callOptions]; [_call start]; } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 2492718046f..e94fd1493a0 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -197,7 +197,7 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testEmptyUnaryRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnary"]; + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnaryWithV2API"]; GPBEmpty *request = [GPBEmpty message]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; @@ -205,7 +205,7 @@ BOOL isRemoteInteropTest(NSString *host) { options.PEMRootCertificates = [[self class] PEMRootCertificates]; options.hostNameOverride = [[self class] hostNameOverride]; - [_service + GRPCUnaryProtoCall *call = [_service emptyCallWithMessage:request responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id message) { @@ -219,6 +219,7 @@ BOOL isRemoteInteropTest(NSString *host) { XCTAssertNil(error, @"Unexpected error: %@", error); }] callOptions:options]; + [call start]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } @@ -246,6 +247,44 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testLargeUnaryRPCWithV2API { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectRecvMessage = [self expectationWithDescription:@"LargeUnaryWithV2API received message"]; + __weak XCTestExpectation *expectRecvComplete = [self expectationWithDescription:@"LargeUnaryWithV2API received complete"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = 314159; + request.payload.body = [NSMutableData dataWithLength:271828]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + + GRPCUnaryProtoCall *call = [_service + unaryCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertNotNil(message); + if (message) { + RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(message, expectedResponse); + + [expectRecvMessage fulfill]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + [expectRecvComplete fulfill]; + }] + callOptions:options]; + [call start]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testPacketCoalescing { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; @@ -473,7 +512,7 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testPingPongRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"]; + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"]; NSArray *requests = @[ @27182, @8, @1828, @45904 ]; NSArray *responses = @[ @31415, @9, @2653, @58979 ]; @@ -517,6 +556,7 @@ BOOL isRemoteInteropTest(NSString *host) { [expectation fulfill]; }] callOptions:options]; + [call start]; [call writeMessage:request]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; @@ -562,7 +602,7 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testCancelAfterBeginRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBegin"]; + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBeginWithV2API"]; // A buffered pipe to which we never write any value acts as a writer that just hangs. __block GRPCStreamingProtoCall *call = [_service @@ -577,6 +617,7 @@ BOOL isRemoteInteropTest(NSString *host) { [expectation fulfill]; }] callOptions:nil]; + [call start]; [call cancel]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; @@ -650,7 +691,7 @@ BOOL isRemoteInteropTest(NSString *host) { [completionExpectation fulfill]; }] callOptions:options]; - + [call start]; [call writeMessage:request]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } @@ -680,7 +721,7 @@ BOOL isRemoteInteropTest(NSString *host) { [completionExpectation fulfill]; }] callOptions:options]; - + [call start]; [call writeMessage:request]; [call cancel]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; From 76f1ec16e1880605215beb60a204b0cab7c36b2d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 12:42:27 -0800 Subject: [PATCH 230/534] sensible nullability annotation for old API --- src/objective-c/GRPCClient/GRPCCall.h | 22 ++++++++++--------- src/objective-c/GRPCClient/GRPCCall.m | 7 +++--- src/objective-c/ProtoRPC/ProtoRPC.h | 10 ++++----- .../examples/SwiftSample/ViewController.swift | 10 ++++----- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 214969af230..51a82263bff 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -282,6 +282,8 @@ NS_ASSUME_NONNULL_END */ @interface GRPCCall : GRXWriter +- (instancetype)init NS_UNAVAILABLE; + /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of * NSMutableDictionary's interface. It will become a NSMutableDictionary later on. @@ -306,7 +308,7 @@ NS_ASSUME_NONNULL_END * * The property is initialized to an empty NSMutableDictionary. */ -@property(nullable, atomic, readonly) NSMutableDictionary *requestHeaders; +@property(nonnull, atomic, readonly) NSMutableDictionary *requestHeaders; /** * This dictionary is populated with the HTTP headers received from the server. This happens before @@ -339,9 +341,9 @@ NS_ASSUME_NONNULL_END * host parameter should not contain the scheme (http:// or https://), only the name or IP addr * and the port number, for example @"localhost:5050". */ -- (nullable instancetype)initWithHost:(nullable NSString *)host - path:(nullable NSString *)path - requestsWriter:(nullable GRXWriter *)requestWriter; +- (nullable instancetype)initWithHost:(nonnull NSString *)host + path:(nonnull NSString *)path + requestsWriter:(nonnull GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -353,11 +355,11 @@ NS_ASSUME_NONNULL_END * The following methods are deprecated. */ + (void)setCallSafety:(GRPCCallSafety)callSafety - host:(nullable NSString *)host - path:(nullable NSString *)path; + host:(nonnull NSString *)host + path:(nonnull NSString *)path; @property(nullable, atomic, copy, readwrite) NSString *serverName; @property NSTimeInterval timeout; -- (void)setResponseDispatchQueue:(nullable dispatch_queue_t)queue; +- (void)setResponseDispatchQueue:(nonnull dispatch_queue_t)queue; @end @@ -368,11 +370,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (nullable id)objectForKeyedSubscript:(nullable id)key; -- (void)setObject:(nullable id)obj forKeyedSubscript:(nullable id)key; +- (nullable id)objectForKeyedSubscript:(nonnull id)key; +- (void)setObject:(nullable id)obj forKeyedSubscript:(nonnull id)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(nullable id)key; +- (void)removeObjectForKey:(nonnull id)key; @end #pragma clang diagnostic push diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index dad8594a264..9b3bcd385e7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -445,6 +445,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; } + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path { + if (host.length == 0 || path.length == 0) { + return; + } NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; switch (callSafety) { case GRPCCallSafetyDefault: @@ -466,10 +469,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; return [callFlags[hostAndPath] intValue]; } -- (instancetype)init { - return [self initWithHost:nil path:nil requestsWriter:nil]; -} - // Designated initializer - (instancetype)initWithHost:(NSString *)host path:(NSString *)path diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 949f52d1b53..1819fa93796 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -142,11 +142,11 @@ __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC * addr and the port number, for example @"localhost:5050". */ - - (nullable instancetype)initWithHost : (nullable NSString *)host method - : (nullable GRPCProtoMethod *)method requestsWriter - : (nullable GRXWriter *)requestsWriter responseClass - : (nullable Class)responseClass responsesWriteable - : (nullable id)responsesWriteable NS_DESIGNATED_INITIALIZER; + (nullable instancetype)initWithHost : (nonnull NSString *)host method + : (nonnull GRPCProtoMethod *)method requestsWriter + : (nonnull GRXWriter *)requestsWriter responseClass + : (nonnull Class)responseClass responsesWriteable + : (nonnull id)responsesWriteable NS_DESIGNATED_INITIALIZER; - (void)start; @end diff --git a/src/objective-c/examples/SwiftSample/ViewController.swift b/src/objective-c/examples/SwiftSample/ViewController.swift index 0ba6e21f02a..4ed10266a4d 100644 --- a/src/objective-c/examples/SwiftSample/ViewController.swift +++ b/src/objective-c/examples/SwiftSample/ViewController.swift @@ -54,8 +54,8 @@ class ViewController: UIViewController { } else { NSLog("2. Finished with error: \(error!)") } - NSLog("2. Response headers: \(RPC.responseHeaders)") - NSLog("2. Response trailers: \(RPC.responseTrailers)") + NSLog("2. Response headers: \(String(describing: RPC.responseHeaders))") + NSLog("2. Response trailers: \(String(describing: RPC.responseTrailers))") } // TODO(jcanizales): Revert to using subscript syntax once XCode 8 is released. @@ -68,7 +68,7 @@ class ViewController: UIViewController { let method = GRPCProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall")! - let requestsWriter = GRXWriter(value: request.data()) + let requestsWriter = GRXWriter(value: request.data())! let call = GRPCCall(host: RemoteHost, path: method.httpPath, requestsWriter: requestsWriter)! @@ -80,8 +80,8 @@ class ViewController: UIViewController { } else { NSLog("3. Finished with error: \(error!)") } - NSLog("3. Response headers: \(call.responseHeaders)") - NSLog("3. Response trailers: \(call.responseTrailers)") + NSLog("3. Response headers: \(String(describing: call.responseHeaders))") + NSLog("3. Response trailers: \(String(describing: call.responseTrailers))") }) } } From eeced98fc556c6a5bc3a5dedc171c98747217078 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 13:08:34 -0800 Subject: [PATCH 231/534] Rename handlers to didXxx --- src/objective-c/GRPCClient/GRPCCall.h | 8 +++---- src/objective-c/GRPCClient/GRPCCall.m | 16 ++++++------- src/objective-c/ProtoRPC/ProtoRPC.h | 12 +++++----- src/objective-c/ProtoRPC/ProtoRPC.m | 24 +++++++++---------- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 6 ++--- src/objective-c/tests/InteropTests.m | 6 ++--- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 51a82263bff..985743433cf 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -158,13 +158,13 @@ extern NSString *const kGRPCTrailersKey; /** * Issued when initial metadata is received from the server. */ -- (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; +- (void)didReceiveInitialMetadata:(nullable NSDictionary *)initialMetadata; /** * Issued when a message is received from the server. The message is the raw data received from the * server, with decompression and without proto deserialization. */ -- (void)receivedRawMessage:(nullable NSData *)message; +- (void)didReceiveRawMessage:(nullable NSData *)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -172,7 +172,7 @@ extern NSString *const kGRPCTrailersKey; * is non-nil and contains the corresponding error information, including gRPC error codes and * error descriptions. */ -- (void)closedWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata +- (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; @required @@ -247,7 +247,7 @@ extern NSString *const kGRPCTrailersKey; /** * Cancel the request of this call at best effort. It attempts to notify the server that the RPC - * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code + * should be cancelled, and issue didCloseWithTrailingMetadata:error: callback with error code * CANCELED if no other error code has already been issued. */ - (void)cancel; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9b3bcd385e7..48253677bd3 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -250,7 +250,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _call = nil; _pipe = nil; - if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ // Copy to local so that block is freed after cancellation completes. id copiedHandler = nil; @@ -259,7 +259,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; self->_handler = nil; } - [copiedHandler closedWithTrailingMetadata:nil + [copiedHandler didCloseWithTrailingMetadata:nil error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ @@ -321,13 +321,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { @synchronized(self) { if (initialMetadata != nil && - [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + [_handler respondsToSelector:@selector(didReceiveInitialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; } - [copiedHandler receivedInitialMetadata:initialMetadata]; + [copiedHandler didReceiveInitialMetadata:initialMetadata]; }); } } @@ -335,13 +335,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)issueMessage:(id)message { @synchronized(self) { - if (message != nil && [_handler respondsToSelector:@selector(receivedRawMessage:)]) { + if (message != nil && [_handler respondsToSelector:@selector(didReceiveRawMessage:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; } - [copiedHandler receivedRawMessage:message]; + [copiedHandler didReceiveRawMessage:message]; }); } } @@ -349,7 +349,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { @synchronized(self) { - if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { @@ -357,7 +357,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; } - [copiedHandler closedWithTrailingMetadata:trailingMetadata error:error]; + [copiedHandler didCloseWithTrailingMetadata:trailingMetadata error:error]; }); } else { _handler = nil; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 1819fa93796..287aa0369b1 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -33,12 +33,12 @@ NS_ASSUME_NONNULL_BEGIN /** * Issued when initial metadata is received from the server. */ -- (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; +- (void)didReceiveInitialMetadata:(nullable NSDictionary *)initialMetadata; /** * Issued when a message is received from the server. The message is the deserialized proto object. */ -- (void)receivedProtoMessage:(nullable GPBMessage *)message; +- (void)didReceiveProtoMessage:(nullable GPBMessage *)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -46,8 +46,8 @@ NS_ASSUME_NONNULL_BEGIN * is non-nil and contains the corresponding error information, including gRPC error codes and * error descriptions. */ -- (void)closedWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata - error:(nullable NSError *)error; +- (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata + error:(nullable NSError *)error; @required @@ -83,7 +83,7 @@ NS_ASSUME_NONNULL_BEGIN /** * Cancel the request of this call at best effort. It attempts to notify the server that the RPC - * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code + * should be cancelled, and issue didCloseWithTrailingMetadata:error: callback with error code * CANCELED if no other error code has already been issued. */ - (void)cancel; @@ -113,7 +113,7 @@ NS_ASSUME_NONNULL_BEGIN /** * Cancel the request of this call at best effort. It attempts to notify the server that the RPC - * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code + * should be cancelled, and issue didCloseWithTrailingMetadata:error: callback with error code * CANCELED if no other error code has already been issued. */ - (void)cancel; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 09f8d03af6f..886e31ce58a 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -144,14 +144,14 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @synchronized(self) { copiedCall = _call; _call = nil; - if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { dispatch_async(_handler.dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; self->_handler = nil; } - [copiedHandler closedWithTrailingMetadata:nil + [copiedHandler didCloseWithTrailingMetadata:nil error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ @@ -187,7 +187,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing [call finish]; } -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { @synchronized(self) { if (initialMetadata != nil && [_handler respondsToSelector:@selector(initialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ @@ -195,35 +195,35 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @synchronized(self) { copiedHandler = self->_handler; } - [copiedHandler receivedInitialMetadata:initialMetadata]; + [copiedHandler didReceiveInitialMetadata:initialMetadata]; }); } } } -- (void)receivedRawMessage:(NSData *)message { +- (void)didReceiveRawMessage:(NSData *)message { if (message == nil) return; NSError *error = nil; GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; @synchronized(self) { - if (parsed && [_handler respondsToSelector:@selector(receivedProtoMessage:)]) { + if (parsed && [_handler respondsToSelector:@selector(didReceiveProtoMessage:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; } - [copiedHandler receivedProtoMessage:parsed]; + [copiedHandler didReceiveProtoMessage:parsed]; }); } else if (!parsed && - [_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + [_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; self->_handler = nil; } - [copiedHandler closedWithTrailingMetadata:nil + [copiedHandler didCloseWithTrailingMetadata:nil error:ErrorForBadProto(message, _responseClass, error)]; }); [_call cancel]; @@ -232,16 +232,16 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { @synchronized(self) { - if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; self->_handler = nil; } - [copiedHandler closedWithTrailingMetadata:trailingMetadata error:error]; + [copiedHandler didCloseWithTrailingMetadata:trailingMetadata error:error]; }); } _call = nil; diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index 32f2122f79b..ca7bf472830 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -81,19 +81,19 @@ static const NSTimeInterval kTestTimeout = 16; return self; } -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { if (self->_initialMetadataCallback) { self->_initialMetadataCallback(initialMetadata); } } -- (void)receivedRawMessage:(GPBMessage *)message { +- (void)didReceiveRawMessage:(GPBMessage *)message { if (self->_messageCallback) { self->_messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { if (self->_closeCallback) { self->_closeCallback(trailingMetadata, error); } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index e94fd1493a0..d17a07f929a 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -102,19 +102,19 @@ BOOL isRemoteInteropTest(NSString *host) { return self; } -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); } } -- (void)receivedProtoMessage:(GPBMessage *)message { +- (void)didReceiveProtoMessage:(GPBMessage *)message { if (_messageCallback) { _messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { if (_closeCallback) { _closeCallback(trailingMetadata, error); } From e00ca0371a332e8d35a7394556883e1693fa8a2f Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 6 Dec 2018 13:40:12 -0800 Subject: [PATCH 232/534] Promote gpr_test_util to part of grpc_test_util, add a sample to show it works, build.yaml change first --- CMakeLists.txt | 375 +--- Makefile | 1895 ++++++++--------- build.yaml | 288 +-- gRPC-Core.podspec | 6 +- grpc.gyp | 21 +- src/core/lib/surface/init.cc | 4 + src/core/lib/surface/init.h | 1 + test/core/bad_client/gen_build_yaml.py | 2 - test/core/bad_ssl/gen_build_yaml.py | 3 - test/core/end2end/gen_build_yaml.py | 2 - test/core/util/test_config.cc | 3 +- test/cpp/naming/gen_build_yaml.py | 4 - .../generated/sources_and_headers.json | 370 +--- 13 files changed, 1074 insertions(+), 1900 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1194d0072e3..c3058de14e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -930,49 +930,6 @@ if (gRPC_INSTALL) ) endif() -if (gRPC_BUILD_TESTS) - -add_library(gpr_test_util - test/core/util/test_config.cc -) - -if(WIN32 AND MSVC) - set_target_properties(gpr_test_util PROPERTIES COMPILE_PDB_NAME "gpr_test_util" - COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" - ) - if (gRPC_INSTALL) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gpr_test_util.pdb - DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL - ) - endif() -endif() - - -target_include_directories(gpr_test_util - PUBLIC $ $ - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${_gRPC_SSL_INCLUDE_DIR} - PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} - PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} - PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} - PRIVATE ${_gRPC_CARES_INCLUDE_DIR} - PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} - PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} -) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(gpr_test_util PROPERTIES LINKER_LANGUAGE C) - # only use the flags for C++ source files - target_compile_options(gpr_test_util PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() -target_link_libraries(gpr_test_util - ${_gRPC_ALLTARGETS_LIBRARIES} - gpr -) - - -endif (gRPC_BUILD_TESTS) add_library(grpc src/core/lib/surface/init.cc @@ -1797,6 +1754,7 @@ add_library(grpc_test_util test/core/util/slice_splitter.cc test/core/util/subprocess_posix.cc test/core/util/subprocess_windows.cc + test/core/util/test_config.cc test/core/util/tracer_util.cc test/core/util/trickle_endpoint.cc test/core/util/cmdline.cc @@ -2041,7 +1999,6 @@ target_include_directories(grpc_test_util endif() target_link_libraries(grpc_test_util ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr grpc ) @@ -2117,6 +2074,7 @@ add_library(grpc_test_util_unsecure test/core/util/slice_splitter.cc test/core/util/subprocess_posix.cc test/core/util/subprocess_windows.cc + test/core/util/test_config.cc test/core/util/tracer_util.cc test/core/util/trickle_endpoint.cc test/core/util/cmdline.cc @@ -2362,7 +2320,6 @@ target_include_directories(grpc_test_util_unsecure target_link_libraries(grpc_test_util_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} gpr - gpr_test_util grpc_unsecure ) @@ -2802,7 +2759,6 @@ target_link_libraries(reconnect_server test_tcp_server grpc_test_util grpc - gpr_test_util gpr ) @@ -2848,7 +2804,6 @@ target_link_libraries(test_tcp_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5140,7 +5095,6 @@ target_link_libraries(interop_client_main grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ) @@ -5260,7 +5214,6 @@ target_link_libraries(interop_server_lib grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ) @@ -5514,7 +5467,6 @@ target_link_libraries(bad_client_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -5560,7 +5512,6 @@ target_link_libraries(bad_ssl_test_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5686,7 +5637,6 @@ target_link_libraries(end2end_tests ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5810,7 +5760,6 @@ target_link_libraries(end2end_nosec_tests ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -5841,7 +5790,6 @@ target_link_libraries(algorithm_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5874,8 +5822,9 @@ target_include_directories(alloc_test target_link_libraries(alloc_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -5909,7 +5858,6 @@ target_link_libraries(alpn_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5942,8 +5890,9 @@ target_include_directories(arena_test target_link_libraries(arena_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -5975,8 +5924,8 @@ target_include_directories(avl_test target_link_libraries(avl_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util grpc ) @@ -6012,7 +5961,6 @@ target_link_libraries(bad_server_response_test test_tcp_server grpc_test_util grpc - gpr_test_util gpr ) @@ -6114,7 +6062,6 @@ target_link_libraries(buffer_list_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6150,7 +6097,6 @@ target_link_libraries(channel_create_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6216,7 +6162,6 @@ target_link_libraries(chttp2_hpack_encoder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6251,7 +6196,6 @@ target_link_libraries(chttp2_stream_map_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6286,7 +6230,6 @@ target_link_libraries(chttp2_varint_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6320,8 +6263,8 @@ target_include_directories(cmdline_test target_link_libraries(cmdline_test ${_gRPC_ALLTARGETS_LIBRARIES} gpr - gpr_test_util grpc_test_util + grpc ) # avoid dependency on libstdc++ @@ -6355,7 +6298,6 @@ target_link_libraries(combiner_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6390,7 +6332,6 @@ target_link_libraries(compression_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6425,7 +6366,6 @@ target_link_libraries(concurrent_connectivity_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6460,7 +6400,6 @@ target_link_libraries(connection_refused_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6495,7 +6434,6 @@ target_link_libraries(dns_resolver_connectivity_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6530,7 +6468,6 @@ target_link_libraries(dns_resolver_cooldown_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6565,7 +6502,6 @@ target_link_libraries(dns_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6601,7 +6537,6 @@ target_link_libraries(dualstack_socket_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6637,7 +6572,6 @@ target_link_libraries(endpoint_pair_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6672,7 +6606,6 @@ target_link_libraries(error_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6708,7 +6641,6 @@ target_link_libraries(ev_epollex_linux_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6744,7 +6676,6 @@ target_link_libraries(fake_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6779,8 +6710,8 @@ target_include_directories(fake_transport_security_test target_link_libraries(fake_transport_security_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util grpc ) @@ -6817,7 +6748,6 @@ target_link_libraries(fd_conservation_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6854,7 +6784,6 @@ target_link_libraries(fd_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6890,7 +6819,6 @@ target_link_libraries(fling_client ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6925,7 +6853,6 @@ target_link_libraries(fling_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6961,7 +6888,6 @@ target_link_libraries(fling_stream_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6998,7 +6924,6 @@ target_link_libraries(fling_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7033,8 +6958,9 @@ target_include_directories(fork_test target_link_libraries(fork_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7070,7 +6996,6 @@ target_link_libraries(goaway_server_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7104,8 +7029,9 @@ target_include_directories(gpr_cpu_test target_link_libraries(gpr_cpu_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7137,8 +7063,9 @@ target_include_directories(gpr_env_test target_link_libraries(gpr_env_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7170,8 +7097,9 @@ target_include_directories(gpr_host_port_test target_link_libraries(gpr_host_port_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7203,8 +7131,9 @@ target_include_directories(gpr_log_test target_link_libraries(gpr_log_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7236,8 +7165,9 @@ target_include_directories(gpr_manual_constructor_test target_link_libraries(gpr_manual_constructor_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7269,8 +7199,9 @@ target_include_directories(gpr_mpscq_test target_link_libraries(gpr_mpscq_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7302,8 +7233,9 @@ target_include_directories(gpr_spinlock_test target_link_libraries(gpr_spinlock_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7335,8 +7267,9 @@ target_include_directories(gpr_string_test target_link_libraries(gpr_string_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7368,8 +7301,9 @@ target_include_directories(gpr_sync_test target_link_libraries(gpr_sync_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7401,8 +7335,9 @@ target_include_directories(gpr_thd_test target_link_libraries(gpr_thd_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7434,8 +7369,9 @@ target_include_directories(gpr_time_test target_link_libraries(gpr_time_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7467,8 +7403,9 @@ target_include_directories(gpr_tls_test target_link_libraries(gpr_tls_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7500,8 +7437,9 @@ target_include_directories(gpr_useful_test target_link_libraries(gpr_useful_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7535,7 +7473,6 @@ target_link_libraries(grpc_auth_context_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7570,7 +7507,6 @@ target_link_libraries(grpc_b64_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7605,7 +7541,6 @@ target_link_libraries(grpc_byte_buffer_reader_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7640,7 +7575,6 @@ target_link_libraries(grpc_channel_args_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7675,7 +7609,6 @@ target_link_libraries(grpc_channel_stack_builder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7710,7 +7643,6 @@ target_link_libraries(grpc_channel_stack_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7745,7 +7677,6 @@ target_link_libraries(grpc_completion_queue_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7780,7 +7711,6 @@ target_link_libraries(grpc_completion_queue_threading_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7848,7 +7778,6 @@ target_link_libraries(grpc_credentials_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7883,7 +7812,6 @@ target_link_libraries(grpc_fetch_oauth2 ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7918,7 +7846,6 @@ target_link_libraries(grpc_ipv6_loopback_available_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7954,7 +7881,6 @@ target_link_libraries(grpc_json_token_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7990,7 +7916,6 @@ target_link_libraries(grpc_jwt_verifier_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8057,7 +7982,6 @@ target_link_libraries(grpc_security_connector_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8092,7 +8016,6 @@ target_link_libraries(grpc_ssl_credentials_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8161,7 +8084,6 @@ target_link_libraries(handshake_client_ssl ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8200,7 +8122,6 @@ target_link_libraries(handshake_server_ssl ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8239,7 +8160,6 @@ target_link_libraries(handshake_server_with_readahead_handshaker ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8277,7 +8197,6 @@ target_link_libraries(handshake_verify_peer_options ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8346,7 +8265,6 @@ target_link_libraries(hpack_parser_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8381,7 +8299,6 @@ target_link_libraries(hpack_table_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8416,7 +8333,6 @@ target_link_libraries(http_parser_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8451,7 +8367,6 @@ target_link_libraries(httpcli_format_request_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8487,7 +8402,6 @@ target_link_libraries(httpcli_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8524,7 +8438,6 @@ target_link_libraries(httpscli_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8560,7 +8473,6 @@ target_link_libraries(init_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8595,7 +8507,6 @@ target_link_libraries(inproc_callback_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8630,7 +8541,6 @@ target_link_libraries(invalid_call_argument_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8665,7 +8575,6 @@ target_link_libraries(json_rewrite ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8700,7 +8609,6 @@ target_link_libraries(json_rewrite_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8735,7 +8643,6 @@ target_link_libraries(json_stream_error_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8770,7 +8677,6 @@ target_link_libraries(json_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8805,7 +8711,6 @@ target_link_libraries(lame_client_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8840,7 +8745,6 @@ target_link_libraries(load_file_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8875,7 +8779,6 @@ target_link_libraries(memory_usage_client ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8910,7 +8813,6 @@ target_link_libraries(memory_usage_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8946,7 +8848,6 @@ target_link_libraries(memory_usage_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8982,7 +8883,6 @@ target_link_libraries(message_compress_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9017,7 +8917,6 @@ target_link_libraries(minimal_stack_is_minimal_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9052,7 +8951,6 @@ target_link_libraries(multiple_server_queues_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9085,8 +8983,9 @@ target_include_directories(murmur_hash_test target_link_libraries(murmur_hash_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -9120,7 +9019,6 @@ target_link_libraries(no_server_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9155,7 +9053,6 @@ target_link_libraries(num_external_connectivity_watchers_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9190,7 +9087,6 @@ target_link_libraries(parse_address_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9225,7 +9121,6 @@ target_link_libraries(percent_encoding_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9261,7 +9156,6 @@ target_link_libraries(resolve_address_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9297,7 +9191,6 @@ target_link_libraries(resolve_address_using_ares_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9332,7 +9225,6 @@ target_link_libraries(resolve_address_using_native_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9367,7 +9259,6 @@ target_link_libraries(resource_quota_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9402,7 +9293,6 @@ target_link_libraries(secure_channel_create_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9437,7 +9327,6 @@ target_link_libraries(secure_endpoint_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9472,7 +9361,6 @@ target_link_libraries(sequential_connectivity_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9507,7 +9395,6 @@ target_link_libraries(server_chttp2_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9542,7 +9429,6 @@ target_link_libraries(server_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9577,7 +9463,6 @@ target_link_libraries(slice_buffer_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9612,7 +9497,6 @@ target_link_libraries(slice_string_helpers_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9647,7 +9531,6 @@ target_link_libraries(slice_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9682,7 +9565,6 @@ target_link_libraries(sockaddr_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9717,7 +9599,6 @@ target_link_libraries(sockaddr_utils_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9753,7 +9634,6 @@ target_link_libraries(socket_utils_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9789,8 +9669,8 @@ target_include_directories(ssl_transport_security_test target_link_libraries(ssl_transport_security_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util grpc ) @@ -9826,7 +9706,6 @@ target_link_libraries(status_conversion_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9861,7 +9740,6 @@ target_link_libraries(stream_compression_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9896,7 +9774,6 @@ target_link_libraries(stream_owned_slice_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9932,7 +9809,6 @@ target_link_libraries(tcp_client_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9968,7 +9844,6 @@ target_link_libraries(tcp_client_uv_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10004,7 +9879,6 @@ target_link_libraries(tcp_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10041,7 +9915,6 @@ target_link_libraries(tcp_server_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10077,7 +9950,6 @@ target_link_libraries(tcp_server_uv_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10112,7 +9984,6 @@ target_link_libraries(time_averaged_stats_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10147,7 +10018,6 @@ target_link_libraries(timeout_encoding_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10182,7 +10052,6 @@ target_link_libraries(timer_heap_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10217,7 +10086,6 @@ target_link_libraries(timer_list_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10252,7 +10120,6 @@ target_link_libraries(transport_connectivity_state_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10287,7 +10154,6 @@ target_link_libraries(transport_metadata_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10323,7 +10189,6 @@ target_link_libraries(transport_security_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10360,7 +10225,6 @@ target_link_libraries(udp_server_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10396,7 +10260,6 @@ target_link_libraries(uri_parser_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10432,7 +10295,6 @@ target_link_libraries(wakeup_fd_cv_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10478,7 +10340,6 @@ target_link_libraries(alarm_test grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -10554,8 +10415,8 @@ target_link_libraries(alts_crypt_test ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} alts_test_util - gpr_test_util gpr + grpc_test_util grpc ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11014,7 +10875,6 @@ target_link_libraries(async_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11055,7 +10915,6 @@ target_link_libraries(auth_property_iterator_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11094,7 +10953,6 @@ target_link_libraries(backoff_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11135,7 +10993,6 @@ target_link_libraries(bdp_estimator_test grpc++ grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11179,7 +11036,6 @@ target_link_libraries(bm_arena grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11225,7 +11081,6 @@ target_link_libraries(bm_call_create grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11271,7 +11126,6 @@ target_link_libraries(bm_channel grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11317,7 +11171,6 @@ target_link_libraries(bm_chttp2_hpack grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11363,7 +11216,6 @@ target_link_libraries(bm_chttp2_transport grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11409,7 +11261,6 @@ target_link_libraries(bm_closure grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11455,7 +11306,6 @@ target_link_libraries(bm_cq grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11501,7 +11351,6 @@ target_link_libraries(bm_cq_multiple_threads grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11547,7 +11396,6 @@ target_link_libraries(bm_error grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11593,7 +11441,6 @@ target_link_libraries(bm_fullstack_streaming_ping_pong grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11639,7 +11486,6 @@ target_link_libraries(bm_fullstack_streaming_pump grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11685,7 +11531,6 @@ target_link_libraries(bm_fullstack_trickle grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11731,7 +11576,6 @@ target_link_libraries(bm_fullstack_unary_ping_pong grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11777,7 +11621,6 @@ target_link_libraries(bm_metadata grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11823,7 +11666,6 @@ target_link_libraries(bm_pollset grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11864,7 +11706,6 @@ target_link_libraries(byte_stream_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11988,7 +11829,6 @@ target_link_libraries(channel_trace_test grpc++_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12029,7 +11869,6 @@ target_link_libraries(channelz_registry_test grpc++_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12078,7 +11917,6 @@ target_link_libraries(channelz_service_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12126,7 +11964,6 @@ target_link_libraries(channelz_test grpc++_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12239,7 +12076,6 @@ target_link_libraries(chttp2_settings_timeout_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12281,7 +12117,6 @@ target_link_libraries(cli_call_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12322,7 +12157,6 @@ target_link_libraries(client_callback_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12370,7 +12204,6 @@ target_link_libraries(client_channel_stress_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12412,7 +12245,6 @@ target_link_libraries(client_crash_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12454,7 +12286,6 @@ target_link_libraries(client_crash_test_server grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12496,7 +12327,6 @@ target_link_libraries(client_interceptors_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12537,7 +12367,6 @@ target_link_libraries(client_lb_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12752,7 +12581,6 @@ target_link_libraries(context_list_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12830,7 +12658,6 @@ target_link_libraries(cxx_byte_buffer_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12870,7 +12697,6 @@ target_link_libraries(cxx_slice_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12947,7 +12773,6 @@ target_link_libraries(cxx_time_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12989,7 +12814,6 @@ target_link_libraries(end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13074,7 +12898,6 @@ target_link_libraries(exception_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13115,7 +12938,6 @@ target_link_libraries(filter_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13156,7 +12978,6 @@ target_link_libraries(generic_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13396,7 +13217,6 @@ target_link_libraries(grpc_linux_system_roots_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13649,7 +13469,6 @@ target_link_libraries(grpc_tool_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13743,7 +13562,6 @@ target_link_libraries(grpclb_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13783,7 +13601,6 @@ target_link_libraries(h2_ssl_cert_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13823,7 +13640,6 @@ target_link_libraries(h2_ssl_session_reuse_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13864,7 +13680,6 @@ target_link_libraries(health_service_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13947,7 +13762,6 @@ target_link_libraries(hybrid_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13987,7 +13801,6 @@ target_link_libraries(inlined_vector_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14031,7 +13844,6 @@ target_link_libraries(inproc_sync_unary_ping_pong_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14076,7 +13888,6 @@ target_link_libraries(interop_client grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14122,7 +13933,6 @@ target_link_libraries(interop_server grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14164,7 +13974,6 @@ target_link_libraries(interop_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14208,7 +14017,6 @@ target_link_libraries(json_run_localhost grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14250,7 +14058,6 @@ target_link_libraries(memory_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14337,7 +14144,6 @@ target_link_libraries(mock_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14378,7 +14184,6 @@ target_link_libraries(nonblocking_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14454,7 +14259,6 @@ target_link_libraries(orphanable_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14497,7 +14301,6 @@ target_link_libraries(proto_server_reflection_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14577,7 +14380,6 @@ target_link_libraries(qps_interarrival_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14622,7 +14424,6 @@ target_link_libraries(qps_json_driver grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14667,7 +14468,6 @@ target_link_libraries(qps_openloop_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14712,7 +14512,6 @@ target_link_libraries(qps_worker grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14754,7 +14553,6 @@ target_link_libraries(raw_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14816,7 +14614,6 @@ target_link_libraries(reconnect_interop_client grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14881,7 +14678,6 @@ target_link_libraries(reconnect_interop_server grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14922,7 +14718,6 @@ target_link_libraries(ref_counted_ptr_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14962,7 +14757,6 @@ target_link_libraries(ref_counted_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15001,7 +14795,6 @@ target_link_libraries(retry_throttle_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15042,7 +14835,6 @@ target_link_libraries(secure_auth_context_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15086,7 +14878,6 @@ target_link_libraries(secure_sync_unary_ping_pong_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -15129,7 +14920,6 @@ target_link_libraries(server_builder_plugin_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15182,7 +14972,6 @@ target_link_libraries(server_builder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -15238,7 +15027,6 @@ target_link_libraries(server_builder_with_socket_mutator_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -15281,7 +15069,6 @@ target_link_libraries(server_context_test_spouse_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15323,7 +15110,6 @@ target_link_libraries(server_crash_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15365,7 +15151,6 @@ target_link_libraries(server_crash_test_client grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15406,7 +15191,6 @@ target_link_libraries(server_early_return_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15448,7 +15232,6 @@ target_link_libraries(server_interceptors_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15501,7 +15284,6 @@ target_link_libraries(server_request_call_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -15544,7 +15326,6 @@ target_link_libraries(shutdown_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15583,7 +15364,6 @@ target_link_libraries(slice_hash_table_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15622,7 +15402,6 @@ target_link_libraries(slice_weak_hash_table_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15662,7 +15441,6 @@ target_link_libraries(stats_test grpc++_test_util grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15776,7 +15554,6 @@ target_link_libraries(streaming_throughput_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15849,7 +15626,6 @@ target_link_libraries(stress_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -15930,7 +15706,6 @@ target_link_libraries(thread_stress_test grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15971,7 +15746,6 @@ target_link_libraries(transport_pid_controller_test grpc++ grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -16051,7 +15825,6 @@ target_link_libraries(writes_per_rpc_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -16187,7 +15960,6 @@ target_link_libraries(badreq_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16224,7 +15996,6 @@ target_link_libraries(connection_prefix_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16261,7 +16032,6 @@ target_link_libraries(duplicate_header_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16298,7 +16068,6 @@ target_link_libraries(head_of_line_blocking_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16335,7 +16104,6 @@ target_link_libraries(headers_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16372,7 +16140,6 @@ target_link_libraries(initial_settings_frame_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16409,7 +16176,6 @@ target_link_libraries(large_metadata_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16446,7 +16212,6 @@ target_link_libraries(server_registered_method_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16483,7 +16248,6 @@ target_link_libraries(simple_request_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16520,7 +16284,6 @@ target_link_libraries(unknown_frame_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16557,7 +16320,6 @@ target_link_libraries(window_overflow_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16594,7 +16356,6 @@ target_link_libraries(bad_ssl_cert_server bad_ssl_test_server grpc_test_util grpc - gpr_test_util gpr ) @@ -16631,7 +16392,6 @@ target_link_libraries(bad_ssl_cert_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -16668,7 +16428,6 @@ target_link_libraries(h2_census_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16704,7 +16463,6 @@ target_link_libraries(h2_compress_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16740,7 +16498,6 @@ target_link_libraries(h2_fakesec_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16777,7 +16534,6 @@ target_link_libraries(h2_fd_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16814,7 +16570,6 @@ target_link_libraries(h2_full_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16851,7 +16606,6 @@ target_link_libraries(h2_full+pipe_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16888,7 +16642,6 @@ target_link_libraries(h2_full+trace_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16924,7 +16677,6 @@ target_link_libraries(h2_full+workarounds_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16960,7 +16712,6 @@ target_link_libraries(h2_http_proxy_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16997,7 +16748,6 @@ target_link_libraries(h2_local_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17034,7 +16784,6 @@ target_link_libraries(h2_oauth2_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17070,7 +16819,6 @@ target_link_libraries(h2_proxy_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17106,7 +16854,6 @@ target_link_libraries(h2_sockpair_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17142,7 +16889,6 @@ target_link_libraries(h2_sockpair+trace_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17178,7 +16924,6 @@ target_link_libraries(h2_sockpair_1byte_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17214,7 +16959,6 @@ target_link_libraries(h2_ssl_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17250,7 +16994,6 @@ target_link_libraries(h2_ssl_proxy_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17287,7 +17030,6 @@ target_link_libraries(h2_uds_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17324,7 +17066,6 @@ target_link_libraries(inproc_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17360,7 +17101,6 @@ target_link_libraries(h2_census_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17396,7 +17136,6 @@ target_link_libraries(h2_compress_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17433,7 +17172,6 @@ target_link_libraries(h2_fd_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17470,7 +17208,6 @@ target_link_libraries(h2_full_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17507,7 +17244,6 @@ target_link_libraries(h2_full+pipe_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17544,7 +17280,6 @@ target_link_libraries(h2_full+trace_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17580,7 +17315,6 @@ target_link_libraries(h2_full+workarounds_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17616,7 +17350,6 @@ target_link_libraries(h2_http_proxy_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17652,7 +17385,6 @@ target_link_libraries(h2_proxy_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17688,7 +17420,6 @@ target_link_libraries(h2_sockpair_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17724,7 +17455,6 @@ target_link_libraries(h2_sockpair+trace_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17760,7 +17490,6 @@ target_link_libraries(h2_sockpair_1byte_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17797,7 +17526,6 @@ target_link_libraries(h2_uds_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17841,7 +17569,6 @@ target_link_libraries(resolver_component_test_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -17883,7 +17610,6 @@ target_link_libraries(resolver_component_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -17926,7 +17652,6 @@ target_link_libraries(resolver_component_tests_runner_invoker_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -17970,7 +17695,6 @@ target_link_libraries(resolver_component_tests_runner_invoker ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -18013,7 +17737,6 @@ target_link_libraries(address_sorting_test_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -18055,7 +17778,6 @@ target_link_libraries(address_sorting_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -18097,7 +17819,6 @@ target_link_libraries(cancel_ares_query_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -18132,7 +17853,6 @@ target_link_libraries(alts_credentials_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18168,7 +17888,6 @@ target_link_libraries(api_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18204,7 +17923,6 @@ target_link_libraries(client_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18240,7 +17958,6 @@ target_link_libraries(hpack_parser_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18276,7 +17993,6 @@ target_link_libraries(http_request_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18312,7 +18028,6 @@ target_link_libraries(http_response_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18348,7 +18063,6 @@ target_link_libraries(json_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18384,7 +18098,6 @@ target_link_libraries(nanopb_fuzzer_response_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18420,7 +18133,6 @@ target_link_libraries(nanopb_fuzzer_serverlist_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18456,7 +18168,6 @@ target_link_libraries(percent_decode_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18492,7 +18203,6 @@ target_link_libraries(percent_encode_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18528,7 +18238,6 @@ target_link_libraries(server_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18564,7 +18273,6 @@ target_link_libraries(ssl_server_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18600,7 +18308,6 @@ target_link_libraries(uri_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) diff --git a/Makefile b/Makefile index 7dfce79c922..d0b09e79289 100644 --- a/Makefile +++ b/Makefile @@ -1411,7 +1411,7 @@ plugins: $(PROTOC_PLUGINS) privatelibs: privatelibs_c privatelibs_cxx -privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a +privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc @@ -3444,31 +3444,6 @@ ifneq ($(NO_DEPS),true) endif -LIBGPR_TEST_UTIL_SRC = \ - test/core/util/test_config.cc \ - -PUBLIC_HEADERS_C += \ - -LIBGPR_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_TEST_UTIL_SRC)))) - - -$(LIBDIR)/$(CONFIG)/libgpr_test_util.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(LIBGPR_TEST_UTIL_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr_test_util.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBGPR_TEST_UTIL_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgpr_test_util.a -endif - - - - -ifneq ($(NO_DEPS),true) --include $(LIBGPR_TEST_UTIL_OBJS:.o=.dep) -endif - - LIBGRPC_SRC = \ src/core/lib/surface/init.cc \ src/core/lib/avl/avl.cc \ @@ -4279,6 +4254,7 @@ LIBGRPC_TEST_UTIL_SRC = \ test/core/util/slice_splitter.cc \ test/core/util/subprocess_posix.cc \ test/core/util/subprocess_windows.cc \ + test/core/util/test_config.cc \ test/core/util/tracer_util.cc \ test/core/util/trickle_endpoint.cc \ test/core/util/cmdline.cc \ @@ -4585,6 +4561,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ test/core/util/slice_splitter.cc \ test/core/util/subprocess_posix.cc \ test/core/util/subprocess_windows.cc \ + test/core/util/test_config.cc \ test/core/util/tracer_util.cc \ test/core/util/trickle_endpoint.cc \ test/core/util/cmdline.cc \ @@ -10545,14 +10522,14 @@ else -$(BINDIR)/$(CONFIG)/algorithm_test: $(ALGORITHM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/algorithm_test: $(ALGORITHM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ALGORITHM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/algorithm_test + $(Q) $(LD) $(LDFLAGS) $(ALGORITHM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/algorithm_test endif -$(OBJDIR)/$(CONFIG)/test/core/compression/algorithm_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/compression/algorithm_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_algorithm_test: $(ALGORITHM_TEST_OBJS:.o=.dep) @@ -10577,14 +10554,14 @@ else -$(BINDIR)/$(CONFIG)/alloc_test: $(ALLOC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/alloc_test: $(ALLOC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ALLOC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alloc_test + $(Q) $(LD) $(LDFLAGS) $(ALLOC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alloc_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/alloc_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/alloc_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_alloc_test: $(ALLOC_TEST_OBJS:.o=.dep) @@ -10609,14 +10586,14 @@ else -$(BINDIR)/$(CONFIG)/alpn_test: $(ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/alpn_test: $(ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alpn_test + $(Q) $(LD) $(LDFLAGS) $(ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alpn_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/alpn_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/alpn_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_alpn_test: $(ALPN_TEST_OBJS:.o=.dep) @@ -10641,14 +10618,14 @@ else -$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer: $(ALTS_CREDENTIALS_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer: $(ALTS_CREDENTIALS_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CREDENTIALS_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CREDENTIALS_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/security/alts_credentials_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/alts_credentials_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_alts_credentials_fuzzer: $(ALTS_CREDENTIALS_FUZZER_OBJS:.o=.dep) @@ -10673,14 +10650,14 @@ else -$(BINDIR)/$(CONFIG)/api_fuzzer: $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/api_fuzzer: $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/api_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/api_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/api_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/api_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_api_fuzzer: $(API_FUZZER_OBJS:.o=.dep) @@ -10705,14 +10682,14 @@ else -$(BINDIR)/$(CONFIG)/arena_test: $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/arena_test: $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/arena_test + $(Q) $(LD) $(LDFLAGS) $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/arena_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/arena_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/arena_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_arena_test: $(ARENA_TEST_OBJS:.o=.dep) @@ -10737,14 +10714,14 @@ else -$(BINDIR)/$(CONFIG)/avl_test: $(AVL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/avl_test: $(AVL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(AVL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/avl_test + $(Q) $(LD) $(LDFLAGS) $(AVL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/avl_test endif -$(OBJDIR)/$(CONFIG)/test/core/avl/avl_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/avl/avl_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_avl_test: $(AVL_TEST_OBJS:.o=.dep) @@ -10769,14 +10746,14 @@ else -$(BINDIR)/$(CONFIG)/bad_server_response_test: $(BAD_SERVER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bad_server_response_test: $(BAD_SERVER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(BAD_SERVER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_server_response_test + $(Q) $(LD) $(LDFLAGS) $(BAD_SERVER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_server_response_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/bad_server_response_test.o: $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/bad_server_response_test.o: $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bad_server_response_test: $(BAD_SERVER_RESPONSE_TEST_OBJS:.o=.dep) @@ -10865,14 +10842,14 @@ else -$(BINDIR)/$(CONFIG)/buffer_list_test: $(BUFFER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/buffer_list_test: $(BUFFER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(BUFFER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/buffer_list_test + $(Q) $(LD) $(LDFLAGS) $(BUFFER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/buffer_list_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/buffer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/buffer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_buffer_list_test: $(BUFFER_LIST_TEST_OBJS:.o=.dep) @@ -10897,14 +10874,14 @@ else -$(BINDIR)/$(CONFIG)/channel_create_test: $(CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channel_create_test: $(CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/channel_create_test + $(Q) $(LD) $(LDFLAGS) $(CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/channel_create_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/channel_create_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/channel_create_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_channel_create_test: $(CHANNEL_CREATE_TEST_OBJS:.o=.dep) @@ -10961,14 +10938,14 @@ else -$(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test: $(CHTTP2_HPACK_ENCODER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test: $(CHTTP2_HPACK_ENCODER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CHTTP2_HPACK_ENCODER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test + $(Q) $(LD) $(LDFLAGS) $(CHTTP2_HPACK_ENCODER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_encoder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_encoder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_chttp2_hpack_encoder_test: $(CHTTP2_HPACK_ENCODER_TEST_OBJS:.o=.dep) @@ -10993,14 +10970,14 @@ else -$(BINDIR)/$(CONFIG)/chttp2_stream_map_test: $(CHTTP2_STREAM_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/chttp2_stream_map_test: $(CHTTP2_STREAM_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CHTTP2_STREAM_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_stream_map_test + $(Q) $(LD) $(LDFLAGS) $(CHTTP2_STREAM_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_stream_map_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/stream_map_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/stream_map_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_chttp2_stream_map_test: $(CHTTP2_STREAM_MAP_TEST_OBJS:.o=.dep) @@ -11025,14 +11002,14 @@ else -$(BINDIR)/$(CONFIG)/chttp2_varint_test: $(CHTTP2_VARINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/chttp2_varint_test: $(CHTTP2_VARINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CHTTP2_VARINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_varint_test + $(Q) $(LD) $(LDFLAGS) $(CHTTP2_VARINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_varint_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/varint_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/varint_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_chttp2_varint_test: $(CHTTP2_VARINT_TEST_OBJS:.o=.dep) @@ -11057,14 +11034,14 @@ else -$(BINDIR)/$(CONFIG)/client_fuzzer: $(CLIENT_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_fuzzer: $(CLIENT_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/client_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/client_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/client_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/client_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_fuzzer: $(CLIENT_FUZZER_OBJS:.o=.dep) @@ -11089,14 +11066,14 @@ else -$(BINDIR)/$(CONFIG)/cmdline_test: $(CMDLINE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a +$(BINDIR)/$(CONFIG)/cmdline_test: $(CMDLINE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CMDLINE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/cmdline_test + $(Q) $(LD) $(LDFLAGS) $(CMDLINE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/cmdline_test endif -$(OBJDIR)/$(CONFIG)/test/core/util/cmdline_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a +$(OBJDIR)/$(CONFIG)/test/core/util/cmdline_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_cmdline_test: $(CMDLINE_TEST_OBJS:.o=.dep) @@ -11121,14 +11098,14 @@ else -$(BINDIR)/$(CONFIG)/combiner_test: $(COMBINER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/combiner_test: $(COMBINER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(COMBINER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/combiner_test + $(Q) $(LD) $(LDFLAGS) $(COMBINER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/combiner_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/combiner_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/combiner_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_combiner_test: $(COMBINER_TEST_OBJS:.o=.dep) @@ -11153,14 +11130,14 @@ else -$(BINDIR)/$(CONFIG)/compression_test: $(COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/compression_test: $(COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/compression_test + $(Q) $(LD) $(LDFLAGS) $(COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/compression_test endif -$(OBJDIR)/$(CONFIG)/test/core/compression/compression_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/compression/compression_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_compression_test: $(COMPRESSION_TEST_OBJS:.o=.dep) @@ -11185,14 +11162,14 @@ else -$(BINDIR)/$(CONFIG)/concurrent_connectivity_test: $(CONCURRENT_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/concurrent_connectivity_test: $(CONCURRENT_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CONCURRENT_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/concurrent_connectivity_test + $(Q) $(LD) $(LDFLAGS) $(CONCURRENT_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/concurrent_connectivity_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/concurrent_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/concurrent_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_concurrent_connectivity_test: $(CONCURRENT_CONNECTIVITY_TEST_OBJS:.o=.dep) @@ -11217,14 +11194,14 @@ else -$(BINDIR)/$(CONFIG)/connection_refused_test: $(CONNECTION_REFUSED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/connection_refused_test: $(CONNECTION_REFUSED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CONNECTION_REFUSED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/connection_refused_test + $(Q) $(LD) $(LDFLAGS) $(CONNECTION_REFUSED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/connection_refused_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/connection_refused_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/connection_refused_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_connection_refused_test: $(CONNECTION_REFUSED_TEST_OBJS:.o=.dep) @@ -11249,14 +11226,14 @@ else -$(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test: $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test: $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test + $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_dns_resolver_connectivity_test: $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS:.o=.dep) @@ -11281,14 +11258,14 @@ else -$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test + $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_cooldown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_cooldown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS:.o=.dep) @@ -11313,14 +11290,14 @@ else -$(BINDIR)/$(CONFIG)/dns_resolver_test: $(DNS_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dns_resolver_test: $(DNS_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_test + $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_dns_resolver_test: $(DNS_RESOLVER_TEST_OBJS:.o=.dep) @@ -11345,14 +11322,14 @@ else -$(BINDIR)/$(CONFIG)/dualstack_socket_test: $(DUALSTACK_SOCKET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dualstack_socket_test: $(DUALSTACK_SOCKET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DUALSTACK_SOCKET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dualstack_socket_test + $(Q) $(LD) $(LDFLAGS) $(DUALSTACK_SOCKET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dualstack_socket_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/dualstack_socket_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/dualstack_socket_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_dualstack_socket_test: $(DUALSTACK_SOCKET_TEST_OBJS:.o=.dep) @@ -11377,14 +11354,14 @@ else -$(BINDIR)/$(CONFIG)/endpoint_pair_test: $(ENDPOINT_PAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/endpoint_pair_test: $(ENDPOINT_PAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ENDPOINT_PAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/endpoint_pair_test + $(Q) $(LD) $(LDFLAGS) $(ENDPOINT_PAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/endpoint_pair_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/endpoint_pair_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/endpoint_pair_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_endpoint_pair_test: $(ENDPOINT_PAIR_TEST_OBJS:.o=.dep) @@ -11409,14 +11386,14 @@ else -$(BINDIR)/$(CONFIG)/error_test: $(ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/error_test: $(ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/error_test + $(Q) $(LD) $(LDFLAGS) $(ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/error_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/error_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/error_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_error_test: $(ERROR_TEST_OBJS:.o=.dep) @@ -11441,14 +11418,14 @@ else -$(BINDIR)/$(CONFIG)/ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(EV_EPOLLEX_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ev_epollex_linux_test + $(Q) $(LD) $(LDFLAGS) $(EV_EPOLLEX_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ev_epollex_linux_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/ev_epollex_linux_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/ev_epollex_linux_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_TEST_OBJS:.o=.dep) @@ -11473,14 +11450,14 @@ else -$(BINDIR)/$(CONFIG)/fake_resolver_test: $(FAKE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fake_resolver_test: $(FAKE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FAKE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fake_resolver_test + $(Q) $(LD) $(LDFLAGS) $(FAKE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fake_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/fake_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/fake_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fake_resolver_test: $(FAKE_RESOLVER_TEST_OBJS:.o=.dep) @@ -11506,16 +11483,16 @@ else -$(BINDIR)/$(CONFIG)/fake_transport_security_test: $(FAKE_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/fake_transport_security_test: $(FAKE_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FAKE_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fake_transport_security_test + $(Q) $(LD) $(LDFLAGS) $(FAKE_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fake_transport_security_test endif -$(OBJDIR)/$(CONFIG)/test/core/tsi/fake_transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/fake_transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a -$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test_lib.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test_lib.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_fake_transport_security_test: $(FAKE_TRANSPORT_SECURITY_TEST_OBJS:.o=.dep) @@ -11540,14 +11517,14 @@ else -$(BINDIR)/$(CONFIG)/fd_conservation_posix_test: $(FD_CONSERVATION_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fd_conservation_posix_test: $(FD_CONSERVATION_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FD_CONSERVATION_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fd_conservation_posix_test + $(Q) $(LD) $(LDFLAGS) $(FD_CONSERVATION_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fd_conservation_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/fd_conservation_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/fd_conservation_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fd_conservation_posix_test: $(FD_CONSERVATION_POSIX_TEST_OBJS:.o=.dep) @@ -11572,14 +11549,14 @@ else -$(BINDIR)/$(CONFIG)/fd_posix_test: $(FD_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fd_posix_test: $(FD_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FD_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fd_posix_test + $(Q) $(LD) $(LDFLAGS) $(FD_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fd_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/fd_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/fd_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fd_posix_test: $(FD_POSIX_TEST_OBJS:.o=.dep) @@ -11604,14 +11581,14 @@ else -$(BINDIR)/$(CONFIG)/fling_client: $(FLING_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fling_client: $(FLING_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FLING_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_client + $(Q) $(LD) $(LDFLAGS) $(FLING_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_client endif -$(OBJDIR)/$(CONFIG)/test/core/fling/client.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/fling/client.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fling_client: $(FLING_CLIENT_OBJS:.o=.dep) @@ -11636,14 +11613,14 @@ else -$(BINDIR)/$(CONFIG)/fling_server: $(FLING_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fling_server: $(FLING_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FLING_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_server + $(Q) $(LD) $(LDFLAGS) $(FLING_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_server endif -$(OBJDIR)/$(CONFIG)/test/core/fling/server.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/fling/server.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fling_server: $(FLING_SERVER_OBJS:.o=.dep) @@ -11668,14 +11645,14 @@ else -$(BINDIR)/$(CONFIG)/fling_stream_test: $(FLING_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fling_stream_test: $(FLING_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FLING_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_stream_test + $(Q) $(LD) $(LDFLAGS) $(FLING_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_stream_test endif -$(OBJDIR)/$(CONFIG)/test/core/fling/fling_stream_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/fling/fling_stream_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fling_stream_test: $(FLING_STREAM_TEST_OBJS:.o=.dep) @@ -11700,14 +11677,14 @@ else -$(BINDIR)/$(CONFIG)/fling_test: $(FLING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fling_test: $(FLING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FLING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_test + $(Q) $(LD) $(LDFLAGS) $(FLING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_test endif -$(OBJDIR)/$(CONFIG)/test/core/fling/fling_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/fling/fling_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fling_test: $(FLING_TEST_OBJS:.o=.dep) @@ -11732,14 +11709,14 @@ else -$(BINDIR)/$(CONFIG)/fork_test: $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fork_test: $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fork_test + $(Q) $(LD) $(LDFLAGS) $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fork_test endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/fork_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/fork_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_fork_test: $(FORK_TEST_OBJS:.o=.dep) @@ -11764,14 +11741,14 @@ else -$(BINDIR)/$(CONFIG)/goaway_server_test: $(GOAWAY_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/goaway_server_test: $(GOAWAY_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GOAWAY_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/goaway_server_test + $(Q) $(LD) $(LDFLAGS) $(GOAWAY_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/goaway_server_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/goaway_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/goaway_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_goaway_server_test: $(GOAWAY_SERVER_TEST_OBJS:.o=.dep) @@ -11796,14 +11773,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_cpu_test: $(GPR_CPU_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_cpu_test: $(GPR_CPU_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_CPU_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_cpu_test + $(Q) $(LD) $(LDFLAGS) $(GPR_CPU_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_cpu_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/cpu_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/cpu_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_cpu_test: $(GPR_CPU_TEST_OBJS:.o=.dep) @@ -11828,14 +11805,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_env_test: $(GPR_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_env_test: $(GPR_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_env_test + $(Q) $(LD) $(LDFLAGS) $(GPR_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_env_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/env_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/env_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_env_test: $(GPR_ENV_TEST_OBJS:.o=.dep) @@ -11860,14 +11837,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_host_port_test + $(Q) $(LD) $(LDFLAGS) $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_host_port_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS:.o=.dep) @@ -11892,14 +11869,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_log_test: $(GPR_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_log_test: $(GPR_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_log_test + $(Q) $(LD) $(LDFLAGS) $(GPR_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_log_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/log_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/log_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_log_test: $(GPR_LOG_TEST_OBJS:.o=.dep) @@ -11924,14 +11901,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test + $(Q) $(LD) $(LDFLAGS) $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/manual_constructor_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/manual_constructor_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS:.o=.dep) @@ -11956,14 +11933,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_mpscq_test: $(GPR_MPSCQ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_mpscq_test: $(GPR_MPSCQ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_MPSCQ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_mpscq_test + $(Q) $(LD) $(LDFLAGS) $(GPR_MPSCQ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_mpscq_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/mpscq_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/mpscq_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_mpscq_test: $(GPR_MPSCQ_TEST_OBJS:.o=.dep) @@ -11988,14 +11965,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_spinlock_test: $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_spinlock_test: $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_spinlock_test + $(Q) $(LD) $(LDFLAGS) $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_spinlock_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/spinlock_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/spinlock_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_spinlock_test: $(GPR_SPINLOCK_TEST_OBJS:.o=.dep) @@ -12020,14 +11997,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_string_test: $(GPR_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_string_test: $(GPR_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_string_test + $(Q) $(LD) $(LDFLAGS) $(GPR_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_string_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/string_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/string_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_string_test: $(GPR_STRING_TEST_OBJS:.o=.dep) @@ -12052,14 +12029,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_sync_test: $(GPR_SYNC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_sync_test: $(GPR_SYNC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_SYNC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_sync_test + $(Q) $(LD) $(LDFLAGS) $(GPR_SYNC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_sync_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/sync_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/sync_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_sync_test: $(GPR_SYNC_TEST_OBJS:.o=.dep) @@ -12084,14 +12061,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_thd_test: $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_thd_test: $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_thd_test + $(Q) $(LD) $(LDFLAGS) $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_thd_test endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/thd_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/thd_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_thd_test: $(GPR_THD_TEST_OBJS:.o=.dep) @@ -12116,14 +12093,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_time_test: $(GPR_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_time_test: $(GPR_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_time_test + $(Q) $(LD) $(LDFLAGS) $(GPR_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_time_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/time_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/time_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_time_test: $(GPR_TIME_TEST_OBJS:.o=.dep) @@ -12148,14 +12125,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_tls_test: $(GPR_TLS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_tls_test: $(GPR_TLS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_TLS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_tls_test + $(Q) $(LD) $(LDFLAGS) $(GPR_TLS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_tls_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/tls_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/tls_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_tls_test: $(GPR_TLS_TEST_OBJS:.o=.dep) @@ -12180,14 +12157,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_useful_test: $(GPR_USEFUL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_useful_test: $(GPR_USEFUL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_USEFUL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_useful_test + $(Q) $(LD) $(LDFLAGS) $(GPR_USEFUL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_useful_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/useful_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/useful_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_useful_test: $(GPR_USEFUL_TEST_OBJS:.o=.dep) @@ -12212,14 +12189,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_auth_context_test: $(GRPC_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_auth_context_test: $(GRPC_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_auth_context_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_auth_context_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/auth_context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/auth_context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_auth_context_test: $(GRPC_AUTH_CONTEXT_TEST_OBJS:.o=.dep) @@ -12244,14 +12221,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_b64_test: $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_b64_test: $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_b64_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_b64_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/b64_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/b64_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_b64_test: $(GRPC_B64_TEST_OBJS:.o=.dep) @@ -12276,14 +12253,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test: $(GRPC_BYTE_BUFFER_READER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test: $(GRPC_BYTE_BUFFER_READER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_BYTE_BUFFER_READER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_BYTE_BUFFER_READER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/byte_buffer_reader_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/byte_buffer_reader_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_byte_buffer_reader_test: $(GRPC_BYTE_BUFFER_READER_TEST_OBJS:.o=.dep) @@ -12308,14 +12285,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_channel_args_test: $(GRPC_CHANNEL_ARGS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_channel_args_test: $(GRPC_CHANNEL_ARGS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_ARGS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_args_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_ARGS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_args_test endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channel_args_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channel_args_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_channel_args_test: $(GRPC_CHANNEL_ARGS_TEST_OBJS:.o=.dep) @@ -12340,14 +12317,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_channel_stack_builder_test: $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_channel_stack_builder_test: $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_stack_builder_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_stack_builder_test endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channel_stack_builder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channel_stack_builder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_channel_stack_builder_test: $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS:.o=.dep) @@ -12372,14 +12349,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_channel_stack_test: $(GRPC_CHANNEL_STACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_channel_stack_test: $(GRPC_CHANNEL_STACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_STACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_stack_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_STACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_stack_test endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channel_stack_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channel_stack_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_channel_stack_test: $(GRPC_CHANNEL_STACK_TEST_OBJS:.o=.dep) @@ -12404,14 +12381,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_completion_queue_test: $(GRPC_COMPLETION_QUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_completion_queue_test: $(GRPC_COMPLETION_QUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_COMPLETION_QUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_completion_queue_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_COMPLETION_QUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_completion_queue_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/completion_queue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/completion_queue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_completion_queue_test: $(GRPC_COMPLETION_QUEUE_TEST_OBJS:.o=.dep) @@ -12436,14 +12413,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test: $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test: $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/completion_queue_threading_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/completion_queue_threading_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_completion_queue_threading_test: $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS:.o=.dep) @@ -12503,14 +12480,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_credentials_test: $(GRPC_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_credentials_test: $(GRPC_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_credentials_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_credentials_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/credentials_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/credentials_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_credentials_test: $(GRPC_CREDENTIALS_TEST_OBJS:.o=.dep) @@ -12535,14 +12512,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 + $(Q) $(LD) $(LDFLAGS) $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 endif -$(OBJDIR)/$(CONFIG)/test/core/security/fetch_oauth2.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/fetch_oauth2.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS:.o=.dep) @@ -12567,14 +12544,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test: $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test: $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/grpc_ipv6_loopback_available_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/grpc_ipv6_loopback_available_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_ipv6_loopback_available_test: $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS:.o=.dep) @@ -12599,14 +12576,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_json_token_test: $(GRPC_JSON_TOKEN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_json_token_test: $(GRPC_JSON_TOKEN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_JSON_TOKEN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_json_token_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_JSON_TOKEN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_json_token_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/json_token_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/json_token_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_json_token_test: $(GRPC_JSON_TOKEN_TEST_OBJS:.o=.dep) @@ -12631,14 +12608,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test: $(GRPC_JWT_VERIFIER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test: $(GRPC_JWT_VERIFIER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_JWT_VERIFIER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_JWT_VERIFIER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/jwt_verifier_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/jwt_verifier_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_jwt_verifier_test: $(GRPC_JWT_VERIFIER_TEST_OBJS:.o=.dep) @@ -12698,14 +12675,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_security_connector_test: $(GRPC_SECURITY_CONNECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_security_connector_test: $(GRPC_SECURITY_CONNECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_SECURITY_CONNECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_security_connector_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_SECURITY_CONNECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_security_connector_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/security_connector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/security_connector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_security_connector_test: $(GRPC_SECURITY_CONNECTOR_TEST_OBJS:.o=.dep) @@ -12730,14 +12707,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test: $(GRPC_SSL_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test: $(GRPC_SSL_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_SSL_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_SSL_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/ssl_credentials_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/ssl_credentials_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_ssl_credentials_test: $(GRPC_SSL_CREDENTIALS_TEST_OBJS:.o=.dep) @@ -12797,14 +12774,14 @@ else -$(BINDIR)/$(CONFIG)/handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_client_ssl + $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_client_ssl endif -$(OBJDIR)/$(CONFIG)/test/core/handshake/client_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/handshake/client_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_OBJS:.o=.dep) @@ -12830,16 +12807,16 @@ else -$(BINDIR)/$(CONFIG)/handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_ssl + $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_ssl endif -$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_OBJS:.o=.dep) @@ -12865,16 +12842,16 @@ else -$(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker + $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker endif -$(OBJDIR)/$(CONFIG)/test/core/handshake/readahead_handshaker_server_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/handshake/readahead_handshaker_server_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_handshake_server_with_readahead_handshaker: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS:.o=.dep) @@ -12899,14 +12876,14 @@ else -$(BINDIR)/$(CONFIG)/handshake_verify_peer_options: $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/handshake_verify_peer_options: $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_verify_peer_options + $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_verify_peer_options endif -$(OBJDIR)/$(CONFIG)/test/core/handshake/verify_peer_options.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/handshake/verify_peer_options.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_handshake_verify_peer_options: $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS:.o=.dep) @@ -12963,14 +12940,14 @@ else -$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test: $(HPACK_PARSER_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test: $(HPACK_PARSER_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HPACK_PARSER_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(HPACK_PARSER_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hpack_parser_fuzzer_test: $(HPACK_PARSER_FUZZER_TEST_OBJS:.o=.dep) @@ -12995,14 +12972,14 @@ else -$(BINDIR)/$(CONFIG)/hpack_parser_test: $(HPACK_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hpack_parser_test: $(HPACK_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HPACK_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_parser_test + $(Q) $(LD) $(LDFLAGS) $(HPACK_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_parser_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hpack_parser_test: $(HPACK_PARSER_TEST_OBJS:.o=.dep) @@ -13027,14 +13004,14 @@ else -$(BINDIR)/$(CONFIG)/hpack_table_test: $(HPACK_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hpack_table_test: $(HPACK_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HPACK_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_table_test + $(Q) $(LD) $(LDFLAGS) $(HPACK_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_table_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hpack_table_test: $(HPACK_TABLE_TEST_OBJS:.o=.dep) @@ -13059,14 +13036,14 @@ else -$(BINDIR)/$(CONFIG)/http_parser_test: $(HTTP_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_parser_test: $(HTTP_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTP_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_parser_test + $(Q) $(LD) $(LDFLAGS) $(HTTP_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_parser_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_parser_test: $(HTTP_PARSER_TEST_OBJS:.o=.dep) @@ -13091,14 +13068,14 @@ else -$(BINDIR)/$(CONFIG)/http_request_fuzzer_test: $(HTTP_REQUEST_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_request_fuzzer_test: $(HTTP_REQUEST_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HTTP_REQUEST_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/http_request_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(HTTP_REQUEST_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/http_request_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/request_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/request_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_request_fuzzer_test: $(HTTP_REQUEST_FUZZER_TEST_OBJS:.o=.dep) @@ -13123,14 +13100,14 @@ else -$(BINDIR)/$(CONFIG)/http_response_fuzzer_test: $(HTTP_RESPONSE_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_response_fuzzer_test: $(HTTP_RESPONSE_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HTTP_RESPONSE_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/http_response_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(HTTP_RESPONSE_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/http_response_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/response_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/response_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_response_fuzzer_test: $(HTTP_RESPONSE_FUZZER_TEST_OBJS:.o=.dep) @@ -13155,14 +13132,14 @@ else -$(BINDIR)/$(CONFIG)/httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_format_request_test + $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_format_request_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/format_request_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/format_request_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS:.o=.dep) @@ -13187,14 +13164,14 @@ else -$(BINDIR)/$(CONFIG)/httpcli_test: $(HTTPCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/httpcli_test: $(HTTPCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_test + $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/httpcli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/httpcli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_httpcli_test: $(HTTPCLI_TEST_OBJS:.o=.dep) @@ -13219,14 +13196,14 @@ else -$(BINDIR)/$(CONFIG)/httpscli_test: $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/httpscli_test: $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpscli_test + $(Q) $(LD) $(LDFLAGS) $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpscli_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/httpscli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/httpscli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_httpscli_test: $(HTTPSCLI_TEST_OBJS:.o=.dep) @@ -13251,14 +13228,14 @@ else -$(BINDIR)/$(CONFIG)/init_test: $(INIT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/init_test: $(INIT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INIT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/init_test + $(Q) $(LD) $(LDFLAGS) $(INIT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/init_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/init_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/init_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_init_test: $(INIT_TEST_OBJS:.o=.dep) @@ -13283,14 +13260,14 @@ else -$(BINDIR)/$(CONFIG)/inproc_callback_test: $(INPROC_CALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/inproc_callback_test: $(INPROC_CALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INPROC_CALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/inproc_callback_test + $(Q) $(LD) $(LDFLAGS) $(INPROC_CALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/inproc_callback_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/inproc_callback_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/inproc_callback_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_inproc_callback_test: $(INPROC_CALLBACK_TEST_OBJS:.o=.dep) @@ -13315,14 +13292,14 @@ else -$(BINDIR)/$(CONFIG)/invalid_call_argument_test: $(INVALID_CALL_ARGUMENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/invalid_call_argument_test: $(INVALID_CALL_ARGUMENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INVALID_CALL_ARGUMENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/invalid_call_argument_test + $(Q) $(LD) $(LDFLAGS) $(INVALID_CALL_ARGUMENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/invalid_call_argument_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/invalid_call_argument_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/invalid_call_argument_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_invalid_call_argument_test: $(INVALID_CALL_ARGUMENT_TEST_OBJS:.o=.dep) @@ -13347,14 +13324,14 @@ else -$(BINDIR)/$(CONFIG)/json_fuzzer_test: $(JSON_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_fuzzer_test: $(JSON_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(JSON_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/json_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(JSON_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/json_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/json/fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/json/fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_fuzzer_test: $(JSON_FUZZER_TEST_OBJS:.o=.dep) @@ -13379,14 +13356,14 @@ else -$(BINDIR)/$(CONFIG)/json_rewrite: $(JSON_REWRITE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_rewrite: $(JSON_REWRITE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(JSON_REWRITE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_rewrite + $(Q) $(LD) $(LDFLAGS) $(JSON_REWRITE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_rewrite endif -$(OBJDIR)/$(CONFIG)/test/core/json/json_rewrite.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/json/json_rewrite.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_rewrite: $(JSON_REWRITE_OBJS:.o=.dep) @@ -13411,14 +13388,14 @@ else -$(BINDIR)/$(CONFIG)/json_rewrite_test: $(JSON_REWRITE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_rewrite_test: $(JSON_REWRITE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(JSON_REWRITE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_rewrite_test + $(Q) $(LD) $(LDFLAGS) $(JSON_REWRITE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_rewrite_test endif -$(OBJDIR)/$(CONFIG)/test/core/json/json_rewrite_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/json/json_rewrite_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_rewrite_test: $(JSON_REWRITE_TEST_OBJS:.o=.dep) @@ -13443,14 +13420,14 @@ else -$(BINDIR)/$(CONFIG)/json_stream_error_test: $(JSON_STREAM_ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_stream_error_test: $(JSON_STREAM_ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(JSON_STREAM_ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_stream_error_test + $(Q) $(LD) $(LDFLAGS) $(JSON_STREAM_ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_stream_error_test endif -$(OBJDIR)/$(CONFIG)/test/core/json/json_stream_error_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/json/json_stream_error_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_stream_error_test: $(JSON_STREAM_ERROR_TEST_OBJS:.o=.dep) @@ -13475,14 +13452,14 @@ else -$(BINDIR)/$(CONFIG)/json_test: $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_test: $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_test + $(Q) $(LD) $(LDFLAGS) $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_test endif -$(OBJDIR)/$(CONFIG)/test/core/json/json_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/json/json_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_test: $(JSON_TEST_OBJS:.o=.dep) @@ -13507,14 +13484,14 @@ else -$(BINDIR)/$(CONFIG)/lame_client_test: $(LAME_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/lame_client_test: $(LAME_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(LAME_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/lame_client_test + $(Q) $(LD) $(LDFLAGS) $(LAME_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/lame_client_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/lame_client_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/lame_client_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_lame_client_test: $(LAME_CLIENT_TEST_OBJS:.o=.dep) @@ -13539,14 +13516,14 @@ else -$(BINDIR)/$(CONFIG)/load_file_test: $(LOAD_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/load_file_test: $(LOAD_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(LOAD_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/load_file_test + $(Q) $(LD) $(LDFLAGS) $(LOAD_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/load_file_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/load_file_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/load_file_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_load_file_test: $(LOAD_FILE_TEST_OBJS:.o=.dep) @@ -13571,14 +13548,14 @@ else -$(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark: $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark: $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark + $(Q) $(LD) $(LDFLAGS) $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark endif -$(OBJDIR)/$(CONFIG)/test/core/network_benchmarks/low_level_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/network_benchmarks/low_level_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_low_level_ping_pong_benchmark: $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS:.o=.dep) @@ -13603,14 +13580,14 @@ else -$(BINDIR)/$(CONFIG)/memory_usage_client: $(MEMORY_USAGE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/memory_usage_client: $(MEMORY_USAGE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_client + $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_client endif -$(OBJDIR)/$(CONFIG)/test/core/memory_usage/client.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/memory_usage/client.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_memory_usage_client: $(MEMORY_USAGE_CLIENT_OBJS:.o=.dep) @@ -13635,14 +13612,14 @@ else -$(BINDIR)/$(CONFIG)/memory_usage_server: $(MEMORY_USAGE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/memory_usage_server: $(MEMORY_USAGE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_server + $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_server endif -$(OBJDIR)/$(CONFIG)/test/core/memory_usage/server.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/memory_usage/server.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_memory_usage_server: $(MEMORY_USAGE_SERVER_OBJS:.o=.dep) @@ -13667,14 +13644,14 @@ else -$(BINDIR)/$(CONFIG)/memory_usage_test: $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/memory_usage_test: $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_test + $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_test endif -$(OBJDIR)/$(CONFIG)/test/core/memory_usage/memory_usage_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/memory_usage/memory_usage_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_memory_usage_test: $(MEMORY_USAGE_TEST_OBJS:.o=.dep) @@ -13699,14 +13676,14 @@ else -$(BINDIR)/$(CONFIG)/message_compress_test: $(MESSAGE_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/message_compress_test: $(MESSAGE_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MESSAGE_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/message_compress_test + $(Q) $(LD) $(LDFLAGS) $(MESSAGE_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/message_compress_test endif -$(OBJDIR)/$(CONFIG)/test/core/compression/message_compress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/compression/message_compress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_message_compress_test: $(MESSAGE_COMPRESS_TEST_OBJS:.o=.dep) @@ -13731,14 +13708,14 @@ else -$(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test: $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test: $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test + $(Q) $(LD) $(LDFLAGS) $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test endif -$(OBJDIR)/$(CONFIG)/test/core/channel/minimal_stack_is_minimal_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/minimal_stack_is_minimal_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_minimal_stack_is_minimal_test: $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS:.o=.dep) @@ -13763,14 +13740,14 @@ else -$(BINDIR)/$(CONFIG)/multiple_server_queues_test: $(MULTIPLE_SERVER_QUEUES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/multiple_server_queues_test: $(MULTIPLE_SERVER_QUEUES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MULTIPLE_SERVER_QUEUES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/multiple_server_queues_test + $(Q) $(LD) $(LDFLAGS) $(MULTIPLE_SERVER_QUEUES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/multiple_server_queues_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/multiple_server_queues_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/multiple_server_queues_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_multiple_server_queues_test: $(MULTIPLE_SERVER_QUEUES_TEST_OBJS:.o=.dep) @@ -13795,14 +13772,14 @@ else -$(BINDIR)/$(CONFIG)/murmur_hash_test: $(MURMUR_HASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/murmur_hash_test: $(MURMUR_HASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MURMUR_HASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/murmur_hash_test + $(Q) $(LD) $(LDFLAGS) $(MURMUR_HASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/murmur_hash_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/murmur_hash_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/murmur_hash_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_murmur_hash_test: $(MURMUR_HASH_TEST_OBJS:.o=.dep) @@ -13827,14 +13804,14 @@ else -$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test: $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test: $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test + $(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test endif -$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_response.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_response.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nanopb_fuzzer_response_test: $(NANOPB_FUZZER_RESPONSE_TEST_OBJS:.o=.dep) @@ -13859,14 +13836,14 @@ else -$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test: $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test: $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test + $(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test endif -$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_serverlist.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_serverlist.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nanopb_fuzzer_serverlist_test: $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS:.o=.dep) @@ -13891,14 +13868,14 @@ else -$(BINDIR)/$(CONFIG)/no_server_test: $(NO_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/no_server_test: $(NO_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(NO_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/no_server_test + $(Q) $(LD) $(LDFLAGS) $(NO_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/no_server_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/no_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/no_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_no_server_test: $(NO_SERVER_TEST_OBJS:.o=.dep) @@ -13923,14 +13900,14 @@ else -$(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test: $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test: $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test + $(Q) $(LD) $(LDFLAGS) $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/num_external_connectivity_watchers_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/num_external_connectivity_watchers_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_num_external_connectivity_watchers_test: $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS:.o=.dep) @@ -13955,14 +13932,14 @@ else -$(BINDIR)/$(CONFIG)/parse_address_test: $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/parse_address_test: $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/parse_address_test + $(Q) $(LD) $(LDFLAGS) $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/parse_address_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/parse_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/parse_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_parse_address_test: $(PARSE_ADDRESS_TEST_OBJS:.o=.dep) @@ -13987,14 +13964,14 @@ else -$(BINDIR)/$(CONFIG)/percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS:.o=.dep) @@ -14019,14 +13996,14 @@ else -$(BINDIR)/$(CONFIG)/percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS:.o=.dep) @@ -14051,14 +14028,14 @@ else -$(BINDIR)/$(CONFIG)/percent_encoding_test: $(PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_encoding_test: $(PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_encoding_test + $(Q) $(LD) $(LDFLAGS) $(PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_encoding_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_encoding_test: $(PERCENT_ENCODING_TEST_OBJS:.o=.dep) @@ -14083,14 +14060,14 @@ else -$(BINDIR)/$(CONFIG)/resolve_address_posix_test: $(RESOLVE_ADDRESS_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resolve_address_posix_test: $(RESOLVE_ADDRESS_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_posix_test + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_resolve_address_posix_test: $(RESOLVE_ADDRESS_POSIX_TEST_OBJS:.o=.dep) @@ -14115,14 +14092,14 @@ else -$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_resolve_address_using_ares_resolver_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS:.o=.dep) @@ -14147,14 +14124,14 @@ else -$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_resolve_address_using_native_resolver_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS:.o=.dep) @@ -14179,14 +14156,14 @@ else -$(BINDIR)/$(CONFIG)/resource_quota_test: $(RESOURCE_QUOTA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resource_quota_test: $(RESOURCE_QUOTA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(RESOURCE_QUOTA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resource_quota_test + $(Q) $(LD) $(LDFLAGS) $(RESOURCE_QUOTA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resource_quota_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/resource_quota_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/resource_quota_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_resource_quota_test: $(RESOURCE_QUOTA_TEST_OBJS:.o=.dep) @@ -14211,14 +14188,14 @@ else -$(BINDIR)/$(CONFIG)/secure_channel_create_test: $(SECURE_CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/secure_channel_create_test: $(SECURE_CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SECURE_CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/secure_channel_create_test + $(Q) $(LD) $(LDFLAGS) $(SECURE_CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/secure_channel_create_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/secure_channel_create_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/secure_channel_create_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_secure_channel_create_test: $(SECURE_CHANNEL_CREATE_TEST_OBJS:.o=.dep) @@ -14243,14 +14220,14 @@ else -$(BINDIR)/$(CONFIG)/secure_endpoint_test: $(SECURE_ENDPOINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/secure_endpoint_test: $(SECURE_ENDPOINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SECURE_ENDPOINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/secure_endpoint_test + $(Q) $(LD) $(LDFLAGS) $(SECURE_ENDPOINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/secure_endpoint_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/secure_endpoint_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/secure_endpoint_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_secure_endpoint_test: $(SECURE_ENDPOINT_TEST_OBJS:.o=.dep) @@ -14275,14 +14252,14 @@ else -$(BINDIR)/$(CONFIG)/sequential_connectivity_test: $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/sequential_connectivity_test: $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sequential_connectivity_test + $(Q) $(LD) $(LDFLAGS) $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sequential_connectivity_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/sequential_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/sequential_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_sequential_connectivity_test: $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS:.o=.dep) @@ -14307,14 +14284,14 @@ else -$(BINDIR)/$(CONFIG)/server_chttp2_test: $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_chttp2_test: $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_chttp2_test + $(Q) $(LD) $(LDFLAGS) $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_chttp2_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/server_chttp2_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/server_chttp2_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_chttp2_test: $(SERVER_CHTTP2_TEST_OBJS:.o=.dep) @@ -14339,14 +14316,14 @@ else -$(BINDIR)/$(CONFIG)/server_fuzzer: $(SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_fuzzer: $(SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/server_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/server_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_fuzzer: $(SERVER_FUZZER_OBJS:.o=.dep) @@ -14371,14 +14348,14 @@ else -$(BINDIR)/$(CONFIG)/server_test: $(SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_test: $(SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_test + $(Q) $(LD) $(LDFLAGS) $(SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_test: $(SERVER_TEST_OBJS:.o=.dep) @@ -14403,14 +14380,14 @@ else -$(BINDIR)/$(CONFIG)/slice_buffer_test: $(SLICE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_buffer_test: $(SLICE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SLICE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_buffer_test + $(Q) $(LD) $(LDFLAGS) $(SLICE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_buffer_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_buffer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/slice_buffer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_buffer_test: $(SLICE_BUFFER_TEST_OBJS:.o=.dep) @@ -14435,14 +14412,14 @@ else -$(BINDIR)/$(CONFIG)/slice_string_helpers_test: $(SLICE_STRING_HELPERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_string_helpers_test: $(SLICE_STRING_HELPERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SLICE_STRING_HELPERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_string_helpers_test + $(Q) $(LD) $(LDFLAGS) $(SLICE_STRING_HELPERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_string_helpers_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_string_helpers_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/slice_string_helpers_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_string_helpers_test: $(SLICE_STRING_HELPERS_TEST_OBJS:.o=.dep) @@ -14467,14 +14444,14 @@ else -$(BINDIR)/$(CONFIG)/slice_test: $(SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_test: $(SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_test + $(Q) $(LD) $(LDFLAGS) $(SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_test: $(SLICE_TEST_OBJS:.o=.dep) @@ -14499,14 +14476,14 @@ else -$(BINDIR)/$(CONFIG)/sockaddr_resolver_test: $(SOCKADDR_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/sockaddr_resolver_test: $(SOCKADDR_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SOCKADDR_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sockaddr_resolver_test + $(Q) $(LD) $(LDFLAGS) $(SOCKADDR_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sockaddr_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/sockaddr_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/sockaddr_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_sockaddr_resolver_test: $(SOCKADDR_RESOLVER_TEST_OBJS:.o=.dep) @@ -14531,14 +14508,14 @@ else -$(BINDIR)/$(CONFIG)/sockaddr_utils_test: $(SOCKADDR_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/sockaddr_utils_test: $(SOCKADDR_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SOCKADDR_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sockaddr_utils_test + $(Q) $(LD) $(LDFLAGS) $(SOCKADDR_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sockaddr_utils_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/sockaddr_utils_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/sockaddr_utils_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_sockaddr_utils_test: $(SOCKADDR_UTILS_TEST_OBJS:.o=.dep) @@ -14563,14 +14540,14 @@ else -$(BINDIR)/$(CONFIG)/socket_utils_test: $(SOCKET_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/socket_utils_test: $(SOCKET_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SOCKET_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/socket_utils_test + $(Q) $(LD) $(LDFLAGS) $(SOCKET_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/socket_utils_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/socket_utils_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/socket_utils_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_socket_utils_test: $(SOCKET_UTILS_TEST_OBJS:.o=.dep) @@ -14595,14 +14572,14 @@ else -$(BINDIR)/$(CONFIG)/ssl_server_fuzzer: $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ssl_server_fuzzer: $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ssl_server_fuzzer: $(SSL_SERVER_FUZZER_OBJS:.o=.dep) @@ -14628,16 +14605,16 @@ else -$(BINDIR)/$(CONFIG)/ssl_transport_security_test: $(SSL_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/ssl_transport_security_test: $(SSL_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SSL_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ssl_transport_security_test + $(Q) $(LD) $(LDFLAGS) $(SSL_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ssl_transport_security_test endif -$(OBJDIR)/$(CONFIG)/test/core/tsi/ssl_transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/ssl_transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a -$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test_lib.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test_lib.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_ssl_transport_security_test: $(SSL_TRANSPORT_SECURITY_TEST_OBJS:.o=.dep) @@ -14662,14 +14639,14 @@ else -$(BINDIR)/$(CONFIG)/status_conversion_test: $(STATUS_CONVERSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/status_conversion_test: $(STATUS_CONVERSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(STATUS_CONVERSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/status_conversion_test + $(Q) $(LD) $(LDFLAGS) $(STATUS_CONVERSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/status_conversion_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/status_conversion_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/status_conversion_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_status_conversion_test: $(STATUS_CONVERSION_TEST_OBJS:.o=.dep) @@ -14694,14 +14671,14 @@ else -$(BINDIR)/$(CONFIG)/stream_compression_test: $(STREAM_COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/stream_compression_test: $(STREAM_COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(STREAM_COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/stream_compression_test + $(Q) $(LD) $(LDFLAGS) $(STREAM_COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/stream_compression_test endif -$(OBJDIR)/$(CONFIG)/test/core/compression/stream_compression_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/compression/stream_compression_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_stream_compression_test: $(STREAM_COMPRESSION_TEST_OBJS:.o=.dep) @@ -14726,14 +14703,14 @@ else -$(BINDIR)/$(CONFIG)/stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/stream_owned_slice_test + $(Q) $(LD) $(LDFLAGS) $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/stream_owned_slice_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/stream_owned_slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/stream_owned_slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS:.o=.dep) @@ -14758,14 +14735,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_client_posix_test: $(TCP_CLIENT_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_client_posix_test: $(TCP_CLIENT_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TCP_CLIENT_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_client_posix_test + $(Q) $(LD) $(LDFLAGS) $(TCP_CLIENT_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_client_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_client_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_client_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_client_posix_test: $(TCP_CLIENT_POSIX_TEST_OBJS:.o=.dep) @@ -14790,14 +14767,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_client_uv_test: $(TCP_CLIENT_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_client_uv_test: $(TCP_CLIENT_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TCP_CLIENT_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_client_uv_test + $(Q) $(LD) $(LDFLAGS) $(TCP_CLIENT_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_client_uv_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_client_uv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_client_uv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_client_uv_test: $(TCP_CLIENT_UV_TEST_OBJS:.o=.dep) @@ -14822,14 +14799,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_posix_test: $(TCP_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_posix_test: $(TCP_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TCP_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_posix_test + $(Q) $(LD) $(LDFLAGS) $(TCP_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_posix_test: $(TCP_POSIX_TEST_OBJS:.o=.dep) @@ -14854,14 +14831,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_server_posix_test: $(TCP_SERVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_server_posix_test: $(TCP_SERVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TCP_SERVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_server_posix_test + $(Q) $(LD) $(LDFLAGS) $(TCP_SERVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_server_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_server_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_server_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_server_posix_test: $(TCP_SERVER_POSIX_TEST_OBJS:.o=.dep) @@ -14886,14 +14863,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_server_uv_test: $(TCP_SERVER_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_server_uv_test: $(TCP_SERVER_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TCP_SERVER_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_server_uv_test + $(Q) $(LD) $(LDFLAGS) $(TCP_SERVER_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_server_uv_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_server_uv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_server_uv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_server_uv_test: $(TCP_SERVER_UV_TEST_OBJS:.o=.dep) @@ -14918,14 +14895,14 @@ else -$(BINDIR)/$(CONFIG)/time_averaged_stats_test: $(TIME_AVERAGED_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/time_averaged_stats_test: $(TIME_AVERAGED_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TIME_AVERAGED_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/time_averaged_stats_test + $(Q) $(LD) $(LDFLAGS) $(TIME_AVERAGED_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/time_averaged_stats_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/time_averaged_stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/time_averaged_stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_time_averaged_stats_test: $(TIME_AVERAGED_STATS_TEST_OBJS:.o=.dep) @@ -14950,14 +14927,14 @@ else -$(BINDIR)/$(CONFIG)/timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timeout_encoding_test + $(Q) $(LD) $(LDFLAGS) $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timeout_encoding_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/timeout_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/timeout_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS:.o=.dep) @@ -14982,14 +14959,14 @@ else -$(BINDIR)/$(CONFIG)/timer_heap_test: $(TIMER_HEAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/timer_heap_test: $(TIMER_HEAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TIMER_HEAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timer_heap_test + $(Q) $(LD) $(LDFLAGS) $(TIMER_HEAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timer_heap_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_heap_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_heap_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_timer_heap_test: $(TIMER_HEAP_TEST_OBJS:.o=.dep) @@ -15014,14 +14991,14 @@ else -$(BINDIR)/$(CONFIG)/timer_list_test: $(TIMER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/timer_list_test: $(TIMER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TIMER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timer_list_test + $(Q) $(LD) $(LDFLAGS) $(TIMER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timer_list_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_timer_list_test: $(TIMER_LIST_TEST_OBJS:.o=.dep) @@ -15046,14 +15023,14 @@ else -$(BINDIR)/$(CONFIG)/transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_connectivity_state_test + $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_connectivity_state_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/connectivity_state_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/connectivity_state_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS:.o=.dep) @@ -15078,14 +15055,14 @@ else -$(BINDIR)/$(CONFIG)/transport_metadata_test: $(TRANSPORT_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/transport_metadata_test: $(TRANSPORT_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_metadata_test + $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_metadata_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/metadata_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/metadata_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_transport_metadata_test: $(TRANSPORT_METADATA_TEST_OBJS:.o=.dep) @@ -15110,14 +15087,14 @@ else -$(BINDIR)/$(CONFIG)/transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_security_test + $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_security_test endif -$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS:.o=.dep) @@ -15142,14 +15119,14 @@ else -$(BINDIR)/$(CONFIG)/udp_server_test: $(UDP_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/udp_server_test: $(UDP_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(UDP_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/udp_server_test + $(Q) $(LD) $(LDFLAGS) $(UDP_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/udp_server_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/udp_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/udp_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_udp_server_test: $(UDP_SERVER_TEST_OBJS:.o=.dep) @@ -15174,14 +15151,14 @@ else -$(BINDIR)/$(CONFIG)/uri_fuzzer_test: $(URI_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/uri_fuzzer_test: $(URI_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(URI_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(URI_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_uri_fuzzer_test: $(URI_FUZZER_TEST_OBJS:.o=.dep) @@ -15206,14 +15183,14 @@ else -$(BINDIR)/$(CONFIG)/uri_parser_test: $(URI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/uri_parser_test: $(URI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(URI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/uri_parser_test + $(Q) $(LD) $(LDFLAGS) $(URI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/uri_parser_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_uri_parser_test: $(URI_PARSER_TEST_OBJS:.o=.dep) @@ -15238,14 +15215,14 @@ else -$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(WAKEUP_FD_CV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test + $(Q) $(LD) $(LDFLAGS) $(WAKEUP_FD_CV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/wakeup_fd_cv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/wakeup_fd_cv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep) @@ -15279,16 +15256,16 @@ $(BINDIR)/$(CONFIG)/alarm_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/alarm_test: $(PROTOBUF_DEP) $(ALARM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/alarm_test: $(PROTOBUF_DEP) $(ALARM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ALARM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alarm_test + $(Q) $(LDXX) $(LDFLAGS) $(ALARM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alarm_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/common/alarm_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/common/alarm_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_alarm_test: $(ALARM_TEST_OBJS:.o=.dep) @@ -15365,16 +15342,16 @@ $(BINDIR)/$(CONFIG)/alts_crypt_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/alts_crypt_test: $(PROTOBUF_DEP) $(ALTS_CRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/alts_crypt_test: $(PROTOBUF_DEP) $(ALTS_CRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alts_crypt_test + $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alts_crypt_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/tsi/alts/crypt/aes_gcm_test.o: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/alts/crypt/aes_gcm_test.o: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_alts_crypt_test: $(ALTS_CRYPT_TEST_OBJS:.o=.dep) @@ -15884,16 +15861,16 @@ $(BINDIR)/$(CONFIG)/async_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/async_end2end_test: $(PROTOBUF_DEP) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/async_end2end_test: $(PROTOBUF_DEP) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/async_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/async_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/async_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/async_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_async_end2end_test: $(ASYNC_END2END_TEST_OBJS:.o=.dep) @@ -15927,16 +15904,16 @@ $(BINDIR)/$(CONFIG)/auth_property_iterator_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/auth_property_iterator_test: $(PROTOBUF_DEP) $(AUTH_PROPERTY_ITERATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/auth_property_iterator_test: $(PROTOBUF_DEP) $(AUTH_PROPERTY_ITERATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(AUTH_PROPERTY_ITERATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/auth_property_iterator_test + $(Q) $(LDXX) $(LDFLAGS) $(AUTH_PROPERTY_ITERATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/auth_property_iterator_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/common/auth_property_iterator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/common/auth_property_iterator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_auth_property_iterator_test: $(AUTH_PROPERTY_ITERATOR_TEST_OBJS:.o=.dep) @@ -15970,16 +15947,16 @@ $(BINDIR)/$(CONFIG)/backoff_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/backoff_test: $(PROTOBUF_DEP) $(BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/backoff_test: $(PROTOBUF_DEP) $(BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/backoff_test + $(Q) $(LDXX) $(LDFLAGS) $(BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/backoff_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/backoff/backoff_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/backoff/backoff_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_backoff_test: $(BACKOFF_TEST_OBJS:.o=.dep) @@ -16013,16 +15990,16 @@ $(BINDIR)/$(CONFIG)/bdp_estimator_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bdp_estimator_test: $(PROTOBUF_DEP) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bdp_estimator_test: $(PROTOBUF_DEP) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bdp_estimator_test + $(Q) $(LDXX) $(LDFLAGS) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bdp_estimator_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/bdp_estimator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/bdp_estimator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bdp_estimator_test: $(BDP_ESTIMATOR_TEST_OBJS:.o=.dep) @@ -16056,17 +16033,17 @@ $(BINDIR)/$(CONFIG)/bm_arena: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_arena: $(PROTOBUF_DEP) $(BM_ARENA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_arena: $(PROTOBUF_DEP) $(BM_ARENA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_ARENA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_arena + $(Q) $(LDXX) $(LDFLAGS) $(BM_ARENA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_arena endif endif $(BM_ARENA_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_arena.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_arena.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_arena: $(BM_ARENA_OBJS:.o=.dep) @@ -16100,17 +16077,17 @@ $(BINDIR)/$(CONFIG)/bm_call_create: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_call_create: $(PROTOBUF_DEP) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_call_create: $(PROTOBUF_DEP) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_call_create + $(Q) $(LDXX) $(LDFLAGS) $(BM_CALL_CREATE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_call_create endif endif $(BM_CALL_CREATE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_call_create.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_call_create.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_call_create: $(BM_CALL_CREATE_OBJS:.o=.dep) @@ -16144,17 +16121,17 @@ $(BINDIR)/$(CONFIG)/bm_channel: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_channel: $(PROTOBUF_DEP) $(BM_CHANNEL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_channel: $(PROTOBUF_DEP) $(BM_CHANNEL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CHANNEL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_channel + $(Q) $(LDXX) $(LDFLAGS) $(BM_CHANNEL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_channel endif endif $(BM_CHANNEL_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_channel.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_channel.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_channel: $(BM_CHANNEL_OBJS:.o=.dep) @@ -16188,17 +16165,17 @@ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: $(PROTOBUF_DEP) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: $(PROTOBUF_DEP) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_hpack + $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_HPACK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_hpack endif endif $(BM_CHTTP2_HPACK_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_hpack.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_hpack.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_chttp2_hpack: $(BM_CHTTP2_HPACK_OBJS:.o=.dep) @@ -16232,17 +16209,17 @@ $(BINDIR)/$(CONFIG)/bm_chttp2_transport: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_chttp2_transport: $(PROTOBUF_DEP) $(BM_CHTTP2_TRANSPORT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_chttp2_transport: $(PROTOBUF_DEP) $(BM_CHTTP2_TRANSPORT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_TRANSPORT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_transport + $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_TRANSPORT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_transport endif endif $(BM_CHTTP2_TRANSPORT_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_transport.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_transport.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_chttp2_transport: $(BM_CHTTP2_TRANSPORT_OBJS:.o=.dep) @@ -16276,17 +16253,17 @@ $(BINDIR)/$(CONFIG)/bm_closure: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_closure + $(Q) $(LDXX) $(LDFLAGS) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_closure endif endif $(BM_CLOSURE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_closure: $(BM_CLOSURE_OBJS:.o=.dep) @@ -16320,17 +16297,17 @@ $(BINDIR)/$(CONFIG)/bm_cq: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_cq: $(PROTOBUF_DEP) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_cq: $(PROTOBUF_DEP) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq + $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq endif endif $(BM_CQ_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_cq: $(BM_CQ_OBJS:.o=.dep) @@ -16364,17 +16341,17 @@ $(BINDIR)/$(CONFIG)/bm_cq_multiple_threads: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_cq_multiple_threads: $(PROTOBUF_DEP) $(BM_CQ_MULTIPLE_THREADS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_cq_multiple_threads: $(PROTOBUF_DEP) $(BM_CQ_MULTIPLE_THREADS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_MULTIPLE_THREADS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq_multiple_threads + $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_MULTIPLE_THREADS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq_multiple_threads endif endif $(BM_CQ_MULTIPLE_THREADS_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq_multiple_threads.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq_multiple_threads.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_cq_multiple_threads: $(BM_CQ_MULTIPLE_THREADS_OBJS:.o=.dep) @@ -16408,17 +16385,17 @@ $(BINDIR)/$(CONFIG)/bm_error: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_error: $(PROTOBUF_DEP) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_error: $(PROTOBUF_DEP) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_error + $(Q) $(LDXX) $(LDFLAGS) $(BM_ERROR_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_error endif endif $(BM_ERROR_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_error.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_error.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_error: $(BM_ERROR_OBJS:.o=.dep) @@ -16452,17 +16429,17 @@ $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong endif endif $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_fullstack_streaming_ping_pong: $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS:.o=.dep) @@ -16496,17 +16473,17 @@ $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PUMP_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump endif endif $(BM_FULLSTACK_STREAMING_PUMP_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_fullstack_streaming_pump: $(BM_FULLSTACK_STREAMING_PUMP_OBJS:.o=.dep) @@ -16540,17 +16517,17 @@ $(BINDIR)/$(CONFIG)/bm_fullstack_trickle: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: $(PROTOBUF_DEP) $(BM_FULLSTACK_TRICKLE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: $(PROTOBUF_DEP) $(BM_FULLSTACK_TRICKLE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_TRICKLE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_trickle + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_TRICKLE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_trickle endif endif $(BM_FULLSTACK_TRICKLE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_trickle.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_trickle.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_fullstack_trickle: $(BM_FULLSTACK_TRICKLE_OBJS:.o=.dep) @@ -16584,17 +16561,17 @@ $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_UNARY_PING_PONG_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong endif endif $(BM_FULLSTACK_UNARY_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_fullstack_unary_ping_pong: $(BM_FULLSTACK_UNARY_PING_PONG_OBJS:.o=.dep) @@ -16628,17 +16605,17 @@ $(BINDIR)/$(CONFIG)/bm_metadata: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_metadata + $(Q) $(LDXX) $(LDFLAGS) $(BM_METADATA_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_metadata endif endif $(BM_METADATA_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_metadata: $(BM_METADATA_OBJS:.o=.dep) @@ -16672,17 +16649,17 @@ $(BINDIR)/$(CONFIG)/bm_pollset: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_pollset: $(PROTOBUF_DEP) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_pollset: $(PROTOBUF_DEP) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_pollset + $(Q) $(LDXX) $(LDFLAGS) $(BM_POLLSET_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_pollset endif endif $(BM_POLLSET_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_pollset.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_pollset.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_pollset: $(BM_POLLSET_OBJS:.o=.dep) @@ -16716,16 +16693,16 @@ $(BINDIR)/$(CONFIG)/byte_stream_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/byte_stream_test: $(PROTOBUF_DEP) $(BYTE_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/byte_stream_test: $(PROTOBUF_DEP) $(BYTE_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BYTE_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/byte_stream_test + $(Q) $(LDXX) $(LDFLAGS) $(BYTE_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/byte_stream_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/byte_stream_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/byte_stream_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_byte_stream_test: $(BYTE_STREAM_TEST_OBJS:.o=.dep) @@ -16846,18 +16823,18 @@ $(BINDIR)/$(CONFIG)/channel_trace_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/channel_trace_test: $(PROTOBUF_DEP) $(CHANNEL_TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channel_trace_test: $(PROTOBUF_DEP) $(CHANNEL_TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CHANNEL_TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channel_trace_test + $(Q) $(LDXX) $(LDFLAGS) $(CHANNEL_TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channel_trace_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channel_trace_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channel_trace_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_channel_trace_test: $(CHANNEL_TRACE_TEST_OBJS:.o=.dep) @@ -16892,16 +16869,16 @@ $(BINDIR)/$(CONFIG)/channelz_registry_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/channelz_registry_test: $(PROTOBUF_DEP) $(CHANNELZ_REGISTRY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channelz_registry_test: $(PROTOBUF_DEP) $(CHANNELZ_REGISTRY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_REGISTRY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_registry_test + $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_REGISTRY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_registry_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channelz_registry_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channelz_registry_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_channelz_registry_test: $(CHANNELZ_REGISTRY_TEST_OBJS:.o=.dep) @@ -16936,18 +16913,18 @@ $(BINDIR)/$(CONFIG)/channelz_service_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/channelz_service_test: $(PROTOBUF_DEP) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channelz_service_test: $(PROTOBUF_DEP) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_service_test + $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_service_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/channelz_service_test.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/channelz_service_test.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_channelz_service_test: $(CHANNELZ_SERVICE_TEST_OBJS:.o=.dep) @@ -16983,18 +16960,18 @@ $(BINDIR)/$(CONFIG)/channelz_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/channelz_test: $(PROTOBUF_DEP) $(CHANNELZ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channelz_test: $(PROTOBUF_DEP) $(CHANNELZ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_test + $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channelz_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channelz_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_channelz_test: $(CHANNELZ_TEST_OBJS:.o=.dep) @@ -17115,16 +17092,16 @@ $(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test: $(PROTOBUF_DEP) $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test: $(PROTOBUF_DEP) $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test + $(Q) $(LDXX) $(LDFLAGS) $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/settings_timeout_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/settings_timeout_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_chttp2_settings_timeout_test: $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS:.o=.dep) @@ -17158,16 +17135,16 @@ $(BINDIR)/$(CONFIG)/cli_call_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cli_call_test: $(PROTOBUF_DEP) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/cli_call_test: $(PROTOBUF_DEP) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cli_call_test + $(Q) $(LDXX) $(LDFLAGS) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cli_call_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_cli_call_test: $(CLI_CALL_TEST_OBJS:.o=.dep) @@ -17201,16 +17178,16 @@ $(BINDIR)/$(CONFIG)/client_callback_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_callback_end2end_test: $(PROTOBUF_DEP) $(CLIENT_CALLBACK_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_callback_end2end_test: $(PROTOBUF_DEP) $(CLIENT_CALLBACK_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CALLBACK_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_callback_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CALLBACK_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_callback_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_callback_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_callback_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_callback_end2end_test: $(CLIENT_CALLBACK_END2END_TEST_OBJS:.o=.dep) @@ -17245,18 +17222,18 @@ $(BINDIR)/$(CONFIG)/client_channel_stress_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_channel_stress_test: $(PROTOBUF_DEP) $(CLIENT_CHANNEL_STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_channel_stress_test: $(PROTOBUF_DEP) $(CLIENT_CHANNEL_STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CHANNEL_STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_channel_stress_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CHANNEL_STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_channel_stress_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/client/client_channel_stress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/client/client_channel_stress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_channel_stress_test: $(CLIENT_CHANNEL_STRESS_TEST_OBJS:.o=.dep) @@ -17291,16 +17268,16 @@ $(BINDIR)/$(CONFIG)/client_crash_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_crash_test: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_crash_test: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_crash_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_crash_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_crash_test: $(CLIENT_CRASH_TEST_OBJS:.o=.dep) @@ -17334,16 +17311,16 @@ $(BINDIR)/$(CONFIG)/client_crash_test_server: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_crash_test_server: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_crash_test_server: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_crash_test_server + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_crash_test_server endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_crash_test_server: $(CLIENT_CRASH_TEST_SERVER_OBJS:.o=.dep) @@ -17378,18 +17355,18 @@ $(BINDIR)/$(CONFIG)/client_interceptors_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_interceptors_end2end_test: $(PROTOBUF_DEP) $(CLIENT_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_interceptors_end2end_test: $(PROTOBUF_DEP) $(CLIENT_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_interceptors_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_interceptors_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_interceptors_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_interceptors_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_interceptors_end2end_test: $(CLIENT_INTERCEPTORS_END2END_TEST_OBJS:.o=.dep) @@ -17423,16 +17400,16 @@ $(BINDIR)/$(CONFIG)/client_lb_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_lb_end2end_test: $(PROTOBUF_DEP) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_lb_end2end_test: $(PROTOBUF_DEP) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_lb_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_lb_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_lb_end2end_test: $(CLIENT_LB_END2END_TEST_OBJS:.o=.dep) @@ -17600,16 +17577,16 @@ $(BINDIR)/$(CONFIG)/context_list_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/context_list_test: $(PROTOBUF_DEP) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/context_list_test: $(PROTOBUF_DEP) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/context_list_test + $(Q) $(LDXX) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/context_list_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_context_list_test: $(CONTEXT_LIST_TEST_OBJS:.o=.dep) @@ -17686,16 +17663,16 @@ $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test: $(PROTOBUF_DEP) $(CXX_BYTE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test: $(PROTOBUF_DEP) $(CXX_BYTE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CXX_BYTE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test + $(Q) $(LDXX) $(LDFLAGS) $(CXX_BYTE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_cxx_byte_buffer_test: $(CXX_BYTE_BUFFER_TEST_OBJS:.o=.dep) @@ -17729,16 +17706,16 @@ $(BINDIR)/$(CONFIG)/cxx_slice_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cxx_slice_test: $(PROTOBUF_DEP) $(CXX_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/cxx_slice_test: $(PROTOBUF_DEP) $(CXX_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CXX_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cxx_slice_test + $(Q) $(LDXX) $(LDFLAGS) $(CXX_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cxx_slice_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_cxx_slice_test: $(CXX_SLICE_TEST_OBJS:.o=.dep) @@ -17815,16 +17792,16 @@ $(BINDIR)/$(CONFIG)/cxx_time_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cxx_time_test: $(PROTOBUF_DEP) $(CXX_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/cxx_time_test: $(PROTOBUF_DEP) $(CXX_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CXX_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cxx_time_test + $(Q) $(LDXX) $(LDFLAGS) $(CXX_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cxx_time_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/time_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/time_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_cxx_time_test: $(CXX_TIME_TEST_OBJS:.o=.dep) @@ -17859,18 +17836,18 @@ $(BINDIR)/$(CONFIG)/end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/end2end_test: $(PROTOBUF_DEP) $(END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/end2end_test: $(PROTOBUF_DEP) $(END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_end2end_test: $(END2END_TEST_OBJS:.o=.dep) @@ -17951,16 +17928,16 @@ $(BINDIR)/$(CONFIG)/exception_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/exception_test: $(PROTOBUF_DEP) $(EXCEPTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/exception_test: $(PROTOBUF_DEP) $(EXCEPTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(EXCEPTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/exception_test + $(Q) $(LDXX) $(LDFLAGS) $(EXCEPTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/exception_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/exception_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/exception_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_exception_test: $(EXCEPTION_TEST_OBJS:.o=.dep) @@ -17994,16 +17971,16 @@ $(BINDIR)/$(CONFIG)/filter_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/filter_end2end_test: $(PROTOBUF_DEP) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/filter_end2end_test: $(PROTOBUF_DEP) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/filter_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/filter_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/filter_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/filter_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_filter_end2end_test: $(FILTER_END2END_TEST_OBJS:.o=.dep) @@ -18037,16 +18014,16 @@ $(BINDIR)/$(CONFIG)/generic_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/generic_end2end_test: $(PROTOBUF_DEP) $(GENERIC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/generic_end2end_test: $(PROTOBUF_DEP) $(GENERIC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GENERIC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/generic_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(GENERIC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/generic_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/generic_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/generic_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_generic_end2end_test: $(GENERIC_END2END_TEST_OBJS:.o=.dep) @@ -18275,16 +18252,16 @@ $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test: $(PROTOBUF_DEP) $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test: $(PROTOBUF_DEP) $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/security/linux_system_roots_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/linux_system_roots_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_linux_system_roots_test: $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS:.o=.dep) @@ -18475,20 +18452,20 @@ $(BINDIR)/$(CONFIG)/grpc_tool_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_tool_test: $(PROTOBUF_DEP) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_tool_test: $(PROTOBUF_DEP) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_tool_test + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_tool_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_tool_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_tool_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_tool_test: $(GRPC_TOOL_TEST_OBJS:.o=.dep) @@ -18571,18 +18548,18 @@ $(BINDIR)/$(CONFIG)/grpclb_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpclb_end2end_test: $(PROTOBUF_DEP) $(GRPCLB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpclb_end2end_test: $(PROTOBUF_DEP) $(GRPCLB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/grpclb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/grpclb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpclb_end2end_test: $(GRPCLB_END2END_TEST_OBJS:.o=.dep) @@ -18617,16 +18594,16 @@ $(BINDIR)/$(CONFIG)/h2_ssl_cert_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: $(PROTOBUF_DEP) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: $(PROTOBUF_DEP) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/h2_ssl_cert_test + $(Q) $(LDXX) $(LDFLAGS) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/h2_ssl_cert_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_cert_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_cert_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_ssl_cert_test: $(H2_SSL_CERT_TEST_OBJS:.o=.dep) @@ -18660,16 +18637,16 @@ $(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test: $(PROTOBUF_DEP) $(H2_SSL_SESSION_REUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test: $(PROTOBUF_DEP) $(H2_SSL_SESSION_REUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(H2_SSL_SESSION_REUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test + $(Q) $(LDXX) $(LDFLAGS) $(H2_SSL_SESSION_REUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_session_reuse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_session_reuse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_ssl_session_reuse_test: $(H2_SSL_SESSION_REUSE_TEST_OBJS:.o=.dep) @@ -18703,16 +18680,16 @@ $(BINDIR)/$(CONFIG)/health_service_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/health_service_end2end_test: $(PROTOBUF_DEP) $(HEALTH_SERVICE_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/health_service_end2end_test: $(PROTOBUF_DEP) $(HEALTH_SERVICE_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HEALTH_SERVICE_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/health_service_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(HEALTH_SERVICE_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/health_service_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/health_service_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/health_service_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_health_service_end2end_test: $(HEALTH_SERVICE_END2END_TEST_OBJS:.o=.dep) @@ -18777,16 +18754,16 @@ $(BINDIR)/$(CONFIG)/hybrid_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/hybrid_end2end_test: $(PROTOBUF_DEP) $(HYBRID_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hybrid_end2end_test: $(PROTOBUF_DEP) $(HYBRID_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HYBRID_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/hybrid_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(HYBRID_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/hybrid_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/hybrid_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/hybrid_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hybrid_end2end_test: $(HYBRID_END2END_TEST_OBJS:.o=.dep) @@ -18820,16 +18797,16 @@ $(BINDIR)/$(CONFIG)/inlined_vector_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/inlined_vector_test: $(PROTOBUF_DEP) $(INLINED_VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/inlined_vector_test: $(PROTOBUF_DEP) $(INLINED_VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(INLINED_VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/inlined_vector_test + $(Q) $(LDXX) $(LDFLAGS) $(INLINED_VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/inlined_vector_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/inlined_vector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/inlined_vector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_inlined_vector_test: $(INLINED_VECTOR_TEST_OBJS:.o=.dep) @@ -18863,16 +18840,16 @@ $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test + $(Q) $(LDXX) $(LDFLAGS) $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/inproc_sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/inproc_sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_inproc_sync_unary_ping_pong_test: $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS:.o=.dep) @@ -18902,10 +18879,10 @@ $(BINDIR)/$(CONFIG)/interop_client: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/interop_client: $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/interop_client: $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_client + $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_client endif @@ -18933,10 +18910,10 @@ $(BINDIR)/$(CONFIG)/interop_server: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/interop_server: $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/interop_server: $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_server + $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_server endif @@ -18968,16 +18945,16 @@ $(BINDIR)/$(CONFIG)/interop_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/interop_test: $(PROTOBUF_DEP) $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/interop_test: $(PROTOBUF_DEP) $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_test + $(Q) $(LDXX) $(LDFLAGS) $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_interop_test: $(INTEROP_TEST_OBJS:.o=.dep) @@ -19011,16 +18988,16 @@ $(BINDIR)/$(CONFIG)/json_run_localhost: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/json_run_localhost: $(PROTOBUF_DEP) $(JSON_RUN_LOCALHOST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/json_run_localhost: $(PROTOBUF_DEP) $(JSON_RUN_LOCALHOST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(JSON_RUN_LOCALHOST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/json_run_localhost + $(Q) $(LDXX) $(LDFLAGS) $(JSON_RUN_LOCALHOST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/json_run_localhost endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/json_run_localhost.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/json_run_localhost.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_json_run_localhost: $(JSON_RUN_LOCALHOST_OBJS:.o=.dep) @@ -19054,16 +19031,16 @@ $(BINDIR)/$(CONFIG)/memory_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/memory_test: $(PROTOBUF_DEP) $(MEMORY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/memory_test: $(PROTOBUF_DEP) $(MEMORY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(MEMORY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/memory_test + $(Q) $(LDXX) $(LDFLAGS) $(MEMORY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/memory_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/memory_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/memory_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_memory_test: $(MEMORY_TEST_OBJS:.o=.dep) @@ -19144,16 +19121,16 @@ $(BINDIR)/$(CONFIG)/mock_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/mock_test: $(PROTOBUF_DEP) $(MOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/mock_test: $(PROTOBUF_DEP) $(MOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(MOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/mock_test + $(Q) $(LDXX) $(LDFLAGS) $(MOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/mock_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/mock_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/mock_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_mock_test: $(MOCK_TEST_OBJS:.o=.dep) @@ -19187,16 +19164,16 @@ $(BINDIR)/$(CONFIG)/nonblocking_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/nonblocking_test: $(PROTOBUF_DEP) $(NONBLOCKING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nonblocking_test: $(PROTOBUF_DEP) $(NONBLOCKING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(NONBLOCKING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/nonblocking_test + $(Q) $(LDXX) $(LDFLAGS) $(NONBLOCKING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/nonblocking_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/nonblocking_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/nonblocking_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nonblocking_test: $(NONBLOCKING_TEST_OBJS:.o=.dep) @@ -19274,16 +19251,16 @@ $(BINDIR)/$(CONFIG)/orphanable_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/orphanable_test: $(PROTOBUF_DEP) $(ORPHANABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/orphanable_test: $(PROTOBUF_DEP) $(ORPHANABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ORPHANABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/orphanable_test + $(Q) $(LDXX) $(LDFLAGS) $(ORPHANABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/orphanable_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/orphanable_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/orphanable_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_orphanable_test: $(ORPHANABLE_TEST_OBJS:.o=.dep) @@ -19317,16 +19294,16 @@ $(BINDIR)/$(CONFIG)/proto_server_reflection_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/proto_server_reflection_test: $(PROTOBUF_DEP) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/proto_server_reflection_test: $(PROTOBUF_DEP) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/proto_server_reflection_test + $(Q) $(LDXX) $(LDFLAGS) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/proto_server_reflection_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/proto_server_reflection_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/proto_server_reflection_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_proto_server_reflection_test: $(PROTO_SERVER_REFLECTION_TEST_OBJS:.o=.dep) @@ -19403,16 +19380,16 @@ $(BINDIR)/$(CONFIG)/qps_interarrival_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_interarrival_test: $(PROTOBUF_DEP) $(QPS_INTERARRIVAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/qps_interarrival_test: $(PROTOBUF_DEP) $(QPS_INTERARRIVAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(QPS_INTERARRIVAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_interarrival_test + $(Q) $(LDXX) $(LDFLAGS) $(QPS_INTERARRIVAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_interarrival_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_interarrival_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_interarrival_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_qps_interarrival_test: $(QPS_INTERARRIVAL_TEST_OBJS:.o=.dep) @@ -19446,16 +19423,16 @@ $(BINDIR)/$(CONFIG)/qps_json_driver: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_json_driver: $(PROTOBUF_DEP) $(QPS_JSON_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/qps_json_driver: $(PROTOBUF_DEP) $(QPS_JSON_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(QPS_JSON_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_json_driver + $(Q) $(LDXX) $(LDFLAGS) $(QPS_JSON_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_json_driver endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_json_driver.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_json_driver.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_qps_json_driver: $(QPS_JSON_DRIVER_OBJS:.o=.dep) @@ -19489,16 +19466,16 @@ $(BINDIR)/$(CONFIG)/qps_openloop_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_openloop_test: $(PROTOBUF_DEP) $(QPS_OPENLOOP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/qps_openloop_test: $(PROTOBUF_DEP) $(QPS_OPENLOOP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(QPS_OPENLOOP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_openloop_test + $(Q) $(LDXX) $(LDFLAGS) $(QPS_OPENLOOP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_openloop_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_openloop_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_openloop_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_qps_openloop_test: $(QPS_OPENLOOP_TEST_OBJS:.o=.dep) @@ -19532,16 +19509,16 @@ $(BINDIR)/$(CONFIG)/qps_worker: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_worker: $(PROTOBUF_DEP) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/qps_worker: $(PROTOBUF_DEP) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_worker + $(Q) $(LDXX) $(LDFLAGS) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_worker endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/worker.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/worker.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_qps_worker: $(QPS_WORKER_OBJS:.o=.dep) @@ -19575,16 +19552,16 @@ $(BINDIR)/$(CONFIG)/raw_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/raw_end2end_test: $(PROTOBUF_DEP) $(RAW_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/raw_end2end_test: $(PROTOBUF_DEP) $(RAW_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RAW_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/raw_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(RAW_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/raw_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/raw_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/raw_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_raw_end2end_test: $(RAW_END2END_TEST_OBJS:.o=.dep) @@ -19621,22 +19598,22 @@ $(BINDIR)/$(CONFIG)/reconnect_interop_client: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/reconnect_interop_client: $(PROTOBUF_DEP) $(RECONNECT_INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/reconnect_interop_client: $(PROTOBUF_DEP) $(RECONNECT_INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RECONNECT_INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reconnect_interop_client + $(Q) $(LDXX) $(LDFLAGS) $(RECONNECT_INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reconnect_interop_client endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_reconnect_interop_client: $(RECONNECT_INTEROP_CLIENT_OBJS:.o=.dep) @@ -19674,22 +19651,22 @@ $(BINDIR)/$(CONFIG)/reconnect_interop_server: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/reconnect_interop_server: $(PROTOBUF_DEP) $(RECONNECT_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/reconnect_interop_server: $(PROTOBUF_DEP) $(RECONNECT_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RECONNECT_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reconnect_interop_server + $(Q) $(LDXX) $(LDFLAGS) $(RECONNECT_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reconnect_interop_server endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_server.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_server.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_reconnect_interop_server: $(RECONNECT_INTEROP_SERVER_OBJS:.o=.dep) @@ -19724,16 +19701,16 @@ $(BINDIR)/$(CONFIG)/ref_counted_ptr_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/ref_counted_ptr_test: $(PROTOBUF_DEP) $(REF_COUNTED_PTR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ref_counted_ptr_test: $(PROTOBUF_DEP) $(REF_COUNTED_PTR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(REF_COUNTED_PTR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/ref_counted_ptr_test + $(Q) $(LDXX) $(LDFLAGS) $(REF_COUNTED_PTR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/ref_counted_ptr_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_ptr_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_ptr_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ref_counted_ptr_test: $(REF_COUNTED_PTR_TEST_OBJS:.o=.dep) @@ -19767,16 +19744,16 @@ $(BINDIR)/$(CONFIG)/ref_counted_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/ref_counted_test: $(PROTOBUF_DEP) $(REF_COUNTED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ref_counted_test: $(PROTOBUF_DEP) $(REF_COUNTED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(REF_COUNTED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/ref_counted_test + $(Q) $(LDXX) $(LDFLAGS) $(REF_COUNTED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/ref_counted_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ref_counted_test: $(REF_COUNTED_TEST_OBJS:.o=.dep) @@ -19810,16 +19787,16 @@ $(BINDIR)/$(CONFIG)/retry_throttle_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/retry_throttle_test: $(PROTOBUF_DEP) $(RETRY_THROTTLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/retry_throttle_test: $(PROTOBUF_DEP) $(RETRY_THROTTLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RETRY_THROTTLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/retry_throttle_test + $(Q) $(LDXX) $(LDFLAGS) $(RETRY_THROTTLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/retry_throttle_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/retry_throttle_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/retry_throttle_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_retry_throttle_test: $(RETRY_THROTTLE_TEST_OBJS:.o=.dep) @@ -19853,16 +19830,16 @@ $(BINDIR)/$(CONFIG)/secure_auth_context_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/secure_auth_context_test: $(PROTOBUF_DEP) $(SECURE_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/secure_auth_context_test: $(PROTOBUF_DEP) $(SECURE_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SECURE_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/secure_auth_context_test + $(Q) $(LDXX) $(LDFLAGS) $(SECURE_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/secure_auth_context_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/common/secure_auth_context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/common/secure_auth_context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_secure_auth_context_test: $(SECURE_AUTH_CONTEXT_TEST_OBJS:.o=.dep) @@ -19896,16 +19873,16 @@ $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test + $(Q) $(LDXX) $(LDFLAGS) $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/secure_sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/secure_sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_secure_sync_unary_ping_pong_test: $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS:.o=.dep) @@ -19939,16 +19916,16 @@ $(BINDIR)/$(CONFIG)/server_builder_plugin_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_builder_plugin_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_PLUGIN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_builder_plugin_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_PLUGIN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_PLUGIN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_plugin_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_PLUGIN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_plugin_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_builder_plugin_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_builder_plugin_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_builder_plugin_test: $(SERVER_BUILDER_PLUGIN_TEST_OBJS:.o=.dep) @@ -19984,20 +19961,20 @@ $(BINDIR)/$(CONFIG)/server_builder_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_builder_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_builder_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_builder_test: $(SERVER_BUILDER_TEST_OBJS:.o=.dep) @@ -20034,20 +20011,20 @@ $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_with_socket_mutator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_with_socket_mutator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_builder_with_socket_mutator_test: $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS:.o=.dep) @@ -20082,16 +20059,16 @@ $(BINDIR)/$(CONFIG)/server_context_test_spouse_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_context_test_spouse_test: $(PROTOBUF_DEP) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_context_test_spouse_test: $(PROTOBUF_DEP) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_context_test_spouse_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_context_test_spouse_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/test/server_context_test_spouse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/test/server_context_test_spouse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_context_test_spouse_test: $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS:.o=.dep) @@ -20125,16 +20102,16 @@ $(BINDIR)/$(CONFIG)/server_crash_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_crash_test: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_crash_test: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_crash_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_crash_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_crash_test: $(SERVER_CRASH_TEST_OBJS:.o=.dep) @@ -20168,16 +20145,16 @@ $(BINDIR)/$(CONFIG)/server_crash_test_client: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_crash_test_client: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_crash_test_client: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_crash_test_client + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_crash_test_client endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_crash_test_client: $(SERVER_CRASH_TEST_CLIENT_OBJS:.o=.dep) @@ -20211,16 +20188,16 @@ $(BINDIR)/$(CONFIG)/server_early_return_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_early_return_test: $(PROTOBUF_DEP) $(SERVER_EARLY_RETURN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_early_return_test: $(PROTOBUF_DEP) $(SERVER_EARLY_RETURN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_EARLY_RETURN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_early_return_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_EARLY_RETURN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_early_return_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_early_return_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_early_return_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_early_return_test: $(SERVER_EARLY_RETURN_TEST_OBJS:.o=.dep) @@ -20255,18 +20232,18 @@ $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_interceptors_end2end_test: $(PROTOBUF_DEP) $(SERVER_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_interceptors_end2end_test: $(PROTOBUF_DEP) $(SERVER_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_interceptors_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_interceptors_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_interceptors_end2end_test: $(SERVER_INTERCEPTORS_END2END_TEST_OBJS:.o=.dep) @@ -20302,20 +20279,20 @@ $(BINDIR)/$(CONFIG)/server_request_call_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_request_call_test: $(PROTOBUF_DEP) $(SERVER_REQUEST_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_request_call_test: $(PROTOBUF_DEP) $(SERVER_REQUEST_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_REQUEST_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_request_call_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_REQUEST_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_request_call_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/server/server_request_call_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/server/server_request_call_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_request_call_test: $(SERVER_REQUEST_CALL_TEST_OBJS:.o=.dep) @@ -20350,16 +20327,16 @@ $(BINDIR)/$(CONFIG)/shutdown_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/shutdown_test: $(PROTOBUF_DEP) $(SHUTDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/shutdown_test: $(PROTOBUF_DEP) $(SHUTDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SHUTDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/shutdown_test + $(Q) $(LDXX) $(LDFLAGS) $(SHUTDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/shutdown_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/shutdown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/shutdown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_shutdown_test: $(SHUTDOWN_TEST_OBJS:.o=.dep) @@ -20393,16 +20370,16 @@ $(BINDIR)/$(CONFIG)/slice_hash_table_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/slice_hash_table_test: $(PROTOBUF_DEP) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_hash_table_test: $(PROTOBUF_DEP) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_hash_table_test + $(Q) $(LDXX) $(LDFLAGS) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_hash_table_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/slice_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_hash_table_test: $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep) @@ -20436,16 +20413,16 @@ $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: $(PROTOBUF_DEP) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: $(PROTOBUF_DEP) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test + $(Q) $(LDXX) $(LDFLAGS) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_weak_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/slice_weak_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_weak_hash_table_test: $(SLICE_WEAK_HASH_TABLE_TEST_OBJS:.o=.dep) @@ -20479,16 +20456,16 @@ $(BINDIR)/$(CONFIG)/stats_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/stats_test: $(PROTOBUF_DEP) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/stats_test: $(PROTOBUF_DEP) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stats_test + $(Q) $(LDXX) $(LDFLAGS) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stats_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/debug/stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/debug/stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_stats_test: $(STATS_TEST_OBJS:.o=.dep) @@ -20608,16 +20585,16 @@ $(BINDIR)/$(CONFIG)/streaming_throughput_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/streaming_throughput_test: $(PROTOBUF_DEP) $(STREAMING_THROUGHPUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/streaming_throughput_test: $(PROTOBUF_DEP) $(STREAMING_THROUGHPUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(STREAMING_THROUGHPUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/streaming_throughput_test + $(Q) $(LDXX) $(LDFLAGS) $(STREAMING_THROUGHPUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/streaming_throughput_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/streaming_throughput_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/streaming_throughput_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_streaming_throughput_test: $(STREAMING_THROUGHPUT_TEST_OBJS:.o=.dep) @@ -20658,30 +20635,30 @@ $(BINDIR)/$(CONFIG)/stress_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/stress_test: $(PROTOBUF_DEP) $(STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/stress_test: $(PROTOBUF_DEP) $(STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stress_test + $(Q) $(LDXX) $(LDFLAGS) $(STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stress_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/metrics.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/metrics.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_stress_test: $(STRESS_TEST_OBJS:.o=.dep) @@ -20762,16 +20739,16 @@ $(BINDIR)/$(CONFIG)/thread_stress_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/thread_stress_test: $(PROTOBUF_DEP) $(THREAD_STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/thread_stress_test: $(PROTOBUF_DEP) $(THREAD_STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(THREAD_STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/thread_stress_test + $(Q) $(LDXX) $(LDFLAGS) $(THREAD_STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/thread_stress_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/thread_stress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/thread_stress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_thread_stress_test: $(THREAD_STRESS_TEST_OBJS:.o=.dep) @@ -20805,16 +20782,16 @@ $(BINDIR)/$(CONFIG)/transport_pid_controller_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/transport_pid_controller_test: $(PROTOBUF_DEP) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/transport_pid_controller_test: $(PROTOBUF_DEP) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/transport_pid_controller_test + $(Q) $(LDXX) $(LDFLAGS) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/transport_pid_controller_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/pid_controller_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/pid_controller_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_transport_pid_controller_test: $(TRANSPORT_PID_CONTROLLER_TEST_OBJS:.o=.dep) @@ -20891,16 +20868,16 @@ $(BINDIR)/$(CONFIG)/writes_per_rpc_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/writes_per_rpc_test: $(PROTOBUF_DEP) $(WRITES_PER_RPC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/writes_per_rpc_test: $(PROTOBUF_DEP) $(WRITES_PER_RPC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(WRITES_PER_RPC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/writes_per_rpc_test + $(Q) $(LDXX) $(LDFLAGS) $(WRITES_PER_RPC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/writes_per_rpc_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/performance/writes_per_rpc_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/performance/writes_per_rpc_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_writes_per_rpc_test: $(WRITES_PER_RPC_TEST_OBJS:.o=.dep) @@ -23089,12 +23066,12 @@ BADREQ_BAD_CLIENT_TEST_SRC = \ BADREQ_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BADREQ_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/badreq_bad_client_test: $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/badreq_bad_client_test: $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/badreq_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/badreq_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/badreq.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/badreq.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_badreq_bad_client_test: $(BADREQ_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23109,12 +23086,12 @@ CONNECTION_PREFIX_BAD_CLIENT_TEST_SRC = \ CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CONNECTION_PREFIX_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test: $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test: $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/connection_prefix.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/connection_prefix.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_connection_prefix_bad_client_test: $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23129,12 +23106,12 @@ DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC = \ DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/duplicate_header.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/duplicate_header.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23149,12 +23126,12 @@ HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC = \ HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/head_of_line_blocking.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/head_of_line_blocking.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23169,12 +23146,12 @@ HEADERS_BAD_CLIENT_TEST_SRC = \ HEADERS_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HEADERS_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/headers_bad_client_test: $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/headers_bad_client_test: $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/headers_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/headers_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/headers.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/headers.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_headers_bad_client_test: $(HEADERS_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23189,12 +23166,12 @@ INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_SRC = \ INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test: $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test: $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/initial_settings_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/initial_settings_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_initial_settings_frame_bad_client_test: $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23209,12 +23186,12 @@ LARGE_METADATA_BAD_CLIENT_TEST_SRC = \ LARGE_METADATA_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LARGE_METADATA_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test: $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test: $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/large_metadata.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/large_metadata.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_large_metadata_bad_client_test: $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23229,12 +23206,12 @@ SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_SRC = \ SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test: $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test: $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/server_registered_method.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/server_registered_method.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_registered_method_bad_client_test: $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23249,12 +23226,12 @@ SIMPLE_REQUEST_BAD_CLIENT_TEST_SRC = \ SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SIMPLE_REQUEST_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/simple_request_bad_client_test: $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/simple_request_bad_client_test: $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/simple_request_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/simple_request_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/simple_request.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/simple_request.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_simple_request_bad_client_test: $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23269,12 +23246,12 @@ UNKNOWN_FRAME_BAD_CLIENT_TEST_SRC = \ UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(UNKNOWN_FRAME_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test: $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test: $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/unknown_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/unknown_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_unknown_frame_bad_client_test: $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23289,12 +23266,12 @@ WINDOW_OVERFLOW_BAD_CLIENT_TEST_SRC = \ WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test: $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test: $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/window_overflow.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/window_overflow.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_window_overflow_bad_client_test: $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23317,14 +23294,14 @@ else -$(BINDIR)/$(CONFIG)/bad_ssl_cert_server: $(BAD_SSL_CERT_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bad_ssl_cert_server: $(BAD_SSL_CERT_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(BAD_SSL_CERT_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_cert_server + $(Q) $(LD) $(LDFLAGS) $(BAD_SSL_CERT_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_cert_server endif -$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/servers/cert.o: $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/servers/cert.o: $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bad_ssl_cert_server: $(BAD_SSL_CERT_SERVER_OBJS:.o=.dep) @@ -23349,14 +23326,14 @@ else -$(BINDIR)/$(CONFIG)/bad_ssl_cert_test: $(BAD_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bad_ssl_cert_test: $(BAD_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(BAD_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_cert_test + $(Q) $(LD) $(LDFLAGS) $(BAD_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_cert_test endif -$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/bad_ssl_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/bad_ssl_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bad_ssl_cert_test: $(BAD_SSL_CERT_TEST_OBJS:.o=.dep) @@ -23381,14 +23358,14 @@ else -$(BINDIR)/$(CONFIG)/h2_census_test: $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_census_test: $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_census_test + $(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_census_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_census_test: $(H2_CENSUS_TEST_OBJS:.o=.dep) @@ -23413,14 +23390,14 @@ else -$(BINDIR)/$(CONFIG)/h2_compress_test: $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_compress_test: $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_compress_test + $(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_compress_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_compress_test: $(H2_COMPRESS_TEST_OBJS:.o=.dep) @@ -23445,14 +23422,14 @@ else -$(BINDIR)/$(CONFIG)/h2_fakesec_test: $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_fakesec_test: $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_fakesec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_fakesec_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fakesec.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fakesec.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_fakesec_test: $(H2_FAKESEC_TEST_OBJS:.o=.dep) @@ -23477,14 +23454,14 @@ else -$(BINDIR)/$(CONFIG)/h2_fd_test: $(H2_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_fd_test: $(H2_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_fd_test + $(Q) $(LD) $(LDFLAGS) $(H2_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_fd_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_fd_test: $(H2_FD_TEST_OBJS:.o=.dep) @@ -23509,14 +23486,14 @@ else -$(BINDIR)/$(CONFIG)/h2_full_test: $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full_test: $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full_test: $(H2_FULL_TEST_OBJS:.o=.dep) @@ -23541,14 +23518,14 @@ else -$(BINDIR)/$(CONFIG)/h2_full+pipe_test: $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+pipe_test: $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+pipe_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+pipe_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+pipe_test: $(H2_FULL+PIPE_TEST_OBJS:.o=.dep) @@ -23573,14 +23550,14 @@ else -$(BINDIR)/$(CONFIG)/h2_full+trace_test: $(H2_FULL+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+trace_test: $(H2_FULL+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+trace_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+trace_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+trace_test: $(H2_FULL+TRACE_TEST_OBJS:.o=.dep) @@ -23605,14 +23582,14 @@ else -$(BINDIR)/$(CONFIG)/h2_full+workarounds_test: $(H2_FULL+WORKAROUNDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+workarounds_test: $(H2_FULL+WORKAROUNDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+WORKAROUNDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+workarounds_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+WORKAROUNDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+workarounds_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+workarounds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+workarounds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+workarounds_test: $(H2_FULL+WORKAROUNDS_TEST_OBJS:.o=.dep) @@ -23637,14 +23614,14 @@ else -$(BINDIR)/$(CONFIG)/h2_http_proxy_test: $(H2_HTTP_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_http_proxy_test: $(H2_HTTP_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_http_proxy_test + $(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_http_proxy_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_http_proxy_test: $(H2_HTTP_PROXY_TEST_OBJS:.o=.dep) @@ -23669,14 +23646,14 @@ else -$(BINDIR)/$(CONFIG)/h2_local_test: $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_local_test: $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_test + $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_local_test: $(H2_LOCAL_TEST_OBJS:.o=.dep) @@ -23701,14 +23678,14 @@ else -$(BINDIR)/$(CONFIG)/h2_oauth2_test: $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_oauth2_test: $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_oauth2_test + $(Q) $(LD) $(LDFLAGS) $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_oauth2_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_oauth2.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_oauth2.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_oauth2_test: $(H2_OAUTH2_TEST_OBJS:.o=.dep) @@ -23733,14 +23710,14 @@ else -$(BINDIR)/$(CONFIG)/h2_proxy_test: $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_proxy_test: $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_proxy_test + $(Q) $(LD) $(LDFLAGS) $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_proxy_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_proxy_test: $(H2_PROXY_TEST_OBJS:.o=.dep) @@ -23765,14 +23742,14 @@ else -$(BINDIR)/$(CONFIG)/h2_sockpair_test: $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair_test: $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair_test: $(H2_SOCKPAIR_TEST_OBJS:.o=.dep) @@ -23797,14 +23774,14 @@ else -$(BINDIR)/$(CONFIG)/h2_sockpair+trace_test: $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair+trace_test: $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair+trace_test: $(H2_SOCKPAIR+TRACE_TEST_OBJS:.o=.dep) @@ -23829,14 +23806,14 @@ else -$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test: $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test: $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair_1byte_test: $(H2_SOCKPAIR_1BYTE_TEST_OBJS:.o=.dep) @@ -23861,14 +23838,14 @@ else -$(BINDIR)/$(CONFIG)/h2_ssl_test: $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_ssl_test: $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_test + $(Q) $(LD) $(LDFLAGS) $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_ssl_test: $(H2_SSL_TEST_OBJS:.o=.dep) @@ -23893,14 +23870,14 @@ else -$(BINDIR)/$(CONFIG)/h2_ssl_proxy_test: $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_ssl_proxy_test: $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test + $(Q) $(LD) $(LDFLAGS) $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_ssl_proxy_test: $(H2_SSL_PROXY_TEST_OBJS:.o=.dep) @@ -23925,14 +23902,14 @@ else -$(BINDIR)/$(CONFIG)/h2_uds_test: $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_uds_test: $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uds_test + $(Q) $(LD) $(LDFLAGS) $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uds_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_uds_test: $(H2_UDS_TEST_OBJS:.o=.dep) @@ -23957,14 +23934,14 @@ else -$(BINDIR)/$(CONFIG)/inproc_test: $(INPROC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/inproc_test: $(INPROC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INPROC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/inproc_test + $(Q) $(LD) $(LDFLAGS) $(INPROC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/inproc_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/inproc.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/inproc.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_inproc_test: $(INPROC_TEST_OBJS:.o=.dep) @@ -23981,12 +23958,12 @@ H2_CENSUS_NOSEC_TEST_SRC = \ H2_CENSUS_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_CENSUS_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_census_nosec_test: $(H2_CENSUS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_census_nosec_test: $(H2_CENSUS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_census_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_census_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_census_nosec_test: $(H2_CENSUS_NOSEC_TEST_OBJS:.o=.dep) @@ -24001,12 +23978,12 @@ H2_COMPRESS_NOSEC_TEST_SRC = \ H2_COMPRESS_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_COMPRESS_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_compress_nosec_test: $(H2_COMPRESS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_compress_nosec_test: $(H2_COMPRESS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_compress_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_compress_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_compress_nosec_test: $(H2_COMPRESS_NOSEC_TEST_OBJS:.o=.dep) @@ -24021,12 +23998,12 @@ H2_FD_NOSEC_TEST_SRC = \ H2_FD_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FD_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_fd_nosec_test: $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_fd_nosec_test: $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_fd_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_fd_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_fd_nosec_test: $(H2_FD_NOSEC_TEST_OBJS:.o=.dep) @@ -24041,12 +24018,12 @@ H2_FULL_NOSEC_TEST_SRC = \ H2_FULL_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_full_nosec_test: $(H2_FULL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full_nosec_test: $(H2_FULL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full_nosec_test: $(H2_FULL_NOSEC_TEST_OBJS:.o=.dep) @@ -24061,12 +24038,12 @@ H2_FULL+PIPE_NOSEC_TEST_SRC = \ H2_FULL+PIPE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL+PIPE_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test: $(H2_FULL+PIPE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test: $(H2_FULL+PIPE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+pipe_nosec_test: $(H2_FULL+PIPE_NOSEC_TEST_OBJS:.o=.dep) @@ -24081,12 +24058,12 @@ H2_FULL+TRACE_NOSEC_TEST_SRC = \ H2_FULL+TRACE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL+TRACE_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test: $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test: $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+trace_nosec_test: $(H2_FULL+TRACE_NOSEC_TEST_OBJS:.o=.dep) @@ -24101,12 +24078,12 @@ H2_FULL+WORKAROUNDS_NOSEC_TEST_SRC = \ H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL+WORKAROUNDS_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test: $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test: $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+workarounds.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+workarounds.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+workarounds_nosec_test: $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS:.o=.dep) @@ -24121,12 +24098,12 @@ H2_HTTP_PROXY_NOSEC_TEST_SRC = \ H2_HTTP_PROXY_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_HTTP_PROXY_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test: $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test: $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_http_proxy_nosec_test: $(H2_HTTP_PROXY_NOSEC_TEST_OBJS:.o=.dep) @@ -24141,12 +24118,12 @@ H2_PROXY_NOSEC_TEST_SRC = \ H2_PROXY_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_PROXY_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_proxy_nosec_test: $(H2_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_proxy_nosec_test: $(H2_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_proxy_nosec_test: $(H2_PROXY_NOSEC_TEST_OBJS:.o=.dep) @@ -24161,12 +24138,12 @@ H2_SOCKPAIR_NOSEC_TEST_SRC = \ H2_SOCKPAIR_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SOCKPAIR_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test: $(H2_SOCKPAIR_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test: $(H2_SOCKPAIR_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair_nosec_test: $(H2_SOCKPAIR_NOSEC_TEST_OBJS:.o=.dep) @@ -24181,12 +24158,12 @@ H2_SOCKPAIR+TRACE_NOSEC_TEST_SRC = \ H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SOCKPAIR+TRACE_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test: $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test: $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair+trace_nosec_test: $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS:.o=.dep) @@ -24201,12 +24178,12 @@ H2_SOCKPAIR_1BYTE_NOSEC_TEST_SRC = \ H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test: $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test: $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair_1byte_nosec_test: $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS:.o=.dep) @@ -24221,12 +24198,12 @@ H2_UDS_NOSEC_TEST_SRC = \ H2_UDS_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_UDS_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_uds_nosec_test: $(H2_UDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_uds_nosec_test: $(H2_UDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_UDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_uds_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_UDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_uds_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_uds_nosec_test: $(H2_UDS_NOSEC_TEST_OBJS:.o=.dep) @@ -24258,16 +24235,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_resolver_component_test_unsecure: $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS:.o=.dep) @@ -24301,16 +24278,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/resolver_component_test: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_test: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_test + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_resolver_component_test: $(RESOLVER_COMPONENT_TEST_OBJS:.o=.dep) @@ -24344,16 +24321,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure: protobuf_d else -$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_tests_runner_invoker.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_tests_runner_invoker.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_resolver_component_tests_runner_invoker_unsecure: $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS:.o=.dep) @@ -24387,16 +24364,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_tests_runner_invoker.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_tests_runner_invoker.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_resolver_component_tests_runner_invoker: $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS:.o=.dep) @@ -24430,16 +24407,16 @@ $(BINDIR)/$(CONFIG)/address_sorting_test_unsecure: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/address_sorting_test_unsecure: $(PROTOBUF_DEP) $(ADDRESS_SORTING_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/address_sorting_test_unsecure: $(PROTOBUF_DEP) $(ADDRESS_SORTING_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ADDRESS_SORTING_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/address_sorting_test_unsecure + $(Q) $(LDXX) $(LDFLAGS) $(ADDRESS_SORTING_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/address_sorting_test_unsecure endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/address_sorting_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/address_sorting_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_address_sorting_test_unsecure: $(ADDRESS_SORTING_TEST_UNSECURE_OBJS:.o=.dep) @@ -24473,16 +24450,16 @@ $(BINDIR)/$(CONFIG)/address_sorting_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/address_sorting_test: $(PROTOBUF_DEP) $(ADDRESS_SORTING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/address_sorting_test: $(PROTOBUF_DEP) $(ADDRESS_SORTING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ADDRESS_SORTING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/address_sorting_test + $(Q) $(LDXX) $(LDFLAGS) $(ADDRESS_SORTING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/address_sorting_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/address_sorting_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/address_sorting_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_address_sorting_test: $(ADDRESS_SORTING_TEST_OBJS:.o=.dep) @@ -24516,16 +24493,16 @@ $(BINDIR)/$(CONFIG)/cancel_ares_query_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cancel_ares_query_test: $(PROTOBUF_DEP) $(CANCEL_ARES_QUERY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/cancel_ares_query_test: $(PROTOBUF_DEP) $(CANCEL_ARES_QUERY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CANCEL_ARES_QUERY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cancel_ares_query_test + $(Q) $(LDXX) $(LDFLAGS) $(CANCEL_ARES_QUERY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cancel_ares_query_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/cancel_ares_query_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/cancel_ares_query_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_cancel_ares_query_test: $(CANCEL_ARES_QUERY_TEST_OBJS:.o=.dep) @@ -24551,16 +24528,16 @@ else -$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry: $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry: $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/security/alts_credentials_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/alts_credentials_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_alts_credentials_fuzzer_one_entry: $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24586,16 +24563,16 @@ else -$(BINDIR)/$(CONFIG)/api_fuzzer_one_entry: $(API_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/api_fuzzer_one_entry: $(API_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(API_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/api_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(API_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/api_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/api_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/api_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_api_fuzzer_one_entry: $(API_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24621,16 +24598,16 @@ else -$(BINDIR)/$(CONFIG)/client_fuzzer_one_entry: $(CLIENT_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_fuzzer_one_entry: $(CLIENT_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CLIENT_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/client_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(CLIENT_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/client_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/client_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/client_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_fuzzer_one_entry: $(CLIENT_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24656,16 +24633,16 @@ else -$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry: $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry: $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hpack_parser_fuzzer_test_one_entry: $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24691,16 +24668,16 @@ else -$(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry: $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry: $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/http/request_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/request_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_request_fuzzer_test_one_entry: $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24726,16 +24703,16 @@ else -$(BINDIR)/$(CONFIG)/http_response_fuzzer_test_one_entry: $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_response_fuzzer_test_one_entry: $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_response_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_response_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/http/response_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/response_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_response_fuzzer_test_one_entry: $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24761,16 +24738,16 @@ else -$(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry: $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry: $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/json/fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/json/fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_fuzzer_test_one_entry: $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24796,16 +24773,16 @@ else -$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry: $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry: $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_response.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_response.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nanopb_fuzzer_response_test_one_entry: $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24831,16 +24808,16 @@ else -$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry: $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry: $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_serverlist.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_serverlist.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nanopb_fuzzer_serverlist_test_one_entry: $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24866,16 +24843,16 @@ else -$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24901,16 +24878,16 @@ else -$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24936,16 +24913,16 @@ else -$(BINDIR)/$(CONFIG)/server_fuzzer_one_entry: $(SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_fuzzer_one_entry: $(SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_fuzzer_one_entry: $(SERVER_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24971,16 +24948,16 @@ else -$(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -25006,16 +24983,16 @@ else -$(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry: $(URI_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry: $(URI_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(URI_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(URI_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_uri_fuzzer_test_one_entry: $(URI_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) diff --git a/build.yaml b/build.yaml index 1e63933f555..74506219d6c 100644 --- a/build.yaml +++ b/build.yaml @@ -913,6 +913,7 @@ filegroups: - test/core/util/port_server_client.h - test/core/util/slice_splitter.h - test/core/util/subprocess.h + - test/core/util/test_config.h - test/core/util/tracer_util.h - test/core/util/trickle_endpoint.h src: @@ -935,10 +936,10 @@ filegroups: - test/core/util/slice_splitter.cc - test/core/util/subprocess_posix.cc - test/core/util/subprocess_windows.cc + - test/core/util/test_config.cc - test/core/util/tracer_util.cc - test/core/util/trickle_endpoint.cc deps: - - gpr_test_util - gpr uses: - cmdline @@ -1499,16 +1500,6 @@ libs: filegroups: - gpr_base secure: false -- name: gpr_test_util - build: private - language: c - headers: - - test/core/util/test_config.h - src: - - test/core/util/test_config.cc - deps: - - gpr - secure: false - name: grpc build: all language: c @@ -1571,7 +1562,6 @@ libs: - test/core/end2end/data/test_root_cert.cc - test/core/security/oauth2_utils.cc deps: - - gpr_test_util - gpr - grpc filegroups: @@ -1581,7 +1571,6 @@ libs: language: c deps: - gpr - - gpr_test_util - grpc_unsecure filegroups: - grpc_test_util_base @@ -1628,7 +1617,6 @@ libs: - test_tcp_server - grpc_test_util - grpc - - gpr_test_util - gpr - name: test_tcp_server build: private @@ -1640,7 +1628,6 @@ libs: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc++ build: all @@ -1965,7 +1952,6 @@ libs: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: interop_server_helper @@ -1995,7 +1981,6 @@ libs: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: interop_server_main @@ -2068,7 +2053,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: alloc_test @@ -2077,8 +2061,9 @@ targets: src: - test/core/gpr/alloc_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: alpn_test build: test @@ -2088,7 +2073,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: alts_credentials_fuzzer build: fuzzer @@ -2098,7 +2082,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/security/corpus/alts_credentials_corpus @@ -2111,7 +2094,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/end2end/fuzzers/api_fuzzer_corpus @@ -2124,8 +2106,9 @@ targets: src: - test/core/gpr/arena_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: avl_test build: test @@ -2133,8 +2116,8 @@ targets: src: - test/core/avl/avl_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util - grpc uses_polling: false - name: bad_server_response_test @@ -2146,7 +2129,6 @@ targets: - test_tcp_server - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2176,7 +2158,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2190,7 +2171,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: check_epollexclusive build: tool @@ -2208,7 +2188,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: chttp2_stream_map_test @@ -2219,7 +2198,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: chttp2_varint_test @@ -2230,7 +2208,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: client_fuzzer @@ -2241,7 +2218,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/end2end/fuzzers/client_fuzzer_corpus @@ -2254,8 +2230,8 @@ targets: - test/core/util/cmdline_test.cc deps: - gpr - - gpr_test_util - grpc_test_util + - grpc uses_polling: false - name: combiner_test cpu_cost: 10 @@ -2266,7 +2242,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: compression_test build: test @@ -2276,7 +2251,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: concurrent_connectivity_test @@ -2288,7 +2262,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2301,7 +2274,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: dns_resolver_connectivity_test cpu_cost: 0.1 @@ -2312,7 +2284,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2324,7 +2295,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: dns_resolver_test build: test @@ -2334,7 +2304,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: dualstack_socket_test cpu_cost: 0.1 @@ -2345,7 +2314,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2361,7 +2329,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2374,7 +2341,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: ev_epollex_linux_test @@ -2386,7 +2352,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2400,7 +2365,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: fake_transport_security_test build: test @@ -2408,8 +2372,8 @@ targets: src: - test/core/tsi/fake_transport_security_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util - grpc filegroups: - transport_security_test_lib @@ -2425,7 +2389,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2441,7 +2404,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2458,7 +2420,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: fling_server build: test @@ -2469,7 +2430,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: fling_stream_test cpu_cost: 1.5 @@ -2480,7 +2440,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -2495,7 +2454,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -2507,8 +2465,9 @@ targets: src: - test/core/gprpp/fork_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure platforms: - mac - linux @@ -2522,7 +2481,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2537,8 +2495,9 @@ targets: src: - test/core/gpr/cpu_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_env_test build: test @@ -2546,8 +2505,9 @@ targets: src: - test/core/gpr/env_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_host_port_test build: test @@ -2555,8 +2515,9 @@ targets: src: - test/core/gpr/host_port_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_log_test build: test @@ -2564,8 +2525,9 @@ targets: src: - test/core/gpr/log_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_manual_constructor_test cpu_cost: 3 @@ -2574,8 +2536,9 @@ targets: src: - test/core/gprpp/manual_constructor_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_mpscq_test cpu_cost: 30 @@ -2584,8 +2547,9 @@ targets: src: - test/core/gpr/mpscq_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_spinlock_test cpu_cost: 3 @@ -2594,8 +2558,9 @@ targets: src: - test/core/gpr/spinlock_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_string_test build: test @@ -2603,8 +2568,9 @@ targets: src: - test/core/gpr/string_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_sync_test cpu_cost: 10 @@ -2613,8 +2579,9 @@ targets: src: - test/core/gpr/sync_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_thd_test cpu_cost: 10 @@ -2623,8 +2590,9 @@ targets: src: - test/core/gprpp/thd_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_time_test build: test @@ -2632,8 +2600,9 @@ targets: src: - test/core/gpr/time_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_tls_test build: test @@ -2641,8 +2610,9 @@ targets: src: - test/core/gpr/tls_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_useful_test build: test @@ -2650,8 +2620,9 @@ targets: src: - test/core/gpr/useful_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: grpc_auth_context_test build: test @@ -2661,7 +2632,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_b64_test @@ -2672,7 +2642,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_byte_buffer_reader_test @@ -2683,7 +2652,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_channel_args_test @@ -2694,7 +2662,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_channel_stack_builder_test @@ -2705,7 +2672,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_channel_stack_test build: test @@ -2715,7 +2681,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_completion_queue_test @@ -2726,7 +2691,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_completion_queue_threading_test build: test @@ -2736,7 +2700,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2760,7 +2723,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_fetch_oauth2 build: test @@ -2771,7 +2733,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_ipv6_loopback_available_test build: test @@ -2781,7 +2742,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2793,7 +2753,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - linux @@ -2808,7 +2767,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_print_google_default_creds_token @@ -2830,7 +2788,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_ssl_credentials_test build: test @@ -2840,7 +2797,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_verify_jwt build: tool @@ -2861,7 +2817,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2879,7 +2834,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2897,7 +2851,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2912,7 +2865,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2936,7 +2888,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/transport/chttp2/hpack_parser_corpus @@ -2950,7 +2901,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: hpack_table_test @@ -2961,7 +2911,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: http_parser_test @@ -2972,7 +2921,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: http_request_fuzzer_test @@ -2983,7 +2931,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/http/request_corpus @@ -2996,7 +2943,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/http/response_corpus @@ -3009,7 +2955,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: httpcli_test cpu_cost: 0.5 @@ -3020,7 +2965,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -3035,7 +2979,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - linux @@ -3047,7 +2990,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: inproc_callback_test @@ -3060,7 +3002,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: invalid_call_argument_test @@ -3072,7 +3013,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: json_fuzzer_test build: fuzzer @@ -3082,7 +3022,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/json/corpus @@ -3096,7 +3035,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: json_rewrite_test @@ -3107,7 +3045,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: json_stream_error_test @@ -3118,7 +3055,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: json_test @@ -3129,7 +3065,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: lame_client_test @@ -3140,7 +3075,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: load_file_test build: test @@ -3150,7 +3084,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: low_level_ping_pong_benchmark @@ -3161,7 +3094,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -3176,7 +3108,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: memory_usage_server @@ -3188,7 +3119,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: memory_usage_test cpu_cost: 1.5 @@ -3199,7 +3129,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -3213,7 +3142,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: minimal_stack_is_minimal_test @@ -3224,7 +3152,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: multiple_server_queues_test @@ -3235,7 +3162,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: murmur_hash_test build: test @@ -3243,8 +3169,9 @@ targets: src: - test/core/gpr/murmur_hash_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: nanopb_fuzzer_response_test build: fuzzer @@ -3254,7 +3181,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/nanopb/corpus_response @@ -3267,7 +3193,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/nanopb/corpus_serverlist @@ -3281,7 +3206,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: num_external_connectivity_watchers_test build: test @@ -3291,7 +3215,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3303,7 +3226,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: percent_decode_fuzzer @@ -3314,7 +3236,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/slice/percent_decode_corpus @@ -3327,7 +3248,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/slice/percent_encode_corpus @@ -3340,7 +3260,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: resolve_address_posix_test @@ -3351,7 +3270,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3367,7 +3285,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr args: - --resolver=ares @@ -3379,7 +3296,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr args: - --resolver=native @@ -3392,7 +3308,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: secure_channel_create_test build: test @@ -3402,7 +3317,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: secure_endpoint_test build: test @@ -3412,7 +3326,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3424,7 +3337,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3436,7 +3348,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: server_fuzzer build: fuzzer @@ -3446,7 +3357,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/end2end/fuzzers/server_fuzzer_corpus @@ -3460,7 +3370,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: slice_buffer_test build: test @@ -3470,7 +3379,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: slice_string_helpers_test @@ -3481,7 +3389,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: slice_test @@ -3492,7 +3399,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: sockaddr_resolver_test @@ -3503,7 +3409,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: sockaddr_utils_test build: test @@ -3513,7 +3418,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: socket_utils_test build: test @@ -3523,7 +3427,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3539,7 +3442,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/security/corpus/ssl_server_corpus @@ -3550,8 +3452,8 @@ targets: src: - test/core/tsi/ssl_transport_security_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util - grpc filegroups: - transport_security_test_lib @@ -3567,7 +3469,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: stream_compression_test @@ -3578,7 +3479,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: stream_owned_slice_test @@ -3589,7 +3489,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: tcp_client_posix_test @@ -3601,7 +3500,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3618,7 +3516,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - native @@ -3631,7 +3528,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3647,7 +3543,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3663,7 +3558,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - native @@ -3675,7 +3569,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: timeout_encoding_test @@ -3686,7 +3579,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: timer_heap_test @@ -3697,7 +3589,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3710,7 +3601,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3723,7 +3613,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: transport_metadata_test build: test @@ -3733,7 +3622,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: transport_security_test build: test @@ -3743,7 +3631,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - linux @@ -3757,7 +3644,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3773,7 +3659,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/client_channel/uri_corpus @@ -3786,7 +3671,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: wakeup_fd_cv_test build: test @@ -3796,7 +3680,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3815,7 +3698,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - name: alts_counter_test build: test @@ -3833,8 +3715,8 @@ targets: - test/core/tsi/alts/crypt/aes_gcm_test.cc deps: - alts_test_util - - gpr_test_util - gpr + - grpc_test_util - grpc - name: alts_crypter_test build: test @@ -3947,7 +3829,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: auth_property_iterator_test gtest: true @@ -3960,7 +3841,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses_polling: false - name: backoff_test @@ -3971,7 +3851,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: bdp_estimator_test @@ -3984,7 +3863,6 @@ targets: - grpc++ - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: bm_arena @@ -3999,7 +3877,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4021,7 +3898,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4043,7 +3919,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4065,7 +3940,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4087,7 +3961,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4108,7 +3981,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4129,7 +4001,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4150,7 +4021,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4172,7 +4042,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4196,7 +4065,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4223,7 +4091,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4248,7 +4115,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4277,7 +4143,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4302,7 +4167,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4324,7 +4188,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4342,7 +4205,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: channel_arguments_test @@ -4378,7 +4240,6 @@ targets: - grpc++_test_util - grpc++ - grpc - - gpr_test_util - gpr filegroups: - grpcpp_channelz_proto @@ -4395,7 +4256,6 @@ targets: - grpc++_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -4412,7 +4272,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr filegroups: - grpcpp_channelz_proto @@ -4427,7 +4286,6 @@ targets: - grpc++_test_util - grpc++ - grpc - - gpr_test_util - gpr filegroups: - grpcpp_channelz_proto @@ -4458,7 +4316,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: true - name: cli_call_test @@ -4473,7 +4330,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_callback_end2end_test gtest: true @@ -4487,7 +4343,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_channel_stress_test gtest: false @@ -4502,7 +4357,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_crash_test gtest: true @@ -4516,7 +4370,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr platforms: - mac @@ -4533,7 +4386,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_interceptors_end2end_test gtest: true @@ -4550,7 +4402,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_lb_end2end_test gtest: true @@ -4563,7 +4414,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: codegen_test_full gtest: true @@ -4616,7 +4466,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: credentials_test @@ -4639,7 +4488,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses_polling: false - name: cxx_slice_test @@ -4652,7 +4500,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses_polling: false - name: cxx_string_ref_test @@ -4675,7 +4522,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses_polling: false - name: end2end_test @@ -4693,7 +4539,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: error_details_test gtest: true @@ -4716,7 +4561,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: filter_end2end_test gtest: true @@ -4729,7 +4573,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: generic_end2end_test gtest: true @@ -4742,7 +4585,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: golden_file_test gtest: true @@ -4804,7 +4646,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_node_plugin build: protoc @@ -4862,7 +4703,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr filegroups: - grpc++_codegen_proto @@ -4890,7 +4730,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: h2_ssl_cert_test gtest: true @@ -4904,7 +4743,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -4920,7 +4758,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -4935,7 +4772,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: http2_client build: test @@ -4964,7 +4800,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: inlined_vector_test gtest: true @@ -4976,7 +4811,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -4992,7 +4826,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5011,7 +4844,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5031,7 +4863,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5047,7 +4878,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5065,7 +4895,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5082,7 +4911,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5115,7 +4943,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: nonblocking_test gtest: true @@ -5128,7 +4955,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: noop-benchmark build: test @@ -5148,7 +4974,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5165,7 +4990,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: proto_utils_test gtest: true @@ -5192,7 +5016,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5213,7 +5036,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: qps_openloop_test @@ -5229,7 +5051,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5252,7 +5073,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: raw_end2end_test @@ -5266,7 +5086,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: reconnect_interop_client build: test @@ -5282,7 +5101,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: reconnect_interop_server @@ -5301,7 +5119,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: ref_counted_ptr_test @@ -5314,7 +5131,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5328,7 +5144,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5341,7 +5156,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: secure_auth_context_test @@ -5355,7 +5169,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: secure_sync_unary_ping_pong_test build: test @@ -5369,7 +5182,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5387,7 +5199,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: server_builder_test gtest: true @@ -5400,7 +5211,6 @@ targets: deps: - grpc++_test_util_unsecure - grpc_test_util_unsecure - - gpr_test_util - grpc++_unsecure - grpc_unsecure - gpr @@ -5415,7 +5225,6 @@ targets: deps: - grpc++_test_util_unsecure - grpc_test_util_unsecure - - gpr_test_util - grpc++_unsecure - grpc_unsecure - gpr @@ -5431,7 +5240,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5447,7 +5255,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr platforms: - mac @@ -5464,7 +5271,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: server_early_return_test gtest: true @@ -5477,7 +5283,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: server_interceptors_end2end_test gtest: true @@ -5494,7 +5299,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: server_request_call_test gtest: true @@ -5507,7 +5311,6 @@ targets: deps: - grpc++_test_util_unsecure - grpc_test_util_unsecure - - gpr_test_util - grpc++_unsecure - grpc_unsecure - gpr @@ -5522,7 +5325,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: slice_hash_table_test gtest: true @@ -5533,7 +5335,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: slice_weak_hash_table_test @@ -5545,7 +5346,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: stats_test @@ -5558,7 +5358,6 @@ targets: - grpc++_test_util - grpc_test_util - grpc - - gpr_test_util - gpr exclude_configs: - tsan @@ -5594,7 +5393,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr platforms: - mac @@ -5624,7 +5422,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: thread_manager_test @@ -5649,7 +5446,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - name: transport_pid_controller_test build: test @@ -5661,7 +5457,6 @@ targets: - grpc++ - grpc_test_util - grpc - - gpr_test_util - gpr - name: transport_security_common_api_test build: test @@ -5684,7 +5479,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr platforms: - mac diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 1d4e1ae35c0..c875fcb4306 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1196,9 +1196,7 @@ Pod::Spec.new do |s| ss.dependency "#{s.name}/Interface", version ss.dependency "#{s.name}/Implementation", version - ss.source_files = 'test/core/util/test_config.cc', - 'test/core/util/test_config.h', - 'test/core/end2end/data/client_certs.cc', + ss.source_files = 'test/core/end2end/data/client_certs.cc', 'test/core/end2end/data/server1_cert.cc', 'test/core/end2end/data/server1_key.cc', 'test/core/end2end/data/test_root_cert.cc', @@ -1221,6 +1219,7 @@ Pod::Spec.new do |s| 'test/core/util/slice_splitter.cc', 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', + 'test/core/util/test_config.cc', 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -1245,6 +1244,7 @@ Pod::Spec.new do |s| 'test/core/util/port_server_client.h', 'test/core/util/slice_splitter.h', 'test/core/util/subprocess.h', + 'test/core/util/test_config.h', 'test/core/util/tracer_util.h', 'test/core/util/trickle_endpoint.h', 'test/core/util/cmdline.h', diff --git a/grpc.gyp b/grpc.gyp index 2b841354baf..d619f395bb4 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -258,16 +258,6 @@ 'src/core/lib/profiling/stap_timers.cc', ], }, - { - 'target_name': 'gpr_test_util', - 'type': 'static_library', - 'dependencies': [ - 'gpr', - ], - 'sources': [ - 'test/core/util/test_config.cc', - ], - }, { 'target_name': 'grpc', 'type': 'static_library', @@ -604,7 +594,6 @@ 'target_name': 'grpc_test_util', 'type': 'static_library', 'dependencies': [ - 'gpr_test_util', 'gpr', 'grpc', ], @@ -633,6 +622,7 @@ 'test/core/util/slice_splitter.cc', 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', + 'test/core/util/test_config.cc', 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -850,7 +840,6 @@ 'type': 'static_library', 'dependencies': [ 'gpr', - 'gpr_test_util', 'grpc_unsecure', ], 'sources': [ @@ -873,6 +862,7 @@ 'test/core/util/slice_splitter.cc', 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', + 'test/core/util/test_config.cc', 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -1351,7 +1341,6 @@ 'test_tcp_server', 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr', ], 'sources': [ @@ -1364,7 +1353,6 @@ 'dependencies': [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr', ], 'sources': [ @@ -1679,7 +1667,6 @@ 'grpc_test_util', 'grpc++', 'grpc', - 'gpr_test_util', 'gpr', 'grpc++_test_config', ], @@ -1714,7 +1701,6 @@ 'grpc_test_util', 'grpc++', 'grpc', - 'gpr_test_util', 'gpr', 'grpc++_test_config', ], @@ -2667,7 +2653,6 @@ 'dependencies': [ 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr', ], 'sources': [ @@ -2680,7 +2665,6 @@ 'dependencies': [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr', ], 'sources': [ @@ -2772,7 +2756,6 @@ 'dependencies': [ 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr', ], 'sources': [ diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 67cf5d89bff..aaa6939c90c 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -195,3 +195,7 @@ int grpc_is_initialized(void) { gpr_mu_unlock(&g_init_mu); return r; } + +void grpc_test_x(void) { + gpr_log(GPR_ERROR, "X"); +} diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index 193f51447d9..2b3e6a64e78 100644 --- a/src/core/lib/surface/init.h +++ b/src/core/lib/surface/init.h @@ -22,5 +22,6 @@ void grpc_register_security_filters(void); void grpc_security_pre_init(void); void grpc_security_init(void); +void grpc_test_x(void); #endif /* GRPC_CORE_LIB_SURFACE_INIT_H */ diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index 32afba5b1f5..6a40b4e5e9d 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -56,7 +56,6 @@ def main(): 'deps': [ 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr' ] }], @@ -74,7 +73,6 @@ def main(): 'bad_client_test', 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr' ] } diff --git a/test/core/bad_ssl/gen_build_yaml.py b/test/core/bad_ssl/gen_build_yaml.py index 6b78e9c7aa4..52f49bea2ad 100755 --- a/test/core/bad_ssl/gen_build_yaml.py +++ b/test/core/bad_ssl/gen_build_yaml.py @@ -45,7 +45,6 @@ def main(): 'deps': [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr' ] } @@ -63,7 +62,6 @@ def main(): 'bad_ssl_test_server', 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr' ] } @@ -79,7 +77,6 @@ def main(): 'deps': [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr' ] } diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 601d3bac387..99063e13e64 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -281,13 +281,11 @@ def main(): sec_deps = [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr' ] unsec_deps = [ 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr' ] json = { diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index fe80bb2d4d0..5db409343b8 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -31,6 +31,7 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/surface/init.h" int64_t g_fixture_slowdown_factor = 1; int64_t g_poller_slowdown_factor = 1; @@ -405,7 +406,7 @@ TestEnvironment::TestEnvironment(int argc, char** argv) { grpc_test_init(argc, argv); } -TestEnvironment::~TestEnvironment() {} +TestEnvironment::~TestEnvironment() { grpc_test_x(); } } // namespace testing } // namespace grpc diff --git a/test/cpp/naming/gen_build_yaml.py b/test/cpp/naming/gen_build_yaml.py index 1c9d0676b89..da0effed935 100755 --- a/test/cpp/naming/gen_build_yaml.py +++ b/test/cpp/naming/gen_build_yaml.py @@ -72,7 +72,6 @@ def main(): 'deps': [ 'grpc++_test_util' + unsecure_build_config_suffix, 'grpc_test_util' + unsecure_build_config_suffix, - 'gpr_test_util', 'grpc++' + unsecure_build_config_suffix, 'grpc' + unsecure_build_config_suffix, 'gpr', @@ -91,7 +90,6 @@ def main(): 'deps': [ 'grpc++_test_util', 'grpc_test_util', - 'gpr_test_util', 'grpc++', 'grpc', 'gpr', @@ -114,7 +112,6 @@ def main(): 'deps': [ 'grpc++_test_util' + unsecure_build_config_suffix, 'grpc_test_util' + unsecure_build_config_suffix, - 'gpr_test_util', 'grpc++' + unsecure_build_config_suffix, 'grpc' + unsecure_build_config_suffix, 'gpr', @@ -133,7 +130,6 @@ def main(): 'deps': [ 'grpc++_test_util', 'grpc_test_util', - 'gpr_test_util', 'grpc++', 'grpc', 'gpr', diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a7231554e3d..191b3872146 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -4,7 +4,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -21,7 +20,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -36,7 +36,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -53,7 +52,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -70,7 +68,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -87,7 +84,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -102,8 +100,8 @@ { "deps": [ "gpr", - "gpr_test_util", - "grpc" + "grpc", + "grpc_test_util" ], "headers": [], "is_filegroup": false, @@ -118,7 +116,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util", "test_tcp_server" @@ -166,7 +163,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -183,7 +179,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -215,7 +210,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -232,7 +226,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -249,7 +242,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -266,7 +258,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -283,7 +274,7 @@ { "deps": [ "gpr", - "gpr_test_util", + "grpc", "grpc_test_util" ], "headers": [], @@ -299,7 +290,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -316,7 +306,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -333,7 +322,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -350,7 +338,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -367,7 +354,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -384,7 +370,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -401,7 +386,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -418,7 +402,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -435,7 +418,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -452,7 +434,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -469,7 +450,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -486,7 +466,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -503,8 +482,8 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", + "grpc_test_util", "transport_security_test_lib" ], "headers": [], @@ -520,7 +499,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -537,7 +515,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -554,7 +531,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -571,7 +547,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -588,7 +563,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -605,7 +579,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -622,7 +595,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -637,7 +611,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -654,7 +627,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -669,7 +643,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -684,7 +659,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -699,7 +675,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -714,7 +691,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -729,7 +707,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -744,7 +723,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -759,7 +739,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -774,7 +755,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -789,7 +771,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -804,7 +787,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -819,7 +803,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -834,7 +819,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -849,7 +835,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -866,7 +851,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -883,7 +867,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -900,7 +883,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -917,7 +899,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -934,7 +915,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -951,7 +931,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -968,7 +947,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1001,7 +979,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1018,7 +995,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1035,7 +1011,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1052,7 +1027,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1069,7 +1043,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1102,7 +1075,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1119,7 +1091,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1152,7 +1123,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1169,7 +1139,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1190,7 +1159,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1211,7 +1179,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1243,7 +1210,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1260,7 +1226,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1277,7 +1242,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1294,7 +1258,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1311,7 +1274,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1328,7 +1290,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1345,7 +1306,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1362,7 +1322,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1379,7 +1338,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1396,7 +1354,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1413,7 +1370,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1433,7 +1389,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1450,7 +1405,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1467,7 +1421,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1484,7 +1437,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1501,7 +1453,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1518,7 +1469,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1535,7 +1485,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1552,7 +1501,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1569,7 +1517,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1586,7 +1533,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1603,7 +1549,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1620,7 +1565,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1637,7 +1581,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1654,7 +1597,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1671,7 +1613,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1688,7 +1629,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -1703,7 +1645,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1720,7 +1661,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1737,7 +1677,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1754,7 +1693,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1771,7 +1709,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1788,7 +1725,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1805,7 +1741,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1822,7 +1757,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1839,7 +1773,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1856,7 +1789,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1873,7 +1805,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1890,7 +1821,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1907,7 +1837,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1924,7 +1853,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1941,7 +1869,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1958,7 +1885,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1975,7 +1901,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1992,7 +1917,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2009,7 +1933,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2026,7 +1949,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2043,7 +1965,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2060,7 +1981,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2077,7 +1997,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2094,7 +2013,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2111,7 +2029,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2128,8 +2045,8 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", + "grpc_test_util", "transport_security_test_lib" ], "headers": [], @@ -2145,7 +2062,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2162,7 +2078,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2179,7 +2094,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2196,7 +2110,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2213,7 +2126,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2230,7 +2142,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2247,7 +2158,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2264,7 +2174,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2281,7 +2190,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2298,7 +2206,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2315,7 +2222,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2332,7 +2238,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2349,7 +2254,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2366,7 +2270,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2383,7 +2286,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2400,7 +2302,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2417,7 +2318,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2434,7 +2334,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2451,7 +2350,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2468,7 +2366,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -2504,8 +2401,8 @@ "deps": [ "alts_test_util", "gpr", - "gpr_test_util", - "grpc" + "grpc", + "grpc_test_util" ], "headers": [], "is_filegroup": false, @@ -2696,7 +2593,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -2715,7 +2611,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -2734,7 +2629,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2751,7 +2645,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -2771,7 +2664,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2793,7 +2685,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2815,7 +2706,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2837,7 +2727,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2859,7 +2748,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2881,7 +2769,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2903,7 +2790,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2925,7 +2811,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2947,7 +2832,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2969,7 +2853,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2994,7 +2877,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3019,7 +2901,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3041,7 +2922,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3066,7 +2946,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3088,7 +2967,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3109,7 +2987,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -3158,7 +3035,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3179,7 +3055,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3199,7 +3074,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3220,7 +3094,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3271,7 +3144,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -3288,7 +3160,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3308,7 +3179,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3327,7 +3197,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3350,7 +3219,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3369,7 +3237,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3388,7 +3255,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3411,7 +3277,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3510,7 +3375,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -3543,7 +3407,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc_test_util" @@ -3561,7 +3424,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc_test_util" @@ -3594,7 +3456,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc_test_util" @@ -3612,7 +3473,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3654,7 +3514,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3673,7 +3532,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3692,7 +3550,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3793,7 +3650,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -3880,7 +3736,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_codegen_proto", @@ -3931,7 +3786,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3954,7 +3808,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3976,7 +3829,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3998,7 +3850,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4034,7 +3885,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4053,7 +3903,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4072,7 +3921,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4094,7 +3942,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4114,7 +3961,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4135,7 +3981,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++_test_config", "grpc_test_util" @@ -4153,7 +3998,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4173,7 +4017,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4215,7 +4058,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4239,7 +4081,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4272,7 +4113,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4291,7 +4131,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_proto_reflection_desc_db", @@ -4329,7 +4168,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4350,7 +4188,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4372,7 +4209,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4394,7 +4230,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4421,7 +4256,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4440,7 +4274,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4470,7 +4303,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4502,7 +4334,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4521,7 +4352,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4540,7 +4370,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -4557,7 +4386,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4576,7 +4404,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4598,7 +4425,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4617,7 +4443,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -4643,7 +4468,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -4669,7 +4493,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4688,7 +4511,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4707,7 +4529,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4726,7 +4547,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4745,7 +4565,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4768,7 +4587,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -4794,7 +4612,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4813,7 +4630,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -4830,7 +4646,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -4847,7 +4662,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++_test_util", "grpc_test_util" @@ -4893,7 +4707,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4912,7 +4725,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4975,7 +4787,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -4994,7 +4805,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -5029,7 +4839,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -5817,7 +5626,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5835,7 +5643,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5853,7 +5660,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5871,7 +5677,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5889,7 +5694,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5907,7 +5711,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5925,7 +5728,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5943,7 +5745,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5961,7 +5762,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5979,7 +5779,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5997,7 +5796,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6015,7 +5813,6 @@ "deps": [ "bad_ssl_test_server", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6032,7 +5829,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6050,7 +5846,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6068,7 +5863,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6086,7 +5880,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6104,7 +5897,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6122,7 +5914,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6140,7 +5931,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6158,7 +5948,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6176,7 +5965,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6194,7 +5982,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6212,7 +5999,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6230,7 +6016,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6248,7 +6033,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6266,7 +6050,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6284,7 +6067,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6302,7 +6084,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6320,7 +6101,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6338,7 +6118,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6356,7 +6135,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6374,7 +6152,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6392,7 +6169,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6410,7 +6186,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6428,7 +6203,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6446,7 +6220,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6464,7 +6237,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6482,7 +6254,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6500,7 +6271,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6518,7 +6288,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6536,7 +6305,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6554,7 +6322,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6572,7 +6339,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6590,7 +6356,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6608,7 +6373,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6625,7 +6389,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -6645,7 +6408,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6665,7 +6427,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6685,7 +6446,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6705,7 +6465,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -6725,7 +6484,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6745,7 +6503,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6765,7 +6522,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6783,7 +6539,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6801,7 +6556,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6819,7 +6573,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6837,7 +6590,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6855,7 +6607,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6873,7 +6624,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6891,7 +6641,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6909,7 +6658,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6927,7 +6675,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6945,7 +6692,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6963,7 +6709,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6981,7 +6726,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6999,7 +6743,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -7069,23 +6812,6 @@ "third_party": false, "type": "lib" }, - { - "deps": [ - "gpr" - ], - "headers": [ - "test/core/util/test_config.h" - ], - "is_filegroup": false, - "language": "c", - "name": "gpr_test_util", - "src": [ - "test/core/util/test_config.cc", - "test/core/util/test_config.h" - ], - "third_party": false, - "type": "lib" - }, { "deps": [ "census", @@ -7142,7 +6868,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util_base" ], @@ -7168,7 +6893,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc_test_util_base", "grpc_unsecure" ], @@ -7217,7 +6941,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util", "test_tcp_server" @@ -7238,7 +6961,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -7745,7 +7467,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -7800,7 +7521,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -8887,7 +8607,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -8907,7 +8626,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -8927,7 +8645,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -9028,7 +8745,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -10644,7 +10360,6 @@ "deps": [ "cmdline", "gpr", - "gpr_test_util", "grpc_base", "grpc_client_channel", "grpc_transport_chttp2" @@ -10667,6 +10382,7 @@ "test/core/util/port_server_client.h", "test/core/util/slice_splitter.h", "test/core/util/subprocess.h", + "test/core/util/test_config.h", "test/core/util/tracer_util.h", "test/core/util/trickle_endpoint.h" ], @@ -10710,6 +10426,8 @@ "test/core/util/subprocess.h", "test/core/util/subprocess_posix.cc", "test/core/util/subprocess_windows.cc", + "test/core/util/test_config.cc", + "test/core/util/test_config.h", "test/core/util/tracer_util.cc", "test/core/util/tracer_util.h", "test/core/util/trickle_endpoint.cc", From 88045f8440610676daa9cf429ba0cf55b4041bc5 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 6 Dec 2018 13:43:46 -0800 Subject: [PATCH 233/534] podsec fix --- templates/gRPC-C++.podspec.template | 4 ++-- templates/gRPC-Core.podspec.template | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template index ab330415af2..a3336f50e64 100644 --- a/templates/gRPC-C++.podspec.template +++ b/templates/gRPC-C++.podspec.template @@ -96,11 +96,11 @@ return out def grpc_test_util_files(libs): - out = grpc_lib_files(libs, ("grpc_test_util", "gpr_test_util"), ("src", "headers")) + out = grpc_lib_files(libs, ("grpc_test_util",), ("src", "headers")) return out def grpc_test_util_headers(libs): - out = grpc_lib_files(libs, ("grpc_test_util", "gpr_test_util"), ("headers",)) + out = grpc_lib_files(libs, ("grpc_test_util",), ("headers",)) return out # Tests subspec is currently disabled since the tests currently use `grpc++` include style instead of `grpcpp`. diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 98b6344a4bf..461e8b767ff 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -59,7 +59,7 @@ return [file for file in out if not file in excl] def grpc_test_util_files(libs): - out = grpc_lib_files(libs, ("grpc_test_util", "gpr_test_util"), ("src", "headers")) + out = grpc_lib_files(libs, ("grpc_test_util",), ("src", "headers")) excl = grpc_private_files(libs) return [file for file in out if not file in excl] From 67742ef63fd13630461abb1287298e8f262276bb Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 6 Dec 2018 14:05:38 -0800 Subject: [PATCH 234/534] Fix BUILD files. Manually edit bzl files --- test/core/avl/BUILD | 2 +- test/core/backoff/BUILD | 1 - test/core/channel/BUILD | 33 ++++++--------- test/core/client_channel/BUILD | 1 - test/core/client_channel/resolvers/BUILD | 5 --- test/core/compression/BUILD | 4 -- test/core/debug/BUILD | 1 - test/core/end2end/BUILD | 9 ---- test/core/end2end/generate_tests.bzl | 2 - test/core/fling/BUILD | 4 -- test/core/gpr/BUILD | 28 ++++++------- test/core/gprpp/BUILD | 16 +++---- test/core/handshake/BUILD | 16 +++---- test/core/http/BUILD | 16 +++---- test/core/iomgr/BUILD | 24 ----------- test/core/json/BUILD | 8 +--- test/core/memory_usage/BUILD | 11 ++--- test/core/network_benchmarks/BUILD | 9 ++-- test/core/security/BUILD | 27 ++++-------- test/core/slice/BUILD | 7 ---- test/core/surface/BUILD | 13 ------ test/core/transport/BUILD | 34 ++++++--------- test/core/transport/chttp2/BUILD | 17 ++------ test/core/tsi/BUILD | 22 +++++----- test/core/tsi/alts/crypt/BUILD | 10 +++-- test/core/tsi/alts/fake_handshaker/BUILD | 7 +++- test/core/tsi/alts/frame_protector/BUILD | 12 +++--- test/core/tsi/alts/handshaker/BUILD | 23 +++++----- .../tsi/alts/zero_copy_frame_protector/BUILD | 8 ++-- test/core/util/BUILD | 34 ++++++--------- test/cpp/client/BUILD | 3 +- test/cpp/codegen/BUILD | 42 +++++++++---------- test/cpp/common/BUILD | 40 +++++++++--------- test/cpp/end2end/BUILD | 28 +------------ test/cpp/ext/filters/census/BUILD | 5 +-- test/cpp/grpclb/BUILD | 1 - test/cpp/interop/BUILD | 1 - test/cpp/microbenchmarks/BUILD | 2 +- test/cpp/naming/BUILD | 14 +++---- .../generate_resolver_component_tests.bzl | 3 -- test/cpp/qps/BUILD | 3 -- test/cpp/qps/qps_benchmark_script.bzl | 1 - test/cpp/server/BUILD | 18 ++++---- test/cpp/server/load_reporter/BUILD | 2 - test/cpp/test/BUILD | 1 - test/cpp/thread_manager/BUILD | 1 - test/cpp/util/BUILD | 14 +++---- 47 files changed, 208 insertions(+), 375 deletions(-) diff --git a/test/core/avl/BUILD b/test/core/avl/BUILD index 48f5baeb1a5..c31abebcbe5 100644 --- a/test/core/avl/BUILD +++ b/test/core/avl/BUILD @@ -25,6 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/backoff/BUILD b/test/core/backoff/BUILD index 6fbd6542d49..e4fc2871054 100644 --- a/test/core/backoff/BUILD +++ b/test/core/backoff/BUILD @@ -33,7 +33,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/channel/BUILD b/test/core/channel/BUILD index da419f00cf9..3249a16edda 100644 --- a/test/core/channel/BUILD +++ b/test/core/channel/BUILD @@ -25,7 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,7 +36,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +47,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +58,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -69,62 +65,59 @@ grpc_cc_test( grpc_cc_test( name = "channel_trace_test", srcs = ["channel_trace_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:channel_trace_proto_helper", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "channelz_test", srcs = ["channelz_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:channel_trace_proto_helper", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "channelz_registry_test", srcs = ["channelz_registry_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "status_util_test", srcs = ["status_util_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:grpc", - "//test/core/util:gpr_test_util", - ], - external_deps = [ - "gtest", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD index db98ffab77b..04485f5240f 100644 --- a/test/core/client_channel/BUILD +++ b/test/core/client_channel/BUILD @@ -64,7 +64,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/client_channel/resolvers/BUILD b/test/core/client_channel/resolvers/BUILD index d8b03958461..3dbee5c9e6d 100644 --- a/test/core/client_channel/resolvers/BUILD +++ b/test/core/client_channel/resolvers/BUILD @@ -25,7 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,7 +36,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +47,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +58,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -74,7 +70,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc_resolver_fake", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/compression/BUILD b/test/core/compression/BUILD index 532972c784e..03c82689a85 100644 --- a/test/core/compression/BUILD +++ b/test/core/compression/BUILD @@ -25,7 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,7 +36,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +47,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +58,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/debug/BUILD b/test/core/debug/BUILD index 1592472532b..c4209296702 100644 --- a/test/core/debug/BUILD +++ b/test/core/debug/BUILD @@ -28,7 +28,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index 398e8a2d9ad..1b4ad284994 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -78,7 +78,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -91,7 +90,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -104,7 +102,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -117,7 +114,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -130,7 +126,6 @@ grpc_cc_test( ":end2end_tests", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -143,7 +138,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -156,7 +150,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -169,7 +162,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -190,7 +182,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 81956db841f..dd9abedebdf 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -388,7 +388,6 @@ def grpc_end2end_tests(): ":end2end_tests", "//test/core/util:grpc_test_util", "//:grpc", - "//test/core/util:gpr_test_util", "//:gpr", ], ) @@ -440,7 +439,6 @@ def grpc_end2end_nosec_tests(): ":end2end_nosec_tests", "//test/core/util:grpc_test_util_unsecure", "//:grpc_unsecure", - "//test/core/util:gpr_test_util", "//:gpr", ], ) diff --git a/test/core/fling/BUILD b/test/core/fling/BUILD index 268e94aacc1..5c6930cc85b 100644 --- a/test/core/fling/BUILD +++ b/test/core/fling/BUILD @@ -29,7 +29,6 @@ grpc_cc_binary( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -43,7 +42,6 @@ grpc_cc_binary( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -59,7 +57,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -75,7 +72,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/gpr/BUILD b/test/core/gpr/BUILD index 67657ee1ce9..434d55e0451 100644 --- a/test/core/gpr/BUILD +++ b/test/core/gpr/BUILD @@ -24,7 +24,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -34,7 +34,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -44,7 +44,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -54,7 +54,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -64,7 +64,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -74,7 +74,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -85,7 +85,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -95,7 +95,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -105,7 +105,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -115,7 +115,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -125,7 +125,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -135,7 +135,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -145,7 +145,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -155,6 +155,6 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index e7232d9df81..fe3fea1df88 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -24,7 +24,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -34,7 +34,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -47,7 +47,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr_base", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -60,7 +60,7 @@ grpc_cc_test( language = "C++", deps = [ "//:inlined_vector", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -73,7 +73,7 @@ grpc_cc_test( language = "C++", deps = [ "//:orphanable", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -86,7 +86,7 @@ grpc_cc_test( language = "C++", deps = [ "//:ref_counted", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -100,7 +100,7 @@ grpc_cc_test( deps = [ "//:ref_counted", "//:ref_counted_ptr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -110,6 +110,6 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/handshake/BUILD b/test/core/handshake/BUILD index 712cd591977..b9d2f31515a 100644 --- a/test/core/handshake/BUILD +++ b/test/core/handshake/BUILD @@ -21,28 +21,26 @@ licenses(["notice"]) # Apache v2 grpc_cc_test( name = "client_ssl", srcs = ["client_ssl.cc"], - language = "C++", data = [ "//src/core/tsi/test_creds:ca.pem", "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) grpc_cc_library( name = "server_ssl_common", - hdrs = ["server_ssl_common.h"], srcs = ["server_ssl_common.cc"], + hdrs = ["server_ssl_common.h"], deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -50,17 +48,16 @@ grpc_cc_library( grpc_cc_test( name = "server_ssl", srcs = ["server_ssl.cc"], - language = "C++", data = [ "//src/core/tsi/test_creds:ca.pem", "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", ], + language = "C++", deps = [ ":server_ssl_common", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -68,17 +65,16 @@ grpc_cc_test( grpc_cc_test( name = "handshake_server_with_readahead_handshaker", srcs = ["readahead_handshaker_server_ssl.cc"], - language = "C++", data = [ "//src/core/tsi/test_creds:ca.pem", "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", ], + language = "C++", deps = [ ":server_ssl_common", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -86,17 +82,15 @@ grpc_cc_test( grpc_cc_test( name = "handshake_verify_peer_options", srcs = ["verify_peer_options.cc"], - language = "C++", data = [ "//src/core/tsi/test_creds:ca.pem", "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) - diff --git a/test/core/http/BUILD b/test/core/http/BUILD index be51ea07371..3e679262555 100644 --- a/test/core/http/BUILD +++ b/test/core/http/BUILD @@ -23,8 +23,8 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( name = "response_fuzzer", srcs = ["response_fuzzer.cc"], - language = "C++", corpus = "response_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -35,8 +35,8 @@ grpc_fuzzer( grpc_fuzzer( name = "request_fuzzer", srcs = ["request_fuzzer.cc"], - language = "C++", corpus = "request_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -65,18 +65,17 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_cc_test( name = "httpcli_test", srcs = ["httpcli_test.cc"], - language = "C++", data = [ "python_wrapper.sh", "test_server.py", + "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", - "//src/core/tsi/test_creds:server1.key" ], + language = "C++", deps = [ "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -84,19 +83,18 @@ grpc_cc_test( grpc_cc_test( name = "httpscli_test", srcs = ["httpscli_test.cc"], - language = "C++", data = [ "python_wrapper.sh", "test_server.py", "//src/core/tsi/test_creds:ca.pem", + "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", - "//src/core/tsi/test_creds:server1.key" ], + language = "C++", deps = [ "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -109,7 +107,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -122,7 +119,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index e278632e502..e920ceacf00 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -32,7 +32,6 @@ grpc_cc_library( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -45,7 +44,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -58,7 +56,6 @@ grpc_cc_test( ":endpoint_tests", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -71,7 +68,6 @@ grpc_cc_test( ":endpoint_tests", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -83,7 +79,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -95,7 +90,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -107,7 +101,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -119,7 +112,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -131,7 +123,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -143,7 +134,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -158,7 +148,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -173,7 +162,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -185,7 +173,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -197,7 +184,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -209,7 +195,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -221,7 +206,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -234,7 +218,6 @@ grpc_cc_test( ":endpoint_tests", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -246,7 +229,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -259,7 +241,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -271,7 +252,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -283,7 +263,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -295,7 +274,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -307,7 +285,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -319,7 +296,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/json/BUILD b/test/core/json/BUILD index b8b36c06528..5684505cbc9 100644 --- a/test/core/json/BUILD +++ b/test/core/json/BUILD @@ -23,8 +23,8 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( name = "json_fuzzer", srcs = ["fuzzer.cc"], - language = "C++", corpus = "corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -40,7 +40,6 @@ grpc_cc_binary( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -48,17 +47,16 @@ grpc_cc_binary( grpc_cc_test( name = "json_rewrite_test", srcs = ["json_rewrite_test.cc"], - language = "C++", data = [ "rewrite_test_input.json", "rewrite_test_output_condensed.json", "rewrite_test_output_indented.json", ":json_stream_error_test", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -70,7 +68,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -82,7 +79,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/memory_usage/BUILD b/test/core/memory_usage/BUILD index f39c309e369..2fe94dfa120 100644 --- a/test/core/memory_usage/BUILD +++ b/test/core/memory_usage/BUILD @@ -25,7 +25,6 @@ grpc_cc_library( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,24 +36,22 @@ grpc_cc_library( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/end2end:ssl_test_data", "//test/core/util:grpc_test_util", - "//test/core/end2end:ssl_test_data" ], ) grpc_cc_test( name = "memory_usage_test", srcs = ["memory_usage_test.cc"], - language = "C++", data = [ - ":client", - ":server", + ":client", + ":server", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/network_benchmarks/BUILD b/test/core/network_benchmarks/BUILD index e1b49536084..fbc611d5fe3 100644 --- a/test/core/network_benchmarks/BUILD +++ b/test/core/network_benchmarks/BUILD @@ -14,8 +14,12 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_cc_binary", "grpc_package") -grpc_package(name = "test/core/network_benchmarks", - features = ["-layering_check", "-parse_headers" ] +grpc_package( + name = "test/core/network_benchmarks", + features = [ + "-layering_check", + "-parse_headers", + ], ) licenses(["notice"]) # Apache v2 @@ -27,7 +31,6 @@ grpc_cc_binary( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/security/BUILD b/test/core/security/BUILD index b7de955cdbe..d8dcdc25231 100644 --- a/test/core/security/BUILD +++ b/test/core/security/BUILD @@ -23,8 +23,8 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( name = "alts_credentials_fuzzer", srcs = ["alts_credentials_fuzzer.cc"], - language = "C++", corpus = "corpus/alts_credentials_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -35,8 +35,8 @@ grpc_fuzzer( grpc_fuzzer( name = "ssl_server_fuzzer", srcs = ["ssl_server_fuzzer.cc"], - language = "C++", corpus = "corpus/ssl_server_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -50,8 +50,8 @@ grpc_cc_library( srcs = ["oauth2_utils.cc"], hdrs = ["oauth2_utils.h"], language = "C++", - deps = ["//:grpc"], visibility = ["//test/cpp:__subpackages__"], + deps = ["//:grpc"], ) grpc_cc_test( @@ -61,7 +61,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -73,7 +72,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -85,7 +83,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -97,12 +94,10 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) - grpc_cc_test( name = "secure_endpoint_test", srcs = ["secure_endpoint_test.cc"], @@ -111,7 +106,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/iomgr:endpoint_tests", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -123,7 +117,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -137,14 +130,13 @@ grpc_cc_test( "//test/core/security/etc:test_roots/cert2.pem", "//test/core/security/etc:test_roots/cert3.pem", ], - language = "C++", external_deps = [ "gtest", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -156,9 +148,8 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", - ] + ], ) grpc_cc_binary( @@ -204,7 +195,7 @@ grpc_cc_test( "//:gpr", "//:gpr_base", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -217,7 +208,7 @@ grpc_cc_test( "//:gpr", "//:gpr_base", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -229,7 +220,7 @@ grpc_cc_test( "//:alts_util", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -244,6 +235,6 @@ grpc_cc_test( "//:grpc_secure", "//:tsi", "//:tsi_interface", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/slice/BUILD b/test/core/slice/BUILD index 9a1a506a43c..12ee42ba9c3 100644 --- a/test/core/slice/BUILD +++ b/test/core/slice/BUILD @@ -51,7 +51,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -63,7 +62,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -75,7 +73,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -87,7 +84,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -102,7 +98,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -117,7 +112,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -129,7 +123,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/surface/BUILD b/test/core/surface/BUILD index 77df1cc989c..34777806cf2 100644 --- a/test/core/surface/BUILD +++ b/test/core/surface/BUILD @@ -25,7 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,7 +36,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +47,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +58,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -73,7 +69,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -85,7 +80,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -98,7 +92,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:cq_verifier", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -111,7 +104,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -123,7 +115,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -135,7 +126,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -148,7 +138,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -160,7 +149,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -172,7 +160,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/transport/BUILD b/test/core/transport/BUILD index 7ca1c1d9435..f38ecf2f66b 100644 --- a/test/core/transport/BUILD +++ b/test/core/transport/BUILD @@ -21,31 +21,29 @@ grpc_package(name = "test/core/transport") grpc_cc_test( name = "bdp_estimator_test", srcs = ["bdp_estimator_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "byte_stream_test", srcs = ["byte_stream_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( @@ -55,7 +53,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -67,7 +64,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -75,16 +71,15 @@ grpc_cc_test( grpc_cc_test( name = "pid_controller_test", srcs = ["pid_controller_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( @@ -94,7 +89,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -106,7 +100,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -118,7 +111,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -126,12 +118,12 @@ grpc_cc_test( grpc_cc_test( name = "status_metadata_test", srcs = ["status_metadata_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:grpc", - "//test/core/util:gpr_test_util", - ], - external_deps = [ - "gtest", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/transport/chttp2/BUILD b/test/core/transport/chttp2/BUILD index 33437373e4e..e5c1a7cff70 100644 --- a/test/core/transport/chttp2/BUILD +++ b/test/core/transport/chttp2/BUILD @@ -37,7 +37,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +48,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +59,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -76,12 +73,10 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) - grpc_cc_test( name = "hpack_encoder_test", srcs = ["hpack_encoder_test.cc"], @@ -89,7 +84,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -101,7 +95,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -113,7 +106,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -125,7 +117,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -133,16 +124,15 @@ grpc_cc_test( grpc_cc_test( name = "settings_timeout_test", srcs = ["settings_timeout_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( @@ -152,7 +142,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/tsi/BUILD b/test/core/tsi/BUILD index ae6e8fdc325..14578c0e48b 100644 --- a/test/core/tsi/BUILD +++ b/test/core/tsi/BUILD @@ -16,7 +16,10 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_c licenses(["notice"]) # Apache v2 -grpc_package(name = "test/core/tsi", visibility = "public") +grpc_package( + name = "test/core/tsi", + visibility = "public", +) grpc_cc_library( name = "transport_security_test_lib", @@ -34,25 +37,25 @@ grpc_cc_test( language = "C++", deps = [ ":transport_security_test_lib", - "//:grpc", "//:gpr", + "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) grpc_cc_test( name = "ssl_session_cache_test", srcs = ["ssl_session_cache_test.cc"], - language = "C++", external_deps = [ "gtest", ], + language = "C++", deps = [ - "//:grpc", "//:gpr", + "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -75,10 +78,10 @@ grpc_cc_test( language = "C++", deps = [ ":transport_security_test_lib", - "//:grpc", "//:gpr", + "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -87,9 +90,8 @@ grpc_cc_test( srcs = ["transport_security_test.cc"], language = "C++", deps = [ - "//:grpc", "//:gpr", - "//test/core/util:gpr_test_util", + "//:grpc", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/tsi/alts/crypt/BUILD b/test/core/tsi/alts/crypt/BUILD index abe1e83656f..767368a2f80 100644 --- a/test/core/tsi/alts/crypt/BUILD +++ b/test/core/tsi/alts/crypt/BUILD @@ -1,5 +1,5 @@ # 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 @@ -16,7 +16,10 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_p licenses(["notice"]) # Apache v2 -grpc_package(name = "test/core/tsi/alts/crypt", visibility = "public") +grpc_package( + name = "test/core/tsi/alts/crypt", + visibility = "public", +) grpc_cc_test( name = "alts_crypt_test", @@ -27,7 +30,7 @@ grpc_cc_test( "//:alts_frame_protector", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -40,4 +43,3 @@ grpc_cc_library( "//:grpc", ], ) - diff --git a/test/core/tsi/alts/fake_handshaker/BUILD b/test/core/tsi/alts/fake_handshaker/BUILD index 98cd628a7d2..8bf9c654d42 100644 --- a/test/core/tsi/alts/fake_handshaker/BUILD +++ b/test/core/tsi/alts/fake_handshaker/BUILD @@ -16,7 +16,10 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_cc_library", "grpc_cc_binary", "grpc_package") -grpc_package(name = "test/core/tsi/alts/fake_handshaker", visibility = "public") +grpc_package( + name = "test/core/tsi/alts/fake_handshaker", + visibility = "public", +) grpc_proto_library( name = "transport_security_common_proto", @@ -52,7 +55,7 @@ grpc_cc_binary( srcs = ["fake_handshaker_server_main.cc"], language = "C++", deps = [ - "//test/cpp/util:test_config", "fake_handshaker_lib", + "//test/cpp/util:test_config", ], ) diff --git a/test/core/tsi/alts/frame_protector/BUILD b/test/core/tsi/alts/frame_protector/BUILD index 6ff3015f4dd..1e3d16df02c 100644 --- a/test/core/tsi/alts/frame_protector/BUILD +++ b/test/core/tsi/alts/frame_protector/BUILD @@ -1,5 +1,5 @@ # 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 @@ -27,7 +27,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -40,7 +40,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -54,9 +54,9 @@ grpc_cc_test( "//:grpc", "//:tsi", "//:tsi_interface", - "//test/core/tsi/alts/crypt:alts_crypt_test_util", "//test/core/tsi:transport_security_test_lib", - "//test/core/util:gpr_test_util", + "//test/core/tsi/alts/crypt:alts_crypt_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -70,6 +70,6 @@ grpc_cc_test( "//:gpr_base", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/tsi/alts/handshaker/BUILD b/test/core/tsi/alts/handshaker/BUILD index 3f1a681c1ad..61ba16ad6db 100644 --- a/test/core/tsi/alts/handshaker/BUILD +++ b/test/core/tsi/alts/handshaker/BUILD @@ -1,5 +1,5 @@ # 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 @@ -14,10 +14,10 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") -licenses(["notice"]) # Apache v2 - +licenses(["notice"]) # Apache v2 + grpc_package(name = "test/core/tsi/alts/handshaker") - + grpc_cc_library( name = "alts_handshaker_service_api_test_lib", srcs = ["alts_handshaker_service_api_test_lib.cc"], @@ -25,7 +25,7 @@ grpc_cc_library( deps = [ "//:alts_util", "//:grpc", - ], + ], ) grpc_cc_test( @@ -34,10 +34,10 @@ grpc_cc_test( language = "C++", deps = [ ":alts_handshaker_service_api_test_lib", + "//:grpc", "//:tsi", "//:tsi_interface", - "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -48,7 +48,7 @@ grpc_cc_test( deps = [ ":alts_handshaker_service_api_test_lib", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -62,7 +62,7 @@ grpc_cc_test( "//:gpr_base", "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -74,7 +74,7 @@ grpc_cc_test( ":alts_handshaker_service_api_test_lib", "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -85,7 +85,6 @@ grpc_cc_test( deps = [ "//:alts_util", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) - diff --git a/test/core/tsi/alts/zero_copy_frame_protector/BUILD b/test/core/tsi/alts/zero_copy_frame_protector/BUILD index a3b797327e4..696fc8dc065 100644 --- a/test/core/tsi/alts/zero_copy_frame_protector/BUILD +++ b/test/core/tsi/alts/zero_copy_frame_protector/BUILD @@ -1,5 +1,5 @@ # 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 @@ -28,7 +28,7 @@ grpc_cc_test( "//:grpc", "//:grpc_base_c", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -41,7 +41,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -55,6 +55,6 @@ grpc_cc_test( "//:grpc", "//:grpc_base_c", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 5492dcfa795..226e41aea7c 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -21,24 +21,6 @@ grpc_package( visibility = "public", ) -grpc_cc_library( - name = "gpr_test_util", - srcs = [ - "memory_counters.cc", - "test_config.cc", - ], - hdrs = [ - "memory_counters.h", - "test_config.h", - ], - deps = ["//:gpr"], - data = [ - "lsan_suppressions.txt", - "tsan_suppressions.txt", - "ubsan_suppressions.txt", - ], -) - grpc_cc_library( name = "grpc_debugger_macros", srcs = [ @@ -48,7 +30,6 @@ grpc_cc_library( "debugger_macros.h", ], deps = [ - ":gpr_test_util", "//:grpc_common", ], ) @@ -60,6 +41,7 @@ grpc_cc_library( "fuzzer_util.cc", "grpc_profiler.cc", "histogram.cc", + "memory_counters.cc", "mock_endpoint.cc", "parse_hexstring.cc", "passthru_endpoint.cc", @@ -70,6 +52,7 @@ grpc_cc_library( "slice_splitter.cc", "subprocess_posix.cc", "subprocess_windows.cc", + "test_config.cc", "test_tcp_server.cc", "tracer_util.cc", "trickle_endpoint.cc", @@ -79,24 +62,31 @@ grpc_cc_library( "fuzzer_util.h", "grpc_profiler.h", "histogram.h", + "memory_counters.h", "mock_endpoint.h", "parse_hexstring.h", "passthru_endpoint.h", "port.h", "port_server_client.h", "reconnect_server.h", - "subprocess.h", "slice_splitter.h", + "subprocess.h", + "test_config.h", "test_tcp_server.h", "tracer_util.h", "trickle_endpoint.h", ], language = "C++", deps = [ - ":gpr_test_util", ":grpc_debugger_macros", + "//:gpr", "//:grpc_common", ], + data = [ + "lsan_suppressions.txt", + "tsan_suppressions.txt", + "ubsan_suppressions.txt", + ], ) grpc_cc_library( @@ -140,7 +130,7 @@ grpc_cc_library( "gflags", ], deps = [ - ":gpr_test_util", + ":grpc_test_util", "//:grpc", ], ) diff --git a/test/cpp/client/BUILD b/test/cpp/client/BUILD index c03ea92d34a..1d90e361913 100644 --- a/test/cpp/client/BUILD +++ b/test/cpp/client/BUILD @@ -28,7 +28,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -44,7 +44,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/end2end:test_service_impl", "//test/cpp/util:test_util", diff --git a/test/cpp/codegen/BUILD b/test/cpp/codegen/BUILD index 12712a3e6c8..558e5e7818c 100644 --- a/test/cpp/codegen/BUILD +++ b/test/cpp/codegen/BUILD @@ -21,76 +21,76 @@ grpc_package(name = "test/cpp/codegen") grpc_cc_test( name = "codegen_test_full", srcs = ["codegen_test_full.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "codegen_test_minimal", srcs = ["codegen_test_minimal.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "proto_utils_test", srcs = ["proto_utils_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", "protobuf", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_binary( name = "golden_file_test", testonly = True, srcs = ["golden_file_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", "gflags", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) genrule( name = "copy_compiler_test_grpc_pb_h", srcs = ["//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen"], - cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.h > $@", outs = ["compiler_test.grpc.pb.h"], + cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.h > $@", ) genrule( name = "copy_compiler_test_mock_grpc_pb_h", srcs = ["//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen"], - cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test_mock.grpc.pb.h > $@", outs = ["compiler_test_mock.grpc.pb.h"], + cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test_mock.grpc.pb.h > $@", ) grpc_sh_test( name = "run_golden_file_test", srcs = ["run_golden_file_test.sh"], data = [ - ":golden_file_test", - ":compiler_test_golden", - ":compiler_test_mock_golden", ":compiler_test.grpc.pb.h", + ":compiler_test_golden", ":compiler_test_mock.grpc.pb.h", + ":compiler_test_mock_golden", + ":golden_file_test", ], ) diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD index 2cf3ad669fa..73fcea94d9f 100644 --- a/test/cpp/common/BUILD +++ b/test/cpp/common/BUILD @@ -21,61 +21,61 @@ grpc_package(name = "test/cpp/common") grpc_cc_test( name = "alarm_test", srcs = ["alarm_test.cc"], - deps = [ - "//:grpc++_unsecure", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++_unsecure", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "auth_property_iterator_test", srcs = ["auth_property_iterator_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:grpc++", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "channel_arguments_test", srcs = ["channel_arguments_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "channel_filter_test", srcs = ["channel_filter_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "secure_auth_context_test", srcs = ["secure_auth_context_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:grpc++", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gtest", - ], ) diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 446804401a7..a648f4f0630 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -63,7 +63,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -85,7 +84,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -106,7 +104,6 @@ grpc_cc_binary( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -124,9 +121,8 @@ grpc_cc_test( "//:grpc", "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", - "//src/proto/grpc/testing:simple_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", + "//src/proto/grpc/testing:simple_messages_proto", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -146,7 +142,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -168,7 +163,6 @@ grpc_cc_library( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -189,7 +183,6 @@ grpc_cc_test( "//src/proto/grpc/channelz:channelz_proto", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -207,7 +200,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -232,7 +224,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -251,7 +242,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -270,7 +260,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -291,7 +280,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -311,7 +299,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -331,7 +318,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -352,7 +338,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -370,7 +355,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -390,7 +374,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -413,7 +396,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -435,7 +417,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:grpc++_proto_reflection_desc_db", "//test/cpp/util:test_util", @@ -456,7 +437,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -478,7 +458,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -499,7 +478,6 @@ grpc_cc_binary( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -519,7 +497,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -552,7 +529,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -571,7 +547,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -590,7 +565,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], diff --git a/test/cpp/ext/filters/census/BUILD b/test/cpp/ext/filters/census/BUILD index 6567dc667aa..78b27e2063c 100644 --- a/test/cpp/ext/filters/census/BUILD +++ b/test/cpp/ext/filters/census/BUILD @@ -24,19 +24,18 @@ grpc_cc_test( srcs = [ "stats_plugin_end2end_test.cc", ], - language = "C++", external_deps = [ "gtest", "gmock", "opencensus-stats-test", ], + language = "C++", deps = [ "//:grpc++", "//:grpc_opencensus_plugin", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", - "//test/cpp/util:test_util", "//test/cpp/util:test_config", + "//test/cpp/util:test_util", ], ) diff --git a/test/cpp/grpclb/BUILD b/test/cpp/grpclb/BUILD index 8319eb5142a..2f74a9bab0e 100644 --- a/test/cpp/grpclb/BUILD +++ b/test/cpp/grpclb/BUILD @@ -32,7 +32,6 @@ grpc_cc_test( "//:grpc", "//:grpc++", "//src/proto/grpc/lb/v1:load_balancer_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index 0f813054053..f36494d98db 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -157,7 +157,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 5ae9a9a7910..f8b5c54e207 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -24,7 +24,7 @@ grpc_cc_test( external_deps = [ "benchmark", ], - deps = ["//test/core/util:gpr_test_util"], + deps = ["//test/core/util:grpc_test_util"], ) grpc_cc_library( diff --git a/test/cpp/naming/BUILD b/test/cpp/naming/BUILD index 2925e8fbcfb..58e70480acf 100644 --- a/test/cpp/naming/BUILD +++ b/test/cpp/naming/BUILD @@ -23,16 +23,15 @@ package( licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_py_binary", "grpc_cc_test") - load(":generate_resolver_component_tests.bzl", "generate_resolver_component_tests") # Meant to be invoked only through the top-level shell script driver. grpc_py_binary( name = "resolver_component_tests_runner", + testonly = True, srcs = [ "resolver_component_tests_runner.py", ], - testonly = True, ) grpc_cc_test( @@ -40,14 +39,13 @@ grpc_cc_test( srcs = ["cancel_ares_query_test.cc"], external_deps = ["gmock"], deps = [ - "//test/cpp/util:test_util", - "//test/core/util:grpc_test_util", - "//test/core/util:gpr_test_util", - "//:grpc++", - "//:grpc", "//:gpr", - "//test/cpp/util:test_config", + "//:grpc", + "//:grpc++", "//test/core/end2end:cq_verifier", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_config", + "//test/cpp/util:test_util", ], ) diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl index 5e9aa63abe0..f36021560c1 100755 --- a/test/cpp/naming/generate_resolver_component_tests.bzl +++ b/test/cpp/naming/generate_resolver_component_tests.bzl @@ -28,7 +28,6 @@ def generate_resolver_component_tests(): deps = [ "//test/cpp/util:test_util%s" % unsecure_build_config_suffix, "//test/core/util:grpc_test_util%s" % unsecure_build_config_suffix, - "//test/core/util:gpr_test_util", "//:grpc++%s" % unsecure_build_config_suffix, "//:grpc%s" % unsecure_build_config_suffix, "//:gpr", @@ -48,7 +47,6 @@ def generate_resolver_component_tests(): deps = [ "//test/cpp/util:test_util%s" % unsecure_build_config_suffix, "//test/core/util:grpc_test_util%s" % unsecure_build_config_suffix, - "//test/core/util:gpr_test_util", "//:grpc++%s" % unsecure_build_config_suffix, "//:grpc%s" % unsecure_build_config_suffix, "//:gpr", @@ -63,7 +61,6 @@ def generate_resolver_component_tests(): deps = [ "//test/cpp/util:test_util", "//test/core/util:grpc_test_util", - "//test/core/util:gpr_test_util", "//:grpc++", "//:grpc", "//:gpr", diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index 626ac5f3f2e..8855a1c155d 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -60,7 +60,6 @@ grpc_cc_library( "//src/proto/grpc/testing:payloads_proto", "//src/proto/grpc/testing:worker_service_proto", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", @@ -86,7 +85,6 @@ grpc_cc_library( "//src/proto/grpc/testing:messages_proto", "//src/proto/grpc/testing:report_qps_scenario_service_proto", "//src/proto/grpc/testing:worker_service_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -205,7 +203,6 @@ grpc_cc_binary( deps = [ ":qps_worker_impl", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", diff --git a/test/cpp/qps/qps_benchmark_script.bzl b/test/cpp/qps/qps_benchmark_script.bzl index b2b67d988ce..855caa0d37c 100644 --- a/test/cpp/qps/qps_benchmark_script.bzl +++ b/test/cpp/qps/qps_benchmark_script.bzl @@ -69,7 +69,6 @@ def json_run_localhost_batch(): ], deps = [ "//:gpr", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD index 3f89d6e26e3..050b83f5c4f 100644 --- a/test/cpp/server/BUILD +++ b/test/cpp/server/BUILD @@ -21,38 +21,38 @@ grpc_package(name = "test/cpp/server") grpc_cc_test( name = "server_builder_test", srcs = ["server_builder_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "server_builder_with_socket_mutator_test", srcs = ["server_builder_with_socket_mutator_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "server_request_call_test", srcs = ["server_request_call_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - external_deps = [ - "gtest", - ], ) diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD index b7c4d29d719..8d876c56d29 100644 --- a/test/cpp/server/load_reporter/BUILD +++ b/test/cpp/server/load_reporter/BUILD @@ -43,7 +43,6 @@ grpc_cc_test( "//:grpc", "//:lb_load_reporter", "//:lb_server_load_reporting_filter", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -58,7 +57,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:lb_get_cpu_stats", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/cpp/test/BUILD b/test/cpp/test/BUILD index c5494789190..cd980dee84d 100644 --- a/test/cpp/test/BUILD +++ b/test/cpp/test/BUILD @@ -32,7 +32,6 @@ grpc_cc_test( "//:grpc", "//:grpc++", "//:grpc++_test", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], diff --git a/test/cpp/thread_manager/BUILD b/test/cpp/thread_manager/BUILD index 093e51e3faa..30488774e4e 100644 --- a/test/cpp/thread_manager/BUILD +++ b/test/cpp/thread_manager/BUILD @@ -32,7 +32,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index 61e65029fff..bb1ca868ffb 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -93,14 +93,14 @@ grpc_cc_library( hdrs = [ "channel_trace_proto_helper.h", ], - deps = [ - "//:grpc++", - "//src/proto/grpc/channelz:channelz_proto", - ], external_deps = [ "gtest", "protobuf", ], + deps = [ + "//:grpc++", + "//src/proto/grpc/channelz:channelz_proto", + ], ) grpc_cc_library( @@ -235,7 +235,7 @@ grpc_cc_test( ], deps = [ "//:grpc++", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -279,7 +279,7 @@ grpc_cc_test( deps = [ "//:grpc++_error_details", "//src/proto/grpc/testing:echo_messages_proto", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -292,8 +292,8 @@ grpc_cc_binary( "gflags", ], deps = [ - ":grpc_cli_libs", ":grpc++_proto_reflection_desc_db", + ":grpc_cli_libs", ":test_config", "//:grpc++", "//src/proto/grpc/reflection/v1alpha:reflection_proto", From f9e50322bf1d6be736b415831eea44130b9dedfe Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 15:58:53 -0800 Subject: [PATCH 235/534] batch fix --- src/objective-c/GRPCClient/GRPCCall.h | 16 +++--- src/objective-c/GRPCClient/GRPCCall.m | 4 +- .../GRPCClient/private/GRPCChannelPool+Test.h | 49 +++++++++++++++++++ .../GRPCClient/private/GRPCChannelPool.h | 28 ----------- .../GRPCClient/private/GRPCChannelPool.m | 7 ++- src/objective-c/ProtoRPC/ProtoRPC.h | 16 +++--- src/objective-c/ProtoRPC/ProtoRPC.m | 5 +- .../tests/ChannelTests/ChannelPoolTest.m | 2 +- .../tests/ChannelTests/ChannelTests.m | 1 + 9 files changed, 73 insertions(+), 55 deletions(-) create mode 100644 src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 985743433cf..6d8b9c1b127 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -153,6 +153,14 @@ extern NSString *const kGRPCTrailersKey; /** An object can implement this protocol to receive responses from server from a call. */ @protocol GRPCResponseHandler +@required + +/** + * All the responses must be issued to a user-provided dispatch queue. This property specifies the + * dispatch queue to be used for issuing the notifications. + */ +@property(atomic, readonly) dispatch_queue_t dispatchQueue; + @optional /** @@ -175,14 +183,6 @@ extern NSString *const kGRPCTrailersKey; - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; -@required - -/** - * All the responses must be issued to a user-provided dispatch queue. This property specifies the - * dispatch queue to be used for issuing the notifications. - */ -@property(atomic, readonly) dispatch_queue_t dispatchQueue; - @end /** diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 48253677bd3..e75ca7193a7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -856,9 +856,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _retainSelf = self; if (_callOptions == nil) { - GRPCMutableCallOptions *callOptions; - - callOptions = [[GRPCHost callOptionsForHost:_host] mutableCopy]; + GRPCMutableCallOptions *callOptions = [[GRPCHost callOptionsForHost:_host] mutableCopy]; if (_serverName.length != 0) { callOptions.serverAuthority = _serverName; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h new file mode 100644 index 00000000000..4e7c988585d --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h @@ -0,0 +1,49 @@ +/* + * + * 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. + * + */ + +#import "GRPCChannelPool.h" + +/** Test-only interface for \a GRPCPooledChannel. */ +@interface GRPCPooledChannel (Test) + +/** + * Initialize a pooled channel with non-default destroy delay for testing purpose. + */ +- (nullable instancetype)initWithChannelConfiguration: +(GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay; + +/** + * Return the pointer to the raw channel wrapped. + */ +@property(atomic, readonly) GRPCChannel *wrappedChannel; + +@end + +/** Test-only interface for \a GRPCChannelPool. */ +@interface GRPCChannelPool (Test) + +/** + * Get an instance of pool isolated from the global shared pool with channels' destroy delay being + * \a destroyDelay. + */ +- (nullable instancetype)initTestPool; + +@end + + diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 7c6f2b3bbfa..d1f28ec9bfa 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -75,23 +75,6 @@ NS_ASSUME_NONNULL_BEGIN @end -/** Test-only interface for \a GRPCPooledChannel. */ -@interface GRPCPooledChannel (Test) - -/** - * Initialize a pooled channel with non-default destroy delay for testing purpose. - */ -- (nullable instancetype)initWithChannelConfiguration: -(GRPCChannelConfiguration *)channelConfiguration - destroyDelay:(NSTimeInterval)destroyDelay; - -/** - * Return the pointer to the raw channel wrapped. - */ -@property(atomic, readonly) GRPCChannel *wrappedChannel; - -@end - /** * Manage the pool of connected channels. When a channel is no longer referenced by any call, * destroy the channel after a certain period of time elapsed. @@ -119,15 +102,4 @@ NS_ASSUME_NONNULL_BEGIN @end -/** Test-only interface for \a GRPCChannelPool. */ -@interface GRPCChannelPool (Test) - -/** - * Get an instance of pool isolated from the global shared pool with channels' destroy delay being - * \a destroyDelay. - */ -- (nullable instancetype)initTestPool; - -@end - NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 391022efd19..349bdd44a65 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -22,6 +22,7 @@ #import "GRPCChannel.h" #import "GRPCChannelFactory.h" #import "GRPCChannelPool.h" +#import "GRPCChannelPool+Test.h" #import "GRPCConnectivityMonitor.h" #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" @@ -59,9 +60,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (void)dealloc { // Disconnect GRPCWrappedCall objects created but not yet removed if (_wrappedCalls.allObjects.count != 0) { - NSEnumerator *enumerator = [_wrappedCalls objectEnumerator]; - GRPCWrappedCall *wrappedCall; - while ((wrappedCall = [enumerator nextObject])) { + for (GRPCWrappedCall *wrappedCall in _wrappedCalls.allObjects) { [wrappedCall channelDisconnected]; }; } @@ -73,7 +72,7 @@ callOptions:(GRPCCallOptions *)callOptions { NSAssert(path.length > 0, @"path must not be empty."); NSAssert(queue != nil, @"completionQueue must not be empty."); NSAssert(callOptions, @"callOptions must not be empty."); - if (path.length == 0 || queue == nil || callOptions == nil) return NULL; + if (path.length == 0 || queue == nil || callOptions == nil) return nil; GRPCWrappedCall *call = nil; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 287aa0369b1..2e0400a323f 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -28,6 +28,14 @@ NS_ASSUME_NONNULL_BEGIN /** An object can implement this protocol to receive responses from server from a call. */ @protocol GRPCProtoResponseHandler +@required + +/** + * All the responses must be issued to a user-provided dispatch queue. This property specifies the + * dispatch queue to be used for issuing the notifications. + */ +@property(atomic, readonly) dispatch_queue_t dispatchQueue; + @optional /** @@ -49,14 +57,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; -@required - -/** - * All the responses must be issued to a user-provided dispatch queue. This property specifies the - * dispatch queue to be used for issuing the notifications. - */ -@property(atomic, readonly) dispatch_queue_t dispatchQueue; - @end /** A unary-request RPC call with Protobuf. */ diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 886e31ce58a..0f63f72f536 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -75,7 +75,6 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)cancel { [_call cancel]; - _call = nil; } @end @@ -124,7 +123,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing #else { #endif - _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } dispatch_set_target_queue(_dispatchQueue, handler.dispatchQueue); @@ -145,7 +144,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing copiedCall = _call; _call = nil; if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { - dispatch_async(_handler.dispatchQueue, ^{ + dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index dc42d7c341d..eab8c5193fb 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -19,7 +19,7 @@ #import #import "../../GRPCClient/private/GRPCChannel.h" -#import "../../GRPCClient/private/GRPCChannelPool.h" +#import "../../GRPCClient/private/GRPCChannelPool+Test.h" #import "../../GRPCClient/private/GRPCCompletionQueue.h" #define TEST_TIMEOUT 32 diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index ee7f8b6fddb..7c80868c2c9 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -21,6 +21,7 @@ #import "../../GRPCClient/GRPCCallOptions.h" #import "../../GRPCClient/private/GRPCChannel.h" #import "../../GRPCClient/private/GRPCChannelPool.h" +#import "../../GRPCClient/private/GRPCChannelPool+Test.h" #import "../../GRPCClient/private/GRPCCompletionQueue.h" #import "../../GRPCClient/private/GRPCWrappedCall.h" From e7be6223d86172f2881935f83fb25b4bc7898942 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 6 Dec 2018 17:10:03 -0800 Subject: [PATCH 236/534] Delete unwanted constructor/assignment --- include/grpcpp/impl/codegen/server_interceptor.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index 5fb5df28b70..030c26a9b05 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -47,8 +47,8 @@ class ServerRpcInfo { ~ServerRpcInfo(){}; ServerRpcInfo(const ServerRpcInfo&) = delete; - ServerRpcInfo(ServerRpcInfo&&) = default; - ServerRpcInfo& operator=(ServerRpcInfo&&) = default; + ServerRpcInfo(ServerRpcInfo&&) = delete; + ServerRpcInfo& operator=(ServerRpcInfo&&) = delete; // Getter methods const char* method() { return method_; } From da759f1fc63ceb0c893bb6027bacfadfda5ab111 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 18:26:51 -0800 Subject: [PATCH 237/534] batch fixes --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 5 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 4 +- src/objective-c/GRPCClient/GRPCCallOptions.m | 32 ++++---- .../GRPCClient/private/GRPCChannel.h | 5 +- .../GRPCClient/private/GRPCChannel.m | 8 +- .../GRPCClient/private/GRPCChannelPool.h | 13 +-- .../GRPCClient/private/GRPCChannelPool.m | 82 ++++++++++--------- .../private/GRPCCronetChannelFactory.m | 8 +- src/objective-c/GRPCClient/private/GRPCHost.m | 7 +- .../private/GRPCSecureChannelFactory.m | 5 +- .../GRPCClient/private/GRPCWrappedCall.m | 11 +-- .../GRPCClient/private/utilities.h | 22 ----- 13 files changed, 89 insertions(+), 115 deletions(-) delete mode 100644 src/objective-c/GRPCClient/private/utilities.h diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 6d8b9c1b127..be63de1af9b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -206,7 +206,7 @@ extern NSString *const kGRPCTrailersKey; @property(copy, readonly) NSString *path; /** * Specify whether the call is idempotent or cachable. gRPC may select different HTTP verbs for the - * call based on this information. + * call based on this information. The default verb used by gRPC is POST. */ @property(readonly) GRPCCallSafety safety; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e75ca7193a7..e56cc72149c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -35,7 +35,6 @@ #import "private/NSData+GRPC.h" #import "private/NSDictionary+GRPC.h" #import "private/NSError+GRPC.h" -#import "private/utilities.h" #import "private/GRPCChannelPool.h" #import "private/GRPCCompletionQueue.h" @@ -277,7 +276,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(NSData *)data { GRXBufferedPipe *copiedPipe = nil; @synchronized(self) { - NSAssert(!_canceled, @"Call arleady canceled."); + NSAssert(!_canceled, @"Call already canceled."); NSAssert(!_finished, @"Call is half-closed before sending data."); if (_canceled) { return; @@ -297,7 +296,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRXBufferedPipe *copiedPipe = nil; @synchronized(self) { NSAssert(_started, @"Call not started."); - NSAssert(!_canceled, @"Call arleady canceled."); + NSAssert(!_canceled, @"Call already canceled."); NSAssert(!_finished, @"Call already half-closed."); if (!_started) { return; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 158a4745d23..85786c74174 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -170,7 +170,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * PEM format certificate chain for client authentication, if required by the server. */ -@property(copy, readonly, nullable) NSString *PEMCertChain; +@property(copy, readonly, nullable) NSString *PEMCertificateChain; /** * Select the transport type to be used for this call. @@ -314,7 +314,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * PEM format certificate chain for client authentication, if required by the server. */ -@property(copy, readwrite, nullable) NSString *PEMCertChain; +@property(copy, readwrite, nullable) NSString *PEMCertificateChain; /** * Select the transport type to be used for this call. diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 9a36ee547cd..1962ad8956d 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -35,7 +35,7 @@ static const NSTimeInterval kDefaultConnectMaxBackoff = 0; static NSDictionary *const kDefaultAdditionalChannelArgs = nil; static NSString *const kDefaultPEMRootCertificates = nil; static NSString *const kDefaultPEMPrivateKey = nil; -static NSString *const kDefaultPEMCertChain = nil; +static NSString *const kDefaultPEMCertificateChain = nil; static NSString *const kDefaultOauth2AccessToken = nil; static const id kDefaultAuthTokenProvider = nil; static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2BoringSSL; @@ -74,7 +74,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { NSDictionary *_additionalChannelArgs; NSString *_PEMRootCertificates; NSString *_PEMPrivateKey; - NSString *_PEMCertChain; + NSString *_PEMCertificateChain; GRPCTransportType _transportType; NSString *_hostNameOverride; id _logContext; @@ -99,7 +99,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { @synthesize additionalChannelArgs = _additionalChannelArgs; @synthesize PEMRootCertificates = _PEMRootCertificates; @synthesize PEMPrivateKey = _PEMPrivateKey; -@synthesize PEMCertChain = _PEMCertChain; +@synthesize PEMCertificateChain = _PEMCertificateChain; @synthesize transportType = _transportType; @synthesize hostNameOverride = _hostNameOverride; @synthesize logContext = _logContext; @@ -124,7 +124,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:kDefaultAdditionalChannelArgs PEMRootCertificates:kDefaultPEMRootCertificates PEMPrivateKey:kDefaultPEMPrivateKey - PEMCertChain:kDefaultPEMCertChain + PEMCertificateChain:kDefaultPEMCertificateChain transportType:kDefaultTransportType hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext @@ -149,7 +149,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:(NSDictionary *)additionalChannelArgs PEMRootCertificates:(NSString *)PEMRootCertificates PEMPrivateKey:(NSString *)PEMPrivateKey - PEMCertChain:(NSString *)PEMCertChain + PEMCertificateChain:(NSString *)PEMCertificateChain transportType:(GRPCTransportType)transportType hostNameOverride:(NSString *)hostNameOverride logContext:(id)logContext @@ -174,7 +174,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; _PEMRootCertificates = [PEMRootCertificates copy]; _PEMPrivateKey = [PEMPrivateKey copy]; - _PEMCertChain = [PEMCertChain copy]; + _PEMCertificateChain = [PEMCertificateChain copy]; _transportType = transportType; _hostNameOverride = [hostNameOverride copy]; _logContext = logContext; @@ -203,7 +203,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:_additionalChannelArgs PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey - PEMCertChain:_PEMCertChain + PEMCertificateChain:_PEMCertificateChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -233,7 +233,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { copyItems:YES] PEMRootCertificates:[_PEMRootCertificates copy] PEMPrivateKey:[_PEMPrivateKey copy] - PEMCertChain:[_PEMCertChain copy] + PEMCertificateChain:[_PEMCertificateChain copy] transportType:_transportType hostNameOverride:[_hostNameOverride copy] logContext:_logContext @@ -256,7 +256,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { if (!areObjectsEqual(callOptions.additionalChannelArgs, _additionalChannelArgs)) return NO; if (!areObjectsEqual(callOptions.PEMRootCertificates, _PEMRootCertificates)) return NO; if (!areObjectsEqual(callOptions.PEMPrivateKey, _PEMPrivateKey)) return NO; - if (!areObjectsEqual(callOptions.PEMCertChain, _PEMCertChain)) return NO; + if (!areObjectsEqual(callOptions.PEMCertificateChain, _PEMCertificateChain)) return NO; if (!areObjectsEqual(callOptions.hostNameOverride, _hostNameOverride)) return NO; if (!(callOptions.transportType == _transportType)) return NO; if (!areObjectsEqual(callOptions.logContext, _logContext)) return NO; @@ -280,7 +280,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { result ^= _additionalChannelArgs.hash; result ^= _PEMRootCertificates.hash; result ^= _PEMPrivateKey.hash; - result ^= _PEMCertChain.hash; + result ^= _PEMCertificateChain.hash; result ^= _hostNameOverride.hash; result ^= _transportType; result ^= _logContext.hash; @@ -311,7 +311,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { @dynamic additionalChannelArgs; @dynamic PEMRootCertificates; @dynamic PEMPrivateKey; -@dynamic PEMCertChain; +@dynamic PEMCertificateChain; @dynamic transportType; @dynamic hostNameOverride; @dynamic logContext; @@ -336,7 +336,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:kDefaultAdditionalChannelArgs PEMRootCertificates:kDefaultPEMRootCertificates PEMPrivateKey:kDefaultPEMPrivateKey - PEMCertChain:kDefaultPEMCertChain + PEMCertificateChain:kDefaultPEMCertificateChain transportType:kDefaultTransportType hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext @@ -363,7 +363,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:_additionalChannelArgs PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey - PEMCertChain:_PEMCertChain + PEMCertificateChain:_PEMCertificateChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -391,7 +391,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:[_additionalChannelArgs copy] PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey - PEMCertChain:_PEMCertChain + PEMCertificateChain:_PEMCertificateChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -493,8 +493,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { _PEMPrivateKey = [PEMPrivateKey copy]; } -- (void)setPEMCertChain:(NSString *)PEMCertChain { - _PEMCertChain = [PEMCertChain copy]; +- (void)setPEMCertificateChain:(NSString *)PEMCertificateChain { + _PEMCertificateChain = [PEMCertificateChain copy]; } - (void)setTransportType:(GRPCTransportType)transportType { diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index c01aeccf81f..bbada0d8cb3 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -29,7 +29,10 @@ struct grpc_channel_credentials; NS_ASSUME_NONNULL_BEGIN -/** Caching signature of a channel. */ +/** + * Signature for the channel. If two channel's signatures are the same and connect to the same + * remote, they share the same underlying \a GRPCChannel object. + */ @interface GRPCChannelConfiguration : NSObject - (instancetype)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 9432e7ab397..edcedf6e24f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -28,7 +28,6 @@ #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" -#import "utilities.h" #import "version.h" #import @@ -63,8 +62,9 @@ factory = [GRPCSecureChannelFactory factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates privateKey:_callOptions.PEMPrivateKey - certChain:_callOptions.PEMCertChain + certChain:_callOptions.PEMCertificateChain error:&error]; + NSAssert(factory != nil, @"Failed to create secure channel factory"); if (factory == nil) { NSLog(@"Error creating secure channel factory: %@", error); } @@ -114,8 +114,8 @@ [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; } - if (_callOptions.retryEnabled == NO) { - args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.retryEnabled]; + if (!_callOptions.retryEnabled) { + args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.retryEnabled ? 1 : 0]; } if (_callOptions.connectMinTimeout > 0) { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index d1f28ec9bfa..19ef4c93ac6 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -16,11 +16,6 @@ * */ -/** - * Signature for the channel. If two channel's signatures are the same, they share the same - * underlying \a GRPCChannel object. - */ - #import #import "GRPCChannelFactory.h" @@ -35,10 +30,10 @@ NS_ASSUME_NONNULL_BEGIN @class GRPCWrappedCall; /** - * A proxied channel object that can be retained and creates GRPCWrappedCall object from. If a - * raw channel is not present (i.e. no tcp connection to the server) when a GRPCWrappedCall object - * is requested, it issues a connection/reconnection. The behavior of this object is to mimic that - * of gRPC core's channel object. + * A proxied channel object that can be retained and used to create GRPCWrappedCall object + * regardless of the current connection status. If a connection is not established when a + * GRPCWrappedCall object is requested, it issues a connection/reconnection. This behavior is to + * follow that of gRPC core's channel object. */ @interface GRPCPooledChannel : NSObject diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 349bdd44a65..17c74e558b4 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -27,7 +27,6 @@ #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" -#import "utilities.h" #import "version.h" #import "GRPCWrappedCall.h" #import "GRPCCompletionQueue.h" @@ -57,6 +56,34 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; return [self initWithChannelConfiguration:channelConfiguration destroyDelay:kDefaultChannelDestroyDelay]; } +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay { + NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); + if (channelConfiguration == nil) { + return nil; + } + + if ((self = [super init])) { + _channelConfiguration = [channelConfiguration copy]; + _destroyDelay = destroyDelay; + _wrappedCalls = [NSHashTable weakObjectsHashTable]; + _wrappedChannel = nil; + _lastTimedDestroy = nil; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { + _timerQueue = dispatch_queue_create(NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + } else { +#else + { +#endif + _timerQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + } + + return self; +} + - (void)dealloc { // Disconnect GRPCWrappedCall objects created but not yet removed if (_wrappedCalls.allObjects.count != 0) { @@ -67,12 +94,14 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (GRPCWrappedCall *)wrappedCallWithPath:(NSString *)path -completionQueue:(GRPCCompletionQueue *)queue -callOptions:(GRPCCallOptions *)callOptions { + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions { NSAssert(path.length > 0, @"path must not be empty."); NSAssert(queue != nil, @"completionQueue must not be empty."); NSAssert(callOptions, @"callOptions must not be empty."); - if (path.length == 0 || queue == nil || callOptions == nil) return nil; + if (path.length == 0 || queue == nil || callOptions == nil) { + return nil; + } GRPCWrappedCall *call = nil; @@ -97,6 +126,7 @@ callOptions:(GRPCCallOptions *)callOptions { call = [[GRPCWrappedCall alloc] initWithUnmanagedCall:unmanagedCall pooledChannel:self]; if (call == nil) { NSAssert(call != nil, @"Unable to create GRPCWrappedCall object"); + grpc_call_unref(unmanagedCall); return nil; } @@ -111,16 +141,22 @@ callOptions:(GRPCCallOptions *)callOptions { return; } @synchronized(self) { - // Detect if all objects weakly referenced in _wrappedCalls are (implicitly) removed. In such - // case the channel is no longer referenced by a grpc_call object and can be destroyed after - // a certain delay. + // Detect if all objects weakly referenced in _wrappedCalls are (implicitly) removed. + // _wrappedCalls.count does not work here since the hash table may include deallocated weak + // references. _wrappedCalls.allObjects forces removal of those objects. if (_wrappedCalls.allObjects.count == 0) { + // No more call has reference to this channel. We may start the timer for destroying the + // channel now. NSDate *now = [NSDate date]; NSAssert(now != nil, @"Unable to create NSDate object 'now'."); _lastTimedDestroy = now; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * NSEC_PER_SEC), _timerQueue, ^{ @synchronized(self) { + // Check _lastTimedDestroy against now in case more calls are created (and + // maybe destroyed) after this dispatch_async. In that case the current + // dispatch_after block should be discarded; the channel should be + // destroyed in a later dispatch_after block. if (now != nil && self->_lastTimedDestroy == now) { self->_wrappedChannel = nil; self->_lastTimedDestroy = nil; @@ -145,38 +181,6 @@ callOptions:(GRPCCallOptions *)callOptions { } } -@end - -@implementation GRPCPooledChannel (Test) - -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration - destroyDelay:(NSTimeInterval)destroyDelay { - NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); - if (channelConfiguration == nil) { - return nil; - } - - if ((self = [super init])) { - _channelConfiguration = [channelConfiguration copy]; - _destroyDelay = destroyDelay; - _wrappedCalls = [NSHashTable weakObjectsHashTable]; - _wrappedChannel = nil; - _lastTimedDestroy = nil; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 - if (@available(iOS 8.0, macOS 10.10, *)) { - _timerQueue = dispatch_queue_create(NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); - } else { -#else - { -#endif - _timerQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } - } - - return self; -} - - (GRPCChannel *)wrappedChannel { GRPCChannel *channel = nil; @synchronized(self) { diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 0aeb67b1426..5bcb021dc4b 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -40,8 +40,8 @@ } - (instancetype)initWithEngine:(stream_engine *)engine { + NSAssert(engine != NULL, @"Cronet engine cannot be empty."); if (!engine) { - [NSException raise:NSInvalidArgumentException format:@"Cronet engine is NULL. Set it first."]; return nil; } if ((self = [super init])) { @@ -65,14 +65,12 @@ @implementation GRPCCronetChannelFactory + (instancetype)sharedInstance { - [NSException raise:NSInvalidArgumentException - format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; + NSAssert(NO, @"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."); return nil; } - (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { - [NSException raise:NSInvalidArgumentException - format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; + NSAssert(NO, @"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."); return NULL; } diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 0f2281ede85..e7a7460221f 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -32,7 +32,6 @@ #import "GRPCCronetChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" -#import "utilities.h" #import "version.h" NS_ASSUME_NONNULL_BEGIN @@ -42,7 +41,7 @@ static NSMutableDictionary *gHostCache; @implementation GRPCHost { NSString *_PEMRootCertificates; NSString *_PEMPrivateKey; - NSString *_pemCertChain; + NSString *_PEMCertificateChain; } + (nullable instancetype)hostWithAddress:(NSString *)address { @@ -96,7 +95,7 @@ static NSMutableDictionary *gHostCache; error:(NSError **)errorPtr { _PEMRootCertificates = [pemRootCerts copy]; _PEMPrivateKey = [pemPrivateKey copy]; - _pemCertChain = [pemCertChain copy]; + _PEMCertificateChain = [pemCertChain copy]; return YES; } @@ -113,7 +112,7 @@ static NSMutableDictionary *gHostCache; options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000; options.PEMRootCertificates = _PEMRootCertificates; options.PEMPrivateKey = _PEMPrivateKey; - options.PEMCertChain = _pemCertChain; + options.PEMCertificateChain = _PEMCertificateChain; options.hostNameOverride = _hostNameOverride; #ifdef GRPC_COMPILE_WITH_CRONET // By old API logic, insecure channel precedes Cronet channel; Cronet channel preceeds default diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 69f70de17d1..3ccc70a7448 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -22,7 +22,6 @@ #import "ChannelArgsUtil.h" #import "GRPCChannel.h" -#import "utilities.h" @implementation GRPCSecureChannelFactory { grpc_channel_credentials *_channelCreds; @@ -116,6 +115,10 @@ } - (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { + NSAssert(host.length != 0, @"host cannot be empty"); + if (host.length == 0) { + return NULL; + } grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 727c9e0a88e..82149e3dba5 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -30,7 +30,6 @@ #import "NSData+GRPC.h" #import "NSDictionary+GRPC.h" #import "NSError+GRPC.h" -#import "utilities.h" #import "GRPCOpBatchLog.h" @@ -237,6 +236,7 @@ #pragma mark GRPCWrappedCall @implementation GRPCWrappedCall { + // pooledChannel holds weak reference to this object so this is ok GRPCPooledChannel *_pooledChannel; grpc_call *_call; } @@ -275,8 +275,7 @@ for (GRPCOperation *operation in operations) { ops_array[i++] = operation.op; } - grpc_call_error 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(); @@ -291,11 +290,7 @@ 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]; - } + NSAssert(error == GRPC_CALL_OK, @"Error starting a batch of operations: %i", error); } } } diff --git a/src/objective-c/GRPCClient/private/utilities.h b/src/objective-c/GRPCClient/private/utilities.h deleted file mode 100644 index 8e3dd793586..00000000000 --- a/src/objective-c/GRPCClient/private/utilities.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * - * 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. - * - */ - -#import - -/** Raise exception when condition not met. */ -#define GRPCAssert(condition, errorString) NSAssert(condition, errorString) From 1a9404876ce0315fc05fe82465dc389600db0965 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 19:07:25 -0800 Subject: [PATCH 238/534] batch fixes --- src/objective-c/GRPCClient/private/GRPCChannel.m | 16 ++++++---------- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.m | 15 ++++++++------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index edcedf6e24f..12acfa14295 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -50,16 +50,17 @@ } - (id)channelFactory { - NSError *error; - id factory; GRPCTransportType type = _callOptions.transportType; switch (type) { case GRPCTransportTypeChttp2BoringSSL: // TODO (mxyan): Remove when the API is deprecated #ifdef GRPC_COMPILE_WITH_CRONET if (![GRPCCall isUsingCronet]) { +#else + { #endif - factory = [GRPCSecureChannelFactory + NSError *error; + id factory = [GRPCSecureChannelFactory factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates privateKey:_callOptions.PEMPrivateKey certChain:_callOptions.PEMCertificateChain @@ -69,9 +70,7 @@ NSLog(@"Error creating secure channel factory: %@", error); } return factory; -#ifdef GRPC_COMPILE_WITH_CRONET } -#endif // fallthrough case GRPCTransportTypeCronet: return [GRPCCronetChannelFactory sharedInstance]; @@ -164,7 +163,7 @@ } - (NSUInteger)hash { - NSUInteger result = 0; + NSUInteger result = 31; result ^= _host.hash; result ^= _callOptions.channelOptionsHash; @@ -230,10 +229,7 @@ NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); if (timeout < 0) return NULL; - grpc_slice host_slice = grpc_empty_slice(); - if (serverAuthority) { - host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); - } + grpc_slice host_slice = serverAuthority ? grpc_slice_from_copied_string(serverAuthority.UTF8String) : grpc_empty_slice(); grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); gpr_timespec deadline_ms = timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index e7a7460221f..24348c3aed7 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -75,7 +75,7 @@ static NSMutableDictionary *gHostCache; } if ((self = [super init])) { - _address = address; + _address = [address copy]; _retryEnabled = YES; gHostCache[address] = self; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 0f63f72f536..89f0b3f3473 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -97,14 +97,13 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { - if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { - [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; - } - if (requestOptions.safety > GRPCCallSafetyCacheableRequest) { - [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; + NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0 && requestOptions.safety <= GRPCCallSafetyCacheableRequest, @"Invalid callOptions."); + NSAssert(handler != nil, @"handler cannot be empty."); + if (requestOptions.host.length == 0 || requestOptions.path.length == 0 || requestOptions.safety > GRPCCallSafetyCacheableRequest) { + return nil; } if (handler == nil) { - [NSException raise:NSInvalidArgumentException format:@"Response handler required."]; + return nil; } if ((self = [super init])) { @@ -166,8 +165,10 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)writeMessage:(GPBMessage *)message { + NSAssert([message isKindOfClass:[GPBMessage class]]); if (![message isKindOfClass:[GPBMessage class]]) { - [NSException raise:NSInvalidArgumentException format:@"Data must be a valid protobuf type."]; + NSLog(@"Failed to send a message that is non-proto."); + return; } GRPCCall2 *call; From f0f6e03212837c67d7e078e6f33074e80aa4bcc0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 22:41:03 -0800 Subject: [PATCH 239/534] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 19 ++--- src/objective-c/GRPCClient/GRPCCallOptions.m | 8 +- .../GRPCClient/private/GRPCChannel.m | 6 +- .../GRPCClient/private/GRPCChannelPool+Test.h | 4 +- .../GRPCClient/private/GRPCChannelPool.h | 2 +- .../GRPCClient/private/GRPCChannelPool.m | 26 ++++--- .../GRPCClient/private/GRPCWrappedCall.h | 2 +- .../GRPCClient/private/GRPCWrappedCall.m | 35 ++++----- src/objective-c/ProtoRPC/ProtoRPC.m | 24 +++--- .../tests/ChannelTests/ChannelTests.m | 49 +++++-------- src/objective-c/tests/InteropTests.m | 73 ++++++++++--------- 12 files changed, 127 insertions(+), 123 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index be63de1af9b..b549f5d2bf3 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -181,7 +181,7 @@ extern NSString *const kGRPCTrailersKey; * error descriptions. */ - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata - error:(nullable NSError *)error; + error:(nullable NSError *)error; @end diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e56cc72149c..589b52031a7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -28,6 +28,8 @@ #include #import "GRPCCallOptions.h" +#import "private/GRPCChannelPool.h" +#import "private/GRPCCompletionQueue.h" #import "private/GRPCConnectivityMonitor.h" #import "private/GRPCHost.h" #import "private/GRPCRequestHeaders.h" @@ -35,8 +37,6 @@ #import "private/NSData+GRPC.h" #import "private/NSDictionary+GRPC.h" #import "private/NSError+GRPC.h" -#import "private/GRPCChannelPool.h" -#import "private/GRPCCompletionQueue.h" // At most 6 ops can be in an op batch for a client: SEND_INITIAL_METADATA, // SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT, RECV_INITIAL_METADATA, RECV_MESSAGE, @@ -259,12 +259,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; } [copiedHandler didCloseWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; }); } else { _handler = nil; @@ -819,7 +819,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - GRPCPooledChannel *channel = [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; + GRPCPooledChannel *channel = + [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:_path completionQueue:[GRPCCompletionQueue completionQueue] callOptions:_callOptions]; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 1962ad8956d..d3440ee6c07 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -233,7 +233,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { copyItems:YES] PEMRootCertificates:[_PEMRootCertificates copy] PEMPrivateKey:[_PEMPrivateKey copy] - PEMCertificateChain:[_PEMCertificateChain copy] + PEMCertificateChain:[_PEMCertificateChain copy] transportType:_transportType hostNameOverride:[_hostNameOverride copy] logContext:_logContext @@ -336,7 +336,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:kDefaultAdditionalChannelArgs PEMRootCertificates:kDefaultPEMRootCertificates PEMPrivateKey:kDefaultPEMPrivateKey - PEMCertificateChain:kDefaultPEMCertificateChain + PEMCertificateChain:kDefaultPEMCertificateChain transportType:kDefaultTransportType hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext @@ -363,7 +363,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:_additionalChannelArgs PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey - PEMCertificateChain:_PEMCertificateChain + PEMCertificateChain:_PEMCertificateChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -391,7 +391,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:[_additionalChannelArgs copy] PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey - PEMCertificateChain:_PEMCertificateChain + PEMCertificateChain:_PEMCertificateChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 12acfa14295..1a79fb04a0d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -57,7 +57,7 @@ #ifdef GRPC_COMPILE_WITH_CRONET if (![GRPCCall isUsingCronet]) { #else - { + { #endif NSError *error; id factory = [GRPCSecureChannelFactory @@ -229,7 +229,9 @@ NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); if (timeout < 0) return NULL; - grpc_slice host_slice = serverAuthority ? grpc_slice_from_copied_string(serverAuthority.UTF8String) : grpc_empty_slice(); + grpc_slice host_slice = serverAuthority + ? grpc_slice_from_copied_string(serverAuthority.UTF8String) + : grpc_empty_slice(); grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); gpr_timespec deadline_ms = timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h index 4e7c988585d..ca0cc51a52c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h @@ -25,7 +25,7 @@ * Initialize a pooled channel with non-default destroy delay for testing purpose. */ - (nullable instancetype)initWithChannelConfiguration: -(GRPCChannelConfiguration *)channelConfiguration + (GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay; /** @@ -45,5 +45,3 @@ - (nullable instancetype)initTestPool; @end - - diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 19ef4c93ac6..d3a99ca8263 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN * Initialize with an actual channel object \a channel and a reference to the channel pool. */ - (nullable instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration; + (GRPCChannelConfiguration *)channelConfiguration; /** * Create a GRPCWrappedCall object (grpc_call) from this channel. If channel is disconnected, get a diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 17c74e558b4..a323f0490c8 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -21,15 +21,15 @@ #import "../internal/GRPCCallOptions+Internal.h" #import "GRPCChannel.h" #import "GRPCChannelFactory.h" -#import "GRPCChannelPool.h" #import "GRPCChannelPool+Test.h" +#import "GRPCChannelPool.h" +#import "GRPCCompletionQueue.h" #import "GRPCConnectivityMonitor.h" #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" -#import "version.h" #import "GRPCWrappedCall.h" -#import "GRPCCompletionQueue.h" +#import "version.h" #import #include @@ -53,10 +53,12 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { - return [self initWithChannelConfiguration:channelConfiguration destroyDelay:kDefaultChannelDestroyDelay]; + return [self initWithChannelConfiguration:channelConfiguration + destroyDelay:kDefaultChannelDestroyDelay]; } -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay { NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); if (channelConfiguration == nil) { @@ -71,8 +73,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; _lastTimedDestroy = nil; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 if (@available(iOS 8.0, macOS 10.10, *)) { - _timerQueue = dispatch_queue_create(NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + _timerQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class( + DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { #else { @@ -115,9 +117,10 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } _lastTimedDestroy = nil; - grpc_call *unmanagedCall = [_wrappedChannel unmanagedCallWithPath:path - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:callOptions]; + grpc_call *unmanagedCall = + [_wrappedChannel unmanagedCallWithPath:path + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:callOptions]; if (unmanagedCall == NULL) { NSAssert(unmanagedCall != NULL, @"Unable to create grpc_call object"); return nil; @@ -203,8 +206,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; + (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ - gChannelPool = - [[GRPCChannelPool alloc] initPrivate]; + gChannelPool = [[GRPCChannelPool alloc] initPrivate]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h index 0432190528f..92bd1be2570 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h @@ -77,7 +77,7 @@ - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; - (instancetype)initWithUnmanagedCall:(grpc_call *)unmanagedCall pooledChannel:(GRPCPooledChannel *)pooledChannel NS_DESIGNATED_INITIALIZER; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 82149e3dba5..9066cb950f4 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -267,7 +267,7 @@ [GRPCOpBatchLog addOpBatchToLog:operations]; #endif - @synchronized (self) { + @synchronized(self) { if (_call != NULL) { size_t nops = operations.count; grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op)); @@ -275,19 +275,20 @@ 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) { - if (!success) { - if (errorHandler) { - errorHandler(); - } else { - return; - } - } - for (GRPCOperation *operation in operations) { - [operation finish]; - } - }), - NULL); + grpc_call_error error = + grpc_call_start_batch(_call, ops_array, nops, (__bridge_retained void *)(^(bool success) { + if (!success) { + if (errorHandler) { + errorHandler(); + } else { + return; + } + } + for (GRPCOperation *operation in operations) { + [operation finish]; + } + }), + NULL); gpr_free(ops_array); NSAssert(error == GRPC_CALL_OK, @"Error starting a batch of operations: %i", error); @@ -296,7 +297,7 @@ } - (void)cancel { - @synchronized (self) { + @synchronized(self) { if (_call != NULL) { grpc_call_cancel(_call, NULL); } @@ -304,7 +305,7 @@ } - (void)channelDisconnected { - @synchronized (self) { + @synchronized(self) { if (_call != NULL) { grpc_call_unref(_call); _call = NULL; @@ -313,7 +314,7 @@ } - (void)dealloc { - @synchronized (self) { + @synchronized(self) { if (_call != NULL) { grpc_call_unref(_call); _call = NULL; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 89f0b3f3473..da534351780 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -97,9 +97,12 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { - NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0 && requestOptions.safety <= GRPCCallSafetyCacheableRequest, @"Invalid callOptions."); + NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0 && + requestOptions.safety <= GRPCCallSafetyCacheableRequest, + @"Invalid callOptions."); NSAssert(handler != nil, @"handler cannot be empty."); - if (requestOptions.host.length == 0 || requestOptions.path.length == 0 || requestOptions.safety > GRPCCallSafetyCacheableRequest) { + if (requestOptions.host.length == 0 || requestOptions.path.length == 0 || + requestOptions.safety > GRPCCallSafetyCacheableRequest) { return nil; } if (handler == nil) { @@ -150,12 +153,12 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing self->_handler = nil; } [copiedHandler didCloseWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; }); } else { _handler = nil; @@ -223,8 +226,9 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing copiedHandler = self->_handler; self->_handler = nil; } - [copiedHandler didCloseWithTrailingMetadata:nil - error:ErrorForBadProto(message, _responseClass, error)]; + [copiedHandler + didCloseWithTrailingMetadata:nil + error:ErrorForBadProto(message, _responseClass, error)]; }); [_call cancel]; _call = nil; diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 7c80868c2c9..df78e8b1162 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -20,8 +20,8 @@ #import "../../GRPCClient/GRPCCallOptions.h" #import "../../GRPCClient/private/GRPCChannel.h" -#import "../../GRPCClient/private/GRPCChannelPool.h" #import "../../GRPCClient/private/GRPCChannelPool+Test.h" +#import "../../GRPCClient/private/GRPCChannelPool.h" #import "../../GRPCClient/private/GRPCCompletionQueue.h" #import "../../GRPCClient/private/GRPCWrappedCall.h" @@ -40,13 +40,12 @@ static NSString *kDummyPath = @"/dummy/path"; - (void)testPooledChannelCreatingChannel { GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost - callOptions:options]; + GRPCChannelConfiguration *config = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options]; GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config]; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + GRPCWrappedCall *wrappedCall = + [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); (void)wrappedCall; } @@ -54,26 +53,22 @@ static NSString *kDummyPath = @"/dummy/path"; - (void)testTimedDestroyChannel { const NSTimeInterval kDestroyDelay = 1.0; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost - callOptions:options]; - GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config - destroyDelay:kDestroyDelay]; + GRPCChannelConfiguration *config = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options]; + GRPCPooledChannel *channel = + [[GRPCPooledChannel alloc] initWithChannelConfiguration:config destroyDelay:kDestroyDelay]; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; GRPCWrappedCall *wrappedCall; GRPCChannel *wrappedChannel; @autoreleasepool { - wrappedCall = [channel wrappedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + wrappedCall = [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); // Unref and ref channel immediately; expect using the same raw channel. wrappedChannel = channel.wrappedChannel; wrappedCall = nil; - wrappedCall = [channel wrappedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + wrappedCall = [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertEqual(channel.wrappedChannel, wrappedChannel); // Unref and ref channel after destroy delay; expect a new raw channel. @@ -81,23 +76,20 @@ static NSString *kDummyPath = @"/dummy/path"; } sleep(kDestroyDelay + 1); XCTAssertNil(channel.wrappedChannel); - wrappedCall = [channel wrappedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + wrappedCall = [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); } - (void)testDisconnect { const NSTimeInterval kDestroyDelay = 1.0; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost - callOptions:options]; - GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config - destroyDelay:kDestroyDelay]; + GRPCChannelConfiguration *config = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options]; + GRPCPooledChannel *channel = + [[GRPCPooledChannel alloc] initWithChannelConfiguration:config destroyDelay:kDestroyDelay]; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + GRPCWrappedCall *wrappedCall = + [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); // Disconnect; expect wrapped channel to be dropped @@ -106,9 +98,8 @@ static NSString *kDummyPath = @"/dummy/path"; // Create a new call and unref the old call; confirm that destroy of the old call does not make // the channel disconnect, even after the destroy delay. - GRPCWrappedCall *wrappedCall2 = [channel wrappedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + GRPCWrappedCall *wrappedCall2 = + [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); GRPCChannel *wrappedChannel = channel.wrappedChannel; wrappedCall = nil; diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index d17a07f929a..3665e9705d8 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -249,8 +249,10 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testLargeUnaryRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectRecvMessage = [self expectationWithDescription:@"LargeUnaryWithV2API received message"]; - __weak XCTestExpectation *expectRecvComplete = [self expectationWithDescription:@"LargeUnaryWithV2API received complete"]; + __weak XCTestExpectation *expectRecvMessage = + [self expectationWithDescription:@"LargeUnaryWithV2API received message"]; + __weak XCTestExpectation *expectRecvComplete = + [self expectationWithDescription:@"LargeUnaryWithV2API received complete"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; request.responseType = RMTPayloadType_Compressable; @@ -263,24 +265,26 @@ BOOL isRemoteInteropTest(NSString *host) { options.hostNameOverride = [[self class] hostNameOverride]; GRPCUnaryProtoCall *call = [_service - unaryCallWithMessage:request - responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - XCTAssertNotNil(message); - if (message) { - RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message]; - expectedResponse.payload.type = RMTPayloadType_Compressable; - expectedResponse.payload.body = [NSMutableData dataWithLength:314159]; - XCTAssertEqualObjects(message, expectedResponse); - - [expectRecvMessage fulfill]; - } - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error, @"Unexpected error: %@", error); - [expectRecvComplete fulfill]; - }] - callOptions:options]; + unaryCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertNotNil(message); + if (message) { + RMTSimpleResponse *expectedResponse = + [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = + [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(message, expectedResponse); + + [expectRecvMessage fulfill]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + [expectRecvComplete fulfill]; + }] + callOptions:options]; [call start]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } @@ -602,7 +606,8 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testCancelAfterBeginRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBeginWithV2API"]; + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"CancelAfterBeginWithV2API"]; // A buffered pipe to which we never write any value acts as a writer that just hangs. __block GRPCStreamingProtoCall *call = [_service @@ -699,7 +704,7 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testCancelAfterFirstRequestWithV2API { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *completionExpectation = - [self expectationWithDescription:@"Call completed."]; + [self expectationWithDescription:@"Call completed."]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = self.class.transportType; @@ -707,20 +712,20 @@ BOOL isRemoteInteropTest(NSString *host) { options.hostNameOverride = [[self class] hostNameOverride]; id request = - [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; + [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; __block GRPCStreamingProtoCall *call = [_service - fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - XCTFail(@"Received unexpected response."); - } - closeCallback:^(NSDictionary *trailingMetadata, - NSError *error) { - XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); - [completionExpectation fulfill]; - }] - callOptions:options]; + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTFail(@"Received unexpected response."); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + [completionExpectation fulfill]; + }] + callOptions:options]; [call start]; [call writeMessage:request]; [call cancel]; From d758ca9196eb157349e6b531218e18849abe65af Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 7 Dec 2018 09:25:54 -0800 Subject: [PATCH 240/534] clang-format --- src/core/lib/surface/init.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index aaa6939c90c..53e3db055dc 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -196,6 +196,4 @@ int grpc_is_initialized(void) { return r; } -void grpc_test_x(void) { - gpr_log(GPR_ERROR, "X"); -} +void grpc_test_x(void) { gpr_log(GPR_ERROR, "X"); } From 7fc52366a093aa23bba5a0daaa6cec0eb43a067f Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 7 Dec 2018 10:01:54 -0800 Subject: [PATCH 241/534] Fix alarm_test --- test/cpp/common/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD index 73fcea94d9f..01699b26add 100644 --- a/test/cpp/common/BUILD +++ b/test/cpp/common/BUILD @@ -26,7 +26,7 @@ grpc_cc_test( ], deps = [ "//:grpc++_unsecure", - "//test/core/util:grpc_test_util", + "//test/core/util:grpc_test_util_unsecure", ], ) From 92db5fc72488f9d62b81ee311a79832df787f3ef Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Dec 2018 10:29:24 -0800 Subject: [PATCH 242/534] Rename getTokenWithHandler --- src/objective-c/GRPCClient/GRPCCall.m | 14 ++++++++++++-- src/objective-c/GRPCClient/GRPCCallOptions.h | 13 ++++++++++++- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 2 +- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 589b52031a7..18f79311a69 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -885,7 +885,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(self) { self.isWaitingForToken = YES; } - [_callOptions.authTokenProvider getTokenWithHandler:^(NSString *token) { + void (^tokenHandler)(NSString *token) = ^(NSString *token) { @synchronized(self) { if (self.isWaitingForToken) { if (token) { @@ -895,7 +895,17 @@ const char *kCFStreamVarName = "grpc_cfstream"; self.isWaitingForToken = NO; } } - }]; + }; + id authTokenProvider = _callOptions.authTokenProvider; + if ([authTokenProvider respondsToSelector:@selector(provideTokenToHandler:)]) { + [_callOptions.authTokenProvider provideTokenToHandler:tokenHandler]; + } else { + NSAssert([authTokenProvider respondsToSelector:@selector(getTokenWithHandler:)], + @"authTokenProvider has no usable method"); + if ([authTokenProvider respondsToSelector:@selector(getTokenWithHandler:)]) { + [_callOptions.authTokenProvider getTokenWithHandler:tokenHandler]; + } + } } else { [self startCallWithWriteable:writeable]; } diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 85786c74174..b7f08480dc0 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -58,13 +58,24 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Implement this protocol to provide a token to gRPC when a call is initiated. */ -@protocol GRPCAuthorizationProtocol +@protocol GRPCAuthorizationProtocol + +@optional + +/** + * This method is called when gRPC is about to start the call. When OAuth token is acquired, + * \a handler is expected to be called with \a token being the new token to be used for this call. + */ +- (void)provideTokenToHandler:(void (^_Nullable)(NSString *_Nullable token))handler; /** + * This method is deprecated. Please use \a provideTokenToHandler. + * * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ - (void)getTokenWithHandler:(void (^_Nullable)(NSString *_Nullable token))handler; + @end @interface GRPCCallOptions : NSObject diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index da534351780..92d7fce33cc 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -168,7 +168,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)writeMessage:(GPBMessage *)message { - NSAssert([message isKindOfClass:[GPBMessage class]]); + NSAssert([message isKindOfClass:[GPBMessage class]], @"Parameter message must be a GPBMessage"); if (![message isKindOfClass:[GPBMessage class]]) { NSLog(@"Failed to send a message that is non-proto."); return; diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index ca7bf472830..fd472aafebd 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -241,7 +241,7 @@ static const NSTimeInterval kTestTimeout = 16; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } -- (void)getTokenWithHandler:(void (^)(NSString *token))handler { +- (void)provideTokenToHandler:(void (^)(NSString *token))handler { dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); dispatch_sync(queue, ^{ handler(@"test-access-token"); From e95d1185e9c594d9df172a9e5be37dc9720c0e10 Mon Sep 17 00:00:00 2001 From: Jihun Cho Date: Tue, 4 Dec 2018 15:40:34 -0800 Subject: [PATCH 243/534] Add grpc-java 1.17.1 to interop matrix --- tools/interop_matrix/client_matrix.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index ff3344cd95d..931beddb9cf 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -207,6 +207,9 @@ LANG_RELEASE_MATRIX = { { 'v1.16.1': None }, + { + 'v1.17.1': None + }, ], 'python': [ { From 2e139e35fcaaabff7a21f85fc8e424ae39d0c586 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 30 Nov 2018 23:24:59 +0100 Subject: [PATCH 244/534] Bazel 0.20.0 workspace fixes. --- WORKSPACE | 2 ++ bazel/grpc_deps.bzl | 35 +++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index a547c24cbe2..c1e63d86e50 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,6 +1,8 @@ workspace(name="com_github_grpc_grpc") load("//bazel:grpc_deps.bzl", "grpc_deps", "grpc_test_only_deps") +load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") + grpc_deps() grpc_test_only_deps() diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 86268178554..82aada24629 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -1,5 +1,8 @@ """Load dependencies needed to compile and test the grpc library as a 3rd-party consumer.""" +load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + def grpc_deps(): """Loads dependencies need to compile and test the grpc library.""" @@ -99,14 +102,14 @@ def grpc_deps(): ) if "boringssl" not in native.existing_rules(): - native.http_archive( + http_archive( name = "boringssl", # on the chromium-stable-with-bazel branch url = "https://boringssl.googlesource.com/boringssl/+archive/afc30d43eef92979b05776ec0963c9cede5fb80f.tar.gz", ) if "com_github_madler_zlib" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_madler_zlib", build_file = "@com_github_grpc_grpc//third_party:zlib.BUILD", strip_prefix = "zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f", @@ -114,14 +117,14 @@ def grpc_deps(): ) if "com_google_protobuf" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_google_protobuf", strip_prefix = "protobuf-48cb18e5c419ddd23d9badcfe4e9df7bde1979b2", url = "https://github.com/google/protobuf/archive/48cb18e5c419ddd23d9badcfe4e9df7bde1979b2.tar.gz", ) if "com_github_nanopb_nanopb" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_nanopb_nanopb", build_file = "@com_github_grpc_grpc//third_party:nanopb.BUILD", strip_prefix = "nanopb-f8ac463766281625ad710900479130c7fcb4d63b", @@ -129,7 +132,7 @@ def grpc_deps(): ) if "com_github_google_googletest" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_google_googletest", build_file = "@com_github_grpc_grpc//third_party:gtest.BUILD", strip_prefix = "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780", @@ -137,14 +140,14 @@ def grpc_deps(): ) if "com_github_gflags_gflags" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_github_gflags_gflags", strip_prefix = "gflags-30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e", url = "https://github.com/gflags/gflags/archive/30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e.tar.gz", ) if "com_github_google_benchmark" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_google_benchmark", build_file = "@com_github_grpc_grpc//third_party:benchmark.BUILD", strip_prefix = "benchmark-9913418d323e64a0111ca0da81388260c2bbe1e9", @@ -152,7 +155,7 @@ def grpc_deps(): ) if "com_github_cares_cares" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_cares_cares", build_file = "@com_github_grpc_grpc//third_party:cares/cares.BUILD", strip_prefix = "c-ares-3be1924221e1326df520f8498d704a5c4c8d0cce", @@ -160,14 +163,14 @@ def grpc_deps(): ) if "com_google_absl" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_google_absl", strip_prefix = "abseil-cpp-cd95e71df6eaf8f2a282b1da556c2cf1c9b09207", url = "https://github.com/abseil/abseil-cpp/archive/cd95e71df6eaf8f2a282b1da556c2cf1c9b09207.tar.gz", ) if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_github_bazelbuild_bazeltoolchains", strip_prefix = "bazel-toolchains-280edaa6f93623074513d2b426068de42e62ea4d", urls = [ @@ -178,7 +181,7 @@ def grpc_deps(): ) if "io_opencensus_cpp" not in native.existing_rules(): - native.http_archive( + http_archive( name = "io_opencensus_cpp", strip_prefix = "opencensus-cpp-fdf0f308b1631bb4a942e32ba5d22536a6170274", url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz", @@ -200,7 +203,7 @@ def grpc_test_only_deps(): ) if "com_github_twisted_twisted" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_twisted_twisted", strip_prefix = "twisted-twisted-17.5.0", url = "https://github.com/twisted/twisted/archive/twisted-17.5.0.zip", @@ -208,7 +211,7 @@ def grpc_test_only_deps(): ) if "com_github_yaml_pyyaml" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_yaml_pyyaml", strip_prefix = "pyyaml-3.12", url = "https://github.com/yaml/pyyaml/archive/3.12.zip", @@ -216,7 +219,7 @@ def grpc_test_only_deps(): ) if "com_github_twisted_incremental" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_twisted_incremental", strip_prefix = "incremental-incremental-17.5.0", url = "https://github.com/twisted/incremental/archive/incremental-17.5.0.zip", @@ -224,7 +227,7 @@ def grpc_test_only_deps(): ) if "com_github_zopefoundation_zope_interface" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_zopefoundation_zope_interface", strip_prefix = "zope.interface-4.4.3", url = "https://github.com/zopefoundation/zope.interface/archive/4.4.3.zip", @@ -232,7 +235,7 @@ def grpc_test_only_deps(): ) if "com_github_twisted_constantly" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_twisted_constantly", strip_prefix = "constantly-15.1.0", url = "https://github.com/twisted/constantly/archive/15.1.0.zip", From d3d8a37a6bdfab94690b75af21c4a4c580c25716 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Sat, 1 Dec 2018 00:42:34 +0100 Subject: [PATCH 245/534] Fix sanity checker. --- tools/run_tests/sanity/check_bazel_workspace.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/run_tests/sanity/check_bazel_workspace.py b/tools/run_tests/sanity/check_bazel_workspace.py index d562fffc8a9..a34f61208e6 100755 --- a/tools/run_tests/sanity/check_bazel_workspace.py +++ b/tools/run_tests/sanity/check_bazel_workspace.py @@ -110,6 +110,8 @@ bazel_file += '\ngrpc_deps()\n' bazel_file += '\ngrpc_test_only_deps()\n' build_rules = { 'native': eval_state, + 'http_archive': lambda **args: eval_state.http_archive(**args), + 'load': lambda a, b: None, } exec bazel_file in build_rules for name in _GRPC_DEP_NAMES: @@ -149,6 +151,8 @@ for name in _GRPC_DEP_NAMES: names_and_urls_with_overridden_name, overridden_name=name) rules = { 'native': state, + 'http_archive': lambda **args: state.http_archive(**args), + 'load': lambda a, b: None, } exec bazel_file in rules assert name not in names_and_urls_with_overridden_name.keys() From bd5d86935f6fdefd22e12eab5c64e7cb1ba7d7bc Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 7 Dec 2018 14:05:48 -0800 Subject: [PATCH 246/534] revert the sample --- src/core/lib/surface/init.cc | 2 -- src/core/lib/surface/init.h | 1 - test/core/util/test_config.cc | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 53e3db055dc..67cf5d89bff 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -195,5 +195,3 @@ int grpc_is_initialized(void) { gpr_mu_unlock(&g_init_mu); return r; } - -void grpc_test_x(void) { gpr_log(GPR_ERROR, "X"); } diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index 2b3e6a64e78..193f51447d9 100644 --- a/src/core/lib/surface/init.h +++ b/src/core/lib/surface/init.h @@ -22,6 +22,5 @@ void grpc_register_security_filters(void); void grpc_security_pre_init(void); void grpc_security_init(void); -void grpc_test_x(void); #endif /* GRPC_CORE_LIB_SURFACE_INIT_H */ diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 5db409343b8..fe80bb2d4d0 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -31,7 +31,6 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/surface/init.h" int64_t g_fixture_slowdown_factor = 1; int64_t g_poller_slowdown_factor = 1; @@ -406,7 +405,7 @@ TestEnvironment::TestEnvironment(int argc, char** argv) { grpc_test_init(argc, argv); } -TestEnvironment::~TestEnvironment() { grpc_test_x(); } +TestEnvironment::~TestEnvironment() {} } // namespace testing } // namespace grpc From df21aab3a6af360cff29a5164f9728ba646d35ab Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Dec 2018 16:01:23 -0800 Subject: [PATCH 247/534] nullability annotation --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.h | 18 ++++++------- src/objective-c/ProtoRPC/ProtoRPC.m | 3 +++ src/objective-c/ProtoRPC/ProtoService.h | 34 ++++++++++++++----------- src/objective-c/ProtoRPC/ProtoService.m | 7 ++--- src/objective-c/tests/GRPCClientTests.m | 3 ++- 6 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 18f79311a69..cfd0de1a8a2 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -485,7 +485,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. - NSAssert(host != nil && path != nil, @"Neither host nor path can be nil."); + NSAssert(host.length != 0 && path.length != 0, @"Neither host nor path can be nil."); NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); NSAssert(requestWriter.state == GRXWriterStateNotStarted, @"The requests writer can't be already started."); diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 2e0400a323f..e6ba1f66ca5 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -70,11 +70,11 @@ NS_ASSUME_NONNULL_BEGIN * Users should not use this initializer directly. Call objects will be created, initialized, and * returned to users by methods of the generated service. */ -- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - message:(GPBMessage *)message - responseHandler:(id)handler - callOptions:(nullable GRPCCallOptions *)callOptions - responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + message:(GPBMessage *)message + responseHandler:(id)handler + callOptions:(nullable GRPCCallOptions *)callOptions + responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** * Start the call. This function must only be called once for each instance. @@ -101,10 +101,10 @@ NS_ASSUME_NONNULL_BEGIN * Users should not use this initializer directly. Call objects will be created, initialized, and * returned to users by methods of the generated service. */ -- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - responseHandler:(id)handler - callOptions:(nullable GRPCCallOptions *)callOptions - responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + responseHandler:(id)handler + callOptions:(nullable GRPCCallOptions *)callOptions + responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** * Start the call. This function must only be called once for each instance. diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 92d7fce33cc..15b0f681ce3 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -57,6 +57,9 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing responseClass:(Class)responseClass { NSAssert(message != nil, @"message cannot be empty."); NSAssert(responseClass != nil, @"responseClass cannot be empty."); + if (message == nil || responseClass == nil) { + return nil; + } if ((self = [super init])) { _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions responseHandler:handler diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 2105de78a38..70423ee9def 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -27,33 +27,35 @@ @class GRPCStreamingProtoCall; @protocol GRPCProtoResponseCallbacks; +NS_ASSUME_NONNULL_BEGIN + __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService : NSObject - - (instancetype)initWithHost : (NSString *)host packageName + (nullable instancetype)initWithHost : (NSString *)host packageName : (NSString *)packageName serviceName : (NSString *)serviceName callOptions - : (GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; + : (nullable GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName serviceName:(NSString *)serviceName; -- (GRPCProtoCall *)RPCToMethod:(NSString *)method - requestsWriter:(GRXWriter *)requestsWriter - responseClass:(Class)responseClass - responsesWriteable:(id)responsesWriteable; +- (nullable GRPCProtoCall *)RPCToMethod:(NSString *)method + requestsWriter:(GRXWriter *)requestsWriter + responseClass:(Class)responseClass + responsesWriteable:(id)responsesWriteable; -- (GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method - message:(id)message - responseHandler:(id)handler - callOptions:(GRPCCallOptions *)callOptions - responseClass:(Class)responseClass; +- (nullable GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method + message:(id)message + responseHandler:(id)handler + callOptions:(nullable GRPCCallOptions *)callOptions + responseClass:(Class)responseClass; -- (GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method - responseHandler:(id)handler - callOptions:(GRPCCallOptions *)callOptions - responseClass:(Class)responseClass; +- (nullable GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method + responseHandler:(id)handler + callOptions:(nullable GRPCCallOptions *)callOptions + responseClass:(Class)responseClass; @end @@ -67,3 +69,5 @@ __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoServ #pragma clang diagnostic pop @end + + NS_ASSUME_NONNULL_END diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m index 6df502fb0c0..3d998bfaeb8 100644 --- a/src/objective-c/ProtoRPC/ProtoService.m +++ b/src/objective-c/ProtoRPC/ProtoService.m @@ -44,9 +44,10 @@ packageName:(NSString *)packageName serviceName:(NSString *)serviceName callOptions:(GRPCCallOptions *)callOptions { - if (!host || !serviceName) { - [NSException raise:NSInvalidArgumentException - format:@"Neither host nor serviceName can be nil."]; + NSAssert(host.length != 0 && packageName.length != 0 && serviceName.length != 0, + @"Invalid parameter."); + if (host.length == 0 || packageName.length == 0 || serviceName.length == 0) { + return nil; } if ((self = [super init])) { _host = [host copy]; diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 2cfdd1a003b..b16720557f7 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -362,9 +362,10 @@ static GRPCProtoMethod *kFullDuplexCallMethod; // TODO(makarandd): Move to a different file that contains only unit tests - (void)testExceptions { + GRXWriter *writer = [GRXWriter writerWithValue:[NSData data]]; // 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:@"" path:@"" requestsWriter:writer]; XCTFail(@"Did not receive an exception when parameters are nil"); } @catch (NSException *theException) { NSLog(@"Received exception as expected: %@", theException.name); From 3f00d61b04874cc5f0159c16f2c598a8f2fb93a7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Dec 2018 16:12:00 -0800 Subject: [PATCH 248/534] batch fix --- .../GRPCClient/private/GRPCWrappedCall.m | 1 + src/objective-c/ProtoRPC/ProtoRPC.m | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 9066cb950f4..4edd9d3e378 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -320,6 +320,7 @@ _call = NULL; } } + // Explicitly converting weak reference _pooledChannel to strong. __strong GRPCPooledChannel *channel = _pooledChannel; [channel notifyWrappedCallDealloc:self]; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 15b0f681ce3..abf224c3cfd 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -140,7 +140,11 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)start { - [_call start]; + GRPCCall2 *copiedCall; + @synchronized(self) { + copiedCall = _call; + } + [copiedCall start]; } - (void)cancel { @@ -177,20 +181,20 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing return; } - GRPCCall2 *call; + GRPCCall2 *copiedCall; @synchronized(self) { - call = _call; + copiedCall = _call; } - [call writeData:[message data]]; + [copiedCall writeData:[message data]]; } - (void)finish { - GRPCCall2 *call; + GRPCCall2 *copiedCall; @synchronized(self) { - call = _call; + copiedCall = _call; _call = nil; } - [call finish]; + [copiedCall finish]; } - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { From cf4e900b82104fe792ca95f1f0b1308dc7a36b11 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Dec 2018 10:08:03 -0800 Subject: [PATCH 249/534] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index e687a65da7d..ddc6ae054d3 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -253,7 +253,8 @@ extern id const kGRPCTrailersKey; + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path; /** - * Set the dispatch queue to be used for callbacks. Current implementation requires \a queue to be a serial queue. + * Set the dispatch queue to be used for callbacks. Current implementation requires \a queue to be a + * serial queue. * * This configuration is only effective before the call starts. */ From ef7d45d2ab2679ecd1ed08f6ce897063a4f783da Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Dec 2018 12:14:24 -0800 Subject: [PATCH 250/534] Add next_value and start_time --- src/core/lib/gpr/sync_posix.cc | 8 ++++++-- src/core/lib/iomgr/exec_ctx.cc | 13 +++++++++++++ src/core/lib/iomgr/timer_manager.cc | 6 ++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 4ded03055c8..6b6c6b6c4b7 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -39,7 +39,8 @@ void (*g_grpc_debug_timer_manager_stats)( int64_t abs_deadline_nsec_value, int64_t now1_sec_value, int64_t now1_nsec_value, int64_t now2_sec_value, int64_t now2_nsec_value, int64_t add_result_sec_value, int64_t add_result_nsec_value, - int64_t sub_result_sec_value, int64_t sub_result_nsec_value) = nullptr; + int64_t sub_result_sec_value, int64_t sub_result_nsec_value, + int64_t next_value, int64_t start_time_sec, int64_t start_time_nsec) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; @@ -58,6 +59,9 @@ int64_t g_add_result_sec_value = -1; int64_t g_add_result_nsec_value = -1; int64_t g_sub_result_sec_value = -1; int64_t g_sub_result_nsec_value = -1; +int64_t g_next_value = -1; +int64_t g_start_time_sec = -1; +int64_t g_start_time_nsec = -1; #endif // GRPC_DEBUG_TIMER_MANAGER #ifdef GPR_LOW_LEVEL_COUNTERS @@ -212,7 +216,7 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { g_abs_deadline_nsec_value, g_now1_sec_value, g_now1_nsec_value, g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value, g_add_result_nsec_value, g_sub_result_sec_value, - g_sub_result_nsec_value); + g_sub_result_nsec_value, g_next_value, g_start_time_sec, g_start_time_nsec); } } #endif diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc index d68fa0714bf..683dd2f6493 100644 --- a/src/core/lib/iomgr/exec_ctx.cc +++ b/src/core/lib/iomgr/exec_ctx.cc @@ -53,6 +53,13 @@ static void exec_ctx_sched(grpc_closure* closure, grpc_error* error) { static gpr_timespec g_start_time; +// For debug of the timer manager crash only. +// TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER +extern int64_t g_start_time_sec; +extern int64_t g_start_time_nsec; +#endif // GRPC_DEBUG_TIMER_MANAGER + static grpc_millis timespec_to_millis_round_down(gpr_timespec ts) { ts = gpr_time_sub(ts, g_start_time); double x = GPR_MS_PER_SEC * static_cast(ts.tv_sec) + @@ -117,6 +124,12 @@ void ExecCtx::TestOnlyGlobalInit(gpr_timespec new_val) { void ExecCtx::GlobalInit(void) { g_start_time = gpr_now(GPR_CLOCK_MONOTONIC); + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER + g_start_time_sec = g_start_time.tv_sec; + g_start_time_nsec = g_start_time.tv_nsec; +#endif gpr_tls_init(&exec_ctx_); } diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index ceba79f6783..143a96c9bc2 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -67,6 +67,7 @@ static void timer_thread(void* completed_thread_ptr); extern int64_t g_timer_manager_init_count; extern int64_t g_timer_manager_shutdown_count; extern int64_t g_fork_count; +extern int64_t g_next_value; #endif // GRPC_DEBUG_TIMER_MANAGER static void gc_completed_threads(void) { @@ -193,6 +194,11 @@ static bool wait_until(grpc_millis next) { gpr_log(GPR_INFO, "sleep until kicked"); } + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER + g_next_value = next; +#endif gpr_cv_wait(&g_cv_wait, &g_mu, grpc_millis_to_timespec(next, GPR_CLOCK_MONOTONIC)); From eea5f1ad3dee4d96c9b86efe89f75c973cc57eed Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Dec 2018 12:38:05 -0800 Subject: [PATCH 251/534] Missing nullable --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index b549f5d2bf3..4ef8cee36de 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -282,7 +282,7 @@ NS_ASSUME_NONNULL_END */ @interface GRPCCall : GRXWriter -- (instancetype)init NS_UNAVAILABLE; +- (nullable instancetype)init NS_UNAVAILABLE; /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of From e9dd13bfcf8d5e699582b92376548038ab635c7c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Dec 2018 12:51:33 -0800 Subject: [PATCH 252/534] clang-format --- src/core/lib/gpr/sync_posix.cc | 6 ++++-- src/core/lib/iomgr/timer_manager.cc | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 6b6c6b6c4b7..c09a7598acb 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -40,7 +40,8 @@ void (*g_grpc_debug_timer_manager_stats)( int64_t now1_nsec_value, int64_t now2_sec_value, int64_t now2_nsec_value, int64_t add_result_sec_value, int64_t add_result_nsec_value, int64_t sub_result_sec_value, int64_t sub_result_nsec_value, - int64_t next_value, int64_t start_time_sec, int64_t start_time_nsec) = nullptr; + int64_t next_value, int64_t start_time_sec, + int64_t start_time_nsec) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; @@ -216,7 +217,8 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { g_abs_deadline_nsec_value, g_now1_sec_value, g_now1_nsec_value, g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value, g_add_result_nsec_value, g_sub_result_sec_value, - g_sub_result_nsec_value, g_next_value, g_start_time_sec, g_start_time_nsec); + g_sub_result_nsec_value, g_next_value, g_start_time_sec, + g_start_time_nsec); } } #endif diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index 143a96c9bc2..cb123298cf5 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -194,8 +194,8 @@ static bool wait_until(grpc_millis next) { gpr_log(GPR_INFO, "sleep until kicked"); } - // For debug of the timer manager crash only. - // TODO (mxyan): remove after bug is fixed. + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER g_next_value = next; #endif From f52e54235294cb71c09d880e8f78a6661b2803f2 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 10 Dec 2018 12:45:00 -0800 Subject: [PATCH 253/534] Add pagination to serversockets --- src/core/lib/channel/channelz.cc | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 0cb28905181..8d449ee6721 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -204,16 +204,27 @@ ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes) ServerNode::~ServerNode() {} char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { + const int kPaginationLimit = 100; grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; ChildSocketsList socket_refs; grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id); + int sockets_added = 0; + bool reached_pagination_limit = false; if (!socket_refs.empty()) { // create list of socket refs grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); for (size_t i = 0; i < socket_refs.size(); ++i) { + // check if we are over pagination limit to determine if we need to set + // the "end" element. If we don't go through this block, we know that + // when the loop terminates, we have <= to kPaginationLimit. + if (sockets_added == kPaginationLimit) { + reached_pagination_limit = true; + break; + } + sockets_added++; grpc_json* socket_ref_json = grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false); @@ -223,11 +234,10 @@ char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { socket_refs[i]->remote(), GRPC_JSON_STRING, false); } } - // For now we do not have any pagination rules. In the future we could - // pick a constant for max_channels_sent for a GetServers request. - // Tracking: https://github.com/grpc/grpc/issues/16019. - json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, - GRPC_JSON_TRUE, false); + if (!reached_pagination_limit) { + json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, + GRPC_JSON_TRUE, false); + } char* json_str = grpc_json_dump_to_string(top_level_json, 0); grpc_json_destroy(top_level_json); return json_str; From 8cb2d0546d14574977c4943d33bb103954078bbd Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 10 Dec 2018 16:19:35 -0800 Subject: [PATCH 254/534] Upgrade sanity Docker image to debian:stretch * Use latest pylint in Python 3.7 (they dropped support for PY2) * Make latest pylint happy * Forced to upgrade to shellcheck 0.4.4 * Make shellcheck 0.4.4 happy * Adopt reviewers' advice to reduce global disabled rules --- .pylintrc | 10 +++++ .pylintrc-tests | 6 +++ src/python/grpcio/grpc/_auth.py | 2 +- src/python/grpcio/grpc/_channel.py | 14 +++---- src/python/grpcio/grpc/_utilities.py | 3 -- .../grpc_testing/_server/_handler.py | 2 +- src/python/grpcio_tests/tests/_runner.py | 2 +- .../protoc_plugin/_split_definitions_test.py | 8 ++-- .../protoc_plugin/beta_python_plugin_test.py | 2 +- .../tests/qps/benchmark_client.py | 2 +- .../grpcio_tests/tests/qps/client_runner.py | 2 +- .../grpcio_tests/tests/qps/worker_server.py | 2 +- .../grpcio_tests/tests/stress/client.py | 4 +- .../tests/testing/_client_application.py | 4 +- .../tests/unit/_from_grpc_import_star.py | 2 +- .../test/sanity/Dockerfile.template | 22 +++++------ tools/distrib/pylint_code.sh | 6 +-- tools/dockerfile/test/sanity/Dockerfile | 38 +++++++++---------- .../artifacts/build_artifact_protoc.sh | 1 + .../artifacts/build_artifact_ruby.sh | 2 + tools/run_tests/artifacts/run_in_workspace.sh | 3 +- .../dockerize/build_and_run_docker.sh | 2 +- .../dockerize/build_docker_and_run_tests.sh | 4 +- .../dockerize/build_interop_image.sh | 2 +- tools/run_tests/dockerize/docker_run_tests.sh | 1 + .../run_tests/helper_scripts/run_grpc-node.sh | 2 + .../helper_scripts/run_tests_in_workspace.sh | 3 +- tools/run_tests/interop/with_nvm.sh | 1 + tools/run_tests/interop/with_rvm.sh | 1 + .../performance/build_performance.sh | 1 + .../performance/build_performance_go.sh | 3 +- .../performance/build_performance_node.sh | 1 + tools/run_tests/performance/run_worker_go.sh | 3 +- .../run_tests/performance/run_worker_node.sh | 1 + tools/run_tests/performance/run_worker_php.sh | 1 + .../run_tests/performance/run_worker_ruby.sh | 1 + 36 files changed, 94 insertions(+), 70 deletions(-) diff --git a/.pylintrc b/.pylintrc index 90e8989ffcc..ba74decb047 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,3 +1,11 @@ +[MASTER] +ignore= + src/python/grpcio/grpc/beta, + src/python/grpcio/grpc/framework, + src/python/grpcio/grpc/framework/common, + src/python/grpcio/grpc/framework/foundation, + src/python/grpcio/grpc/framework/interfaces, + [VARIABLES] # TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection @@ -82,3 +90,5 @@ disable= # if:/else: and for:/else:. useless-else-on-loop, no-else-return, + # NOTE(lidiz): Python 3 make object inheritance default, but not PY2 + useless-object-inheritance, diff --git a/.pylintrc-tests b/.pylintrc-tests index e68755c674e..0d408fbb565 100644 --- a/.pylintrc-tests +++ b/.pylintrc-tests @@ -1,3 +1,7 @@ +[MASTER] +ignore-patterns= + .+?(beta|framework).+?\.py + [VARIABLES] # TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection @@ -115,3 +119,5 @@ disable= # if:/else: and for:/else:. useless-else-on-loop, no-else-return, + # NOTE(lidiz): Python 3 make object inheritance default, but not PY2 + useless-object-inheritance, diff --git a/src/python/grpcio/grpc/_auth.py b/src/python/grpcio/grpc/_auth.py index c17824563d7..9b990f490de 100644 --- a/src/python/grpcio/grpc/_auth.py +++ b/src/python/grpcio/grpc/_auth.py @@ -46,7 +46,7 @@ class GoogleCallCredentials(grpc.AuthMetadataPlugin): # Hack to determine if these are JWT creds and we need to pass # additional_claims when getting a token - self._is_jwt = 'additional_claims' in inspect.getargspec( + self._is_jwt = 'additional_claims' in inspect.getargspec( # pylint: disable=deprecated-method credentials.get_access_token).args def __call__(self, context, callback): diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 35fa82d56bd..951c6f33ff5 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -525,7 +525,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): state, operations, deadline, rendezvous = self._prepare( request, timeout, metadata, wait_for_ready) if state is None: - raise rendezvous + raise rendezvous # pylint: disable-msg=raising-bad-type else: call = self._channel.segregated_call( 0, self._method, None, deadline, metadata, None @@ -535,7 +535,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): ),)) event = call.next_event() _handle_event(event, state, self._response_deserializer) - return state, call, + return state, call def __call__(self, request, @@ -566,7 +566,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): state, operations, deadline, rendezvous = self._prepare( request, timeout, metadata, wait_for_ready) if state is None: - raise rendezvous + raise rendezvous # pylint: disable-msg=raising-bad-type else: event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( @@ -599,7 +599,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) if serialized_request is None: - raise rendezvous + raise rendezvous # pylint: disable-msg=raising-bad-type else: state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None) operationses = ( @@ -653,7 +653,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): state.condition.notify_all() if not state.due: break - return state, call, + return state, call def __call__(self, request_iterator, @@ -745,10 +745,10 @@ class _InitialMetadataFlags(int): def with_wait_for_ready(self, wait_for_ready): if wait_for_ready is not None: if wait_for_ready: - self = self.__class__(self | cygrpc.InitialMetadataFlags.wait_for_ready | \ + return self.__class__(self | cygrpc.InitialMetadataFlags.wait_for_ready | \ cygrpc.InitialMetadataFlags.wait_for_ready_explicitly_set) elif not wait_for_ready: - self = self.__class__(self & ~cygrpc.InitialMetadataFlags.wait_for_ready | \ + return self.__class__(self & ~cygrpc.InitialMetadataFlags.wait_for_ready | \ cygrpc.InitialMetadataFlags.wait_for_ready_explicitly_set) return self diff --git a/src/python/grpcio/grpc/_utilities.py b/src/python/grpcio/grpc/_utilities.py index d90b34bcbd4..2938a38b44e 100644 --- a/src/python/grpcio/grpc/_utilities.py +++ b/src/python/grpcio/grpc/_utilities.py @@ -132,15 +132,12 @@ class _ChannelReadyFuture(grpc.Future): def result(self, timeout=None): self._block(timeout) - return None def exception(self, timeout=None): self._block(timeout) - return None def traceback(self, timeout=None): self._block(timeout) - return None def add_done_callback(self, fn): with self._condition: diff --git a/src/python/grpcio_testing/grpc_testing/_server/_handler.py b/src/python/grpcio_testing/grpc_testing/_server/_handler.py index 0e3404b0d06..100d8195f62 100644 --- a/src/python/grpcio_testing/grpc_testing/_server/_handler.py +++ b/src/python/grpcio_testing/grpc_testing/_server/_handler.py @@ -185,7 +185,7 @@ class _Handler(Handler): elif self._code is None: self._condition.wait() else: - return self._trailing_metadata, self._code, self._details, + return self._trailing_metadata, self._code, self._details def expire(self): with self._condition: diff --git a/src/python/grpcio_tests/tests/_runner.py b/src/python/grpcio_tests/tests/_runner.py index eaaa027e61f..9ef0f176840 100644 --- a/src/python/grpcio_tests/tests/_runner.py +++ b/src/python/grpcio_tests/tests/_runner.py @@ -203,7 +203,7 @@ class Runner(object): check_kill_self() time.sleep(0) case_thread.join() - except: + except: # pylint: disable=try-except-raise # re-raise the exception after forcing the with-block to end raise result.set_output(augmented_case.case, stdout_pipe.output(), diff --git a/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py index e21ea0010ad..2b735526cb0 100644 --- a/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py +++ b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py @@ -144,7 +144,7 @@ class _ProtoBeforeGrpcProtocStyle(object): absolute_proto_file_names) pb2_grpc_protoc_exit_code = _protoc( proto_path, None, 'grpc_2_0', python_out, absolute_proto_file_names) - return pb2_protoc_exit_code, pb2_grpc_protoc_exit_code, + return pb2_protoc_exit_code, pb2_grpc_protoc_exit_code class _GrpcBeforeProtoProtocStyle(object): @@ -160,7 +160,7 @@ class _GrpcBeforeProtoProtocStyle(object): proto_path, None, 'grpc_2_0', python_out, absolute_proto_file_names) pb2_protoc_exit_code = _protoc(proto_path, python_out, None, None, absolute_proto_file_names) - return pb2_grpc_protoc_exit_code, pb2_protoc_exit_code, + return pb2_grpc_protoc_exit_code, pb2_protoc_exit_code _PROTOC_STYLES = ( @@ -243,9 +243,9 @@ class _Test(six.with_metaclass(abc.ABCMeta, unittest.TestCase)): def _services_modules(self): if self.PROTOC_STYLE.grpc_in_pb2_expected(): - return self._services_pb2, self._services_pb2_grpc, + return self._services_pb2, self._services_pb2_grpc else: - return self._services_pb2_grpc, + return (self._services_pb2_grpc,) def test_imported_attributes(self): self._protoc() diff --git a/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py b/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py index b46e53315e6..43c90af6a70 100644 --- a/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py +++ b/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py @@ -223,7 +223,7 @@ def _CreateService(payload_pb2, responses_pb2, service_pb2): server.start() channel = implementations.insecure_channel('localhost', port) stub = getattr(service_pb2, STUB_FACTORY_IDENTIFIER)(channel) - yield servicer_methods, stub, + yield servicer_methods, stub server.stop(0) diff --git a/src/python/grpcio_tests/tests/qps/benchmark_client.py b/src/python/grpcio_tests/tests/qps/benchmark_client.py index 0488450740a..fac0e44e5a4 100644 --- a/src/python/grpcio_tests/tests/qps/benchmark_client.py +++ b/src/python/grpcio_tests/tests/qps/benchmark_client.py @@ -180,7 +180,7 @@ class StreamingSyncBenchmarkClient(BenchmarkClient): self._streams = [ _SyncStream(self._stub, self._generic, self._request, self._handle_response) - for _ in xrange(config.outstanding_rpcs_per_channel) + for _ in range(config.outstanding_rpcs_per_channel) ] self._curr_stream = 0 diff --git a/src/python/grpcio_tests/tests/qps/client_runner.py b/src/python/grpcio_tests/tests/qps/client_runner.py index e79abab3c71..a57524c74e3 100644 --- a/src/python/grpcio_tests/tests/qps/client_runner.py +++ b/src/python/grpcio_tests/tests/qps/client_runner.py @@ -77,7 +77,7 @@ class ClosedLoopClientRunner(ClientRunner): def start(self): self._is_running = True self._client.start() - for _ in xrange(self._request_count): + for _ in range(self._request_count): self._client.send_request() def stop(self): diff --git a/src/python/grpcio_tests/tests/qps/worker_server.py b/src/python/grpcio_tests/tests/qps/worker_server.py index 337a94b546c..a03367ec63a 100644 --- a/src/python/grpcio_tests/tests/qps/worker_server.py +++ b/src/python/grpcio_tests/tests/qps/worker_server.py @@ -109,7 +109,7 @@ class WorkerServer(worker_service_pb2_grpc.WorkerServiceServicer): start_time = time.time() # Create a client for each channel - for i in xrange(config.client_channels): + for i in range(config.client_channels): server = config.server_targets[i % len(config.server_targets)] runner = self._create_client_runner(server, config, qps_data) client_runners.append(runner) diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py index 41f2e1b6c2d..a318b308e61 100644 --- a/src/python/grpcio_tests/tests/stress/client.py +++ b/src/python/grpcio_tests/tests/stress/client.py @@ -132,9 +132,9 @@ def run_test(args): server.start() for test_server_target in test_server_targets: - for _ in xrange(args.num_channels_per_server): + for _ in range(args.num_channels_per_server): channel = _get_channel(test_server_target, args) - for _ in xrange(args.num_stubs_per_channel): + for _ in range(args.num_stubs_per_channel): stub = test_pb2_grpc.TestServiceStub(channel) runner = test_runner.TestRunner(stub, test_cases, hist, exception_queue, stop_event) diff --git a/src/python/grpcio_tests/tests/testing/_client_application.py b/src/python/grpcio_tests/tests/testing/_client_application.py index 3ddeba23735..4d42df03897 100644 --- a/src/python/grpcio_tests/tests/testing/_client_application.py +++ b/src/python/grpcio_tests/tests/testing/_client_application.py @@ -130,9 +130,9 @@ def _run_stream_stream(stub): request_pipe = _Pipe() response_iterator = stub.StreStre(iter(request_pipe)) request_pipe.add(_application_common.STREAM_STREAM_REQUEST) - first_responses = next(response_iterator), next(response_iterator), + first_responses = next(response_iterator), next(response_iterator) request_pipe.add(_application_common.STREAM_STREAM_REQUEST) - second_responses = next(response_iterator), next(response_iterator), + second_responses = next(response_iterator), next(response_iterator) request_pipe.close() try: next(response_iterator) diff --git a/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py b/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py index ad847ae03eb..1ada25382de 100644 --- a/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py +++ b/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py @@ -14,7 +14,7 @@ _BEFORE_IMPORT = tuple(globals()) -from grpc import * # pylint: disable=wildcard-import +from grpc import * # pylint: disable=wildcard-import,unused-wildcard-import _AFTER_IMPORT = tuple(globals()) diff --git a/templates/tools/dockerfile/test/sanity/Dockerfile.template b/templates/tools/dockerfile/test/sanity/Dockerfile.template index eac7f2ab013..a4f9183beac 100644 --- a/templates/tools/dockerfile/test/sanity/Dockerfile.template +++ b/templates/tools/dockerfile/test/sanity/Dockerfile.template @@ -14,28 +14,24 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie - - <%include file="../../apt_get_basic.include"/> - <%include file="../../gcp_api_libraries.include"/> - <%include file="../../python_deps.include"/> + <%include file="../../python_stretch.include"/> <%include file="../../cxx_deps.include"/> #======================== # Sanity test dependencies + RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev + RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 + # Make Python 3.7 the default Python 3 version + RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 1 RUN apt-get update && apt-get install -y ${"\\"} - python-pip ${"\\"} autoconf ${"\\"} automake ${"\\"} libtool ${"\\"} curl ${"\\"} - python-virtualenv ${"\\"} - python-lxml ${"\\"} shellcheck - RUN pip install simplejson mako - + RUN python2 -m pip install simplejson mako virtualenv lxml + RUN python3 -m pip install simplejson mako virtualenv lxml + <%include file="../../clang5.include"/> - <%include file="../../run_tests_addons.include"/> - + # Define the default command. CMD ["bash"] - diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh index d17eb9fdb82..cb3966d6914 100755 --- a/tools/distrib/pylint_code.sh +++ b/tools/distrib/pylint_code.sh @@ -31,12 +31,12 @@ TEST_DIRS=( ) VIRTUALENV=python_pylint_venv -python -m virtualenv $VIRTUALENV +python3 -m virtualenv $VIRTUALENV PYTHON=$VIRTUALENV/bin/python -$PYTHON -m pip install --upgrade pip==10.0.1 -$PYTHON -m pip install pylint==1.9.2 +$PYTHON -m pip install --upgrade pip==18.1 +$PYTHON -m pip install --upgrade pylint==2.2.2 EXIT=0 for dir in "${DIRS[@]}"; do diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile index e6bdb4ee035..aeee02a50fa 100644 --- a/tools/dockerfile/test/sanity/Dockerfile +++ b/tools/dockerfile/test/sanity/Dockerfile @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM debian:jessie - +FROM debian:stretch + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ @@ -53,20 +53,19 @@ RUN apt-get update && apt-get install -y time && apt-get clean RUN apt-get update && apt-get install -y python-pip && apt-get clean RUN pip install --upgrade google-api-python-client oauth2client -#==================== -# Python dependencies +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 -# Install dependencies +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local -RUN apt-get update && apt-get install -y \ - python-all-dev \ - python3-all-dev \ - python-pip -# Install Python packages from PyPI -RUN pip install --upgrade pip==10.0.1 -RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0 +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] #================= # C++ dependencies @@ -74,16 +73,18 @@ RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev c #======================== # Sanity test dependencies +RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 +# Make Python 3.7 the default Python 3 version +RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 1 RUN apt-get update && apt-get install -y \ - python-pip \ autoconf \ automake \ libtool \ curl \ - python-virtualenv \ - python-lxml \ shellcheck -RUN pip install simplejson mako +RUN python2 -m pip install simplejson mako virtualenv lxml +RUN python3 -m pip install simplejson mako virtualenv lxml RUN apt-get update && apt-get -y install wget xz-utils RUN wget http://releases.llvm.org/5.0.0/clang+llvm-5.0.0-linux-x86_64-ubuntu14.04.tar.xz @@ -94,8 +95,5 @@ RUN ln -s /clang+llvm-5.0.0-linux-x86_64-ubuntu14.04/bin/clang-tidy /usr/local/b ENV CLANG_TIDY=clang-tidy -RUN mkdir /var/local/jenkins - - # Define the default command. CMD ["bash"] diff --git a/tools/run_tests/artifacts/build_artifact_protoc.sh b/tools/run_tests/artifacts/build_artifact_protoc.sh index 6d433f2dad4..a5b6e2f3482 100755 --- a/tools/run_tests/artifacts/build_artifact_protoc.sh +++ b/tools/run_tests/artifacts/build_artifact_protoc.sh @@ -14,6 +14,7 @@ # limitations under the License. # Use devtoolset environment that has GCC 4.8 before set -ex +# shellcheck disable=SC1091 source scl_source enable devtoolset-2 set -ex diff --git a/tools/run_tests/artifacts/build_artifact_ruby.sh b/tools/run_tests/artifacts/build_artifact_ruby.sh index 5ab4cf21b4e..c910374376d 100755 --- a/tools/run_tests/artifacts/build_artifact_ruby.sh +++ b/tools/run_tests/artifacts/build_artifact_ruby.sh @@ -18,7 +18,9 @@ SYSTEM=$(uname | cut -f 1 -d_) cd "$(dirname "$0")/../../.." set +ex +# shellcheck disable=SC1091 [[ -s /etc/profile.d/rvm.sh ]] && . /etc/profile.d/rvm.sh +# shellcheck disable=SC1090 [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" set -ex diff --git a/tools/run_tests/artifacts/run_in_workspace.sh b/tools/run_tests/artifacts/run_in_workspace.sh index 20181e077c2..f4719b0a4ae 100755 --- a/tools/run_tests/artifacts/run_in_workspace.sh +++ b/tools/run_tests/artifacts/run_in_workspace.sh @@ -19,7 +19,8 @@ set -ex cd "$(dirname "$0")/../../.." -export repo_root=$(pwd) +repo_root=$(pwd) +export repo_root # TODO: fix file to pass shellcheck diff --git a/tools/run_tests/dockerize/build_and_run_docker.sh b/tools/run_tests/dockerize/build_and_run_docker.sh index 3f01fbc7b7d..9d0efc8b407 100755 --- a/tools/run_tests/dockerize/build_and_run_docker.sh +++ b/tools/run_tests/dockerize/build_and_run_docker.sh @@ -20,7 +20,7 @@ set -ex cd "$(dirname "$0")/../../.." git_root=$(pwd) -cd - +cd - # shellcheck disable=SC2103 # Inputs # DOCKERFILE_DIR - Directory in which Dockerfile file is located. diff --git a/tools/run_tests/dockerize/build_docker_and_run_tests.sh b/tools/run_tests/dockerize/build_docker_and_run_tests.sh index 1741b3268be..a63e1be96d2 100755 --- a/tools/run_tests/dockerize/build_docker_and_run_tests.sh +++ b/tools/run_tests/dockerize/build_docker_and_run_tests.sh @@ -20,7 +20,7 @@ set -ex cd "$(dirname "$0")/../../.." git_root=$(pwd) -cd - +cd - # shellcheck disable=SC2103 # Inputs # DOCKERFILE_DIR - Directory in which Dockerfile file is located. @@ -48,7 +48,7 @@ docker_instance_git_root=/var/local/jenkins/grpc # Run tests inside docker DOCKER_EXIT_CODE=0 # TODO: silence complaint about $TTY_FLAG expansion in some other way -# shellcheck disable=SC2086 +# shellcheck disable=SC2086,SC2154 docker run \ --cap-add SYS_PTRACE \ -e "RUN_TESTS_COMMAND=$RUN_TESTS_COMMAND" \ diff --git a/tools/run_tests/dockerize/build_interop_image.sh b/tools/run_tests/dockerize/build_interop_image.sh index 126dd4065e0..0f88787639a 100755 --- a/tools/run_tests/dockerize/build_interop_image.sh +++ b/tools/run_tests/dockerize/build_interop_image.sh @@ -16,7 +16,7 @@ # This script is invoked by run_interop_tests.py to build the docker image # for interop testing. You should never need to call this script on your own. -set -x +set -ex # Params: # INTEROP_IMAGE - name of tag of the final interop image diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh index b7686e48ba3..5214938208b 100755 --- a/tools/run_tests/dockerize/docker_run_tests.sh +++ b/tools/run_tests/dockerize/docker_run_tests.sh @@ -18,6 +18,7 @@ set -e +# shellcheck disable=SC2154 export CONFIG=$config export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer export PATH=$PATH:/usr/bin/llvm-symbolizer diff --git a/tools/run_tests/helper_scripts/run_grpc-node.sh b/tools/run_tests/helper_scripts/run_grpc-node.sh index 747aae7fd57..d14753a4d54 100755 --- a/tools/run_tests/helper_scripts/run_grpc-node.sh +++ b/tools/run_tests/helper_scripts/run_grpc-node.sh @@ -16,6 +16,8 @@ # This script runs grpc/grpc-node tests with their grpc submodule updated # to this reference +set -ex + # cd to gRPC root directory cd "$(dirname "$0")/../../.." diff --git a/tools/run_tests/helper_scripts/run_tests_in_workspace.sh b/tools/run_tests/helper_scripts/run_tests_in_workspace.sh index 790c0418816..fa7a7aac0a0 100755 --- a/tools/run_tests/helper_scripts/run_tests_in_workspace.sh +++ b/tools/run_tests/helper_scripts/run_tests_in_workspace.sh @@ -20,7 +20,8 @@ set -ex cd "$(dirname "$0")/../../.." -export repo_root="$(pwd)" +repo_root="$(pwd)" +export repo_root rm -rf "${WORKSPACE_NAME}" git clone . "${WORKSPACE_NAME}" diff --git a/tools/run_tests/interop/with_nvm.sh b/tools/run_tests/interop/with_nvm.sh index 887f9f6a9f2..55f4b2b8759 100755 --- a/tools/run_tests/interop/with_nvm.sh +++ b/tools/run_tests/interop/with_nvm.sh @@ -15,5 +15,6 @@ # limitations under the License. # Makes sure NVM is loaded before executing the command passed as an argument +# shellcheck disable=SC1090 source ~/.nvm/nvm.sh "$@" diff --git a/tools/run_tests/interop/with_rvm.sh b/tools/run_tests/interop/with_rvm.sh index 41e6efcb566..82bce9da125 100755 --- a/tools/run_tests/interop/with_rvm.sh +++ b/tools/run_tests/interop/with_rvm.sh @@ -15,5 +15,6 @@ # limitations under the License. # Makes sure RVM is loaded before executing the command passed as an argument +# shellcheck disable=SC1091 source /usr/local/rvm/scripts/rvm "$@" diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh index ab6bffdc34a..6c22e2d37d0 100755 --- a/tools/run_tests/performance/build_performance.sh +++ b/tools/run_tests/performance/build_performance.sh @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC1090 source ~/.rvm/scripts/rvm set -ex diff --git a/tools/run_tests/performance/build_performance_go.sh b/tools/run_tests/performance/build_performance_go.sh index 812728d4ceb..3aa203a6eed 100755 --- a/tools/run_tests/performance/build_performance_go.sh +++ b/tools/run_tests/performance/build_performance_go.sh @@ -17,7 +17,8 @@ set -ex cd "$(dirname "$0")/../../.." -export GOPATH=$(pwd)/../gopath +GOPATH=$(pwd)/../gopath +export GOPATH # Get grpc-go and the dependencies but get rid of the upstream/master version go get google.golang.org/grpc diff --git a/tools/run_tests/performance/build_performance_node.sh b/tools/run_tests/performance/build_performance_node.sh index 12e08722648..b5b5d9a1a27 100755 --- a/tools/run_tests/performance/build_performance_node.sh +++ b/tools/run_tests/performance/build_performance_node.sh @@ -15,6 +15,7 @@ set +ex +# shellcheck disable=SC1090 . "$HOME/.nvm/nvm.sh" nvm install 10 diff --git a/tools/run_tests/performance/run_worker_go.sh b/tools/run_tests/performance/run_worker_go.sh index f8e821a2656..1127f4f25ac 100755 --- a/tools/run_tests/performance/run_worker_go.sh +++ b/tools/run_tests/performance/run_worker_go.sh @@ -17,6 +17,7 @@ set -ex cd "$(dirname "$0")/../../.." -export GOPATH=$(pwd)/../gopath +GOPATH=$(pwd)/../gopath +export GOPATH "${GOPATH}/bin/worker" "$@" diff --git a/tools/run_tests/performance/run_worker_node.sh b/tools/run_tests/performance/run_worker_node.sh index 3e5dd18edb3..658cd508116 100755 --- a/tools/run_tests/performance/run_worker_node.sh +++ b/tools/run_tests/performance/run_worker_node.sh @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC1090 . "$HOME/.nvm/nvm.sh" nvm use 10 diff --git a/tools/run_tests/performance/run_worker_php.sh b/tools/run_tests/performance/run_worker_php.sh index 2fe2493e601..97292a9978f 100755 --- a/tools/run_tests/performance/run_worker_php.sh +++ b/tools/run_tests/performance/run_worker_php.sh @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC1090 source ~/.rvm/scripts/rvm set -ex diff --git a/tools/run_tests/performance/run_worker_ruby.sh b/tools/run_tests/performance/run_worker_ruby.sh index 729c5cec977..ed448463360 100755 --- a/tools/run_tests/performance/run_worker_ruby.sh +++ b/tools/run_tests/performance/run_worker_ruby.sh @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC1090 source ~/.rvm/scripts/rvm set -ex From 20c8cc72920b14520160c4e2001caec2b8acddc0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Dec 2018 18:06:34 -0800 Subject: [PATCH 255/534] nullability failing --- src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h index ca0cc51a52c..e2c3aee3d92 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h @@ -18,6 +18,8 @@ #import "GRPCChannelPool.h" +NS_ASSUME_NONNULL_BEGIN + /** Test-only interface for \a GRPCPooledChannel. */ @interface GRPCPooledChannel (Test) @@ -31,7 +33,7 @@ /** * Return the pointer to the raw channel wrapped. */ -@property(atomic, readonly) GRPCChannel *wrappedChannel; +@property(atomic, readonly, nullable) GRPCChannel *wrappedChannel; @end @@ -45,3 +47,5 @@ - (nullable instancetype)initTestPool; @end + +NS_ASSUME_NONNULL_END From c5f344deaf84bd074419d42ed4af47e7c9ca6b42 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 11 Dec 2018 07:48:14 -0800 Subject: [PATCH 256/534] Revert "Revert "Allow encoding arbitrary channel args on a per-address basis."" --- BUILD | 3 +- CMakeLists.txt | 12 +- Makefile | 12 +- build.yaml | 3 +- config.m4 | 2 +- config.w32 | 2 +- gRPC-C++.podspec | 1 + gRPC-Core.podspec | 4 +- grpc.gemspec | 3 +- grpc.gyp | 8 +- package.xml | 3 +- .../filters/client_channel/client_channel.cc | 16 +- .../ext/filters/client_channel/lb_policy.h | 9 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 242 +++++++---------- .../lb_policy/grpclb/grpclb_channel.h | 2 +- .../lb_policy/grpclb/grpclb_channel_secure.cc | 33 +-- .../lb_policy/grpclb/load_balancer_api.h | 2 +- .../lb_policy/pick_first/pick_first.cc | 19 +- .../lb_policy/round_robin/round_robin.cc | 40 +-- .../lb_policy/subchannel_list.h | 53 ++-- .../client_channel/lb_policy/xds/xds.cc | 247 +++++------------- .../lb_policy/xds/xds_channel.h | 2 +- .../lb_policy/xds/xds_channel_secure.cc | 33 +-- .../lb_policy/xds/xds_load_balancer_api.h | 2 +- .../client_channel/lb_policy_factory.cc | 163 ------------ .../client_channel/lb_policy_factory.h | 86 +----- .../resolver/dns/c_ares/dns_resolver_ares.cc | 12 +- .../dns/c_ares/grpc_ares_ev_driver.cc | 1 + .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 149 +++++------ .../resolver/dns/c_ares/grpc_ares_wrapper.h | 13 +- .../dns/c_ares/grpc_ares_wrapper_fallback.cc | 9 +- .../dns/c_ares/grpc_ares_wrapper_posix.cc | 3 +- .../dns/c_ares/grpc_ares_wrapper_windows.cc | 26 +- .../resolver/dns/native/dns_resolver.cc | 14 +- .../resolver/fake/fake_resolver.cc | 3 +- .../resolver/fake/fake_resolver.h | 3 +- .../resolver/sockaddr/sockaddr_resolver.cc | 34 +-- .../client_channel/resolver_result_parsing.cc | 20 +- .../filters/client_channel/server_address.cc | 103 ++++++++ .../filters/client_channel/server_address.h | 108 ++++++++ .../ext/filters/client_channel/subchannel.cc | 6 +- .../ext/filters/client_channel/subchannel.h | 13 +- src/core/lib/iomgr/sockaddr_utils.cc | 1 + src/python/grpcio/grpc_core_dependencies.py | 2 +- .../dns_resolver_connectivity_test.cc | 12 +- .../resolvers/dns_resolver_cooldown_test.cc | 15 +- .../resolvers/fake_resolver_test.cc | 42 +-- test/core/end2end/fuzzers/api_fuzzer.cc | 28 +- test/core/end2end/goaway_server_test.cc | 29 +- test/core/end2end/no_server_test.cc | 1 + test/core/util/ubsan_suppressions.txt | 3 +- test/cpp/client/client_channel_stress_test.cc | 28 +- test/cpp/end2end/client_lb_end2end_test.cc | 18 +- test/cpp/end2end/grpclb_end2end_test.cc | 37 ++- test/cpp/naming/address_sorting_test.cc | 127 +++++---- test/cpp/naming/resolver_component_test.cc | 21 +- tools/doxygen/Doxyfile.core.internal | 3 +- .../generated/sources_and_headers.json | 4 +- 58 files changed, 846 insertions(+), 1044 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/lb_policy_factory.cc create mode 100644 src/core/ext/filters/client_channel/server_address.cc create mode 100644 src/core/ext/filters/client_channel/server_address.h diff --git a/BUILD b/BUILD index 9e3e594038d..5550e583a87 100644 --- a/BUILD +++ b/BUILD @@ -1048,7 +1048,6 @@ grpc_cc_library( "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_proxy.cc", "src/core/ext/filters/client_channel/lb_policy.cc", - "src/core/ext/filters/client_channel/lb_policy_factory.cc", "src/core/ext/filters/client_channel/lb_policy_registry.cc", "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/proxy_mapper.cc", @@ -1057,6 +1056,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/resolver_registry.cc", "src/core/ext/filters/client_channel/resolver_result_parsing.cc", "src/core/ext/filters/client_channel/retry_throttle.cc", + "src/core/ext/filters/client_channel/server_address.cc", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel_index.cc", ], @@ -1080,6 +1080,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.h", "src/core/ext/filters/client_channel/retry_throttle.h", + "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_index.h", ], diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b02d778d1d..9c660c77012 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1240,7 +1240,6 @@ add_library(grpc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc - src/core/ext/filters/client_channel/lb_policy_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -1249,6 +1248,7 @@ add_library(grpc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/deadline/deadline_filter.cc @@ -1592,7 +1592,6 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc - src/core/ext/filters/client_channel/lb_policy_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -1601,6 +1600,7 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/deadline/deadline_filter.cc @@ -1963,7 +1963,6 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc - src/core/ext/filters/client_channel/lb_policy_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -1972,6 +1971,7 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/deadline/deadline_filter.cc @@ -2283,7 +2283,6 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc - src/core/ext/filters/client_channel/lb_policy_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -2292,6 +2291,7 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/deadline/deadline_filter.cc @@ -2617,7 +2617,6 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc - src/core/ext/filters/client_channel/lb_policy_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -2626,6 +2625,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/deadline/deadline_filter.cc @@ -3469,7 +3469,6 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc - src/core/ext/filters/client_channel/lb_policy_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -3478,6 +3477,7 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/deadline/deadline_filter.cc diff --git a/Makefile b/Makefile index ed4e219f8b7..0163dc414a5 100644 --- a/Makefile +++ b/Makefile @@ -3735,7 +3735,6 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ - src/core/ext/filters/client_channel/lb_policy_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -3744,6 +3743,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ @@ -4081,7 +4081,6 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ - src/core/ext/filters/client_channel/lb_policy_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -4090,6 +4089,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ @@ -4445,7 +4445,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ - src/core/ext/filters/client_channel/lb_policy_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -4454,6 +4453,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ @@ -4751,7 +4751,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ - src/core/ext/filters/client_channel/lb_policy_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -4760,6 +4759,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ @@ -5058,7 +5058,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ - src/core/ext/filters/client_channel/lb_policy_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -5067,6 +5066,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ @@ -5885,7 +5885,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ - src/core/ext/filters/client_channel/lb_policy_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -5894,6 +5893,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ diff --git a/build.yaml b/build.yaml index af70be8459a..4521169e6c1 100644 --- a/build.yaml +++ b/build.yaml @@ -589,6 +589,7 @@ filegroups: - src/core/ext/filters/client_channel/resolver_registry.h - src/core/ext/filters/client_channel/resolver_result_parsing.h - src/core/ext/filters/client_channel/retry_throttle.h + - src/core/ext/filters/client_channel/server_address.h - src/core/ext/filters/client_channel/subchannel.h - src/core/ext/filters/client_channel/subchannel_index.h src: @@ -603,7 +604,6 @@ filegroups: - src/core/ext/filters/client_channel/http_connect_handshaker.cc - src/core/ext/filters/client_channel/http_proxy.cc - src/core/ext/filters/client_channel/lb_policy.cc - - src/core/ext/filters/client_channel/lb_policy_factory.cc - src/core/ext/filters/client_channel/lb_policy_registry.cc - src/core/ext/filters/client_channel/parse_address.cc - src/core/ext/filters/client_channel/proxy_mapper.cc @@ -612,6 +612,7 @@ filegroups: - src/core/ext/filters/client_channel/resolver_registry.cc - src/core/ext/filters/client_channel/resolver_result_parsing.cc - src/core/ext/filters/client_channel/retry_throttle.cc + - src/core/ext/filters/client_channel/server_address.cc - src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc plugin: grpc_client_channel diff --git a/config.m4 b/config.m4 index 3db660aceea..16de5204bb2 100644 --- a/config.m4 +++ b/config.m4 @@ -348,7 +348,6 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ - src/core/ext/filters/client_channel/lb_policy_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -357,6 +356,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ diff --git a/config.w32 b/config.w32 index 7f8b6eee5fa..be10faab9cd 100644 --- a/config.w32 +++ b/config.w32 @@ -323,7 +323,6 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " + "src\\core\\ext\\filters\\client_channel\\http_proxy.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy.cc " + - "src\\core\\ext\\filters\\client_channel\\lb_policy_factory.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " + "src\\core\\ext\\filters\\client_channel\\parse_address.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " + @@ -332,6 +331,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\resolver_registry.cc " + "src\\core\\ext\\filters\\client_channel\\resolver_result_parsing.cc " + "src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " + + "src\\core\\ext\\filters\\client_channel\\server_address.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel_index.cc " + "src\\core\\ext\\filters\\deadline\\deadline_filter.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index e939bead1b7..30fcb51ee19 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -356,6 +356,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', 'src/core/ext/filters/client_channel/retry_throttle.h', + 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', 'src/core/ext/filters/client_channel/subchannel_index.h', 'src/core/ext/filters/deadline/deadline_filter.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 1d4e1ae35c0..5ab7a49cd27 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -354,6 +354,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', 'src/core/ext/filters/client_channel/retry_throttle.h', + 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', 'src/core/ext/filters/client_channel/subchannel_index.h', 'src/core/ext/filters/deadline/deadline_filter.h', @@ -786,7 +787,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', - 'src/core/ext/filters/client_channel/lb_policy_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -795,6 +795,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', @@ -974,6 +975,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', 'src/core/ext/filters/client_channel/retry_throttle.h', + 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', 'src/core/ext/filters/client_channel/subchannel_index.h', 'src/core/ext/filters/deadline/deadline_filter.h', diff --git a/grpc.gemspec b/grpc.gemspec index 92b1e0be689..1ee7bec8e7d 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -290,6 +290,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver_registry.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.h ) s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h ) + s.files += %w( src/core/ext/filters/client_channel/server_address.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.h ) @@ -725,7 +726,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.cc ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc ) - s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.cc ) s.files += %w( src/core/ext/filters/client_channel/parse_address.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc ) @@ -734,6 +734,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver_registry.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.cc ) s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc ) + s.files += %w( src/core/ext/filters/client_channel/server_address.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel_index.cc ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc ) diff --git a/grpc.gyp b/grpc.gyp index 564922ff727..00f06a1e54e 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -540,7 +540,6 @@ 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', - 'src/core/ext/filters/client_channel/lb_policy_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -549,6 +548,7 @@ 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', @@ -799,7 +799,6 @@ 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', - 'src/core/ext/filters/client_channel/lb_policy_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -808,6 +807,7 @@ 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', @@ -1039,7 +1039,6 @@ 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', - 'src/core/ext/filters/client_channel/lb_policy_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -1048,6 +1047,7 @@ 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', @@ -1292,7 +1292,6 @@ 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', - 'src/core/ext/filters/client_channel/lb_policy_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -1301,6 +1300,7 @@ 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', diff --git a/package.xml b/package.xml index bdcb12bfc5e..68fc7433cb4 100644 --- a/package.xml +++ b/package.xml @@ -295,6 +295,7 @@ + @@ -730,7 +731,6 @@ - @@ -739,6 +739,7 @@ + diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index ebc412b468d..70aac472314 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -38,6 +38,7 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/ext/filters/deadline/deadline_filter.h" #include "src/core/lib/backoff/backoff.h" @@ -62,6 +63,7 @@ #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" +using grpc_core::ServerAddressList; using grpc_core::internal::ClientChannelMethodParams; using grpc_core::internal::ClientChannelMethodParamsTable; using grpc_core::internal::ProcessedResolverResult; @@ -383,16 +385,10 @@ static void create_new_lb_policy_locked( static void maybe_add_trace_message_for_address_changes_locked( channel_data* chand, TraceStringVector* trace_strings) { - int resolution_contains_addresses = false; - const grpc_arg* channel_arg = - grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES); - if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) { - grpc_lb_addresses* addresses = - static_cast(channel_arg->value.pointer.p); - if (addresses->num_addresses > 0) { - resolution_contains_addresses = true; - } - } + const ServerAddressList* addresses = + grpc_core::FindServerAddressListChannelArg(chand->resolver_result); + const bool resolution_contains_addresses = + addresses != nullptr && addresses->size() > 0; if (!resolution_contains_addresses && chand->previous_resolution_contained_addresses) { trace_strings->push_back(gpr_strdup("Address list became empty")); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 7034da6249c..6b76fe5d5d7 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -55,7 +55,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_client_channel_factory* client_channel_factory = nullptr; /// Channel args from the resolver. /// Note that the LB policy gets the set of addresses from the - /// GRPC_ARG_LB_ADDRESSES channel arg. + /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. grpc_channel_args* args = nullptr; /// Load balancing config from the resolver. grpc_json* lb_config = nullptr; @@ -80,11 +80,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Will be populated with context to pass to the subchannel call, if /// needed. grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {}; - /// Upon success, \a *user_data will be set to whatever opaque information - /// may need to be propagated from the LB policy, or nullptr if not needed. - // TODO(roth): As part of revamping our metadata APIs, try to find a - // way to clean this up and C++-ify it. - void** user_data = nullptr; /// Next pointer. For internal use by LB policy. PickState* next = nullptr; }; @@ -95,7 +90,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Updates the policy with a new set of \a args and a new \a lb_config from /// the resolver. Note that the LB policy gets the set of addresses from the - /// GRPC_ARG_LB_ADDRESSES channel arg. + /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. virtual void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) GRPC_ABSTRACT; diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index a46579c7f74..a9a5965ed1c 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -84,6 +84,7 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" @@ -113,6 +114,8 @@ #define GRPC_GRPCLB_RECONNECT_JITTER 0.2 #define GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS 10000 +#define GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN "grpc.grpclb_address_lb_token" + namespace grpc_core { TraceFlag grpc_lb_glb_trace(false, "glb"); @@ -121,7 +124,7 @@ namespace { class GrpcLb : public LoadBalancingPolicy { public: - GrpcLb(const grpc_lb_addresses* addresses, const Args& args); + explicit GrpcLb(const Args& args); void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; @@ -161,9 +164,6 @@ class GrpcLb : public LoadBalancingPolicy { // Our on_complete closure and the original one. grpc_closure on_complete; grpc_closure* original_on_complete; - // The LB token associated with the pick. This is set via user_data in - // the pick. - grpc_mdelem lb_token; // Stats for client-side load reporting. RefCountedPtr client_stats; // Next pending pick. @@ -329,7 +329,7 @@ class GrpcLb : public LoadBalancingPolicy { // 0 means not using fallback. int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. - grpc_lb_addresses* fallback_backend_addresses_ = nullptr; + UniquePtr fallback_backend_addresses_; // Fallback timer. bool fallback_timer_callback_pending_ = false; grpc_timer lb_fallback_timer_; @@ -349,7 +349,7 @@ class GrpcLb : public LoadBalancingPolicy { // serverlist parsing code // -// vtable for LB tokens in grpc_lb_addresses +// vtable for LB token channel arg. void* lb_token_copy(void* token) { return token == nullptr ? nullptr @@ -361,38 +361,11 @@ void lb_token_destroy(void* token) { } } int lb_token_cmp(void* token1, void* token2) { - if (token1 > token2) return 1; - if (token1 < token2) return -1; - return 0; + return GPR_ICMP(token1, token2); } -const grpc_lb_user_data_vtable lb_token_vtable = { +const grpc_arg_pointer_vtable lb_token_arg_vtable = { lb_token_copy, lb_token_destroy, lb_token_cmp}; -// Returns the backend addresses extracted from the given addresses. -grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) { - // First pass: count the number of backend addresses. - size_t num_backends = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) { - ++num_backends; - } - } - // Second pass: actually populate the addresses and (empty) LB tokens. - grpc_lb_addresses* backend_addresses = - grpc_lb_addresses_create(num_backends, &lb_token_vtable); - size_t num_copied = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) continue; - const grpc_resolved_address* addr = &addresses->addresses[i].address; - grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr, - addr->len, false /* is_balancer */, - nullptr /* balancer_name */, - (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload); - ++num_copied; - } - return backend_addresses; -} - bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) { if (server->drop) return false; const grpc_grpclb_ip_address* ip = &server->ip_address; @@ -440,30 +413,16 @@ void ParseServer(const grpc_grpclb_server* server, } // Returns addresses extracted from \a serverlist. -grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { - size_t num_valid = 0; - /* first pass: count how many are valid in order to allocate the necessary - * memory in a single block */ +ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { + ServerAddressList addresses; for (size_t i = 0; i < serverlist->num_servers; ++i) { - if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid; - } - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_valid, &lb_token_vtable); - /* second pass: actually populate the addresses and LB tokens (aka user data - * to the outside world) to be read by the RR policy during its creation. - * Given that the validity tests are very cheap, they are performed again - * instead of marking the valid ones during the first pass, as this would - * incurr in an allocation due to the arbitrary number of server */ - size_t addr_idx = 0; - for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) { - const grpc_grpclb_server* server = serverlist->servers[sl_idx]; - if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue; - GPR_ASSERT(addr_idx < num_valid); - /* address processing */ + const grpc_grpclb_server* server = serverlist->servers[i]; + if (!IsServerValid(serverlist->servers[i], i, false)) continue; + // Address processing. grpc_resolved_address addr; ParseServer(server, &addr); - /* lb token processing */ - void* user_data; + // LB token processing. + void* lb_token; if (server->has_load_balance_token) { const size_t lb_token_max_length = GPR_ARRAY_SIZE(server->load_balance_token); @@ -471,7 +430,7 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { strnlen(server->load_balance_token, lb_token_max_length); grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( server->load_balance_token, lb_token_length); - user_data = + lb_token = (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr) .payload; } else { @@ -481,15 +440,16 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { "be used instead", uri); gpr_free(uri); - user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; + lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; } - grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len, - false /* is_balancer */, - nullptr /* balancer_name */, user_data); - ++addr_idx; - } - GPR_ASSERT(addr_idx == num_valid); - return lb_addresses; + // Add address. + grpc_arg arg = grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token, + &lb_token_arg_vtable); + grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + addresses.emplace_back(addr, args); + } + return addresses; } // @@ -829,8 +789,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_); } else { // Dispose of the fallback. - grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_); - grpclb_policy->fallback_backend_addresses_ = nullptr; + grpclb_policy->fallback_backend_addresses_.reset(); if (grpclb_policy->fallback_timer_callback_pending_) { grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); } @@ -910,31 +869,25 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( // helper code for creating balancer channel // -grpc_lb_addresses* ExtractBalancerAddresses( - const grpc_lb_addresses* addresses) { - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - // There must be at least one balancer address, or else the - // client_channel would not have chosen this LB policy. - GPR_ASSERT(num_grpclb_addrs > 0); - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_grpclb_addrs, nullptr); - size_t lb_addresses_idx = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) continue; - if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) { - gpr_log(GPR_ERROR, - "This LB policy doesn't support user data. It will be ignored"); +ServerAddressList ExtractBalancerAddresses(const ServerAddressList& addresses) { + ServerAddressList balancer_addresses; + for (size_t i = 0; i < addresses.size(); ++i) { + if (addresses[i].IsBalancer()) { + // Strip out the is_balancer channel arg, since we don't want to + // recursively use the grpclb policy in the channel used to talk to + // the balancers. Note that we do NOT strip out the balancer_name + // channel arg, since we need that to set the authority correctly + // to talk to the balancers. + static const char* args_to_remove[] = { + GRPC_ARG_ADDRESS_IS_BALANCER, + }; + balancer_addresses.emplace_back( + addresses[i].address(), + grpc_channel_args_copy_and_remove(addresses[i].args(), args_to_remove, + GPR_ARRAY_SIZE(args_to_remove))); } - grpc_lb_addresses_set_address( - lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr, - addresses->addresses[i].address.len, false /* is balancer */, - addresses->addresses[i].balancer_name, nullptr /* user data */); } - GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx); - return lb_addresses; + return balancer_addresses; } /* Returns the channel args for the LB channel, used to create a bidirectional @@ -946,10 +899,10 @@ grpc_lb_addresses* ExtractBalancerAddresses( * above the grpclb policy. * - \a args: other args inherited from the grpclb policy. */ grpc_channel_args* BuildBalancerChannelArgs( - const grpc_lb_addresses* addresses, + const ServerAddressList& addresses, FakeResolverResponseGenerator* response_generator, const grpc_channel_args* args) { - grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses); + ServerAddressList balancer_addresses = ExtractBalancerAddresses(addresses); // Channel args to remove. static const char* args_to_remove[] = { // LB policy name, since we want to use the default (pick_first) in @@ -967,7 +920,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // is_balancer=true. We need the LB channel to return addresses with // is_balancer=false so that it does not wind up recursively using the // grpclb LB policy, as per the special case logic in client_channel.c. - GRPC_ARG_LB_ADDRESSES, + GRPC_ARG_SERVER_ADDRESS_LIST, // The fake resolver response generator, because we are replacing it // with the one from the grpclb policy, used to propagate updates to // the LB channel. @@ -983,10 +936,10 @@ grpc_channel_args* BuildBalancerChannelArgs( }; // Channel args to add. const grpc_arg args_to_add[] = { - // New LB addresses. + // New address list. // Note that we pass these in both when creating the LB channel // and via the fake resolver. The latter is what actually gets used. - grpc_lb_addresses_create_channel_arg(lb_addresses), + CreateServerAddressListChannelArg(&balancer_addresses), // The fake resolver response generator, which we use to inject // address updates into the LB channel. grpc_core::FakeResolverResponseGenerator::MakeChannelArg( @@ -1004,18 +957,14 @@ grpc_channel_args* BuildBalancerChannelArgs( args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add, GPR_ARRAY_SIZE(args_to_add)); // Make any necessary modifications for security. - new_args = grpc_lb_policy_grpclb_modify_lb_channel_args(new_args); - // Clean up. - grpc_lb_addresses_destroy(lb_addresses); - return new_args; + return grpc_lb_policy_grpclb_modify_lb_channel_args(new_args); } // // ctor and dtor // -GrpcLb::GrpcLb(const grpc_lb_addresses* addresses, - const LoadBalancingPolicy::Args& args) +GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args) : LoadBalancingPolicy(args), response_generator_(MakeRefCounted()), lb_call_backoff_( @@ -1072,9 +1021,6 @@ GrpcLb::~GrpcLb() { if (serverlist_ != nullptr) { grpc_grpclb_destroy_serverlist(serverlist_); } - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } grpc_subchannel_index_unref(); } @@ -1122,7 +1068,6 @@ void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { while ((pp = pending_picks_) != nullptr) { pending_picks_ = pp->next; pp->pick->on_complete = pp->original_on_complete; - pp->pick->user_data = nullptr; grpc_error* error = GRPC_ERROR_NONE; if (new_policy->PickLocked(pp->pick, &error)) { // Synchronous return; schedule closure. @@ -1276,9 +1221,27 @@ void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, notify); } +// Returns the backend addresses extracted from the given addresses. +UniquePtr ExtractBackendAddresses( + const ServerAddressList& addresses) { + void* lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; + grpc_arg arg = grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token, + &lb_token_arg_vtable); + auto backend_addresses = MakeUnique(); + for (size_t i = 0; i < addresses.size(); ++i) { + if (!addresses[i].IsBalancer()) { + backend_addresses->emplace_back( + addresses[i].address(), + grpc_channel_args_copy_and_add(addresses[i].args(), &arg, 1)); + } + } + return backend_addresses; +} + void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { + const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); + if (addresses == nullptr) { // Ignore this update. gpr_log( GPR_ERROR, @@ -1286,13 +1249,8 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { this); return; } - const grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); // Update fallback address list. - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } - fallback_backend_addresses_ = ExtractBackendAddresses(addresses); + fallback_backend_addresses_ = ExtractBackendAddresses(*addresses); // Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args, // since we use this to trigger the client_load_reporting filter. static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME}; @@ -1303,7 +1261,7 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1); // Construct args for balancer channel. grpc_channel_args* lb_channel_args = - BuildBalancerChannelArgs(addresses, response_generator_.get(), &args); + BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args); // Create balancer channel if needed. if (lb_channel_ == nullptr) { char* uri_str; @@ -1509,12 +1467,17 @@ void DestroyClientStats(void* arg) { } void GrpcLb::PendingPickSetMetadataAndContext(PendingPick* pp) { - /* if connected_subchannel is nullptr, no pick has been made by the RR - * policy (e.g., all addresses failed to connect). There won't be any - * user_data/token available */ + // If connected_subchannel is nullptr, no pick has been made by the RR + // policy (e.g., all addresses failed to connect). There won't be any + // LB token available. if (pp->pick->connected_subchannel != nullptr) { - if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) { - AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token), + const grpc_arg* arg = + grpc_channel_args_find(pp->pick->connected_subchannel->args(), + GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); + if (arg != nullptr) { + grpc_mdelem lb_token = { + reinterpret_cast(arg->value.pointer.p)}; + AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(lb_token), &pp->pick->lb_token_mdelem_storage, pp->pick->initial_metadata); } else { @@ -1598,12 +1561,10 @@ bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, return true; } } - // Set client_stats and user_data. + // Set client_stats. if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { pp->client_stats = lb_calld_->client_stats()->Ref(); } - GPR_ASSERT(pp->pick->user_data == nullptr); - pp->pick->user_data = (void**)&pp->lb_token; // Pick via the RR policy. bool pick_done = rr_policy_->PickLocked(pp->pick, error); if (pick_done) { @@ -1668,10 +1629,11 @@ void GrpcLb::CreateRoundRobinPolicyLocked(const Args& args) { } grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { - grpc_lb_addresses* addresses; + ServerAddressList tmp_addresses; + ServerAddressList* addresses = &tmp_addresses; bool is_backend_from_grpclb_load_balancer = false; if (serverlist_ != nullptr) { - addresses = ProcessServerlist(serverlist_); + tmp_addresses = ProcessServerlist(serverlist_); is_backend_from_grpclb_load_balancer = true; } else { // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't @@ -1680,14 +1642,14 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { // empty, in which case the new round_robin policy will keep the requested // picks pending. GPR_ASSERT(fallback_backend_addresses_ != nullptr); - addresses = grpc_lb_addresses_copy(fallback_backend_addresses_); + addresses = fallback_backend_addresses_.get(); } GPR_ASSERT(addresses != nullptr); - // Replace the LB addresses in the channel args that we pass down to + // Replace the server address list in the channel args that we pass down to // the subchannel. - static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES}; + static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST}; grpc_arg args_to_add[3] = { - grpc_lb_addresses_create_channel_arg(addresses), + CreateServerAddressListChannelArg(addresses), // A channel arg indicating if the target is a backend inferred from a // grpclb load balancer. grpc_channel_arg_integer_create( @@ -1704,7 +1666,6 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove( args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, num_args_to_add); - grpc_lb_addresses_destroy(addresses); return args; } @@ -1837,19 +1798,18 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { OrphanablePtr CreateLoadBalancingPolicy( const LoadBalancingPolicy::Args& args) const override { /* Count the number of gRPC-LB addresses. There must be at least one. */ - const grpc_arg* arg = - grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES); - if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { - return nullptr; - } - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; + const ServerAddressList* addresses = + FindServerAddressListChannelArg(args.args); + if (addresses == nullptr) return nullptr; + bool found_balancer = false; + for (size_t i = 0; i < addresses->size(); ++i) { + if ((*addresses)[i].IsBalancer()) { + found_balancer = true; + break; + } } - if (num_grpclb_addrs == 0) return nullptr; - return OrphanablePtr(New(addresses, args)); + if (!found_balancer) return nullptr; + return OrphanablePtr(New(args)); } const char* name() const override { return "grpclb"; } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h index 825065a9c32..3b2dc370eb3 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h @@ -21,7 +21,7 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include /// Makes any necessary modifications to \a args for use in the grpclb /// balancer channel. diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc index 441efd5e23b..6e8fbdcab77 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc @@ -26,6 +26,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -42,22 +43,23 @@ int BalancerNameCmp(const grpc_core::UniquePtr& a, } RefCountedPtr CreateTargetAuthorityTable( - grpc_lb_addresses* addresses) { + const ServerAddressList& addresses) { TargetAuthorityTable::Entry* target_authority_entries = - static_cast(gpr_zalloc( - sizeof(*target_authority_entries) * addresses->num_addresses)); - for (size_t i = 0; i < addresses->num_addresses; ++i) { + static_cast( + gpr_zalloc(sizeof(*target_authority_entries) * addresses.size())); + for (size_t i = 0; i < addresses.size(); ++i) { char* addr_str; - GPR_ASSERT(grpc_sockaddr_to_string( - &addr_str, &addresses->addresses[i].address, true) > 0); + GPR_ASSERT( + grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true) > 0); target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str); - target_authority_entries[i].value.reset( - gpr_strdup(addresses->addresses[i].balancer_name)); gpr_free(addr_str); + char* balancer_name = grpc_channel_arg_get_string(grpc_channel_args_find( + addresses[i].args(), GRPC_ARG_ADDRESS_BALANCER_NAME)); + target_authority_entries[i].value.reset(gpr_strdup(balancer_name)); } RefCountedPtr target_authority_table = - TargetAuthorityTable::Create(addresses->num_addresses, - target_authority_entries, BalancerNameCmp); + TargetAuthorityTable::Create(addresses.size(), target_authority_entries, + BalancerNameCmp); gpr_free(target_authority_entries); return target_authority_table; } @@ -72,13 +74,12 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( grpc_arg args_to_add[2]; size_t num_args_to_add = 0; // Add arg for targets info table. - const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES); - GPR_ASSERT(arg != nullptr); - GPR_ASSERT(arg->type == GRPC_ARG_POINTER); - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); + grpc_core::ServerAddressList* addresses = + grpc_core::FindServerAddressListChannelArg(args); + GPR_ASSERT(addresses != nullptr); grpc_core::RefCountedPtr - target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses); + target_authority_table = + grpc_core::CreateTargetAuthorityTable(*addresses); args_to_add[num_args_to_add++] = grpc_core::CreateTargetAuthorityTableChannelArg( target_authority_table.get()); diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h index 9ca7b28d8e6..71d371c880a 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h @@ -25,7 +25,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/lib/iomgr/exec_ctx.h" #define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128 diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index d1a05f12554..74c17612a28 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -24,6 +24,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/channel/channel_args.h" @@ -75,11 +76,9 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner) - : SubchannelData(subchannel_list, user_data_vtable, address, subchannel, - combiner) {} + : SubchannelData(subchannel_list, address, subchannel, combiner) {} void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state, grpc_error* error) override; @@ -95,7 +94,7 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData> { public: PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, + const ServerAddressList& addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) @@ -337,8 +336,8 @@ void PickFirst::UpdateChildRefsLocked() { void PickFirst::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { AutoChildRefsUpdater guard(this); - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { + const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); + if (addresses == nullptr) { if (subchannel_list_ == nullptr) { // If we don't have a current subchannel list, go into TRANSIENT FAILURE. grpc_connectivity_state_set( @@ -354,19 +353,17 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, } return; } - const grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p received update with %" PRIuPTR " addresses", this, - addresses->num_addresses); + addresses->size()); } grpc_arg new_arg = grpc_channel_arg_integer_create( const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); grpc_channel_args* new_args = grpc_channel_args_copy_and_add(&args, &new_arg, 1); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, addresses, combiner(), + this, &grpc_lb_pick_first_trace, *addresses, combiner(), client_channel_factory(), *new_args); grpc_channel_args_destroy(new_args); if (subchannel_list->num_subchannels() == 0) { diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 2a169751317..63089afbd78 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -82,8 +82,6 @@ class RoundRobin : public LoadBalancingPolicy { // Data for a particular subchannel in a subchannel list. // This subclass adds the following functionality: - // - Tracks user_data associated with each address, which will be - // returned along with picks that select the subchannel. // - Tracks the previous connectivity state of the subchannel, so that // we know how many subchannels are in each state. class RoundRobinSubchannelData @@ -93,26 +91,9 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner) - : SubchannelData(subchannel_list, user_data_vtable, address, subchannel, - combiner), - user_data_vtable_(user_data_vtable), - user_data_(user_data_vtable_ != nullptr - ? user_data_vtable_->copy(address.user_data) - : nullptr) {} - - void UnrefSubchannelLocked(const char* reason) override { - SubchannelData::UnrefSubchannelLocked(reason); - if (user_data_ != nullptr) { - GPR_ASSERT(user_data_vtable_ != nullptr); - user_data_vtable_->destroy(user_data_); - user_data_ = nullptr; - } - } - - void* user_data() const { return user_data_; } + : SubchannelData(subchannel_list, address, subchannel, combiner) {} grpc_connectivity_state connectivity_state() const { return last_connectivity_state_; @@ -125,8 +106,6 @@ class RoundRobin : public LoadBalancingPolicy { void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state, grpc_error* error) override; - const grpc_lb_user_data_vtable* user_data_vtable_; - void* user_data_ = nullptr; grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE; }; @@ -137,7 +116,7 @@ class RoundRobin : public LoadBalancingPolicy { public: RoundRobinSubchannelList( RoundRobin* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, grpc_combiner* combiner, + const ServerAddressList& addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, @@ -354,9 +333,6 @@ bool RoundRobin::DoPickLocked(PickState* pick) { subchannel_list_->subchannel(next_ready_index); GPR_ASSERT(sd->connected_subchannel() != nullptr); pick->connected_subchannel = sd->connected_subchannel()->Ref(); - if (pick->user_data != nullptr) { - *pick->user_data = sd->user_data(); - } if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, " @@ -667,9 +643,9 @@ void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current, void RoundRobin::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); AutoChildRefsUpdater guard(this); - if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { + const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); + if (addresses == nullptr) { gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", this); // If we don't have a current subchannel list, go into TRANSIENT_FAILURE. // Otherwise, keep using the current subchannel list (ignore this update). @@ -681,11 +657,9 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } return; } - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses", - this, addresses->num_addresses); + this, addresses->size()); } // Replace latest_pending_subchannel_list_. if (latest_pending_subchannel_list_ != nullptr) { @@ -696,7 +670,7 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, addresses, combiner(), + this, &grpc_lb_round_robin_trace, *addresses, combiner(), client_channel_factory(), args); // If we haven't started picking yet or the new list is empty, // immediately promote the new list to the current list. diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index f31401502c3..6f31a643c1d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -26,6 +26,7 @@ #include #include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" @@ -141,8 +142,7 @@ class SubchannelData { protected: SubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner); virtual ~SubchannelData(); @@ -156,9 +156,8 @@ class SubchannelData { grpc_connectivity_state connectivity_state, grpc_error* error) GRPC_ABSTRACT; - // Unrefs the subchannel. May be overridden by subclasses that need - // to perform extra cleanup when unreffing the subchannel. - virtual void UnrefSubchannelLocked(const char* reason); + // Unrefs the subchannel. + void UnrefSubchannelLocked(const char* reason); private: // Updates connected_subchannel_ based on pending_connectivity_state_unsafe_. @@ -232,7 +231,7 @@ class SubchannelList : public InternallyRefCounted { protected: SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, grpc_combiner* combiner, + const ServerAddressList& addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args); @@ -277,8 +276,7 @@ class SubchannelList : public InternallyRefCounted { template SubchannelData::SubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner) : subchannel_list_(subchannel_list), subchannel_(subchannel), @@ -488,7 +486,7 @@ void SubchannelData::ShutdownLocked() { template SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, grpc_combiner* combiner, + const ServerAddressList& addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : InternallyRefCounted(tracer), @@ -498,9 +496,9 @@ SubchannelList::SubchannelList( if (tracer_->enabled()) { gpr_log(GPR_INFO, "[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels", - tracer_->name(), policy, this, addresses->num_addresses); + tracer_->name(), policy, this, addresses.size()); } - subchannels_.reserve(addresses->num_addresses); + subchannels_.reserve(addresses.size()); // We need to remove the LB addresses in order to be able to compare the // subchannel keys of subchannels from a different batch of addresses. // We also remove the inhibit-health-checking arg, since we are @@ -508,19 +506,27 @@ SubchannelList::SubchannelList( inhibit_health_checking_ = grpc_channel_arg_get_bool( grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false); static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS, - GRPC_ARG_LB_ADDRESSES, + GRPC_ARG_SERVER_ADDRESS_LIST, GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. grpc_subchannel_args sc_args; - for (size_t i = 0; i < addresses->num_addresses; i++) { - // If there were any balancer, we would have chosen grpclb policy instead. - GPR_ASSERT(!addresses->addresses[i].is_balancer); + for (size_t i = 0; i < addresses.size(); i++) { + // If there were any balancer addresses, we would have chosen grpclb + // policy, which does not use a SubchannelList. + GPR_ASSERT(!addresses[i].IsBalancer()); memset(&sc_args, 0, sizeof(grpc_subchannel_args)); - grpc_arg addr_arg = - grpc_create_subchannel_address_arg(&addresses->addresses[i].address); + InlinedVector args_to_add; + args_to_add.emplace_back( + grpc_create_subchannel_address_arg(&addresses[i].address())); + if (addresses[i].args() != nullptr) { + for (size_t j = 0; j < addresses[i].args()->num_args; ++j) { + args_to_add.emplace_back(addresses[i].args()->args[j]); + } + } grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( - &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg, 1); - gpr_free(addr_arg.value.string); + &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), + args_to_add.data(), args_to_add.size()); + gpr_free(args_to_add[0].value.string); sc_args.args = new_args; grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel( client_channel_factory, &sc_args); @@ -528,8 +534,7 @@ SubchannelList::SubchannelList( if (subchannel == nullptr) { // Subchannel could not be created. if (tracer_->enabled()) { - char* address_uri = - grpc_sockaddr_to_uri(&addresses->addresses[i].address); + char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address()); gpr_log(GPR_INFO, "[%s %p] could not create subchannel for address uri %s, " "ignoring", @@ -539,8 +544,7 @@ SubchannelList::SubchannelList( continue; } if (tracer_->enabled()) { - char* address_uri = - grpc_sockaddr_to_uri(&addresses->addresses[i].address); + char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address()); gpr_log(GPR_INFO, "[%s %p] subchannel list %p index %" PRIuPTR ": Created subchannel %p for address uri %s", @@ -548,8 +552,7 @@ SubchannelList::SubchannelList( address_uri); gpr_free(address_uri); } - subchannels_.emplace_back(this, addresses->user_data_vtable, - addresses->addresses[i], subchannel, combiner); + subchannels_.emplace_back(this, addresses[i], subchannel, combiner); } } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index faedc0a9194..3c25de2386c 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -79,6 +79,7 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" @@ -116,7 +117,7 @@ namespace { class XdsLb : public LoadBalancingPolicy { public: - XdsLb(const grpc_lb_addresses* addresses, const Args& args); + explicit XdsLb(const Args& args); void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; @@ -156,9 +157,6 @@ class XdsLb : public LoadBalancingPolicy { // Our on_complete closure and the original one. grpc_closure on_complete; grpc_closure* original_on_complete; - // The LB token associated with the pick. This is set via user_data in - // the pick. - grpc_mdelem lb_token; // Stats for client-side load reporting. RefCountedPtr client_stats; // Next pending pick. @@ -256,7 +254,7 @@ class XdsLb : public LoadBalancingPolicy { grpc_error* error); // Pending pick methods. - static void PendingPickSetMetadataAndContext(PendingPick* pp); + static void PendingPickCleanup(PendingPick* pp); PendingPick* PendingPickCreate(PickState* pick); void AddPendingPick(PendingPick* pp); static void OnPendingPickComplete(void* arg, grpc_error* error); @@ -319,7 +317,7 @@ class XdsLb : public LoadBalancingPolicy { // 0 means not using fallback. int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. - grpc_lb_addresses* fallback_backend_addresses_ = nullptr; + UniquePtr fallback_backend_addresses_; // Fallback timer. bool fallback_timer_callback_pending_ = false; grpc_timer lb_fallback_timer_; @@ -339,47 +337,15 @@ class XdsLb : public LoadBalancingPolicy { // serverlist parsing code // -// vtable for LB tokens in grpc_lb_addresses -void* lb_token_copy(void* token) { - return token == nullptr - ? nullptr - : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload; -} -void lb_token_destroy(void* token) { - if (token != nullptr) { - GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token}); - } -} -int lb_token_cmp(void* token1, void* token2) { - if (token1 > token2) return 1; - if (token1 < token2) return -1; - return 0; -} -const grpc_lb_user_data_vtable lb_token_vtable = { - lb_token_copy, lb_token_destroy, lb_token_cmp}; - // Returns the backend addresses extracted from the given addresses. -grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) { - // First pass: count the number of backend addresses. - size_t num_backends = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) { - ++num_backends; +UniquePtr ExtractBackendAddresses( + const ServerAddressList& addresses) { + auto backend_addresses = MakeUnique(); + for (size_t i = 0; i < addresses.size(); ++i) { + if (!addresses[i].IsBalancer()) { + backend_addresses->emplace_back(addresses[i]); } } - // Second pass: actually populate the addresses and (empty) LB tokens. - grpc_lb_addresses* backend_addresses = - grpc_lb_addresses_create(num_backends, &lb_token_vtable); - size_t num_copied = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) continue; - const grpc_resolved_address* addr = &addresses->addresses[i].address; - grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr, - addr->len, false /* is_balancer */, - nullptr /* balancer_name */, - (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload); - ++num_copied; - } return backend_addresses; } @@ -429,56 +395,17 @@ void ParseServer(const xds_grpclb_server* server, grpc_resolved_address* addr) { } // Returns addresses extracted from \a serverlist. -grpc_lb_addresses* ProcessServerlist(const xds_grpclb_serverlist* serverlist) { - size_t num_valid = 0; - /* first pass: count how many are valid in order to allocate the necessary - * memory in a single block */ +UniquePtr ProcessServerlist( + const xds_grpclb_serverlist* serverlist) { + auto addresses = MakeUnique(); for (size_t i = 0; i < serverlist->num_servers; ++i) { - if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid; - } - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_valid, &lb_token_vtable); - /* second pass: actually populate the addresses and LB tokens (aka user data - * to the outside world) to be read by the child policy during its creation. - * Given that the validity tests are very cheap, they are performed again - * instead of marking the valid ones during the first pass, as this would - * incurr in an allocation due to the arbitrary number of server */ - size_t addr_idx = 0; - for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) { - const xds_grpclb_server* server = serverlist->servers[sl_idx]; - if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue; - GPR_ASSERT(addr_idx < num_valid); - /* address processing */ + const xds_grpclb_server* server = serverlist->servers[i]; + if (!IsServerValid(serverlist->servers[i], i, false)) continue; grpc_resolved_address addr; ParseServer(server, &addr); - /* lb token processing */ - void* user_data; - if (server->has_load_balance_token) { - const size_t lb_token_max_length = - GPR_ARRAY_SIZE(server->load_balance_token); - const size_t lb_token_length = - strnlen(server->load_balance_token, lb_token_max_length); - grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( - server->load_balance_token, lb_token_length); - user_data = - (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr) - .payload; - } else { - char* uri = grpc_sockaddr_to_uri(&addr); - gpr_log(GPR_INFO, - "Missing LB token for backend address '%s'. The empty token will " - "be used instead", - uri); - gpr_free(uri); - user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; - } - grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len, - false /* is_balancer */, - nullptr /* balancer_name */, user_data); - ++addr_idx; + addresses->emplace_back(addr, nullptr); } - GPR_ASSERT(addr_idx == num_valid); - return lb_addresses; + return addresses; } // @@ -789,8 +716,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( xds_grpclb_destroy_serverlist(xdslb_policy->serverlist_); } else { /* or dispose of the fallback */ - grpc_lb_addresses_destroy(xdslb_policy->fallback_backend_addresses_); - xdslb_policy->fallback_backend_addresses_ = nullptr; + xdslb_policy->fallback_backend_addresses_.reset(); if (xdslb_policy->fallback_timer_callback_pending_) { grpc_timer_cancel(&xdslb_policy->lb_fallback_timer_); } @@ -876,31 +802,15 @@ void XdsLb::BalancerCallState::OnBalancerStatusReceivedLocked( // helper code for creating balancer channel // -grpc_lb_addresses* ExtractBalancerAddresses( - const grpc_lb_addresses* addresses) { - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - // There must be at least one balancer address, or else the - // client_channel would not have chosen this LB policy. - GPR_ASSERT(num_grpclb_addrs > 0); - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_grpclb_addrs, nullptr); - size_t lb_addresses_idx = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) continue; - if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) { - gpr_log(GPR_ERROR, - "This LB policy doesn't support user data. It will be ignored"); +UniquePtr ExtractBalancerAddresses( + const ServerAddressList& addresses) { + auto balancer_addresses = MakeUnique(); + for (size_t i = 0; i < addresses.size(); ++i) { + if (addresses[i].IsBalancer()) { + balancer_addresses->emplace_back(addresses[i]); } - grpc_lb_addresses_set_address( - lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr, - addresses->addresses[i].address.len, false /* is balancer */, - addresses->addresses[i].balancer_name, nullptr /* user data */); } - GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx); - return lb_addresses; + return balancer_addresses; } /* Returns the channel args for the LB channel, used to create a bidirectional @@ -912,10 +822,11 @@ grpc_lb_addresses* ExtractBalancerAddresses( * above the grpclb policy. * - \a args: other args inherited from the xds policy. */ grpc_channel_args* BuildBalancerChannelArgs( - const grpc_lb_addresses* addresses, + const ServerAddressList& addresses, FakeResolverResponseGenerator* response_generator, const grpc_channel_args* args) { - grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses); + UniquePtr balancer_addresses = + ExtractBalancerAddresses(addresses); // Channel args to remove. static const char* args_to_remove[] = { // LB policy name, since we want to use the default (pick_first) in @@ -933,7 +844,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // is_balancer=true. We need the LB channel to return addresses with // is_balancer=false so that it does not wind up recursively using the // xds LB policy, as per the special case logic in client_channel.c. - GRPC_ARG_LB_ADDRESSES, + GRPC_ARG_SERVER_ADDRESS_LIST, // The fake resolver response generator, because we are replacing it // with the one from the xds policy, used to propagate updates to // the LB channel. @@ -949,10 +860,10 @@ grpc_channel_args* BuildBalancerChannelArgs( }; // Channel args to add. const grpc_arg args_to_add[] = { - // New LB addresses. + // New server address list. // Note that we pass these in both when creating the LB channel // and via the fake resolver. The latter is what actually gets used. - grpc_lb_addresses_create_channel_arg(lb_addresses), + CreateServerAddressListChannelArg(balancer_addresses.get()), // The fake resolver response generator, which we use to inject // address updates into the LB channel. grpc_core::FakeResolverResponseGenerator::MakeChannelArg( @@ -970,10 +881,7 @@ grpc_channel_args* BuildBalancerChannelArgs( args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add, GPR_ARRAY_SIZE(args_to_add)); // Make any necessary modifications for security. - new_args = grpc_lb_policy_xds_modify_lb_channel_args(new_args); - // Clean up. - grpc_lb_addresses_destroy(lb_addresses); - return new_args; + return grpc_lb_policy_xds_modify_lb_channel_args(new_args); } // @@ -981,8 +889,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // // TODO(vishalpowar): Use lb_config in args to configure LB policy. -XdsLb::XdsLb(const grpc_lb_addresses* addresses, - const LoadBalancingPolicy::Args& args) +XdsLb::XdsLb(const LoadBalancingPolicy::Args& args) : LoadBalancingPolicy(args), response_generator_(MakeRefCounted()), lb_call_backoff_( @@ -1038,9 +945,6 @@ XdsLb::~XdsLb() { if (serverlist_ != nullptr) { xds_grpclb_destroy_serverlist(serverlist_); } - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } grpc_subchannel_index_unref(); } @@ -1088,7 +992,6 @@ void XdsLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { while ((pp = pending_picks_) != nullptr) { pending_picks_ = pp->next; pp->pick->on_complete = pp->original_on_complete; - pp->pick->user_data = nullptr; grpc_error* error = GRPC_ERROR_NONE; if (new_policy->PickLocked(pp->pick, &error)) { // Synchronous return; schedule closure. @@ -1241,21 +1144,16 @@ void XdsLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, } void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { + const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); + if (addresses == nullptr) { // Ignore this update. gpr_log(GPR_ERROR, "[xdslb %p] No valid LB addresses channel arg in update, ignoring.", this); return; } - const grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); // Update fallback address list. - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } - fallback_backend_addresses_ = ExtractBackendAddresses(addresses); + fallback_backend_addresses_ = ExtractBackendAddresses(*addresses); // Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args, // since we use this to trigger the client_load_reporting filter. static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME}; @@ -1266,7 +1164,7 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1); // Construct args for balancer channel. grpc_channel_args* lb_channel_args = - BuildBalancerChannelArgs(addresses, response_generator_.get(), &args); + BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args); // Create balancer channel if needed. if (lb_channel_ == nullptr) { char* uri_str; @@ -1457,37 +1355,15 @@ void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg, // PendingPick // -// Adds lb_token of selected subchannel (address) to the call's initial -// metadata. -grpc_error* AddLbTokenToInitialMetadata( - grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage, - grpc_metadata_batch* initial_metadata) { - GPR_ASSERT(lb_token_mdelem_storage != nullptr); - GPR_ASSERT(!GRPC_MDISNULL(lb_token)); - return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage, - lb_token); -} - // Destroy function used when embedding client stats in call context. void DestroyClientStats(void* arg) { static_cast(arg)->Unref(); } -void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) { - /* if connected_subchannel is nullptr, no pick has been made by the - * child policy (e.g., all addresses failed to connect). There won't be any - * user_data/token available */ +void XdsLb::PendingPickCleanup(PendingPick* pp) { + // If connected_subchannel is nullptr, no pick has been made by the + // child policy (e.g., all addresses failed to connect). if (pp->pick->connected_subchannel != nullptr) { - if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) { - AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token), - &pp->pick->lb_token_mdelem_storage, - pp->pick->initial_metadata); - } else { - gpr_log(GPR_ERROR, - "[xdslb %p] No LB token for connected subchannel pick %p", - pp->xdslb_policy, pp->pick); - abort(); - } // Pass on client stats via context. Passes ownership of the reference. if (pp->client_stats != nullptr) { pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = @@ -1505,7 +1381,7 @@ void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) { * order to unref the child policy instance upon its invocation */ void XdsLb::OnPendingPickComplete(void* arg, grpc_error* error) { PendingPick* pp = static_cast(arg); - PendingPickSetMetadataAndContext(pp); + PendingPickCleanup(pp); GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error)); Delete(pp); } @@ -1537,16 +1413,14 @@ void XdsLb::AddPendingPick(PendingPick* pp) { // completion callback even if the pick is available immediately. bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp, grpc_error** error) { - // Set client_stats and user_data. + // Set client_stats. if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { pp->client_stats = lb_calld_->client_stats()->Ref(); } - GPR_ASSERT(pp->pick->user_data == nullptr); - pp->pick->user_data = (void**)&pp->lb_token; // Pick via the child policy. bool pick_done = child_policy_->PickLocked(pp->pick, error); if (pick_done) { - PendingPickSetMetadataAndContext(pp); + PendingPickCleanup(pp); if (force_async) { GRPC_CLOSURE_SCHED(pp->original_on_complete, *error); *error = GRPC_ERROR_NONE; @@ -1608,20 +1482,19 @@ void XdsLb::CreateChildPolicyLocked(const Args& args) { } grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { - grpc_lb_addresses* addresses; bool is_backend_from_grpclb_load_balancer = false; // This should never be invoked if we do not have serverlist_, as fallback // mode is disabled for xDS plugin. GPR_ASSERT(serverlist_ != nullptr); GPR_ASSERT(serverlist_->num_servers > 0); - addresses = ProcessServerlist(serverlist_); - is_backend_from_grpclb_load_balancer = true; + UniquePtr addresses = ProcessServerlist(serverlist_); GPR_ASSERT(addresses != nullptr); - // Replace the LB addresses in the channel args that we pass down to + is_backend_from_grpclb_load_balancer = true; + // Replace the server address list in the channel args that we pass down to // the subchannel. - static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES}; + static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST}; const grpc_arg args_to_add[] = { - grpc_lb_addresses_create_channel_arg(addresses), + CreateServerAddressListChannelArg(addresses.get()), // A channel arg indicating if the target is a backend inferred from a // grpclb load balancer. grpc_channel_arg_integer_create( @@ -1631,7 +1504,6 @@ grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove( args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, GPR_ARRAY_SIZE(args_to_add)); - grpc_lb_addresses_destroy(addresses); return args; } @@ -1765,19 +1637,18 @@ class XdsFactory : public LoadBalancingPolicyFactory { OrphanablePtr CreateLoadBalancingPolicy( const LoadBalancingPolicy::Args& args) const override { /* Count the number of gRPC-LB addresses. There must be at least one. */ - const grpc_arg* arg = - grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES); - if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { - return nullptr; - } - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; + const ServerAddressList* addresses = + FindServerAddressListChannelArg(args.args); + if (addresses == nullptr) return nullptr; + bool found_balancer_address = false; + for (size_t i = 0; i < addresses->size(); ++i) { + if ((*addresses)[i].IsBalancer()) { + found_balancer_address = true; + break; + } } - if (num_grpclb_addrs == 0) return nullptr; - return OrphanablePtr(New(addresses, args)); + if (!found_balancer_address) return nullptr; + return OrphanablePtr(New(args)); } const char* name() const override { return "xds_experimental"; } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h index 32c4acc8a3e..f713b7f563d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h @@ -21,7 +21,7 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include /// Makes any necessary modifications to \a args for use in the xds /// balancer channel. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc index 5ab72efce46..9a11f8e39fd 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc @@ -25,6 +25,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -41,22 +42,23 @@ int BalancerNameCmp(const grpc_core::UniquePtr& a, } RefCountedPtr CreateTargetAuthorityTable( - grpc_lb_addresses* addresses) { + const ServerAddressList& addresses) { TargetAuthorityTable::Entry* target_authority_entries = - static_cast(gpr_zalloc( - sizeof(*target_authority_entries) * addresses->num_addresses)); - for (size_t i = 0; i < addresses->num_addresses; ++i) { + static_cast( + gpr_zalloc(sizeof(*target_authority_entries) * addresses.size())); + for (size_t i = 0; i < addresses.size(); ++i) { char* addr_str; - GPR_ASSERT(grpc_sockaddr_to_string( - &addr_str, &addresses->addresses[i].address, true) > 0); + GPR_ASSERT( + grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true) > 0); target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str); - target_authority_entries[i].value.reset( - gpr_strdup(addresses->addresses[i].balancer_name)); gpr_free(addr_str); + char* balancer_name = grpc_channel_arg_get_string(grpc_channel_args_find( + addresses[i].args(), GRPC_ARG_ADDRESS_BALANCER_NAME)); + target_authority_entries[i].value.reset(gpr_strdup(balancer_name)); } RefCountedPtr target_authority_table = - TargetAuthorityTable::Create(addresses->num_addresses, - target_authority_entries, BalancerNameCmp); + TargetAuthorityTable::Create(addresses.size(), target_authority_entries, + BalancerNameCmp); gpr_free(target_authority_entries); return target_authority_table; } @@ -71,13 +73,12 @@ grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args( grpc_arg args_to_add[2]; size_t num_args_to_add = 0; // Add arg for targets info table. - const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES); - GPR_ASSERT(arg != nullptr); - GPR_ASSERT(arg->type == GRPC_ARG_POINTER); - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); + grpc_core::ServerAddressList* addresses = + grpc_core::FindServerAddressListChannelArg(args); + GPR_ASSERT(addresses != nullptr); grpc_core::RefCountedPtr - target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses); + target_authority_table = + grpc_core::CreateTargetAuthorityTable(*addresses); args_to_add[num_args_to_add++] = grpc_core::CreateTargetAuthorityTableChannelArg( target_authority_table.get()); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h index 9d08defa7ef..67049956417 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h @@ -25,7 +25,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/lib/iomgr/exec_ctx.h" #define XDS_SERVICE_NAME_MAX_LENGTH 128 diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.cc b/src/core/ext/filters/client_channel/lb_policy_factory.cc deleted file mode 100644 index 5c6363d2952..00000000000 --- a/src/core/ext/filters/client_channel/lb_policy_factory.cc +++ /dev/null @@ -1,163 +0,0 @@ -/* - * - * Copyright 2015 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 - -#include - -#include -#include - -#include "src/core/lib/channel/channel_args.h" - -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" -#include "src/core/ext/filters/client_channel/parse_address.h" - -grpc_lb_addresses* grpc_lb_addresses_create( - size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable) { - grpc_lb_addresses* addresses = - static_cast(gpr_zalloc(sizeof(grpc_lb_addresses))); - addresses->num_addresses = num_addresses; - addresses->user_data_vtable = user_data_vtable; - const size_t addresses_size = sizeof(grpc_lb_address) * num_addresses; - addresses->addresses = - static_cast(gpr_zalloc(addresses_size)); - return addresses; -} - -grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses) { - grpc_lb_addresses* new_addresses = grpc_lb_addresses_create( - addresses->num_addresses, addresses->user_data_vtable); - memcpy(new_addresses->addresses, addresses->addresses, - sizeof(grpc_lb_address) * addresses->num_addresses); - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (new_addresses->addresses[i].balancer_name != nullptr) { - new_addresses->addresses[i].balancer_name = - gpr_strdup(new_addresses->addresses[i].balancer_name); - } - if (new_addresses->addresses[i].user_data != nullptr) { - new_addresses->addresses[i].user_data = addresses->user_data_vtable->copy( - new_addresses->addresses[i].user_data); - } - } - return new_addresses; -} - -void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index, - const void* address, size_t address_len, - bool is_balancer, const char* balancer_name, - void* user_data) { - GPR_ASSERT(index < addresses->num_addresses); - if (user_data != nullptr) GPR_ASSERT(addresses->user_data_vtable != nullptr); - grpc_lb_address* target = &addresses->addresses[index]; - memcpy(target->address.addr, address, address_len); - target->address.len = static_cast(address_len); - target->is_balancer = is_balancer; - target->balancer_name = gpr_strdup(balancer_name); - target->user_data = user_data; -} - -bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses, - size_t index, const grpc_uri* uri, - bool is_balancer, - const char* balancer_name, - void* user_data) { - grpc_resolved_address address; - if (!grpc_parse_uri(uri, &address)) return false; - grpc_lb_addresses_set_address(addresses, index, address.addr, address.len, - is_balancer, balancer_name, user_data); - return true; -} - -int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1, - const grpc_lb_addresses* addresses2) { - if (addresses1->num_addresses > addresses2->num_addresses) return 1; - if (addresses1->num_addresses < addresses2->num_addresses) return -1; - if (addresses1->user_data_vtable > addresses2->user_data_vtable) return 1; - if (addresses1->user_data_vtable < addresses2->user_data_vtable) return -1; - for (size_t i = 0; i < addresses1->num_addresses; ++i) { - const grpc_lb_address* target1 = &addresses1->addresses[i]; - const grpc_lb_address* target2 = &addresses2->addresses[i]; - if (target1->address.len > target2->address.len) return 1; - if (target1->address.len < target2->address.len) return -1; - int retval = memcmp(target1->address.addr, target2->address.addr, - target1->address.len); - if (retval != 0) return retval; - if (target1->is_balancer > target2->is_balancer) return 1; - if (target1->is_balancer < target2->is_balancer) return -1; - const char* balancer_name1 = - target1->balancer_name != nullptr ? target1->balancer_name : ""; - const char* balancer_name2 = - target2->balancer_name != nullptr ? target2->balancer_name : ""; - retval = strcmp(balancer_name1, balancer_name2); - if (retval != 0) return retval; - if (addresses1->user_data_vtable != nullptr) { - retval = addresses1->user_data_vtable->cmp(target1->user_data, - target2->user_data); - if (retval != 0) return retval; - } - } - return 0; -} - -void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses) { - for (size_t i = 0; i < addresses->num_addresses; ++i) { - gpr_free(addresses->addresses[i].balancer_name); - if (addresses->addresses[i].user_data != nullptr) { - addresses->user_data_vtable->destroy(addresses->addresses[i].user_data); - } - } - gpr_free(addresses->addresses); - gpr_free(addresses); -} - -static void* lb_addresses_copy(void* addresses) { - return grpc_lb_addresses_copy(static_cast(addresses)); -} -static void lb_addresses_destroy(void* addresses) { - grpc_lb_addresses_destroy(static_cast(addresses)); -} -static int lb_addresses_cmp(void* addresses1, void* addresses2) { - return grpc_lb_addresses_cmp(static_cast(addresses1), - static_cast(addresses2)); -} -static const grpc_arg_pointer_vtable lb_addresses_arg_vtable = { - lb_addresses_copy, lb_addresses_destroy, lb_addresses_cmp}; - -grpc_arg grpc_lb_addresses_create_channel_arg( - const grpc_lb_addresses* addresses) { - return grpc_channel_arg_pointer_create( - (char*)GRPC_ARG_LB_ADDRESSES, (void*)addresses, &lb_addresses_arg_vtable); -} - -grpc_lb_addresses* grpc_lb_addresses_find_channel_arg( - const grpc_channel_args* channel_args) { - const grpc_arg* lb_addresses_arg = - grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES); - if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER) - return nullptr; - return static_cast(lb_addresses_arg->value.pointer.p); -} - -bool grpc_lb_addresses_contains_balancer_address( - const grpc_lb_addresses& addresses) { - for (size_t i = 0; i < addresses.num_addresses; ++i) { - if (addresses.addresses[i].is_balancer) return true; - } - return false; -} diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h index a59deadb265..a165ebafaba 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -21,91 +21,9 @@ #include -#include "src/core/lib/iomgr/resolve_address.h" - -#include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/lb_policy.h" -#include "src/core/lib/uri/uri_parser.h" - -// -// representation of an LB address -// - -// Channel arg key for grpc_lb_addresses. -#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses" - -/** A resolved address alongside any LB related information associated with it. - * \a user_data, if not NULL, contains opaque data meant to be consumed by the - * gRPC LB policy. Note that no all LB policies support \a user_data as input. - * Those who don't will simply ignore it and will correspondingly return NULL in - * their namesake pick() output argument. */ -// TODO(roth): Once we figure out a better way of handling user_data in -// LB policies, convert these structs to C++ classes. -typedef struct grpc_lb_address { - grpc_resolved_address address; - bool is_balancer; - char* balancer_name; /* For secure naming. */ - void* user_data; -} grpc_lb_address; - -typedef struct grpc_lb_user_data_vtable { - void* (*copy)(void*); - void (*destroy)(void*); - int (*cmp)(void*, void*); -} grpc_lb_user_data_vtable; - -typedef struct grpc_lb_addresses { - size_t num_addresses; - grpc_lb_address* addresses; - const grpc_lb_user_data_vtable* user_data_vtable; -} grpc_lb_addresses; - -/** Returns a grpc_addresses struct with enough space for - \a num_addresses addresses. The \a user_data_vtable argument may be - NULL if no user data will be added. */ -grpc_lb_addresses* grpc_lb_addresses_create( - size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable); - -/** Creates a copy of \a addresses. */ -grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses); - -/** Sets the value of the address at index \a index of \a addresses. - * \a address is a socket address of length \a address_len. */ -void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index, - const void* address, size_t address_len, - bool is_balancer, const char* balancer_name, - void* user_data); - -/** Sets the value of the address at index \a index of \a addresses from \a uri. - * Returns true upon success, false otherwise. */ -bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses, - size_t index, const grpc_uri* uri, - bool is_balancer, - const char* balancer_name, - void* user_data); - -/** Compares \a addresses1 and \a addresses2. */ -int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1, - const grpc_lb_addresses* addresses2); - -/** Destroys \a addresses. */ -void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses); - -/** Returns a channel arg containing \a addresses. */ -grpc_arg grpc_lb_addresses_create_channel_arg( - const grpc_lb_addresses* addresses); - -/** Returns the \a grpc_lb_addresses instance in \a channel_args or NULL */ -grpc_lb_addresses* grpc_lb_addresses_find_channel_arg( - const grpc_channel_args* channel_args); - -// Returns true if addresses contains at least one balancer address. -bool grpc_lb_addresses_contains_balancer_address( - const grpc_lb_addresses& addresses); - -// -// LB policy factory -// +#include "src/core/lib/gprpp/abstract.h" +#include "src/core/lib/gprpp/orphanable.h" namespace grpc_core { diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 4ebc2c8161c..c8425ae3365 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -33,6 +33,7 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -117,7 +118,7 @@ class AresDnsResolver : public Resolver { /// retry backoff state BackOff backoff_; /// currently resolving addresses - grpc_lb_addresses* lb_addresses_ = nullptr; + UniquePtr addresses_; /// currently resolving service config char* service_config_json_ = nullptr; // has shutdown been initiated @@ -314,13 +315,13 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { r->resolving_ = false; gpr_free(r->pending_request_); r->pending_request_ = nullptr; - if (r->lb_addresses_ != nullptr) { + if (r->addresses_ != nullptr) { static const char* args_to_remove[1]; size_t num_args_to_remove = 0; grpc_arg args_to_add[2]; size_t num_args_to_add = 0; args_to_add[num_args_to_add++] = - grpc_lb_addresses_create_channel_arg(r->lb_addresses_); + CreateServerAddressListChannelArg(r->addresses_.get()); char* service_config_string = nullptr; if (r->service_config_json_ != nullptr) { service_config_string = ChooseServiceConfig(r->service_config_json_); @@ -337,7 +338,7 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { r->channel_args_, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add); gpr_free(service_config_string); - grpc_lb_addresses_destroy(r->lb_addresses_); + r->addresses_.reset(); // Reset backoff state so that we start from the beginning when the // next request gets triggered. r->backoff_.Reset(); @@ -412,11 +413,10 @@ void AresDnsResolver::StartResolvingLocked() { self.release(); GPR_ASSERT(!resolving_); resolving_ = true; - lb_addresses_ = nullptr; service_config_json_ = nullptr; pending_request_ = grpc_dns_lookup_ares_locked( dns_server_, name_to_resolve_, kDefaultPort, interested_parties_, - &on_resolved_, &lb_addresses_, true /* check_grpclb */, + &on_resolved_, &addresses_, true /* check_grpclb */, request_service_config_ ? &service_config_json_ : nullptr, query_timeout_ms_, combiner()); last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc index f42b1e309df..8abc34c6edb 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -31,6 +31,7 @@ #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/iomgr/timer.h" diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index 55715869b63..1b1c2303da3 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -37,12 +37,16 @@ #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/nameser.h" #include "src/core/lib/iomgr/sockaddr_utils.h" +using grpc_core::ServerAddress; +using grpc_core::ServerAddressList; + static gpr_once g_basic_init = GPR_ONCE_INIT; static gpr_mu g_init_mu; @@ -58,7 +62,7 @@ struct grpc_ares_request { /** closure to call when the request completes */ grpc_closure* on_done; /** the pointer to receive the resolved addresses */ - grpc_lb_addresses** lb_addrs_out; + grpc_core::UniquePtr* addresses_out; /** the pointer to receive the service config in JSON */ char** service_config_json_out; /** the evernt driver used by this request */ @@ -87,12 +91,11 @@ typedef struct grpc_ares_hostbyname_request { static void do_basic_init(void) { gpr_mu_init(&g_init_mu); } -static void log_address_sorting_list(grpc_lb_addresses* lb_addrs, +static void log_address_sorting_list(const ServerAddressList& addresses, const char* input_output_str) { - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { + for (size_t i = 0; i < addresses.size(); i++) { char* addr_str; - if (grpc_sockaddr_to_string(&addr_str, &lb_addrs->addresses[i].address, - true)) { + if (grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true)) { gpr_log(GPR_DEBUG, "c-ares address sorting: %s[%" PRIuPTR "]=%s", input_output_str, i, addr_str); gpr_free(addr_str); @@ -104,29 +107,28 @@ static void log_address_sorting_list(grpc_lb_addresses* lb_addrs, } } -void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs) { +void grpc_cares_wrapper_address_sorting_sort(ServerAddressList* addresses) { if (grpc_trace_cares_address_sorting.enabled()) { - log_address_sorting_list(lb_addrs, "input"); + log_address_sorting_list(*addresses, "input"); } address_sorting_sortable* sortables = (address_sorting_sortable*)gpr_zalloc( - sizeof(address_sorting_sortable) * lb_addrs->num_addresses); - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { - sortables[i].user_data = &lb_addrs->addresses[i]; - memcpy(&sortables[i].dest_addr.addr, &lb_addrs->addresses[i].address.addr, - lb_addrs->addresses[i].address.len); - sortables[i].dest_addr.len = lb_addrs->addresses[i].address.len; + sizeof(address_sorting_sortable) * addresses->size()); + for (size_t i = 0; i < addresses->size(); ++i) { + sortables[i].user_data = &(*addresses)[i]; + memcpy(&sortables[i].dest_addr.addr, &(*addresses)[i].address().addr, + (*addresses)[i].address().len); + sortables[i].dest_addr.len = (*addresses)[i].address().len; } - address_sorting_rfc_6724_sort(sortables, lb_addrs->num_addresses); - grpc_lb_address* sorted_lb_addrs = (grpc_lb_address*)gpr_zalloc( - sizeof(grpc_lb_address) * lb_addrs->num_addresses); - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { - sorted_lb_addrs[i] = *(grpc_lb_address*)sortables[i].user_data; + address_sorting_rfc_6724_sort(sortables, addresses->size()); + ServerAddressList sorted; + sorted.reserve(addresses->size()); + for (size_t i = 0; i < addresses->size(); ++i) { + sorted.emplace_back(*static_cast(sortables[i].user_data)); } gpr_free(sortables); - gpr_free(lb_addrs->addresses); - lb_addrs->addresses = sorted_lb_addrs; + *addresses = std::move(sorted); if (grpc_trace_cares_address_sorting.enabled()) { - log_address_sorting_list(lb_addrs, "output"); + log_address_sorting_list(*addresses, "output"); } } @@ -145,9 +147,9 @@ void grpc_ares_complete_request_locked(grpc_ares_request* r) { /* Invoke on_done callback and destroy the request */ r->ev_driver = nullptr; - grpc_lb_addresses* lb_addrs = *(r->lb_addrs_out); - if (lb_addrs != nullptr) { - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + ServerAddressList* addresses = r->addresses_out->get(); + if (addresses != nullptr) { + grpc_cares_wrapper_address_sorting_sort(addresses); } GRPC_CLOSURE_SCHED(r->on_done, r->error); } @@ -181,33 +183,30 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, GRPC_ERROR_UNREF(r->error); r->error = GRPC_ERROR_NONE; r->success = true; - grpc_lb_addresses** lb_addresses = r->lb_addrs_out; - if (*lb_addresses == nullptr) { - *lb_addresses = grpc_lb_addresses_create(0, nullptr); - } - size_t prev_naddr = (*lb_addresses)->num_addresses; - size_t i; - for (i = 0; hostent->h_addr_list[i] != nullptr; i++) { + if (*r->addresses_out == nullptr) { + *r->addresses_out = grpc_core::MakeUnique(); } - (*lb_addresses)->num_addresses += i; - (*lb_addresses)->addresses = static_cast( - gpr_realloc((*lb_addresses)->addresses, - sizeof(grpc_lb_address) * (*lb_addresses)->num_addresses)); - for (i = prev_naddr; i < (*lb_addresses)->num_addresses; i++) { + ServerAddressList& addresses = **r->addresses_out; + for (size_t i = 0; hostent->h_addr_list[i] != nullptr; ++i) { + grpc_core::InlinedVector args_to_add; + if (hr->is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), hr->host)); + } + grpc_channel_args* args = grpc_channel_args_copy_and_add( + nullptr, args_to_add.data(), args_to_add.size()); switch (hostent->h_addrtype) { case AF_INET6: { size_t addr_len = sizeof(struct sockaddr_in6); struct sockaddr_in6 addr; memset(&addr, 0, addr_len); - memcpy(&addr.sin6_addr, hostent->h_addr_list[i - prev_naddr], + memcpy(&addr.sin6_addr, hostent->h_addr_list[i], sizeof(struct in6_addr)); addr.sin6_family = static_cast(hostent->h_addrtype); addr.sin6_port = hr->port; - grpc_lb_addresses_set_address( - *lb_addresses, i, &addr, addr_len, - hr->is_balancer /* is_balancer */, - hr->is_balancer ? hr->host : nullptr /* balancer_name */, - nullptr /* user_data */); + addresses.emplace_back(&addr, addr_len, args); char output[INET6_ADDRSTRLEN]; ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN); gpr_log(GPR_DEBUG, @@ -220,15 +219,11 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, size_t addr_len = sizeof(struct sockaddr_in); struct sockaddr_in addr; memset(&addr, 0, addr_len); - memcpy(&addr.sin_addr, hostent->h_addr_list[i - prev_naddr], + memcpy(&addr.sin_addr, hostent->h_addr_list[i], sizeof(struct in_addr)); addr.sin_family = static_cast(hostent->h_addrtype); addr.sin_port = hr->port; - grpc_lb_addresses_set_address( - *lb_addresses, i, &addr, addr_len, - hr->is_balancer /* is_balancer */, - hr->is_balancer ? hr->host : nullptr /* balancer_name */, - nullptr /* user_data */); + addresses.emplace_back(&addr, addr_len, args); char output[INET_ADDRSTRLEN]; ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN); gpr_log(GPR_DEBUG, @@ -467,11 +462,10 @@ error_cleanup: gpr_free(port); } -static bool inner_resolve_as_ip_literal_locked(const char* name, - const char* default_port, - grpc_lb_addresses** addrs, - char** host, char** port, - char** hostport) { +static bool inner_resolve_as_ip_literal_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port, char** hostport) { gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, @@ -495,18 +489,16 @@ static bool inner_resolve_as_ip_literal_locked(const char* name, if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) || grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) { GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_lb_addresses_create(1, nullptr); - grpc_lb_addresses_set_address( - *addrs, 0, addr.addr, addr.len, false /* is_balancer */, - nullptr /* balancer_name */, nullptr /* user_data */); + *addrs = grpc_core::MakeUnique(); + (*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */); return true; } return false; } -static bool resolve_as_ip_literal_locked(const char* name, - const char* default_port, - grpc_lb_addresses** addrs) { +static bool resolve_as_ip_literal_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { char* host = nullptr; char* port = nullptr; char* hostport = nullptr; @@ -521,13 +513,14 @@ static bool resolve_as_ip_literal_locked(const char* name, static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { grpc_ares_request* r = static_cast(gpr_zalloc(sizeof(grpc_ares_request))); r->ev_driver = nullptr; r->on_done = on_done; - r->lb_addrs_out = addrs; + r->addresses_out = addrs; r->service_config_json_out = service_config_json; r->success = false; r->error = GRPC_ERROR_NONE; @@ -553,8 +546,8 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) { @@ -599,8 +592,8 @@ typedef struct grpc_resolve_address_ares_request { grpc_combiner* combiner; /** the pointer to receive the resolved addresses */ grpc_resolved_addresses** addrs_out; - /** currently resolving lb addresses */ - grpc_lb_addresses* lb_addrs; + /** currently resolving addresses */ + grpc_core::UniquePtr addresses; /** closure to call when the resolve_address_ares request completes */ grpc_closure* on_resolve_address_done; /** a closure wrapping on_resolve_address_done, which should be invoked when @@ -613,7 +606,7 @@ typedef struct grpc_resolve_address_ares_request { /* pollset_set to be driven by */ grpc_pollset_set* interested_parties; /* underlying ares_request that the query is performed on */ - grpc_ares_request* ares_request; + grpc_ares_request* ares_request = nullptr; } grpc_resolve_address_ares_request; static void on_dns_lookup_done_locked(void* arg, grpc_error* error) { @@ -621,25 +614,24 @@ static void on_dns_lookup_done_locked(void* arg, grpc_error* error) { static_cast(arg); gpr_free(r->ares_request); grpc_resolved_addresses** resolved_addresses = r->addrs_out; - if (r->lb_addrs == nullptr || r->lb_addrs->num_addresses == 0) { + if (r->addresses == nullptr || r->addresses->empty()) { *resolved_addresses = nullptr; } else { *resolved_addresses = static_cast( gpr_zalloc(sizeof(grpc_resolved_addresses))); - (*resolved_addresses)->naddrs = r->lb_addrs->num_addresses; + (*resolved_addresses)->naddrs = r->addresses->size(); (*resolved_addresses)->addrs = static_cast(gpr_zalloc( sizeof(grpc_resolved_address) * (*resolved_addresses)->naddrs)); - for (size_t i = 0; i < (*resolved_addresses)->naddrs; i++) { - GPR_ASSERT(!r->lb_addrs->addresses[i].is_balancer); - memcpy(&(*resolved_addresses)->addrs[i], - &r->lb_addrs->addresses[i].address, sizeof(grpc_resolved_address)); + for (size_t i = 0; i < (*resolved_addresses)->naddrs; ++i) { + GPR_ASSERT(!(*r->addresses)[i].IsBalancer()); + memcpy(&(*resolved_addresses)->addrs[i], &(*r->addresses)[i].address(), + sizeof(grpc_resolved_address)); } } GRPC_CLOSURE_SCHED(r->on_resolve_address_done, GRPC_ERROR_REF(error)); - if (r->lb_addrs != nullptr) grpc_lb_addresses_destroy(r->lb_addrs); GRPC_COMBINER_UNREF(r->combiner, "on_dns_lookup_done_cb"); - gpr_free(r); + grpc_core::Delete(r); } static void grpc_resolve_address_invoke_dns_lookup_ares_locked( @@ -648,7 +640,7 @@ static void grpc_resolve_address_invoke_dns_lookup_ares_locked( static_cast(arg); r->ares_request = grpc_dns_lookup_ares_locked( nullptr /* dns_server */, r->name, r->default_port, r->interested_parties, - &r->on_dns_lookup_done_locked, &r->lb_addrs, false /* check_grpclb */, + &r->on_dns_lookup_done_locked, &r->addresses, false /* check_grpclb */, nullptr /* service_config_json */, GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, r->combiner); } @@ -659,8 +651,7 @@ static void grpc_resolve_address_ares_impl(const char* name, grpc_closure* on_done, grpc_resolved_addresses** addrs) { grpc_resolve_address_ares_request* r = - static_cast( - gpr_zalloc(sizeof(grpc_resolve_address_ares_request))); + grpc_core::New(); r->combiner = grpc_combiner_create(); r->addrs_out = addrs; r->on_resolve_address_done = on_done; diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index 9acef1d0ca9..28082504565 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -21,7 +21,7 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -61,8 +61,9 @@ extern void (*grpc_resolve_address_ares)(const char* name, extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addresses, bool check_grpclb, - char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner); /* Cancel the pending grpc_ares_request \a request */ extern void (*grpc_cancel_ares_request_locked)(grpc_ares_request* request); @@ -89,10 +90,12 @@ bool grpc_ares_query_ipv6(); * Returns a bool indicating whether or not such an action was performed. * See https://github.com/grpc/grpc/issues/15158. */ bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs); + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs); /* Sorts destinations in lb_addrs according to RFC 6724. */ -void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs); +void grpc_cares_wrapper_address_sorting_sort( + grpc_core::ServerAddressList* addresses); #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H \ */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc index fc78b183044..1f4701c9994 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc @@ -29,16 +29,17 @@ struct grpc_ares_request { static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { return NULL; } grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {} diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc index 639eec2323f..028d8442169 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc @@ -27,7 +27,8 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs) { + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { return false; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index 7e34784691f..202452f1b2b 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -23,9 +23,9 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_windows.h" @@ -33,8 +33,9 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } static bool inner_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs, - char** host, char** port) { + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port) { gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, @@ -55,7 +56,7 @@ static bool inner_maybe_resolve_localhost_manually_locked( } if (gpr_stricmp(*host, "localhost") == 0) { GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_lb_addresses_create(2, nullptr); + *addrs = grpc_core::MakeUnique(); uint16_t numeric_port = grpc_strhtons(*port); // Append the ipv6 loopback address. struct sockaddr_in6 ipv6_loopback_addr; @@ -63,10 +64,8 @@ static bool inner_maybe_resolve_localhost_manually_locked( ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; ipv6_loopback_addr.sin6_family = AF_INET6; ipv6_loopback_addr.sin6_port = numeric_port; - grpc_lb_addresses_set_address( - *addrs, 0, &ipv6_loopback_addr, sizeof(ipv6_loopback_addr), - false /* is_balancer */, nullptr /* balancer_name */, - nullptr /* user_data */); + (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), + nullptr /* args */); // Append the ipv4 loopback address. struct sockaddr_in ipv4_loopback_addr; memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); @@ -74,19 +73,18 @@ static bool inner_maybe_resolve_localhost_manually_locked( ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; ipv4_loopback_addr.sin_family = AF_INET; ipv4_loopback_addr.sin_port = numeric_port; - grpc_lb_addresses_set_address( - *addrs, 1, &ipv4_loopback_addr, sizeof(ipv4_loopback_addr), - false /* is_balancer */, nullptr /* balancer_name */, - nullptr /* user_data */); + (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), + nullptr /* args */); // Let the address sorter figure out which one should be tried first. - grpc_cares_wrapper_address_sorting_sort(*addrs); + grpc_cares_wrapper_address_sorting_sort(addrs->get()); return true; } return false; } bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs) { + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { char* host = nullptr; char* port = nullptr; bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index 65ff1ec1a5b..c365f1abfd8 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -26,8 +26,8 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -198,18 +198,14 @@ void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(r->name_to_resolve_)); if (r->addresses_ != nullptr) { - grpc_lb_addresses* addresses = grpc_lb_addresses_create( - r->addresses_->naddrs, nullptr /* user_data_vtable */); + ServerAddressList addresses; for (size_t i = 0; i < r->addresses_->naddrs; ++i) { - grpc_lb_addresses_set_address( - addresses, i, &r->addresses_->addrs[i].addr, - r->addresses_->addrs[i].len, false /* is_balancer */, - nullptr /* balancer_name */, nullptr /* user_data */); + addresses.emplace_back(&r->addresses_->addrs[i].addr, + r->addresses_->addrs[i].len, nullptr /* args */); } - grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses); + grpc_arg new_arg = CreateServerAddressListChannelArg(&addresses); result = grpc_channel_args_copy_and_add(r->channel_args_, &new_arg, 1); grpc_resolved_addresses_destroy(r->addresses_); - grpc_lb_addresses_destroy(addresses); // Reset backoff state so that we start from the beginning when the // next request gets triggered. r->backoff_.Reset(); diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index 3aa690bea41..258339491c1 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -28,12 +28,13 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h index 7f690593510..d86111c3829 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h @@ -19,10 +19,9 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted.h" -#include "src/core/lib/uri/uri_parser.h" +#include "src/core/lib/iomgr/error.h" #define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR \ "grpc.fake_resolver.response_generator" diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc index 801734764b4..1654747a79f 100644 --- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -26,9 +26,9 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" @@ -45,7 +45,8 @@ namespace { class SockaddrResolver : public Resolver { public: /// Takes ownership of \a addresses. - SockaddrResolver(const ResolverArgs& args, grpc_lb_addresses* addresses); + SockaddrResolver(const ResolverArgs& args, + UniquePtr addresses); void NextLocked(grpc_channel_args** result, grpc_closure* on_complete) override; @@ -58,7 +59,7 @@ class SockaddrResolver : public Resolver { void MaybeFinishNextLocked(); /// the addresses that we've "resolved" - grpc_lb_addresses* addresses_ = nullptr; + UniquePtr addresses_; /// channel args grpc_channel_args* channel_args_ = nullptr; /// have we published? @@ -70,13 +71,12 @@ class SockaddrResolver : public Resolver { }; SockaddrResolver::SockaddrResolver(const ResolverArgs& args, - grpc_lb_addresses* addresses) + UniquePtr addresses) : Resolver(args.combiner), - addresses_(addresses), + addresses_(std::move(addresses)), channel_args_(grpc_channel_args_copy(args.args)) {} SockaddrResolver::~SockaddrResolver() { - grpc_lb_addresses_destroy(addresses_); grpc_channel_args_destroy(channel_args_); } @@ -100,7 +100,7 @@ void SockaddrResolver::ShutdownLocked() { void SockaddrResolver::MaybeFinishNextLocked() { if (next_completion_ != nullptr && !published_) { published_ = true; - grpc_arg arg = grpc_lb_addresses_create_channel_arg(addresses_); + grpc_arg arg = CreateServerAddressListChannelArg(addresses_.get()); *target_result_ = grpc_channel_args_copy_and_add(channel_args_, &arg, 1); GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE); next_completion_ = nullptr; @@ -127,27 +127,27 @@ OrphanablePtr CreateSockaddrResolver( grpc_slice_buffer path_parts; grpc_slice_buffer_init(&path_parts); grpc_slice_split(path_slice, ",", &path_parts); - grpc_lb_addresses* addresses = grpc_lb_addresses_create( - path_parts.count, nullptr /* user_data_vtable */); + auto addresses = MakeUnique(); bool errors_found = false; - for (size_t i = 0; i < addresses->num_addresses; i++) { + for (size_t i = 0; i < path_parts.count; i++) { grpc_uri ith_uri = *args.uri; - char* part_str = grpc_slice_to_c_string(path_parts.slices[i]); - ith_uri.path = part_str; - if (!parse(&ith_uri, &addresses->addresses[i].address)) { + UniquePtr part_str(grpc_slice_to_c_string(path_parts.slices[i])); + ith_uri.path = part_str.get(); + grpc_resolved_address addr; + if (!parse(&ith_uri, &addr)) { errors_found = true; /* GPR_TRUE */ + break; } - gpr_free(part_str); - if (errors_found) break; + addresses->emplace_back(addr, nullptr /* args */); } grpc_slice_buffer_destroy_internal(&path_parts); grpc_slice_unref_internal(path_slice); if (errors_found) { - grpc_lb_addresses_destroy(addresses); return OrphanablePtr(nullptr); } // Instantiate resolver. - return OrphanablePtr(New(args, addresses)); + return OrphanablePtr( + New(args, std::move(addresses))); } class IPv4ResolverFactory : public ResolverFactory { diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 4f7fd6b4243..22b06db45c4 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -30,9 +30,11 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/status_util.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/uri/uri_parser.h" // As per the retry design, we do not allow more than 5 retry attempts. #define MAX_MAX_RETRY_ATTEMPTS 5 @@ -99,12 +101,18 @@ void ProcessedResolverResult::ProcessLbPolicyName( } // Special case: If at least one balancer address is present, we use // the grpclb policy, regardless of what the resolver has returned. - const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result, GRPC_ARG_LB_ADDRESSES); - if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) { - grpc_lb_addresses* addresses = - static_cast(channel_arg->value.pointer.p); - if (grpc_lb_addresses_contains_balancer_address(*addresses)) { + const ServerAddressList* addresses = + FindServerAddressListChannelArg(resolver_result); + if (addresses != nullptr) { + bool found_balancer_address = false; + for (size_t i = 0; i < addresses->size(); ++i) { + const ServerAddress& address = (*addresses)[i]; + if (address.IsBalancer()) { + found_balancer_address = true; + break; + } + } + if (found_balancer_address) { if (lb_policy_name_ != nullptr && strcmp(lb_policy_name_.get(), "grpclb") != 0) { gpr_log(GPR_INFO, diff --git a/src/core/ext/filters/client_channel/server_address.cc b/src/core/ext/filters/client_channel/server_address.cc new file mode 100644 index 00000000000..ec33cbbd956 --- /dev/null +++ b/src/core/ext/filters/client_channel/server_address.cc @@ -0,0 +1,103 @@ +/* + * + * 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 + +#include "src/core/ext/filters/client_channel/server_address.h" + +#include + +namespace grpc_core { + +// +// ServerAddress +// + +ServerAddress::ServerAddress(const grpc_resolved_address& address, + grpc_channel_args* args) + : address_(address), args_(args) {} + +ServerAddress::ServerAddress(const void* address, size_t address_len, + grpc_channel_args* args) + : args_(args) { + memcpy(address_.addr, address, address_len); + address_.len = static_cast(address_len); +} + +int ServerAddress::Cmp(const ServerAddress& other) const { + if (address_.len > other.address_.len) return 1; + if (address_.len < other.address_.len) return -1; + int retval = memcmp(address_.addr, other.address_.addr, address_.len); + if (retval != 0) return retval; + return grpc_channel_args_compare(args_, other.args_); +} + +bool ServerAddress::IsBalancer() const { + return grpc_channel_arg_get_bool( + grpc_channel_args_find(args_, GRPC_ARG_ADDRESS_IS_BALANCER), false); +} + +// +// ServerAddressList +// + +namespace { + +void* ServerAddressListCopy(void* addresses) { + ServerAddressList* a = static_cast(addresses); + return New(*a); +} + +void ServerAddressListDestroy(void* addresses) { + ServerAddressList* a = static_cast(addresses); + Delete(a); +} + +int ServerAddressListCompare(void* addresses1, void* addresses2) { + ServerAddressList* a1 = static_cast(addresses1); + ServerAddressList* a2 = static_cast(addresses2); + if (a1->size() > a2->size()) return 1; + if (a1->size() < a2->size()) return -1; + for (size_t i = 0; i < a1->size(); ++i) { + int retval = (*a1)[i].Cmp((*a2)[i]); + if (retval != 0) return retval; + } + return 0; +} + +const grpc_arg_pointer_vtable server_addresses_arg_vtable = { + ServerAddressListCopy, ServerAddressListDestroy, ServerAddressListCompare}; + +} // namespace + +grpc_arg CreateServerAddressListChannelArg(const ServerAddressList* addresses) { + return grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_SERVER_ADDRESS_LIST), + const_cast(addresses), &server_addresses_arg_vtable); +} + +ServerAddressList* FindServerAddressListChannelArg( + const grpc_channel_args* channel_args) { + const grpc_arg* lb_addresses_arg = + grpc_channel_args_find(channel_args, GRPC_ARG_SERVER_ADDRESS_LIST); + if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER) + return nullptr; + return static_cast(lb_addresses_arg->value.pointer.p); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/server_address.h b/src/core/ext/filters/client_channel/server_address.h new file mode 100644 index 00000000000..3a1bf1df67d --- /dev/null +++ b/src/core/ext/filters/client_channel/server_address.h @@ -0,0 +1,108 @@ +/* + * + * 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. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H + +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/uri/uri_parser.h" + +// Channel arg key for ServerAddressList. +#define GRPC_ARG_SERVER_ADDRESS_LIST "grpc.server_address_list" + +// Channel arg key for a bool indicating whether an address is a grpclb +// load balancer (as opposed to a backend). +#define GRPC_ARG_ADDRESS_IS_BALANCER "grpc.address_is_balancer" + +// Channel arg key for a string indicating an address's balancer name. +#define GRPC_ARG_ADDRESS_BALANCER_NAME "grpc.address_balancer_name" + +namespace grpc_core { + +// +// ServerAddress +// + +// A server address is a grpc_resolved_address with an associated set of +// channel args. Any args present here will be merged into the channel +// args when a subchannel is created for this address. +class ServerAddress { + public: + // Takes ownership of args. + ServerAddress(const grpc_resolved_address& address, grpc_channel_args* args); + ServerAddress(const void* address, size_t address_len, + grpc_channel_args* args); + + ~ServerAddress() { grpc_channel_args_destroy(args_); } + + // Copyable. + ServerAddress(const ServerAddress& other) + : address_(other.address_), args_(grpc_channel_args_copy(other.args_)) {} + ServerAddress& operator=(const ServerAddress& other) { + address_ = other.address_; + grpc_channel_args_destroy(args_); + args_ = grpc_channel_args_copy(other.args_); + return *this; + } + + // Movable. + ServerAddress(ServerAddress&& other) + : address_(other.address_), args_(other.args_) { + other.args_ = nullptr; + } + ServerAddress& operator=(ServerAddress&& other) { + address_ = other.address_; + args_ = other.args_; + other.args_ = nullptr; + return *this; + } + + bool operator==(const ServerAddress& other) const { return Cmp(other) == 0; } + + int Cmp(const ServerAddress& other) const; + + const grpc_resolved_address& address() const { return address_; } + const grpc_channel_args* args() const { return args_; } + + bool IsBalancer() const; + + private: + grpc_resolved_address address_; + grpc_channel_args* args_; +}; + +// +// ServerAddressList +// + +typedef InlinedVector ServerAddressList; + +// Returns a channel arg containing \a addresses. +grpc_arg CreateServerAddressListChannelArg(const ServerAddressList* addresses); + +// Returns the ServerListAddress instance in channel_args or NULL. +ServerAddressList* FindServerAddressListChannelArg( + const grpc_channel_args* channel_args); + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H */ diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index af55f7710e2..9077aa97539 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -837,7 +837,7 @@ static bool publish_transport_locked(grpc_subchannel* c) { /* publish */ c->connected_subchannel.reset(grpc_core::New( - stk, c->channelz_subchannel, socket_uuid)); + stk, c->args, c->channelz_subchannel, socket_uuid)); gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", c->connected_subchannel.get(), c); @@ -1068,16 +1068,18 @@ grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) { namespace grpc_core { ConnectedSubchannel::ConnectedSubchannel( - grpc_channel_stack* channel_stack, + grpc_channel_stack* channel_stack, const grpc_channel_args* args, grpc_core::RefCountedPtr channelz_subchannel, intptr_t socket_uuid) : RefCounted(&grpc_trace_stream_refcount), channel_stack_(channel_stack), + args_(grpc_channel_args_copy(args)), channelz_subchannel_(std::move(channelz_subchannel)), socket_uuid_(socket_uuid) {} ConnectedSubchannel::~ConnectedSubchannel() { + grpc_channel_args_destroy(args_); GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 69c2456ec20..14f87f2c68e 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -85,28 +85,31 @@ class ConnectedSubchannel : public RefCounted { size_t parent_data_size; }; - explicit ConnectedSubchannel( - grpc_channel_stack* channel_stack, + ConnectedSubchannel( + grpc_channel_stack* channel_stack, const grpc_channel_args* args, grpc_core::RefCountedPtr channelz_subchannel, intptr_t socket_uuid); ~ConnectedSubchannel(); - grpc_channel_stack* channel_stack() { return channel_stack_; } void NotifyOnStateChange(grpc_pollset_set* interested_parties, grpc_connectivity_state* state, grpc_closure* closure); void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call); - channelz::SubchannelNode* channelz_subchannel() { + + grpc_channel_stack* channel_stack() const { return channel_stack_; } + const grpc_channel_args* args() const { return args_; } + channelz::SubchannelNode* channelz_subchannel() const { return channelz_subchannel_.get(); } - intptr_t socket_uuid() { return socket_uuid_; } + intptr_t socket_uuid() const { return socket_uuid_; } size_t GetInitialCallSizeEstimate(size_t parent_data_size) const; private: grpc_channel_stack* channel_stack_; + grpc_channel_args* args_; // ref counted pointer to the channelz node in this connected subchannel's // owning subchannel. grpc_core::RefCountedPtr diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc index 1b66dceb130..0839bdfef2d 100644 --- a/src/core/lib/iomgr/sockaddr_utils.cc +++ b/src/core/lib/iomgr/sockaddr_utils.cc @@ -217,6 +217,7 @@ void grpc_string_to_sockaddr(grpc_resolved_address* out, char* addr, int port) { } char* grpc_sockaddr_to_uri(const grpc_resolved_address* resolved_addr) { + if (resolved_addr->len == 0) return nullptr; grpc_resolved_address addr_normalized; if (grpc_sockaddr_is_v4mapped(resolved_addr, &addr_normalized)) { resolved_addr = &addr_normalized; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index ce65c594fe2..c6ca970beee 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -322,7 +322,6 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', - 'src/core/ext/filters/client_channel/lb_policy_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -331,6 +330,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc index 76769b2b64a..1a7a7c9ccc9 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -21,10 +21,10 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -63,8 +63,9 @@ static grpc_address_resolver_vtable test_resolver = {my_resolve_address, static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { gpr_mu_lock(&g_mu); GPR_ASSERT(0 == strcmp("test", addr)); grpc_error* error = GRPC_ERROR_NONE; @@ -74,9 +75,8 @@ static grpc_ares_request* my_dns_lookup_ares_locked( error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { gpr_mu_unlock(&g_mu); - *lb_addrs = grpc_lb_addresses_create(1, nullptr); - grpc_lb_addresses_set_address(*lb_addrs, 0, nullptr, 0, false, nullptr, - nullptr); + *addresses = grpc_core::MakeUnique(); + (*addresses)->emplace_back(nullptr, 0, nullptr); } GRPC_CLOSURE_SCHED(on_done, error); return nullptr; diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc index cdbe33dbe79..16210b8164b 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -22,6 +22,7 @@ #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/combiner.h" @@ -40,8 +41,9 @@ static grpc_combiner* g_combiner; static grpc_ares_request* (*g_default_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner); + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner); // Counter incremented by test_resolve_address_impl indicating the number of // times a system-level resolution has happened. @@ -90,11 +92,12 @@ static grpc_address_resolver_vtable test_resolver = { static grpc_ares_request* test_dns_lookup_ares_locked( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { grpc_ares_request* result = g_default_dns_lookup_ares_locked( - dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, addrs, - check_grpclb, service_config_json, query_timeout_ms, combiner); + dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, + addresses, check_grpclb, service_config_json, query_timeout_ms, combiner); ++g_resolution_count; static grpc_millis last_resolution_time = 0; if (last_resolution_time == 0) { diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc index 6362b95e50e..3b06fe063ae 100644 --- a/test/core/client_channel/resolvers/fake_resolver_test.cc +++ b/test/core/client_channel/resolvers/fake_resolver_test.cc @@ -22,10 +22,10 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/combiner.h" @@ -63,12 +63,14 @@ void on_resolution_cb(void* arg, grpc_error* error) { // We only check the addresses channel arg because that's the only one // explicitly set by the test via // FakeResolverResponseGenerator::SetResponse(). - const grpc_lb_addresses* actual_lb_addresses = - grpc_lb_addresses_find_channel_arg(res->resolver_result); - const grpc_lb_addresses* expected_lb_addresses = - grpc_lb_addresses_find_channel_arg(res->expected_resolver_result); - GPR_ASSERT( - grpc_lb_addresses_cmp(actual_lb_addresses, expected_lb_addresses) == 0); + const grpc_core::ServerAddressList* actual_addresses = + grpc_core::FindServerAddressListChannelArg(res->resolver_result); + const grpc_core::ServerAddressList* expected_addresses = + grpc_core::FindServerAddressListChannelArg(res->expected_resolver_result); + GPR_ASSERT(actual_addresses->size() == expected_addresses->size()); + for (size_t i = 0; i < expected_addresses->size(); ++i) { + GPR_ASSERT((*actual_addresses)[i] == (*expected_addresses)[i]); + } grpc_channel_args_destroy(res->resolver_result); grpc_channel_args_destroy(res->expected_resolver_result); gpr_event_set(&res->ev, (void*)1); @@ -80,27 +82,35 @@ static grpc_channel_args* create_new_resolver_result() { const size_t num_addresses = 2; char* uri_string; char* balancer_name; - // Create grpc_lb_addresses. - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(num_addresses, nullptr); + // Create address list. + grpc_core::ServerAddressList addresses; for (size_t i = 0; i < num_addresses; ++i) { gpr_asprintf(&uri_string, "ipv4:127.0.0.1:100%" PRIuPTR, test_counter * num_addresses + i); grpc_uri* uri = grpc_uri_parse(uri_string, true); gpr_asprintf(&balancer_name, "balancer%" PRIuPTR, test_counter * num_addresses + i); - grpc_lb_addresses_set_address_from_uri( - addresses, i, uri, bool(num_addresses % 2), balancer_name, nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(uri, &address)); + grpc_core::InlinedVector args_to_add; + const bool is_balancer = num_addresses % 2; + if (is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), balancer_name)); + } + grpc_channel_args* args = grpc_channel_args_copy_and_add( + nullptr, args_to_add.data(), args_to_add.size()); + addresses.emplace_back(address.addr, address.len, args); gpr_free(balancer_name); grpc_uri_destroy(uri); gpr_free(uri_string); } - // Convert grpc_lb_addresses to grpc_channel_args. - const grpc_arg addresses_arg = - grpc_lb_addresses_create_channel_arg(addresses); + // Embed the address list in channel args. + const grpc_arg addresses_arg = CreateServerAddressListChannelArg(&addresses); grpc_channel_args* results = grpc_channel_args_copy_and_add(nullptr, &addresses_arg, 1); - grpc_lb_addresses_destroy(addresses); ++test_counter; return results; } diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index a3de56d4f9f..fe471279841 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -24,8 +24,8 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -325,7 +325,7 @@ typedef struct addr_req { char* addr; grpc_closure* on_done; grpc_resolved_addresses** addrs; - grpc_lb_addresses** lb_addrs; + grpc_core::UniquePtr* addresses; } addr_req; static void finish_resolve(void* arg, grpc_error* error) { @@ -340,11 +340,9 @@ static void finish_resolve(void* arg, grpc_error* error) { gpr_malloc(sizeof(*addrs->addrs))); addrs->addrs[0].len = 0; *r->addrs = addrs; - } else if (r->lb_addrs != nullptr) { - grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(1, nullptr); - grpc_lb_addresses_set_address(lb_addrs, 0, nullptr, 0, false, nullptr, - nullptr); - *r->lb_addrs = lb_addrs; + } else if (r->addresses != nullptr) { + *r->addresses = grpc_core::MakeUnique(); + (*r->addresses)->emplace_back(nullptr, 0, nullptr); } GRPC_CLOSURE_SCHED(r->on_done, GRPC_ERROR_NONE); } else { @@ -354,18 +352,17 @@ static void finish_resolve(void* arg, grpc_error* error) { } gpr_free(r->addr); - gpr_free(r); + grpc_core::Delete(r); } void my_resolve_address(const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_resolved_addresses** addresses) { - addr_req* r = static_cast(gpr_malloc(sizeof(*r))); + grpc_resolved_addresses** addrs) { + addr_req* r = grpc_core::New(); r->addr = gpr_strdup(addr); r->on_done = on_done; - r->addrs = addresses; - r->lb_addrs = nullptr; + r->addrs = addrs; grpc_timer_init( &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); @@ -377,13 +374,14 @@ static grpc_address_resolver_vtable fuzzer_resolver = {my_resolve_address, grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - int query_timeout, grpc_combiner* combiner) { + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout, + grpc_combiner* combiner) { addr_req* r = static_cast(gpr_malloc(sizeof(*r))); r->addr = gpr_strdup(addr); r->on_done = on_done; r->addrs = nullptr; - r->lb_addrs = lb_addrs; + r->addresses = addresses; grpc_timer_init( &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 66e8ca51614..7e3b418cd94 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -28,8 +28,8 @@ #include #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr.h" #include "test/core/end2end/cq_verifier.h" @@ -47,8 +47,9 @@ static int g_resolve_port = -1; static grpc_ares_request* (*iomgr_dns_lookup_ares_locked)( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addresses, bool check_grpclb, - char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner); static void (*iomgr_cancel_ares_request_locked)(grpc_ares_request* request); @@ -103,11 +104,12 @@ static grpc_address_resolver_vtable test_resolver = { static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { if (0 != strcmp(addr, "test")) { return iomgr_dns_lookup_ares_locked( - dns_server, addr, default_port, interested_parties, on_done, lb_addrs, + dns_server, addr, default_port, interested_parties, on_done, addresses, check_grpclb, service_config_json, query_timeout_ms, combiner); } @@ -117,15 +119,12 @@ static grpc_ares_request* my_dns_lookup_ares_locked( gpr_mu_unlock(&g_mu); error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { - *lb_addrs = grpc_lb_addresses_create(1, nullptr); - grpc_sockaddr_in* sa = - static_cast(gpr_zalloc(sizeof(grpc_sockaddr_in))); - sa->sin_family = GRPC_AF_INET; - sa->sin_addr.s_addr = 0x100007f; - sa->sin_port = grpc_htons(static_cast(g_resolve_port)); - grpc_lb_addresses_set_address(*lb_addrs, 0, sa, sizeof(*sa), false, nullptr, - nullptr); - gpr_free(sa); + *addresses = grpc_core::MakeUnique(); + grpc_sockaddr_in sa; + sa.sin_family = GRPC_AF_INET; + sa.sin_addr.s_addr = 0x100007f; + sa.sin_port = grpc_htons(static_cast(g_resolve_port)); + (*addresses)->emplace_back(&sa, sizeof(sa), nullptr); gpr_mu_unlock(&g_mu); } GRPC_CLOSURE_SCHED(on_done, error); diff --git a/test/core/end2end/no_server_test.cc b/test/core/end2end/no_server_test.cc index 5dda748f5a5..c289e719eea 100644 --- a/test/core/end2end/no_server_test.cc +++ b/test/core/end2end/no_server_test.cc @@ -23,6 +23,7 @@ #include #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/test_config.h" diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt index 63898ea3b1c..8ed7d4d7fb6 100644 --- a/test/core/util/ubsan_suppressions.txt +++ b/test/core/util/ubsan_suppressions.txt @@ -25,7 +25,6 @@ alignment:absl::little_endian::Store64 alignment:absl::little_endian::Load64 float-divide-by-zero:grpc::testing::postprocess_scenario_result enum:grpc_op_string -nonnull-attribute:grpc_lb_addresses_copy signed-integer-overflow:chrono enum:grpc_http2_error_to_grpc_status -enum:grpc_chttp2_cancel_stream \ No newline at end of file +enum:grpc_chttp2_cancel_stream diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index bf321d8a89e..124557eb567 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -34,7 +34,9 @@ #include #include +#include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -216,23 +218,31 @@ class ClientChannelStressTest { void SetNextResolution(const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(address_data.size(), nullptr); - for (size_t i = 0; i < address_data.size(); ++i) { + grpc_core::ServerAddressList addresses; + for (const auto& addr : address_data) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port); grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); GPR_ASSERT(lb_uri != nullptr); - grpc_lb_addresses_set_address_from_uri( - addresses, i, lb_uri, address_data[i].is_balancer, - address_data[i].balancer_name.c_str(), nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + std::vector args_to_add; + if (addr.is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), + const_cast(addr.balancer_name.c_str()))); + } + grpc_channel_args* args = grpc_channel_args_copy_and_add( + nullptr, args_to_add.data(), args_to_add.size()); + addresses.emplace_back(address.addr, address.len, args); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } - grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); + grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); grpc_channel_args fake_result = {1, &fake_addresses}; response_generator_->SetResponse(&fake_result); - grpc_lb_addresses_destroy(addresses); } void KeepSendingRequests() { diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 1dfa91a76c7..929c2bb5899 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -35,7 +35,9 @@ #include #include +#include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/gpr/env.h" @@ -159,24 +161,22 @@ class ClientLbEnd2endTest : public ::testing::Test { } grpc_channel_args* BuildFakeResults(const std::vector& ports) { - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(ports.size(), nullptr); - for (size_t i = 0; i < ports.size(); ++i) { + grpc_core::ServerAddressList addresses; + for (const int& port : ports) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", ports[i]); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port); grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); GPR_ASSERT(lb_uri != nullptr); - grpc_lb_addresses_set_address_from_uri(addresses, i, lb_uri, - false /* is balancer */, - "" /* balancer name */, nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + addresses.emplace_back(address.addr, address.len, nullptr /* args */); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } const grpc_arg fake_addresses = - grpc_lb_addresses_create_channel_arg(addresses); + CreateServerAddressListChannelArg(&addresses); grpc_channel_args* fake_results = grpc_channel_args_copy_and_add(nullptr, &fake_addresses, 1); - grpc_lb_addresses_destroy(addresses); return fake_results; } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 9c4cd050619..bf990a07b5a 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -32,7 +32,9 @@ #include #include +#include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -486,18 +488,27 @@ class GrpclbEnd2endTest : public ::testing::Test { grpc::string balancer_name; }; - grpc_lb_addresses* CreateLbAddressesFromAddressDataList( + grpc_core::ServerAddressList CreateLbAddressesFromAddressDataList( const std::vector& address_data) { - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(address_data.size(), nullptr); - for (size_t i = 0; i < address_data.size(); ++i) { + grpc_core::ServerAddressList addresses; + for (const auto& addr : address_data) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port); grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); GPR_ASSERT(lb_uri != nullptr); - grpc_lb_addresses_set_address_from_uri( - addresses, i, lb_uri, address_data[i].is_balancer, - address_data[i].balancer_name.c_str(), nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + std::vector args_to_add; + if (addr.is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), + const_cast(addr.balancer_name.c_str()))); + } + grpc_channel_args* args = grpc_channel_args_copy_and_add( + nullptr, args_to_add.data(), args_to_add.size()); + addresses.emplace_back(address.addr, address.len, args); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } @@ -506,23 +517,21 @@ class GrpclbEnd2endTest : public ::testing::Test { void SetNextResolution(const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses* addresses = + grpc_core::ServerAddressList addresses = CreateLbAddressesFromAddressDataList(address_data); - grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); + grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); grpc_channel_args fake_result = {1, &fake_addresses}; response_generator_->SetResponse(&fake_result); - grpc_lb_addresses_destroy(addresses); } void SetNextReresolutionResponse( const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses* addresses = + grpc_core::ServerAddressList addresses = CreateLbAddressesFromAddressDataList(address_data); - grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); + grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); grpc_channel_args fake_result = {1, &fake_addresses}; response_generator_->SetReresolutionResponse(&fake_result); - grpc_lb_addresses_destroy(addresses); } const std::vector GetBackendPorts(const size_t start_index = 0) const { diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index 3eb0e7d7254..09e705df789 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -37,6 +37,7 @@ #include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" @@ -167,30 +168,26 @@ void OverrideAddressSortingSourceAddrFactory( address_sorting_override_source_addr_factory_for_testing(factory); } -grpc_lb_addresses* BuildLbAddrInputs(std::vector test_addrs) { - grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(0, nullptr); - lb_addrs->addresses = - (grpc_lb_address*)gpr_zalloc(sizeof(grpc_lb_address) * test_addrs.size()); - lb_addrs->num_addresses = test_addrs.size(); - for (size_t i = 0; i < test_addrs.size(); i++) { - lb_addrs->addresses[i].address = - TestAddressToGrpcResolvedAddress(test_addrs[i]); +grpc_core::ServerAddressList BuildLbAddrInputs( + const std::vector& test_addrs) { + grpc_core::ServerAddressList addresses; + for (const auto& addr : test_addrs) { + addresses.emplace_back(TestAddressToGrpcResolvedAddress(addr), nullptr); } - return lb_addrs; + return addresses; } -void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs, +void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses, std::vector expected_addrs) { - EXPECT_EQ(lb_addrs->num_addresses, expected_addrs.size()); - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { + EXPECT_EQ(addresses.size(), expected_addrs.size()); + for (size_t i = 0; i < addresses.size(); ++i) { char* ip_addr_str; - grpc_sockaddr_to_string(&ip_addr_str, &lb_addrs->addresses[i].address, + grpc_sockaddr_to_string(&ip_addr_str, &addresses[i].address(), false /* normalize */); EXPECT_EQ(expected_addrs[i], ip_addr_str); gpr_free(ip_addr_str); } grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses_destroy(lb_addrs); } /* We need to run each test case inside of its own @@ -212,11 +209,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) { { {"1.2.3.4:443", {"4.3.2.1:443", AF_INET}}, }); - auto* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"1.2.3.4:443", AF_INET}, {"5.6.7.8:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "1.2.3.4:443", "5.6.7.8:443", @@ -235,7 +232,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) { {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "1.2.3.4:443", "[2607:f8b0:400a:801::1002]:443", @@ -251,11 +248,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) { {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}}, {"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2607:f8b0:400a:801::1002]:443", "1.2.3.4:443", @@ -275,11 +272,11 @@ TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) { {"[fec0::5000]:443", {"[fec0::5001]:0", AF_INET6}}, // site-local and site-local scope }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2000:f8b0:400a:801::1002]:443", AF_INET6}, {"[fec0::5000]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fec0::5000]:443", "[2000:f8b0:400a:801::1002]:443", @@ -298,11 +295,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) { {"[2001::5001]:443", {"[2001::5002]:0", AF_INET6}}, // matching labels }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2002::5001]:443", AF_INET6}, {"[2001::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2001::5001]:443", "[2002::5001]:443", @@ -321,11 +318,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) { {"[2001::5001]:443", {"[2001::5002]:0", AF_INET6}}, // matching labels }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2001::5001]:443", AF_INET6}, {"[2002::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2001::5001]:443", "[2002::5001]:443", @@ -344,11 +341,11 @@ TEST_F(AddressSortingTest, {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}}, {"1.2.3.4:443", {"5.6.7.8:0", AF_INET}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs( lb_addrs, { // The AF_INET address should be IPv4-mapped by the sort, @@ -377,11 +374,11 @@ TEST_F(AddressSortingTest, {"[::1]:443", {"[::1]:0", AF_INET6}}, {v4_compat_dest, {v4_compat_src, AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {v4_compat_dest, AF_INET6}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", v4_compat_dest, @@ -400,11 +397,11 @@ TEST_F(AddressSortingTest, {"[1234::2]:443", {"[1234::2]:0", AF_INET6}}, {"[::1]:443", {"[::1]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[1234::2]:443", AF_INET6}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs( lb_addrs, { @@ -424,11 +421,11 @@ TEST_F(AddressSortingTest, {"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}}, {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2001::1234]:443", AF_INET6}, {"[2000::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs( lb_addrs, { // The 2000::/16 address should match the ::/0 prefix rule @@ -448,11 +445,11 @@ TEST_F( {"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}}, {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2001::1231]:443", AF_INET6}, {"[2000::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2000::5001]:443", "[2001::1231]:443", @@ -469,11 +466,11 @@ TEST_F(AddressSortingTest, {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}}, {"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[fec0::1234]:443", AF_INET6}, {"[fc00::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fc00::5001]:443", "[fec0::1234]:443", @@ -494,11 +491,11 @@ TEST_F( {"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}}, {"[1234::2]:443", {"[1234::3]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[::ffff:1.1.1.2]:443", AF_INET6}, {"[1234::2]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { // ::ffff:0:2 should match the v4-mapped // precedence entry and be deprioritized. @@ -521,11 +518,11 @@ TEST_F(AddressSortingTest, TestPrefersSmallerScope) { {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}}, {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"[fec0::1234]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fec0::1234]:443", "[3ffe::5001]:443", @@ -546,11 +543,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) { {"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}}, {"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:5001::]:443", AF_INET6}, {"[3ffe:1234::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:1234::]:443", "[3ffe:5001::]:443", @@ -567,11 +564,11 @@ TEST_F(AddressSortingTest, {"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}}, {"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1234]:443", "[3ffe::5001]:443", @@ -587,11 +584,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) { {"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}}, {"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:8000::]:443", AF_INET6}, {"[3ffe:2000::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:2000::]:443", "[3ffe:8000::]:443", @@ -607,11 +604,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) { {"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}}, {"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:6::]:443", AF_INET6}, {"[3ffe:c::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:c::]:443", "[3ffe:6::]:443", @@ -629,11 +626,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) { {"[3ffe:1111:1111:1110::]:443", {"[3ffe:1111:1111:1111::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:1111:1111:1110::]:443", AF_INET6}, {"[3ffe:1111:1111:1111::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:1111:1111:1111::]:443", "[3ffe:1111:1111:1110::]:443", @@ -651,11 +648,11 @@ TEST_F(AddressSortingTest, TestStableSort) { {"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}}, {"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1234]:443", "[3ffe::1235]:443", @@ -674,14 +671,14 @@ TEST_F(AddressSortingTest, TestStableSortFiveElements) { {"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}}, {"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::1231]:443", AF_INET6}, {"[3ffe::1232]:443", AF_INET6}, {"[3ffe::1233]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1231]:443", "[3ffe::1232]:443", @@ -695,14 +692,14 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) { bool ipv4_supported = true; bool ipv6_supported = true; OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {}); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::1231]:443", AF_INET6}, {"[3ffe::1232]:443", AF_INET6}, {"[3ffe::1233]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1231]:443", "[3ffe::1232]:443", @@ -716,11 +713,11 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) { bool ipv4_supported = true; bool ipv6_supported = true; OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {}); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[::ffff:5.6.7.8]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::ffff:5.6.7.8]:443", "1.2.3.4:443", @@ -744,11 +741,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) { {"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}}, {v4_compat_dest, {v4_compat_src, AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[fec0::2000]:443", AF_INET6}, {v4_compat_dest, AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { // The sort should be stable since @@ -765,11 +762,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) { * (whether ipv4 loopback is available or not, an available ipv6 * loopback should be preferred). */ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) { - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[::1]:443", AF_INET6}, {"127.0.0.1:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", "127.0.0.1:443", @@ -779,11 +776,11 @@ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) { /* Flip the order of the inputs above and expect the same output order * (try to rule out influence of arbitrary qsort ordering) */ TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) { - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"127.0.0.1:443", AF_INET}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", "127.0.0.1:443", diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index fe6fcb8d9cb..2ac2c237cea 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -41,6 +41,7 @@ #include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" @@ -382,23 +383,19 @@ void CheckResolverResultLocked(void* argsp, grpc_error* err) { EXPECT_EQ(err, GRPC_ERROR_NONE); ArgsStruct* args = (ArgsStruct*)argsp; grpc_channel_args* channel_args = args->channel_args; - const grpc_arg* channel_arg = - grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES); - GPR_ASSERT(channel_arg != nullptr); - GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER); - grpc_lb_addresses* addresses = - (grpc_lb_addresses*)channel_arg->value.pointer.p; + grpc_core::ServerAddressList* addresses = + grpc_core::FindServerAddressListChannelArg(channel_args); gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR, - addresses->num_addresses, args->expected_addrs.size()); - GPR_ASSERT(addresses->num_addresses == args->expected_addrs.size()); + addresses->size(), args->expected_addrs.size()); + GPR_ASSERT(addresses->size() == args->expected_addrs.size()); std::vector found_lb_addrs; - for (size_t i = 0; i < addresses->num_addresses; i++) { - grpc_lb_address addr = addresses->addresses[i]; + for (size_t i = 0; i < addresses->size(); i++) { + grpc_core::ServerAddress& addr = (*addresses)[i]; char* str; - grpc_sockaddr_to_string(&str, &addr.address, 1 /* normalize */); + grpc_sockaddr_to_string(&str, &addr.address(), 1 /* normalize */); gpr_log(GPR_INFO, "%s", str); found_lb_addrs.emplace_back( - GrpcLBAddress(std::string(str), addr.is_balancer)); + GrpcLBAddress(std::string(str), addr.IsBalancer())); gpr_free(str); } if (args->expected_addrs.size() != found_lb_addrs.size()) { diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index dd5bead58ca..5011e19b03a 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -923,7 +923,6 @@ src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc \ src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h \ src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc \ src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h \ -src/core/ext/filters/client_channel/lb_policy_factory.cc \ src/core/ext/filters/client_channel/lb_policy_factory.h \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/lb_policy_registry.h \ @@ -959,6 +958,8 @@ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.h \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/retry_throttle.h \ +src/core/ext/filters/client_channel/server_address.cc \ +src/core/ext/filters/client_channel/server_address.h \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel.h \ src/core/ext/filters/client_channel/subchannel_index.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 0a7a4daf7de..2451101f58d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10074,6 +10074,7 @@ "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.h", "src/core/ext/filters/client_channel/retry_throttle.h", + "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_index.h" ], @@ -10101,7 +10102,6 @@ "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.cc", "src/core/ext/filters/client_channel/lb_policy.h", - "src/core/ext/filters/client_channel/lb_policy_factory.cc", "src/core/ext/filters/client_channel/lb_policy_factory.h", "src/core/ext/filters/client_channel/lb_policy_registry.cc", "src/core/ext/filters/client_channel/lb_policy_registry.h", @@ -10120,6 +10120,8 @@ "src/core/ext/filters/client_channel/resolver_result_parsing.h", "src/core/ext/filters/client_channel/retry_throttle.cc", "src/core/ext/filters/client_channel/retry_throttle.h", + "src/core/ext/filters/client_channel/server_address.cc", + "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_index.cc", From 07fc27c20d694021669f2d77449da0666b6b1626 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 11 Dec 2018 08:08:34 -0800 Subject: [PATCH 257/534] Update channelz proto --- src/proto/grpc/channelz/channelz.proto | 38 ++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/proto/grpc/channelz/channelz.proto b/src/proto/grpc/channelz/channelz.proto index 6202e5e817d..9d73f375541 100644 --- a/src/proto/grpc/channelz/channelz.proto +++ b/src/proto/grpc/channelz/channelz.proto @@ -177,6 +177,7 @@ message SubchannelRef { // SocketRef is a reference to a Socket. message SocketRef { + // The globally unique id for this socket. Must be a positive number. int64 socket_id = 3; // An optional name associated with the socket. string name = 4; @@ -288,7 +289,8 @@ message SocketData { // include stream level or TCP level flow control info. google.protobuf.Int64Value remote_flow_control_window = 12; - // Socket options set on this socket. May be absent. + // Socket options set on this socket. May be absent if 'summary' is set + // on GetSocketRequest. repeated SocketOption option = 13; } @@ -439,12 +441,21 @@ service Channelz { message GetTopChannelsRequest { // start_channel_id indicates that only channels at or above this id should be // included in the results. + // To request the first page, this should be set to 0. To request + // subsequent pages, the client generates this value by adding 1 to + // the highest seen result ID. int64 start_channel_id = 1; + + // If non-zero, the server will return a page of results containing + // at most this many items. If zero, the server will choose a + // reasonable page size. Must never be negative. + int64 max_results = 2; } message GetTopChannelsResponse { // list of channels that the connection detail service knows about. Sorted in // ascending channel_id order. + // Must contain at least 1 result, otherwise 'end' must be true. repeated Channel channel = 1; // If set, indicates that the list of channels is the final list. Requesting // more channels can only return more if they are created after this RPC @@ -455,12 +466,21 @@ message GetTopChannelsResponse { message GetServersRequest { // start_server_id indicates that only servers at or above this id should be // included in the results. + // To request the first page, this must be set to 0. To request + // subsequent pages, the client generates this value by adding 1 to + // the highest seen result ID. int64 start_server_id = 1; + + // If non-zero, the server will return a page of results containing + // at most this many items. If zero, the server will choose a + // reasonable page size. Must never be negative. + int64 max_results = 2; } message GetServersResponse { // list of servers that the connection detail service knows about. Sorted in // ascending server_id order. + // Must contain at least 1 result, otherwise 'end' must be true. repeated Server server = 1; // If set, indicates that the list of servers is the final list. Requesting // more servers will only return more if they are created after this RPC @@ -483,12 +503,21 @@ message GetServerSocketsRequest { int64 server_id = 1; // start_socket_id indicates that only sockets at or above this id should be // included in the results. + // To request the first page, this must be set to 0. To request + // subsequent pages, the client generates this value by adding 1 to + // the highest seen result ID. int64 start_socket_id = 2; + + // If non-zero, the server will return a page of results containing + // at most this many items. If zero, the server will choose a + // reasonable page size. Must never be negative. + int64 max_results = 3; } message GetServerSocketsResponse { // list of socket refs that the connection detail service knows about. Sorted in // ascending socket_id order. + // Must contain at least 1 result, otherwise 'end' must be true. repeated SocketRef socket_ref = 1; // If set, indicates that the list of sockets is the final list. Requesting // more sockets will only return more if they are created after this RPC @@ -521,10 +550,15 @@ message GetSubchannelResponse { message GetSocketRequest { // socket_id is the identifier of the specific socket to get. int64 socket_id = 1; + + // If true, the response will contain only high level information + // that is inexpensive to obtain. Fields thay may be omitted are + // documented. + bool summary = 2; } message GetSocketResponse { // The Socket that corresponds to the requested socket_id. This field // should be set. Socket socket = 1; -} +} \ No newline at end of file From 7b1fc0faa23b2cc1807450498b8c69afb079c2d2 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 11 Dec 2018 08:22:51 -0800 Subject: [PATCH 258/534] Add max_results to ServerSockets --- include/grpc/grpc.h | 3 ++- src/core/lib/channel/channelz.cc | 10 ++++++---- src/core/lib/channel/channelz.h | 3 ++- src/core/lib/channel/channelz_registry.cc | 5 +++-- .../grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi | 8 +++++--- src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi | 3 ++- .../grpcio_channelz/grpc_channelz/v1/channelz.py | 3 ++- src/ruby/ext/grpc/rb_grpc_imports.generated.h | 2 +- test/core/end2end/tests/channelz.cc | 2 +- 9 files changed, 24 insertions(+), 15 deletions(-) diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index d3b74cabab5..fec7f5269e1 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -511,7 +511,8 @@ GRPCAPI char* grpc_channelz_get_server(intptr_t server_id); /* Gets all server sockets that exist in the server. */ GRPCAPI char* grpc_channelz_get_server_sockets(intptr_t server_id, - intptr_t start_socket_id); + intptr_t start_socket_id, + intptr_t max_results); /* Returns a single Channel, or else a NOT_FOUND code. The returned string is allocated and must be freed by the application. */ diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 8d449ee6721..3fcfa2a4125 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -203,8 +203,10 @@ ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes) ServerNode::~ServerNode() {} -char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { - const int kPaginationLimit = 100; +char* ServerNode::RenderServerSockets(intptr_t start_socket_id, + intptr_t max_results) { + // if user does not set max_results, we choose 500. + int pagination_limit = max_results == 0 ? 500 : max_results; grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; @@ -219,8 +221,8 @@ char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { for (size_t i = 0; i < socket_refs.size(); ++i) { // check if we are over pagination limit to determine if we need to set // the "end" element. If we don't go through this block, we know that - // when the loop terminates, we have <= to kPaginationLimit. - if (sockets_added == kPaginationLimit) { + // when the loop terminates, we have <= to pagination_limit. + if (sockets_added == pagination_limit) { reached_pagination_limit = true; break; } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 96a4333083a..e43792126f0 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -210,7 +210,8 @@ class ServerNode : public BaseNode { grpc_json* RenderJson() override; - char* RenderServerSockets(intptr_t start_socket_id); + char* RenderServerSockets(intptr_t start_socket_id, + intptr_t pagination_limit); // proxy methods to composed classes. void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index bc23b90a661..7cca247d64d 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -252,7 +252,8 @@ char* grpc_channelz_get_server(intptr_t server_id) { } char* grpc_channelz_get_server_sockets(intptr_t server_id, - intptr_t start_socket_id) { + intptr_t start_socket_id, + intptr_t max_results) { grpc_core::channelz::BaseNode* base_node = grpc_core::channelz::ChannelzRegistry::Get(server_id); if (base_node == nullptr || @@ -263,7 +264,7 @@ char* grpc_channelz_get_server_sockets(intptr_t server_id, // actually a server node grpc_core::channelz::ServerNode* server_node = static_cast(base_node); - return server_node->RenderServerSockets(start_socket_id); + return server_node->RenderServerSockets(start_socket_id, max_results); } char* grpc_channelz_get_channel(intptr_t channel_id) { diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi index 113f7976dd9..36c8cd121c7 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi @@ -36,15 +36,17 @@ def channelz_get_server(server_id): ' server_id==%s is valid' % server_id) return c_returned_str -def channelz_get_server_sockets(server_id, start_socket_id): +def channelz_get_server_sockets(server_id, start_socket_id, max_results): cdef char *c_returned_str = grpc_channelz_get_server_sockets( server_id, start_socket_id, + max_results, ) if c_returned_str == NULL: raise ValueError('Failed to get server sockets, please ensure your' \ - ' server_id==%s and start_socket_id==%s is valid' % - (server_id, start_socket_id)) + ' server_id==%s and start_socket_id==%s and' \ + ' max_results==%s is valid' % + (server_id, start_socket_id, max_results)) return c_returned_str def channelz_get_channel(channel_id): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 5bbc10af25d..fc7a9ba4395 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -389,7 +389,8 @@ cdef extern from "grpc/grpc.h": char* grpc_channelz_get_servers(intptr_t start_server_id) char* grpc_channelz_get_server(intptr_t server_id) char* grpc_channelz_get_server_sockets(intptr_t server_id, - intptr_t start_socket_id) + intptr_t start_socket_id, + intptr_t max_results) char* grpc_channelz_get_channel(intptr_t channel_id) char* grpc_channelz_get_subchannel(intptr_t subchannel_id) char* grpc_channelz_get_socket(intptr_t socket_id) diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py index 573b9d0d5ac..00eca311dc1 100644 --- a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py +++ b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py @@ -66,7 +66,8 @@ class ChannelzServicer(_channelz_pb2_grpc.ChannelzServicer): try: return json_format.Parse( cygrpc.channelz_get_server_sockets(request.server_id, - request.start_socket_id), + request.start_socket_id, + request.max_results), _channelz_pb2.GetServerSocketsResponse(), ) except ValueError as e: diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 56d222c7ec8..e61a35d09fa 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -272,7 +272,7 @@ extern grpc_channelz_get_servers_type grpc_channelz_get_servers_import; typedef char*(*grpc_channelz_get_server_type)(intptr_t server_id); extern grpc_channelz_get_server_type grpc_channelz_get_server_import; #define grpc_channelz_get_server grpc_channelz_get_server_import -typedef char*(*grpc_channelz_get_server_sockets_type)(intptr_t server_id, intptr_t start_socket_id); +typedef char*(*grpc_channelz_get_server_sockets_type)(intptr_t server_id, intptr_t start_socket_id, intptr_t max_results); extern grpc_channelz_get_server_sockets_type grpc_channelz_get_server_sockets_import; #define grpc_channelz_get_server_sockets grpc_channelz_get_server_sockets_import typedef char*(*grpc_channelz_get_channel_type)(intptr_t channel_id); diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 49a0bc80112..169190eec06 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -259,7 +259,7 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); gpr_free(json); - json = channelz_server->RenderServerSockets(0); + json = channelz_server->RenderServerSockets(0, 100); GPR_ASSERT(nullptr != strstr(json, "\"end\":true")); gpr_free(json); From a6ed43b41fec1201c3d239ee2910aac65cba9d90 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 11 Dec 2018 10:27:11 -0800 Subject: [PATCH 259/534] reviewer feedback --- src/core/lib/channel/channelz.cc | 20 ++++++-------------- src/proto/grpc/channelz/channelz.proto | 2 +- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 3fcfa2a4125..10d5e1b581c 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -205,28 +205,20 @@ ServerNode::~ServerNode() {} char* ServerNode::RenderServerSockets(intptr_t start_socket_id, intptr_t max_results) { - // if user does not set max_results, we choose 500. - int pagination_limit = max_results == 0 ? 500 : max_results; + // if user does not set max_results, we choose 1000. + size_t pagination_limit = max_results == 0 ? 500 : max_results; grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; ChildSocketsList socket_refs; grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id); - int sockets_added = 0; - bool reached_pagination_limit = false; + // declared early so it can be used outside of the loop. + size_t i = 0; if (!socket_refs.empty()) { // create list of socket refs grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); - for (size_t i = 0; i < socket_refs.size(); ++i) { - // check if we are over pagination limit to determine if we need to set - // the "end" element. If we don't go through this block, we know that - // when the loop terminates, we have <= to pagination_limit. - if (sockets_added == pagination_limit) { - reached_pagination_limit = true; - break; - } - sockets_added++; + for (i = 0; i < GPR_MIN(socket_refs.size(), pagination_limit); ++i) { grpc_json* socket_ref_json = grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false); @@ -236,7 +228,7 @@ char* ServerNode::RenderServerSockets(intptr_t start_socket_id, socket_refs[i]->remote(), GRPC_JSON_STRING, false); } } - if (!reached_pagination_limit) { + if (i == socket_refs.size()) { json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, GRPC_JSON_TRUE, false); } diff --git a/src/proto/grpc/channelz/channelz.proto b/src/proto/grpc/channelz/channelz.proto index 9d73f375541..20de23f7fa3 100644 --- a/src/proto/grpc/channelz/channelz.proto +++ b/src/proto/grpc/channelz/channelz.proto @@ -561,4 +561,4 @@ message GetSocketResponse { // The Socket that corresponds to the requested socket_id. This field // should be set. Socket socket = 1; -} \ No newline at end of file +} From c7f7db65e0fdc058b4caa2b76baaa308465fda9e Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 11 Dec 2018 11:28:12 -0800 Subject: [PATCH 260/534] Add test and fix bug --- src/core/lib/channel/channelz.cc | 7 +- src/cpp/server/channelz/channelz_service.cc | 4 +- test/cpp/end2end/channelz_service_test.cc | 82 +++++++++++++++++++++ 3 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 10d5e1b581c..8a596ad4605 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -205,7 +205,7 @@ ServerNode::~ServerNode() {} char* ServerNode::RenderServerSockets(intptr_t start_socket_id, intptr_t max_results) { - // if user does not set max_results, we choose 1000. + // if user does not set max_results, we choose 500. size_t pagination_limit = max_results == 0 ? 500 : max_results; grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; @@ -219,9 +219,8 @@ char* ServerNode::RenderServerSockets(intptr_t start_socket_id, grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); for (i = 0; i < GPR_MIN(socket_refs.size(), pagination_limit); ++i) { - grpc_json* socket_ref_json = - grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, - GRPC_JSON_OBJECT, false); + grpc_json* socket_ref_json = grpc_json_create_child( + nullptr, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false); json_iterator = grpc_json_add_number_string_child( socket_ref_json, nullptr, "socketId", socket_refs[i]->uuid()); grpc_json_create_child(json_iterator, socket_ref_json, "name", diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc index 9ecb9de7e4b..c44a9ac0de6 100644 --- a/src/cpp/server/channelz/channelz_service.cc +++ b/src/cpp/server/channelz/channelz_service.cc @@ -79,8 +79,8 @@ Status ChannelzService::GetServer(ServerContext* unused, Status ChannelzService::GetServerSockets( ServerContext* unused, const channelz::v1::GetServerSocketsRequest* request, channelz::v1::GetServerSocketsResponse* response) { - char* json_str = grpc_channelz_get_server_sockets(request->server_id(), - request->start_socket_id()); + char* json_str = grpc_channelz_get_server_sockets( + request->server_id(), request->start_socket_id(), request->max_results()); if (json_str == nullptr) { return Status(StatusCode::INTERNAL, "grpc_channelz_get_server_sockets returned null"); diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index 29b59e4e5e1..425334d972e 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -54,6 +54,14 @@ using grpc::channelz::v1::GetSubchannelResponse; using grpc::channelz::v1::GetTopChannelsRequest; using grpc::channelz::v1::GetTopChannelsResponse; +// This code snippet can be used to print out any responses for +// visual debugging. +// +// +// string out_str; +// google::protobuf::TextFormat::PrintToString(resp, &out_str); +// std::cout << "resp: " << out_str << "\n"; + namespace grpc { namespace testing { namespace { @@ -164,6 +172,19 @@ class ChannelzServerTest : public ::testing::Test { echo_stub_ = grpc::testing::EchoTestService::NewStub(channel); } + std::unique_ptr NewEchoStub() { + static int salt = 0; + string target = "dns:localhost:" + to_string(proxy_port_); + ChannelArguments args; + // disable channelz. We only want to focus on proxy to backend outbound. + args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0); + // This ensures that gRPC will not do connection sharing. + args.SetInt("salt", salt++); + std::shared_ptr channel = + CreateCustomChannel(target, InsecureChannelCredentials(), args); + return grpc::testing::EchoTestService::NewStub(channel); + } + void SendSuccessfulEcho(int channel_idx) { EchoRequest request; EchoResponse response; @@ -651,6 +672,67 @@ TEST_F(ChannelzServerTest, GetServerSocketsTest) { EXPECT_EQ(get_server_sockets_response.socket_ref_size(), 1); } +TEST_F(ChannelzServerTest, GetServerSocketsPaginationTest) { + ResetStubs(); + ConfigureProxy(1); + std::vector> stubs; + const int kNumServerSocketsCreated = 20; + for (int i = 0; i < kNumServerSocketsCreated; ++i) { + stubs.push_back(NewEchoStub()); + EchoRequest request; + EchoResponse response; + request.set_message("Hello channelz"); + request.mutable_param()->set_backend_channel_idx(0); + ClientContext context; + Status s = stubs.back()->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + } + GetServersRequest get_server_request; + GetServersResponse get_server_response; + get_server_request.set_start_server_id(0); + ClientContext get_server_context; + Status s = channelz_stub_->GetServers(&get_server_context, get_server_request, + &get_server_response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + EXPECT_EQ(get_server_response.server_size(), 1); + // Make a request that gets all of the serversockets + { + GetServerSocketsRequest get_server_sockets_request; + GetServerSocketsResponse get_server_sockets_response; + get_server_sockets_request.set_server_id( + get_server_response.server(0).ref().server_id()); + get_server_sockets_request.set_start_socket_id(0); + ClientContext get_server_sockets_context; + s = channelz_stub_->GetServerSockets(&get_server_sockets_context, + get_server_sockets_request, + &get_server_sockets_response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + // We add one to account the the channelz stub that will end up creating + // a serversocket. + EXPECT_EQ(get_server_sockets_response.socket_ref_size(), + kNumServerSocketsCreated + 1); + EXPECT_TRUE(get_server_sockets_response.end()); + } + // Now we make a request that exercises pagination. + { + GetServerSocketsRequest get_server_sockets_request; + GetServerSocketsResponse get_server_sockets_response; + get_server_sockets_request.set_server_id( + get_server_response.server(0).ref().server_id()); + get_server_sockets_request.set_start_socket_id(0); + const int kMaxResults = 10; + get_server_sockets_request.set_max_results(kMaxResults); + ClientContext get_server_sockets_context; + s = channelz_stub_->GetServerSockets(&get_server_sockets_context, + get_server_sockets_request, + &get_server_sockets_response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + EXPECT_EQ(get_server_sockets_response.socket_ref_size(), kMaxResults); + EXPECT_FALSE(get_server_sockets_response.end()); + } +} + TEST_F(ChannelzServerTest, GetServerListenSocketsTest) { ResetStubs(); ConfigureProxy(1); From 6b3baf26185847f02c11401c971647624ba3d039 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 11 Dec 2018 10:18:43 -0800 Subject: [PATCH 261/534] Add hooks for census context propagation Appease the yapf gods Reformat --- src/python/grpcio/grpc/_cython/BUILD.bazel | 47 ++++++------ .../grpc/_cython/_cygrpc/_hooks.pyx.pxi | 15 ++++ .../grpc/_cython/_cygrpc/channel.pyx.pxi | 27 ++++--- .../_cython/_cygrpc/propagation_bits.pxd.pxi | 20 ++++++ .../_cython/_cygrpc/propagation_bits.pyx.pxi | 20 ++++++ src/python/grpcio/grpc/_cython/cygrpc.pxd | 1 + src/python/grpcio/grpc/_cython/cygrpc.pyx | 1 + src/python/grpcio/grpc/_server.py | 72 ++++++++++--------- 8 files changed, 139 insertions(+), 64 deletions(-) create mode 100644 src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi create mode 100644 src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi diff --git a/src/python/grpcio/grpc/_cython/BUILD.bazel b/src/python/grpcio/grpc/_cython/BUILD.bazel index e318298d0ab..42db7b87213 100644 --- a/src/python/grpcio/grpc/_cython/BUILD.bazel +++ b/src/python/grpcio/grpc/_cython/BUILD.bazel @@ -6,46 +6,47 @@ pyx_library( name = "cygrpc", srcs = [ "__init__.py", - "cygrpc.pxd", - "cygrpc.pyx", + "_cygrpc/_hooks.pxd.pxi", "_cygrpc/_hooks.pyx.pxi", - "_cygrpc/grpc_string.pyx.pxi", + "_cygrpc/arguments.pxd.pxi", "_cygrpc/arguments.pyx.pxi", + "_cygrpc/call.pxd.pxi", "_cygrpc/call.pyx.pxi", - "_cygrpc/channelz.pyx.pxi", + "_cygrpc/channel.pxd.pxi", "_cygrpc/channel.pyx.pxi", - "_cygrpc/credentials.pyx.pxi", + "_cygrpc/channelz.pyx.pxi", + "_cygrpc/completion_queue.pxd.pxi", "_cygrpc/completion_queue.pyx.pxi", - "_cygrpc/event.pyx.pxi", - "_cygrpc/fork_posix.pyx.pxi", - "_cygrpc/metadata.pyx.pxi", - "_cygrpc/operation.pyx.pxi", - "_cygrpc/records.pyx.pxi", - "_cygrpc/security.pyx.pxi", - "_cygrpc/server.pyx.pxi", - "_cygrpc/tag.pyx.pxi", - "_cygrpc/time.pyx.pxi", - "_cygrpc/grpc_gevent.pyx.pxi", - "_cygrpc/grpc.pxi", - "_cygrpc/_hooks.pxd.pxi", - "_cygrpc/arguments.pxd.pxi", - "_cygrpc/call.pxd.pxi", - "_cygrpc/channel.pxd.pxi", "_cygrpc/credentials.pxd.pxi", - "_cygrpc/completion_queue.pxd.pxi", + "_cygrpc/credentials.pyx.pxi", "_cygrpc/event.pxd.pxi", + "_cygrpc/event.pyx.pxi", "_cygrpc/fork_posix.pxd.pxi", + "_cygrpc/fork_posix.pyx.pxi", + "_cygrpc/grpc.pxi", + "_cygrpc/grpc_gevent.pxd.pxi", + "_cygrpc/grpc_gevent.pyx.pxi", + "_cygrpc/grpc_string.pyx.pxi", "_cygrpc/metadata.pxd.pxi", + "_cygrpc/metadata.pyx.pxi", "_cygrpc/operation.pxd.pxi", + "_cygrpc/operation.pyx.pxi", + "_cygrpc/propagation_bits.pxd.pxi", + "_cygrpc/propagation_bits.pyx.pxi", "_cygrpc/records.pxd.pxi", + "_cygrpc/records.pyx.pxi", "_cygrpc/security.pxd.pxi", + "_cygrpc/security.pyx.pxi", "_cygrpc/server.pxd.pxi", + "_cygrpc/server.pyx.pxi", "_cygrpc/tag.pxd.pxi", + "_cygrpc/tag.pyx.pxi", "_cygrpc/time.pxd.pxi", - "_cygrpc/grpc_gevent.pxd.pxi", + "_cygrpc/time.pyx.pxi", + "cygrpc.pxd", + "cygrpc.pyx", ], deps = [ "//:grpc", ], ) - diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi index 38cf629dc24..cd4a51a635e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi @@ -15,3 +15,18 @@ cdef object _custom_op_on_c_call(int op, grpc_call *call): raise NotImplementedError("No custom hooks are implemented") + +def install_census_context_from_call(Call call): + pass + +def uninstall_context(): + pass + +def build_context(): + pass + +cdef class CensusContext: + pass + +def set_census_context_on_call(_CallState call_state, CensusContext census_ctx): + pass diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index a81ff4d823b..135d224095e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -159,7 +159,8 @@ cdef void _call( _ChannelState channel_state, _CallState call_state, grpc_completion_queue *c_completion_queue, on_success, int flags, method, host, object deadline, CallCredentials credentials, - object operationses_and_user_tags, object metadata) except *: + object operationses_and_user_tags, object metadata, + object context) except *: """Invokes an RPC. Args: @@ -185,6 +186,7 @@ cdef void _call( which is an object to be used as a tag. A SendInitialMetadataOperation must be present in the first element of this value. metadata: The metadata for this call. + context: Context object for distributed tracing. """ cdef grpc_slice method_slice cdef grpc_slice host_slice @@ -208,6 +210,8 @@ cdef void _call( grpc_slice_unref(method_slice) if host_slice_ptr: grpc_slice_unref(host_slice) + if context is not None: + set_census_context_on_call(call_state, context) if credentials is not None: c_call_credentials = credentials.c() c_call_error = grpc_call_set_credentials( @@ -257,7 +261,8 @@ cdef class IntegratedCall: cdef IntegratedCall _integrated_call( _ChannelState state, int flags, method, host, object deadline, - object metadata, CallCredentials credentials, operationses_and_user_tags): + object metadata, CallCredentials credentials, operationses_and_user_tags, + object context): call_state = _CallState() def on_success(started_tags): @@ -266,7 +271,7 @@ cdef IntegratedCall _integrated_call( _call( state, call_state, state.c_call_completion_queue, on_success, flags, - method, host, deadline, credentials, operationses_and_user_tags, metadata) + method, host, deadline, credentials, operationses_and_user_tags, metadata, context) return IntegratedCall(state, call_state) @@ -308,7 +313,8 @@ cdef class SegregatedCall: cdef SegregatedCall _segregated_call( _ChannelState state, int flags, method, host, object deadline, - object metadata, CallCredentials credentials, operationses_and_user_tags): + object metadata, CallCredentials credentials, operationses_and_user_tags, + object context): cdef _CallState call_state = _CallState() cdef SegregatedCall segregated_call cdef grpc_completion_queue *c_completion_queue @@ -325,7 +331,8 @@ cdef SegregatedCall _segregated_call( try: _call( state, call_state, c_completion_queue, on_success, flags, method, host, - deadline, credentials, operationses_and_user_tags, metadata) + deadline, credentials, operationses_and_user_tags, metadata, + context) except: _destroy_c_completion_queue(c_completion_queue) raise @@ -443,10 +450,11 @@ cdef class Channel: def integrated_call( self, int flags, method, host, object deadline, object metadata, - CallCredentials credentials, operationses_and_tags): + CallCredentials credentials, operationses_and_tags, + object context = None): return _integrated_call( self._state, flags, method, host, deadline, metadata, credentials, - operationses_and_tags) + operationses_and_tags, context) def next_call_event(self): def on_success(tag): @@ -461,10 +469,11 @@ cdef class Channel: def segregated_call( self, int flags, method, host, object deadline, object metadata, - CallCredentials credentials, operationses_and_tags): + CallCredentials credentials, operationses_and_tags, + object context = None): return _segregated_call( self._state, flags, method, host, deadline, metadata, credentials, - operationses_and_tags) + operationses_and_tags, context) def check_connectivity_state(self, bint try_to_connect): with self._state.condition: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi new file mode 100644 index 00000000000..cd6e94c816c --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi @@ -0,0 +1,20 @@ +# Copyright 2018 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. + +cdef extern from "grpc/impl/codegen/propagation_bits.h": + cdef int _GRPC_PROPAGATE_DEADLINE "GRPC_PROPAGATE_DEADLINE" + cdef int _GRPC_PROPAGATE_CENSUS_STATS_CONTEXT "GRPC_PROPAGATE_CENSUS_STATS_CONTEXT" + cdef int _GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT "GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT" + cdef int _GRPC_PROPAGATE_CANCELLATION "GRPC_PROPAGATE_CANCELLATION" + cdef int _GRPC_PROPAGATE_DEFAULTS "GRPC_PROPAGATE_DEFAULTS" diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi new file mode 100644 index 00000000000..2dcc76a2db2 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi @@ -0,0 +1,20 @@ +# Copyright 2018 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. + +class PropagationConstants: + GRPC_PROPAGATE_DEADLINE = _GRPC_PROPAGATE_DEADLINE + GRPC_PROPAGATE_CENSUS_STATS_CONTEXT = _GRPC_PROPAGATE_CENSUS_STATS_CONTEXT + GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT = _GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT + GRPC_PROPAGATE_CANCELLATION = _GRPC_PROPAGATE_CANCELLATION + GRPC_PROPAGATE_DEFAULTS = _GRPC_PROPAGATE_DEFAULTS diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd index 8258b857bc4..64cae6b34d6 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pxd +++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd @@ -29,6 +29,7 @@ include "_cygrpc/server.pxd.pxi" include "_cygrpc/tag.pxd.pxi" include "_cygrpc/time.pxd.pxi" include "_cygrpc/_hooks.pxd.pxi" +include "_cygrpc/propagation_bits.pxd.pxi" include "_cygrpc/grpc_gevent.pxd.pxi" diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index 9ab919375c0..ce98fa3a8e6 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -36,6 +36,7 @@ include "_cygrpc/tag.pyx.pxi" include "_cygrpc/time.pyx.pxi" include "_cygrpc/_hooks.pyx.pxi" include "_cygrpc/channelz.pyx.pxi" +include "_cygrpc/propagation_bits.pyx.pxi" include "_cygrpc/grpc_gevent.pyx.pxi" diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 7276a7fd90e..e939f615dfd 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -480,43 +480,51 @@ def _status(rpc_event, state, serialized_response): def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - argument = argument_thunk() - if argument is not None: - response, proceed = _call_behavior(rpc_event, state, behavior, argument, - request_deserializer) - if proceed: - serialized_response = _serialize_response( - rpc_event, state, response, response_serializer) - if serialized_response is not None: - _status(rpc_event, state, serialized_response) + cygrpc.install_census_context_from_call(rpc_event.call) + try: + argument = argument_thunk() + if argument is not None: + response, proceed = _call_behavior(rpc_event, state, behavior, + argument, request_deserializer) + if proceed: + serialized_response = _serialize_response( + rpc_event, state, response, response_serializer) + if serialized_response is not None: + _status(rpc_event, state, serialized_response) + finally: + cygrpc.uninstall_context() def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - argument = argument_thunk() - if argument is not None: - response_iterator, proceed = _call_behavior( - rpc_event, state, behavior, argument, request_deserializer) - if proceed: - while True: - response, proceed = _take_response_from_response_iterator( - rpc_event, state, response_iterator) - if proceed: - if response is None: - _status(rpc_event, state, None) - break - else: - serialized_response = _serialize_response( - rpc_event, state, response, response_serializer) - if serialized_response is not None: - proceed = _send_response(rpc_event, state, - serialized_response) - if not proceed: - break - else: + cygrpc.install_census_context_from_call(rpc_event.call) + try: + argument = argument_thunk() + if argument is not None: + response_iterator, proceed = _call_behavior( + rpc_event, state, behavior, argument, request_deserializer) + if proceed: + while True: + response, proceed = _take_response_from_response_iterator( + rpc_event, state, response_iterator) + if proceed: + if response is None: + _status(rpc_event, state, None) break - else: - break + else: + serialized_response = _serialize_response( + rpc_event, state, response, response_serializer) + if serialized_response is not None: + proceed = _send_response( + rpc_event, state, serialized_response) + if not proceed: + break + else: + break + else: + break + finally: + cygrpc.uninstall_context() def _handle_unary_unary(rpc_event, state, method_handler, thread_pool): From 3bc323977fb049ac0a10306ec9c964387b204d7c Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Tue, 11 Dec 2018 13:12:39 -0800 Subject: [PATCH 262/534] Streaming support for callback server --- test/cpp/qps/server_callback.cc | 46 ++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/test/cpp/qps/server_callback.cc b/test/cpp/qps/server_callback.cc index 8bedd447392..4a346dd0178 100644 --- a/test/cpp/qps/server_callback.cc +++ b/test/cpp/qps/server_callback.cc @@ -34,13 +34,53 @@ class BenchmarkCallbackServiceImpl final : public BenchmarkService::ExperimentalCallbackService { public: void UnaryCall( - ServerContext* context, const SimpleRequest* request, - SimpleResponse* response, - experimental::ServerCallbackRpcController* controller) override { + ServerContext* context, const ::grpc::testing::SimpleRequest* request, + ::grpc::testing::SimpleResponse* response, + ::grpc::experimental::ServerCallbackRpcController* controller) override { auto s = SetResponse(request, response); controller->Finish(s); } + ::grpc::experimental::ServerBidiReactor<::grpc::testing::SimpleRequest, + ::grpc::testing::SimpleResponse>* + StreamingCall() override { + class Reactor + : public ::grpc::experimental::ServerBidiReactor< + ::grpc::testing::SimpleRequest, ::grpc::testing::SimpleResponse> { + public: + Reactor() {} + void OnStarted(ServerContext* context) override { StartRead(&request_); } + + void OnReadDone(bool ok) override { + if (!ok) { + Finish(::grpc::Status::OK); + return; + } + auto s = SetResponse(&request_, &response_); + if (!s.ok()) { + Finish(s); + return; + } + StartWrite(&response_); + } + + void OnWriteDone(bool ok) override { + if (!ok) { + Finish(::grpc::Status::OK); + return; + } + StartRead(&request_); + } + + void OnDone() override { delete (this); } + + private: + SimpleRequest request_; + SimpleResponse response_; + }; + return new Reactor; + } + private: static Status SetResponse(const SimpleRequest* request, SimpleResponse* response) { From 62027b7e14624283f758a7785a0a1347eda0a147 Mon Sep 17 00:00:00 2001 From: Vishal Powar Date: Fri, 30 Nov 2018 14:27:52 -0800 Subject: [PATCH 263/534] Changes add a script for generating C code and build rule for protobuf protos All these changes need to go together to make sense - changes to use new version of upb in bazel - allowing includes in build target option - script for generating c code for protos - generated code for example build - adding changes for non-bazel builds - change sanity tests to ignore the generated files. --- BUILD | 25 + CMakeLists.txt | 53 + Makefile | 38 +- bazel/grpc_build_system.bzl | 1 + bazel/grpc_deps.bzl | 6 +- build.yaml | 2 + grpc.gyp | 19 + .../upb-generated/google/protobuf/any.upb.c | 24 + .../upb-generated/google/protobuf/any.upb.h | 63 + .../google/protobuf/descriptor.upb.c | 549 +++++ .../google/protobuf/descriptor.upb.h | 1879 +++++++++++++++++ .../google/protobuf/duration.upb.c | 24 + .../google/protobuf/duration.upb.h | 65 + .../google/protobuf/struct.upb.c | 88 + .../google/protobuf/struct.upb.h | 226 ++ .../google/protobuf/timestamp.upb.c | 24 + .../google/protobuf/timestamp.upb.h | 65 + .../google/protobuf/wrappers.upb.c | 87 + .../google/protobuf/wrappers.upb.h | 305 +++ src/upb/gen_build_yaml.py | 69 + tools/buildgen/generate_build_additions.sh | 1 + tools/codegen/core/gen_upb_api.sh | 38 + tools/distrib/check_copyright.py | 14 + tools/distrib/check_include_guards.py | 14 + .../generated/sources_and_headers.json | 21 + tools/run_tests/sanity/check_port_platform.py | 3 + 26 files changed, 3699 insertions(+), 4 deletions(-) create mode 100644 src/core/ext/upb-generated/google/protobuf/any.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/any.upb.h create mode 100644 src/core/ext/upb-generated/google/protobuf/descriptor.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/descriptor.upb.h create mode 100644 src/core/ext/upb-generated/google/protobuf/duration.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/duration.upb.h create mode 100644 src/core/ext/upb-generated/google/protobuf/struct.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/struct.upb.h create mode 100644 src/core/ext/upb-generated/google/protobuf/timestamp.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/timestamp.upb.h create mode 100644 src/core/ext/upb-generated/google/protobuf/wrappers.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/wrappers.upb.h create mode 100755 src/upb/gen_build_yaml.py create mode 100755 tools/codegen/core/gen_upb_api.sh diff --git a/BUILD b/BUILD index 9a2c16c6012..0d789ae7c00 100644 --- a/BUILD +++ b/BUILD @@ -2272,4 +2272,29 @@ grpc_cc_library( ], ) +# TODO: Get this into build.yaml once we start using it. +grpc_cc_library( + name = "google_protobuf", + srcs = [ + "src/core/ext/upb-generated/google/protobuf/any.upb.c", + "src/core/ext/upb-generated/google/protobuf/descriptor.upb.c", + "src/core/ext/upb-generated/google/protobuf/duration.upb.c", + "src/core/ext/upb-generated/google/protobuf/struct.upb.c", + "src/core/ext/upb-generated/google/protobuf/timestamp.upb.c", + "src/core/ext/upb-generated/google/protobuf/wrappers.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/google/protobuf/any.upb.h", + "src/core/ext/upb-generated/google/protobuf/descriptor.upb.h", + "src/core/ext/upb-generated/google/protobuf/duration.upb.h", + "src/core/ext/upb-generated/google/protobuf/struct.upb.h", + "src/core/ext/upb-generated/google/protobuf/timestamp.upb.h", + "src/core/ext/upb-generated/google/protobuf/wrappers.upb.h", + ], + language = "c++", + external_deps = [ + "upb_lib", + ], +) + grpc_generate_one_off_targets() diff --git a/CMakeLists.txt b/CMakeLists.txt index 1194d0072e3..a9562960920 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5476,6 +5476,59 @@ endif() endif (gRPC_BUILD_CSHARP_EXT) if (gRPC_BUILD_TESTS) +add_library(upb + third_party/upb/google/protobuf/descriptor.upb.c + third_party/upb/upb/decode.c + third_party/upb/upb/def.c + third_party/upb/upb/encode.c + third_party/upb/upb/handlers.c + third_party/upb/upb/msg.c + third_party/upb/upb/msgfactory.c + third_party/upb/upb/refcounted.c + third_party/upb/upb/sink.c + third_party/upb/upb/table.c + third_party/upb/upb/upb.c +) + +if(WIN32 AND MSVC) + set_target_properties(upb PROPERTIES COMPILE_PDB_NAME "upb" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if (gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/upb.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + + +target_include_directories(upb + PUBLIC $ $ + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(upb PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(upb PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() +target_link_libraries(upb + ${_gRPC_SSL_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_library(bad_client_test test/core/bad_client/bad_client.cc ) diff --git a/Makefile b/Makefile index 7dfce79c922..e1ae7e7ad61 100644 --- a/Makefile +++ b/Makefile @@ -1411,7 +1411,7 @@ plugins: $(PROTOC_PLUGINS) privatelibs: privatelibs_c privatelibs_cxx -privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a +privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libupb.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc @@ -10113,6 +10113,42 @@ ifneq ($(NO_DEPS),true) endif +LIBUPB_SRC = \ + third_party/upb/google/protobuf/descriptor.upb.c \ + third_party/upb/upb/decode.c \ + third_party/upb/upb/def.c \ + third_party/upb/upb/encode.c \ + third_party/upb/upb/handlers.c \ + third_party/upb/upb/msg.c \ + third_party/upb/upb/msgfactory.c \ + third_party/upb/upb/refcounted.c \ + third_party/upb/upb/sink.c \ + third_party/upb/upb/table.c \ + third_party/upb/upb/upb.c \ + +PUBLIC_HEADERS_C += \ + +LIBUPB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBUPB_SRC)))) + +$(LIBUPB_OBJS): CFLAGS += -Ithird_party/upb -Wno-sign-conversion -Wno-shadow -Wno-conversion -Wno-implicit-fallthrough + +$(LIBDIR)/$(CONFIG)/libupb.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(LIBUPB_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libupb.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libupb.a $(LIBUPB_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libupb.a +endif + + + + +ifneq ($(NO_DEPS),true) +-include $(LIBUPB_OBJS:.o=.dep) +endif + + LIBZ_SRC = \ third_party/zlib/adler32.c \ third_party/zlib/compress.c \ diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 65fe5a10aa2..06b05f79525 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -99,6 +99,7 @@ def grpc_cc_library( linkopts = if_not_windows(["-pthread"]), includes = [ "include", + "src/core/ext/upb-generated", ], alwayslink = alwayslink, data = data, diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 3eacd2b0475..2738e39abf7 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -12,7 +12,7 @@ def grpc_deps(): ) native.bind( - name = "upblib", + name = "upb_lib", actual = "@upb//:upb", ) @@ -195,8 +195,8 @@ def grpc_deps(): if "upb" not in native.existing_rules(): http_archive( name = "upb", - strip_prefix = "upb-9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3", - url = "https://github.com/google/upb/archive/9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3.tar.gz", + strip_prefix = "upb-fb6f7e96895c3a9a8ae2e66516160937e7ac1779", + url = "https://github.com/google/upb/archive/fb6f7e96895c3a9a8ae2e66516160937e7ac1779.tar.gz", ) diff --git a/build.yaml b/build.yaml index 41c63d133a9..fa8d65b7606 100644 --- a/build.yaml +++ b/build.yaml @@ -5890,6 +5890,8 @@ defaults: -Wno-deprecated-declarations -Ithird_party/nanopb -DPB_FIELD_32BIT CXXFLAGS: -Wnon-virtual-dtor LDFLAGS: -g + upb: + CFLAGS: -Ithird_party/upb -Wno-sign-conversion -Wno-shadow -Wno-conversion -Wno-implicit-fallthrough zlib: CFLAGS: -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration -Wno-implicit-fallthrough $(W_NO_SHIFT_NEGATIVE_VALUE) -fvisibility=hidden diff --git a/grpc.gyp b/grpc.gyp index 2b841354baf..10277110dd8 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -2638,6 +2638,25 @@ 'third_party/benchmark/src/timers.cc', ], }, + { + 'target_name': 'upb', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'third_party/upb/google/protobuf/descriptor.upb.c', + 'third_party/upb/upb/decode.c', + 'third_party/upb/upb/def.c', + 'third_party/upb/upb/encode.c', + 'third_party/upb/upb/handlers.c', + 'third_party/upb/upb/msg.c', + 'third_party/upb/upb/msgfactory.c', + 'third_party/upb/upb/refcounted.c', + 'third_party/upb/upb/sink.c', + 'third_party/upb/upb/table.c', + 'third_party/upb/upb/upb.c', + ], + }, { 'target_name': 'z', 'type': 'static_library', diff --git a/src/core/ext/upb-generated/google/protobuf/any.upb.c b/src/core/ext/upb-generated/google/protobuf/any.upb.c new file mode 100644 index 00000000000..1005a48e909 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/any.upb.c @@ -0,0 +1,24 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/any.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include "google/protobuf/any.upb.h" +#include +#include "upb/msg.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field google_protobuf_Any__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 12, 1}, +}; + +const upb_msglayout google_protobuf_Any_msginit = { + NULL, &google_protobuf_Any__fields[0], UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" diff --git a/src/core/ext/upb-generated/google/protobuf/any.upb.h b/src/core/ext/upb-generated/google/protobuf/any.upb.h new file mode 100644 index 00000000000..d29265553f7 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/any.upb.h @@ -0,0 +1,63 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/any.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +UPB_BEGIN_EXTERN_C + +struct google_protobuf_Any; +typedef struct google_protobuf_Any google_protobuf_Any; + +/* Enums */ + +/* google.protobuf.Any */ + +extern const upb_msglayout google_protobuf_Any_msginit; +UPB_INLINE google_protobuf_Any* google_protobuf_Any_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_Any_msginit, arena); +} +UPB_INLINE google_protobuf_Any* google_protobuf_Any_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_Any* ret = google_protobuf_Any_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Any_msginit)) ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_Any_serialize(const google_protobuf_Any* msg, + upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_Any_msginit, arena, len); +} + +UPB_INLINE upb_stringview +google_protobuf_Any_type_url(const google_protobuf_Any* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); +} +UPB_INLINE upb_stringview +google_protobuf_Any_value(const google_protobuf_Any* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} + +UPB_INLINE void google_protobuf_Any_set_type_url(google_protobuf_Any* msg, + upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Any_set_value(google_protobuf_Any* msg, + upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} + +UPB_END_EXTERN_C + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c new file mode 100644 index 00000000000..f774873d614 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c @@ -0,0 +1,549 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include "google/protobuf/descriptor.upb.h" +#include +#include "upb/msg.h" + +#include "upb/port_def.inc" + +static const upb_msglayout* const google_protobuf_FileDescriptorSet_submsgs[1] = + { + &google_protobuf_FileDescriptorProto_msginit, +}; + +static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = + { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_FileDescriptorSet_msginit = { + &google_protobuf_FileDescriptorSet_submsgs[0], + &google_protobuf_FileDescriptorSet__fields[0], + UPB_SIZE(4, 8), + 1, + false, +}; + +static const upb_msglayout* const + google_protobuf_FileDescriptorProto_submsgs[6] = { + &google_protobuf_DescriptorProto_msginit, + &google_protobuf_EnumDescriptorProto_msginit, + &google_protobuf_FieldDescriptorProto_msginit, + &google_protobuf_FileOptions_msginit, + &google_protobuf_ServiceDescriptorProto_msginit, + &google_protobuf_SourceCodeInfo_msginit, +}; + +static const upb_msglayout_field + google_protobuf_FileDescriptorProto__fields[12] = { + {1, UPB_SIZE(8, 16), 1, 0, 9, 1}, + {2, UPB_SIZE(16, 32), 2, 0, 9, 1}, + {3, UPB_SIZE(40, 80), 0, 0, 9, 3}, + {4, UPB_SIZE(44, 88), 0, 0, 11, 3}, + {5, UPB_SIZE(48, 96), 0, 1, 11, 3}, + {6, UPB_SIZE(52, 104), 0, 4, 11, 3}, + {7, UPB_SIZE(56, 112), 0, 2, 11, 3}, + {8, UPB_SIZE(32, 64), 4, 3, 11, 1}, + {9, UPB_SIZE(36, 72), 5, 5, 11, 1}, + {10, UPB_SIZE(60, 120), 0, 0, 5, 3}, + {11, UPB_SIZE(64, 128), 0, 0, 5, 3}, + {12, UPB_SIZE(24, 48), 3, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_FileDescriptorProto_msginit = { + &google_protobuf_FileDescriptorProto_submsgs[0], + &google_protobuf_FileDescriptorProto__fields[0], + UPB_SIZE(72, 144), + 12, + false, +}; + +static const upb_msglayout* const google_protobuf_DescriptorProto_submsgs[8] = { + &google_protobuf_DescriptorProto_msginit, + &google_protobuf_DescriptorProto_ExtensionRange_msginit, + &google_protobuf_DescriptorProto_ReservedRange_msginit, + &google_protobuf_EnumDescriptorProto_msginit, + &google_protobuf_FieldDescriptorProto_msginit, + &google_protobuf_MessageOptions_msginit, + &google_protobuf_OneofDescriptorProto_msginit, +}; + +static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = { + {1, UPB_SIZE(8, 16), 1, 0, 9, 1}, {2, UPB_SIZE(20, 40), 0, 4, 11, 3}, + {3, UPB_SIZE(24, 48), 0, 0, 11, 3}, {4, UPB_SIZE(28, 56), 0, 3, 11, 3}, + {5, UPB_SIZE(32, 64), 0, 1, 11, 3}, {6, UPB_SIZE(36, 72), 0, 4, 11, 3}, + {7, UPB_SIZE(16, 32), 2, 5, 11, 1}, {8, UPB_SIZE(40, 80), 0, 6, 11, 3}, + {9, UPB_SIZE(44, 88), 0, 2, 11, 3}, {10, UPB_SIZE(48, 96), 0, 0, 9, 3}, +}; + +const upb_msglayout google_protobuf_DescriptorProto_msginit = { + &google_protobuf_DescriptorProto_submsgs[0], + &google_protobuf_DescriptorProto__fields[0], + UPB_SIZE(56, 112), + 10, + false, +}; + +static const upb_msglayout* const + google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = { + &google_protobuf_ExtensionRangeOptions_msginit, +}; + +static const upb_msglayout_field + google_protobuf_DescriptorProto_ExtensionRange__fields[3] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, + {3, UPB_SIZE(12, 16), 3, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = { + &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0], + &google_protobuf_DescriptorProto_ExtensionRange__fields[0], + UPB_SIZE(16, 24), + 3, + false, +}; + +static const upb_msglayout_field + google_protobuf_DescriptorProto_ReservedRange__fields[2] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = { + NULL, + &google_protobuf_DescriptorProto_ReservedRange__fields[0], + UPB_SIZE(12, 12), + 2, + false, +}; + +static const upb_msglayout* const + google_protobuf_ExtensionRangeOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field + google_protobuf_ExtensionRangeOptions__fields[1] = { + {999, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = { + &google_protobuf_ExtensionRangeOptions_submsgs[0], + &google_protobuf_ExtensionRangeOptions__fields[0], + UPB_SIZE(4, 8), + 1, + false, +}; + +static const upb_msglayout* const + google_protobuf_FieldDescriptorProto_submsgs[1] = { + &google_protobuf_FieldOptions_msginit, +}; + +static const upb_msglayout_field + google_protobuf_FieldDescriptorProto__fields[10] = { + {1, UPB_SIZE(32, 32), 5, 0, 9, 1}, + {2, UPB_SIZE(40, 48), 6, 0, 9, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 5, 1}, + {4, UPB_SIZE(8, 8), 1, 0, 14, 1}, + {5, UPB_SIZE(16, 16), 2, 0, 14, 1}, + {6, UPB_SIZE(48, 64), 7, 0, 9, 1}, + {7, UPB_SIZE(56, 80), 8, 0, 9, 1}, + {8, UPB_SIZE(72, 112), 10, 0, 11, 1}, + {9, UPB_SIZE(28, 28), 4, 0, 5, 1}, + {10, UPB_SIZE(64, 96), 9, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = { + &google_protobuf_FieldDescriptorProto_submsgs[0], + &google_protobuf_FieldDescriptorProto__fields[0], + UPB_SIZE(80, 128), + 10, + false, +}; + +static const upb_msglayout* const + google_protobuf_OneofDescriptorProto_submsgs[1] = { + &google_protobuf_OneofOptions_msginit, +}; + +static const upb_msglayout_field + google_protobuf_OneofDescriptorProto__fields[2] = { + {1, UPB_SIZE(8, 16), 1, 0, 9, 1}, + {2, UPB_SIZE(16, 32), 2, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = { + &google_protobuf_OneofDescriptorProto_submsgs[0], + &google_protobuf_OneofDescriptorProto__fields[0], + UPB_SIZE(24, 48), + 2, + false, +}; + +static const upb_msglayout* const + google_protobuf_EnumDescriptorProto_submsgs[3] = { + &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, + &google_protobuf_EnumOptions_msginit, + &google_protobuf_EnumValueDescriptorProto_msginit, +}; + +static const upb_msglayout_field + google_protobuf_EnumDescriptorProto__fields[5] = { + {1, UPB_SIZE(8, 16), 1, 0, 9, 1}, {2, UPB_SIZE(20, 40), 0, 2, 11, 3}, + {3, UPB_SIZE(16, 32), 2, 1, 11, 1}, {4, UPB_SIZE(24, 48), 0, 0, 11, 3}, + {5, UPB_SIZE(28, 56), 0, 0, 9, 3}, +}; + +const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = { + &google_protobuf_EnumDescriptorProto_submsgs[0], + &google_protobuf_EnumDescriptorProto__fields[0], + UPB_SIZE(32, 64), + 5, + false, +}; + +static const upb_msglayout_field + google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, +}; + +const upb_msglayout + google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = { + NULL, + &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0], + UPB_SIZE(12, 12), + 2, + false, +}; + +static const upb_msglayout* const + google_protobuf_EnumValueDescriptorProto_submsgs[1] = { + &google_protobuf_EnumValueOptions_msginit, +}; + +static const upb_msglayout_field + google_protobuf_EnumValueDescriptorProto__fields[3] = { + {1, UPB_SIZE(8, 16), 2, 0, 9, 1}, + {2, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {3, UPB_SIZE(16, 32), 3, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = { + &google_protobuf_EnumValueDescriptorProto_submsgs[0], + &google_protobuf_EnumValueDescriptorProto__fields[0], + UPB_SIZE(24, 48), + 3, + false, +}; + +static const upb_msglayout* const + google_protobuf_ServiceDescriptorProto_submsgs[2] = { + &google_protobuf_MethodDescriptorProto_msginit, + &google_protobuf_ServiceOptions_msginit, +}; + +static const upb_msglayout_field + google_protobuf_ServiceDescriptorProto__fields[3] = { + {1, UPB_SIZE(8, 16), 1, 0, 9, 1}, + {2, UPB_SIZE(20, 40), 0, 0, 11, 3}, + {3, UPB_SIZE(16, 32), 2, 1, 11, 1}, +}; + +const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = { + &google_protobuf_ServiceDescriptorProto_submsgs[0], + &google_protobuf_ServiceDescriptorProto__fields[0], + UPB_SIZE(24, 48), + 3, + false, +}; + +static const upb_msglayout* const + google_protobuf_MethodDescriptorProto_submsgs[1] = { + &google_protobuf_MethodOptions_msginit, +}; + +static const upb_msglayout_field + google_protobuf_MethodDescriptorProto__fields[6] = { + {1, UPB_SIZE(8, 16), 3, 0, 9, 1}, {2, UPB_SIZE(16, 32), 4, 0, 9, 1}, + {3, UPB_SIZE(24, 48), 5, 0, 9, 1}, {4, UPB_SIZE(32, 64), 6, 0, 11, 1}, + {5, UPB_SIZE(1, 1), 1, 0, 8, 1}, {6, UPB_SIZE(2, 2), 2, 0, 8, 1}, +}; + +const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = { + &google_protobuf_MethodDescriptorProto_submsgs[0], + &google_protobuf_MethodDescriptorProto__fields[0], + UPB_SIZE(40, 80), + 6, + false, +}; + +static const upb_msglayout* const google_protobuf_FileOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = { + {1, UPB_SIZE(32, 32), 11, 0, 9, 1}, + {8, UPB_SIZE(40, 48), 12, 0, 9, 1}, + {9, UPB_SIZE(8, 8), 1, 0, 14, 1}, + {10, UPB_SIZE(16, 16), 2, 0, 8, 1}, + {11, UPB_SIZE(48, 64), 13, 0, 9, 1}, + {16, UPB_SIZE(17, 17), 3, 0, 8, 1}, + {17, UPB_SIZE(18, 18), 4, 0, 8, 1}, + {18, UPB_SIZE(19, 19), 5, 0, 8, 1}, + {20, UPB_SIZE(20, 20), 6, 0, 8, 1}, + {23, UPB_SIZE(21, 21), 7, 0, 8, 1}, + {27, UPB_SIZE(22, 22), 8, 0, 8, 1}, + {31, UPB_SIZE(23, 23), 9, 0, 8, 1}, + {36, UPB_SIZE(56, 80), 14, 0, 9, 1}, + {37, UPB_SIZE(64, 96), 15, 0, 9, 1}, + {39, UPB_SIZE(72, 112), 16, 0, 9, 1}, + {40, UPB_SIZE(80, 128), 17, 0, 9, 1}, + {41, UPB_SIZE(88, 144), 18, 0, 9, 1}, + {42, UPB_SIZE(24, 24), 10, 0, 8, 1}, + {44, UPB_SIZE(96, 160), 19, 0, 9, 1}, + {45, UPB_SIZE(104, 176), 20, 0, 9, 1}, + {999, UPB_SIZE(112, 192), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_FileOptions_msginit = { + &google_protobuf_FileOptions_submsgs[0], + &google_protobuf_FileOptions__fields[0], + UPB_SIZE(120, 208), + 21, + false, +}; + +static const upb_msglayout* const google_protobuf_MessageOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, {2, UPB_SIZE(2, 2), 2, 0, 8, 1}, + {3, UPB_SIZE(3, 3), 3, 0, 8, 1}, {7, UPB_SIZE(4, 4), 4, 0, 8, 1}, + {999, UPB_SIZE(8, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_MessageOptions_msginit = { + &google_protobuf_MessageOptions_submsgs[0], + &google_protobuf_MessageOptions__fields[0], + UPB_SIZE(12, 16), + 5, + false, +}; + +static const upb_msglayout* const google_protobuf_FieldOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 14, 1}, {2, UPB_SIZE(24, 24), 3, 0, 8, 1}, + {3, UPB_SIZE(25, 25), 4, 0, 8, 1}, {5, UPB_SIZE(26, 26), 5, 0, 8, 1}, + {6, UPB_SIZE(16, 16), 2, 0, 14, 1}, {10, UPB_SIZE(27, 27), 6, 0, 8, 1}, + {999, UPB_SIZE(28, 32), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_FieldOptions_msginit = { + &google_protobuf_FieldOptions_submsgs[0], + &google_protobuf_FieldOptions__fields[0], + UPB_SIZE(32, 40), + 7, + false, +}; + +static const upb_msglayout* const google_protobuf_OneofOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = { + {999, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_OneofOptions_msginit = { + &google_protobuf_OneofOptions_submsgs[0], + &google_protobuf_OneofOptions__fields[0], + UPB_SIZE(4, 8), + 1, + false, +}; + +static const upb_msglayout* const google_protobuf_EnumOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = { + {2, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {3, UPB_SIZE(2, 2), 2, 0, 8, 1}, + {999, UPB_SIZE(4, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_EnumOptions_msginit = { + &google_protobuf_EnumOptions_submsgs[0], + &google_protobuf_EnumOptions__fields[0], + UPB_SIZE(8, 16), + 3, + false, +}; + +static const upb_msglayout* const google_protobuf_EnumValueOptions_submsgs[1] = + { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {999, UPB_SIZE(4, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_EnumValueOptions_msginit = { + &google_protobuf_EnumValueOptions_submsgs[0], + &google_protobuf_EnumValueOptions__fields[0], + UPB_SIZE(8, 16), + 2, + false, +}; + +static const upb_msglayout* const google_protobuf_ServiceOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = { + {33, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {999, UPB_SIZE(4, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_ServiceOptions_msginit = { + &google_protobuf_ServiceOptions_submsgs[0], + &google_protobuf_ServiceOptions__fields[0], + UPB_SIZE(8, 16), + 2, + false, +}; + +static const upb_msglayout* const google_protobuf_MethodOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = { + {33, UPB_SIZE(16, 16), 2, 0, 8, 1}, + {34, UPB_SIZE(8, 8), 1, 0, 14, 1}, + {999, UPB_SIZE(20, 24), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_MethodOptions_msginit = { + &google_protobuf_MethodOptions_submsgs[0], + &google_protobuf_MethodOptions__fields[0], + UPB_SIZE(24, 32), + 3, + false, +}; + +static const upb_msglayout* const + google_protobuf_UninterpretedOption_submsgs[1] = { + &google_protobuf_UninterpretedOption_NamePart_msginit, +}; + +static const upb_msglayout_field + google_protobuf_UninterpretedOption__fields[7] = { + {2, UPB_SIZE(56, 80), 0, 0, 11, 3}, {3, UPB_SIZE(32, 32), 4, 0, 9, 1}, + {4, UPB_SIZE(8, 8), 1, 0, 4, 1}, {5, UPB_SIZE(16, 16), 2, 0, 3, 1}, + {6, UPB_SIZE(24, 24), 3, 0, 1, 1}, {7, UPB_SIZE(40, 48), 5, 0, 12, 1}, + {8, UPB_SIZE(48, 64), 6, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_UninterpretedOption_msginit = { + &google_protobuf_UninterpretedOption_submsgs[0], + &google_protobuf_UninterpretedOption__fields[0], + UPB_SIZE(64, 96), + 7, + false, +}; + +static const upb_msglayout_field + google_protobuf_UninterpretedOption_NamePart__fields[2] = { + {1, UPB_SIZE(8, 16), 2, 0, 9, 2}, + {2, UPB_SIZE(1, 1), 1, 0, 8, 2}, +}; + +const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = { + NULL, + &google_protobuf_UninterpretedOption_NamePart__fields[0], + UPB_SIZE(16, 32), + 2, + false, +}; + +static const upb_msglayout* const google_protobuf_SourceCodeInfo_submsgs[1] = { + &google_protobuf_SourceCodeInfo_Location_msginit, +}; + +static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_SourceCodeInfo_msginit = { + &google_protobuf_SourceCodeInfo_submsgs[0], + &google_protobuf_SourceCodeInfo__fields[0], + UPB_SIZE(4, 8), + 1, + false, +}; + +static const upb_msglayout_field + google_protobuf_SourceCodeInfo_Location__fields[5] = { + {1, UPB_SIZE(24, 48), 0, 0, 5, 3}, {2, UPB_SIZE(28, 56), 0, 0, 5, 3}, + {3, UPB_SIZE(8, 16), 1, 0, 9, 1}, {4, UPB_SIZE(16, 32), 2, 0, 9, 1}, + {6, UPB_SIZE(32, 64), 0, 0, 9, 3}, +}; + +const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = { + NULL, + &google_protobuf_SourceCodeInfo_Location__fields[0], + UPB_SIZE(40, 80), + 5, + false, +}; + +static const upb_msglayout* const google_protobuf_GeneratedCodeInfo_submsgs[1] = + { + &google_protobuf_GeneratedCodeInfo_Annotation_msginit, +}; + +static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = + { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = { + &google_protobuf_GeneratedCodeInfo_submsgs[0], + &google_protobuf_GeneratedCodeInfo__fields[0], + UPB_SIZE(4, 8), + 1, + false, +}; + +static const upb_msglayout_field + google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = { + {1, UPB_SIZE(24, 32), 0, 0, 5, 3}, + {2, UPB_SIZE(16, 16), 3, 0, 9, 1}, + {3, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {4, UPB_SIZE(8, 8), 2, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = { + NULL, + &google_protobuf_GeneratedCodeInfo_Annotation__fields[0], + UPB_SIZE(32, 48), + 4, + false, +}; + +#include "upb/port_undef.inc" diff --git a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h new file mode 100644 index 00000000000..37f0139ce32 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h @@ -0,0 +1,1879 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +UPB_BEGIN_EXTERN_C + +struct google_protobuf_FileDescriptorSet; +struct google_protobuf_FileDescriptorProto; +struct google_protobuf_DescriptorProto; +struct google_protobuf_DescriptorProto_ExtensionRange; +struct google_protobuf_DescriptorProto_ReservedRange; +struct google_protobuf_ExtensionRangeOptions; +struct google_protobuf_FieldDescriptorProto; +struct google_protobuf_OneofDescriptorProto; +struct google_protobuf_EnumDescriptorProto; +struct google_protobuf_EnumDescriptorProto_EnumReservedRange; +struct google_protobuf_EnumValueDescriptorProto; +struct google_protobuf_ServiceDescriptorProto; +struct google_protobuf_MethodDescriptorProto; +struct google_protobuf_FileOptions; +struct google_protobuf_MessageOptions; +struct google_protobuf_FieldOptions; +struct google_protobuf_OneofOptions; +struct google_protobuf_EnumOptions; +struct google_protobuf_EnumValueOptions; +struct google_protobuf_ServiceOptions; +struct google_protobuf_MethodOptions; +struct google_protobuf_UninterpretedOption; +struct google_protobuf_UninterpretedOption_NamePart; +struct google_protobuf_SourceCodeInfo; +struct google_protobuf_SourceCodeInfo_Location; +struct google_protobuf_GeneratedCodeInfo; +struct google_protobuf_GeneratedCodeInfo_Annotation; +typedef struct google_protobuf_FileDescriptorSet + google_protobuf_FileDescriptorSet; +typedef struct google_protobuf_FileDescriptorProto + google_protobuf_FileDescriptorProto; +typedef struct google_protobuf_DescriptorProto google_protobuf_DescriptorProto; +typedef struct google_protobuf_DescriptorProto_ExtensionRange + google_protobuf_DescriptorProto_ExtensionRange; +typedef struct google_protobuf_DescriptorProto_ReservedRange + google_protobuf_DescriptorProto_ReservedRange; +typedef struct google_protobuf_ExtensionRangeOptions + google_protobuf_ExtensionRangeOptions; +typedef struct google_protobuf_FieldDescriptorProto + google_protobuf_FieldDescriptorProto; +typedef struct google_protobuf_OneofDescriptorProto + google_protobuf_OneofDescriptorProto; +typedef struct google_protobuf_EnumDescriptorProto + google_protobuf_EnumDescriptorProto; +typedef struct google_protobuf_EnumDescriptorProto_EnumReservedRange + google_protobuf_EnumDescriptorProto_EnumReservedRange; +typedef struct google_protobuf_EnumValueDescriptorProto + google_protobuf_EnumValueDescriptorProto; +typedef struct google_protobuf_ServiceDescriptorProto + google_protobuf_ServiceDescriptorProto; +typedef struct google_protobuf_MethodDescriptorProto + google_protobuf_MethodDescriptorProto; +typedef struct google_protobuf_FileOptions google_protobuf_FileOptions; +typedef struct google_protobuf_MessageOptions google_protobuf_MessageOptions; +typedef struct google_protobuf_FieldOptions google_protobuf_FieldOptions; +typedef struct google_protobuf_OneofOptions google_protobuf_OneofOptions; +typedef struct google_protobuf_EnumOptions google_protobuf_EnumOptions; +typedef struct google_protobuf_EnumValueOptions + google_protobuf_EnumValueOptions; +typedef struct google_protobuf_ServiceOptions google_protobuf_ServiceOptions; +typedef struct google_protobuf_MethodOptions google_protobuf_MethodOptions; +typedef struct google_protobuf_UninterpretedOption + google_protobuf_UninterpretedOption; +typedef struct google_protobuf_UninterpretedOption_NamePart + google_protobuf_UninterpretedOption_NamePart; +typedef struct google_protobuf_SourceCodeInfo google_protobuf_SourceCodeInfo; +typedef struct google_protobuf_SourceCodeInfo_Location + google_protobuf_SourceCodeInfo_Location; +typedef struct google_protobuf_GeneratedCodeInfo + google_protobuf_GeneratedCodeInfo; +typedef struct google_protobuf_GeneratedCodeInfo_Annotation + google_protobuf_GeneratedCodeInfo_Annotation; + +/* Enums */ + +typedef enum { + google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, + google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2, + google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3 +} google_protobuf_FieldDescriptorProto_Label; + +typedef enum { + google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1, + google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2, + google_protobuf_FieldDescriptorProto_TYPE_INT64 = 3, + google_protobuf_FieldDescriptorProto_TYPE_UINT64 = 4, + google_protobuf_FieldDescriptorProto_TYPE_INT32 = 5, + google_protobuf_FieldDescriptorProto_TYPE_FIXED64 = 6, + google_protobuf_FieldDescriptorProto_TYPE_FIXED32 = 7, + google_protobuf_FieldDescriptorProto_TYPE_BOOL = 8, + google_protobuf_FieldDescriptorProto_TYPE_STRING = 9, + google_protobuf_FieldDescriptorProto_TYPE_GROUP = 10, + google_protobuf_FieldDescriptorProto_TYPE_MESSAGE = 11, + google_protobuf_FieldDescriptorProto_TYPE_BYTES = 12, + google_protobuf_FieldDescriptorProto_TYPE_UINT32 = 13, + google_protobuf_FieldDescriptorProto_TYPE_ENUM = 14, + google_protobuf_FieldDescriptorProto_TYPE_SFIXED32 = 15, + google_protobuf_FieldDescriptorProto_TYPE_SFIXED64 = 16, + google_protobuf_FieldDescriptorProto_TYPE_SINT32 = 17, + google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18 +} google_protobuf_FieldDescriptorProto_Type; + +typedef enum { + google_protobuf_FieldOptions_STRING = 0, + google_protobuf_FieldOptions_CORD = 1, + google_protobuf_FieldOptions_STRING_PIECE = 2 +} google_protobuf_FieldOptions_CType; + +typedef enum { + google_protobuf_FieldOptions_JS_NORMAL = 0, + google_protobuf_FieldOptions_JS_STRING = 1, + google_protobuf_FieldOptions_JS_NUMBER = 2 +} google_protobuf_FieldOptions_JSType; + +typedef enum { + google_protobuf_FileOptions_SPEED = 1, + google_protobuf_FileOptions_CODE_SIZE = 2, + google_protobuf_FileOptions_LITE_RUNTIME = 3 +} google_protobuf_FileOptions_OptimizeMode; + +typedef enum { + google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0, + google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1, + google_protobuf_MethodOptions_IDEMPOTENT = 2 +} google_protobuf_MethodOptions_IdempotencyLevel; + +/* google.protobuf.FileDescriptorSet */ + +extern const upb_msglayout google_protobuf_FileDescriptorSet_msginit; +UPB_INLINE google_protobuf_FileDescriptorSet* +google_protobuf_FileDescriptorSet_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_FileDescriptorSet_msginit, arena); +} +UPB_INLINE google_protobuf_FileDescriptorSet* +google_protobuf_FileDescriptorSet_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_FileDescriptorSet* ret = + google_protobuf_FileDescriptorSet_new(arena); + return (ret && + upb_decode(buf, ret, &google_protobuf_FileDescriptorSet_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_FileDescriptorSet_serialize( + const google_protobuf_FileDescriptorSet* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, arena, + len); +} + +UPB_INLINE const upb_array* google_protobuf_FileDescriptorSet_file( + const google_protobuf_FileDescriptorSet* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_FileDescriptorSet_set_file( + google_protobuf_FileDescriptorSet* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.FileDescriptorProto */ + +extern const upb_msglayout google_protobuf_FileDescriptorProto_msginit; +UPB_INLINE google_protobuf_FileDescriptorProto* +google_protobuf_FileDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_FileDescriptorProto* +google_protobuf_FileDescriptorProto_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_FileDescriptorProto* ret = + google_protobuf_FileDescriptorProto_new(arena); + return (ret && + upb_decode(buf, ret, &google_protobuf_FileDescriptorProto_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_FileDescriptorProto_serialize( + const google_protobuf_FileDescriptorProto* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_FileDescriptorProto_msginit, arena, + len); +} + +UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_name( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_package( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); +} +UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_dependency( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(40, 80)); +} +UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_message_type( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(44, 88)); +} +UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_enum_type( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(48, 96)); +} +UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_service( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(52, 104)); +} +UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_extension( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(56, 112)); +} +UPB_INLINE const google_protobuf_FileOptions* +google_protobuf_FileDescriptorProto_options( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const google_protobuf_FileOptions*, + UPB_SIZE(32, 64)); +} +UPB_INLINE const google_protobuf_SourceCodeInfo* +google_protobuf_FileDescriptorProto_source_code_info( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const google_protobuf_SourceCodeInfo*, + UPB_SIZE(36, 72)); +} +UPB_INLINE const upb_array* +google_protobuf_FileDescriptorProto_public_dependency( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(60, 120)); +} +UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_weak_dependency( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(64, 128)); +} +UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_syntax( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)); +} + +UPB_INLINE void google_protobuf_FileDescriptorProto_set_name( + google_protobuf_FileDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_package( + google_protobuf_FileDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_dependency( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(40, 80)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_message_type( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(44, 88)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_enum_type( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(48, 96)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_service( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(52, 104)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_extension( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(56, 112)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_options( + google_protobuf_FileDescriptorProto* msg, + google_protobuf_FileOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_FileOptions*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info( + google_protobuf_FileDescriptorProto* msg, + google_protobuf_SourceCodeInfo* value) { + UPB_FIELD_AT(msg, google_protobuf_SourceCodeInfo*, UPB_SIZE(36, 72)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_public_dependency( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(60, 120)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_weak_dependency( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(64, 128)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax( + google_protobuf_FileDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)) = value; +} + +/* google.protobuf.DescriptorProto */ + +extern const upb_msglayout google_protobuf_DescriptorProto_msginit; +UPB_INLINE google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_DescriptorProto* +google_protobuf_DescriptorProto_parsenew(upb_stringview buf, upb_arena* arena) { + google_protobuf_DescriptorProto* ret = + google_protobuf_DescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_DescriptorProto_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_DescriptorProto_serialize( + const google_protobuf_DescriptorProto* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_DescriptorProto_msginit, arena, len); +} + +UPB_INLINE upb_stringview google_protobuf_DescriptorProto_name( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_field( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_nested_type( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_enum_type( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_extension_range( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(32, 64)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_extension( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(36, 72)); +} +UPB_INLINE const google_protobuf_MessageOptions* +google_protobuf_DescriptorProto_options( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const google_protobuf_MessageOptions*, + UPB_SIZE(16, 32)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_oneof_decl( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(40, 80)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_reserved_range( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(44, 88)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_reserved_name( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(48, 96)); +} + +UPB_INLINE void google_protobuf_DescriptorProto_set_name( + google_protobuf_DescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_field( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_nested_type( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_enum_type( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_extension_range( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_extension( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(36, 72)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_options( + google_protobuf_DescriptorProto* msg, + google_protobuf_MessageOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_MessageOptions*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_oneof_decl( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(40, 80)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_reserved_range( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(44, 88)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_reserved_name( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(48, 96)) = value; +} + +/* google.protobuf.DescriptorProto.ExtensionRange */ + +extern const upb_msglayout + google_protobuf_DescriptorProto_ExtensionRange_msginit; +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* +google_protobuf_DescriptorProto_ExtensionRange_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, + arena); +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* +google_protobuf_DescriptorProto_ExtensionRange_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_DescriptorProto_ExtensionRange* ret = + google_protobuf_DescriptorProto_ExtensionRange_new(arena); + return (ret && + upb_decode(buf, ret, + &google_protobuf_DescriptorProto_ExtensionRange_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_DescriptorProto_ExtensionRange_serialize( + const google_protobuf_DescriptorProto_ExtensionRange* msg, upb_arena* arena, + size_t* len) { + return upb_encode( + msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, len); +} + +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start( + const google_protobuf_DescriptorProto_ExtensionRange* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end( + const google_protobuf_DescriptorProto_ExtensionRange* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); +} +UPB_INLINE const google_protobuf_ExtensionRangeOptions* +google_protobuf_DescriptorProto_ExtensionRange_options( + const google_protobuf_DescriptorProto_ExtensionRange* msg) { + return UPB_FIELD_AT(msg, const google_protobuf_ExtensionRangeOptions*, + UPB_SIZE(12, 16)); +} + +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_start( + google_protobuf_DescriptorProto_ExtensionRange* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_end( + google_protobuf_DescriptorProto_ExtensionRange* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_options( + google_protobuf_DescriptorProto_ExtensionRange* msg, + google_protobuf_ExtensionRangeOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)) = + value; +} + +/* google.protobuf.DescriptorProto.ReservedRange */ + +extern const upb_msglayout + google_protobuf_DescriptorProto_ReservedRange_msginit; +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* +google_protobuf_DescriptorProto_ReservedRange_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, + arena); +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* +google_protobuf_DescriptorProto_ReservedRange_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_DescriptorProto_ReservedRange* ret = + google_protobuf_DescriptorProto_ReservedRange_new(arena); + return (ret && + upb_decode(buf, ret, + &google_protobuf_DescriptorProto_ReservedRange_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_DescriptorProto_ReservedRange_serialize( + const google_protobuf_DescriptorProto_ReservedRange* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, + arena, len); +} + +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start( + const google_protobuf_DescriptorProto_ReservedRange* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end( + const google_protobuf_DescriptorProto_ReservedRange* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); +} + +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_start( + google_protobuf_DescriptorProto_ReservedRange* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_end( + google_protobuf_DescriptorProto_ReservedRange* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + +/* google.protobuf.ExtensionRangeOptions */ + +extern const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit; +UPB_INLINE google_protobuf_ExtensionRangeOptions* +google_protobuf_ExtensionRangeOptions_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena); +} +UPB_INLINE google_protobuf_ExtensionRangeOptions* +google_protobuf_ExtensionRangeOptions_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_ExtensionRangeOptions* ret = + google_protobuf_ExtensionRangeOptions_new(arena); + return (ret && + upb_decode(buf, ret, &google_protobuf_ExtensionRangeOptions_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_ExtensionRangeOptions_serialize( + const google_protobuf_ExtensionRangeOptions* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, arena, + len); +} + +UPB_INLINE const upb_array* +google_protobuf_ExtensionRangeOptions_uninterpreted_option( + const google_protobuf_ExtensionRangeOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_ExtensionRangeOptions_set_uninterpreted_option( + google_protobuf_ExtensionRangeOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.FieldDescriptorProto */ + +extern const upb_msglayout google_protobuf_FieldDescriptorProto_msginit; +UPB_INLINE google_protobuf_FieldDescriptorProto* +google_protobuf_FieldDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_FieldDescriptorProto* +google_protobuf_FieldDescriptorProto_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_FieldDescriptorProto* ret = + google_protobuf_FieldDescriptorProto_new(arena); + return (ret && + upb_decode(buf, ret, &google_protobuf_FieldDescriptorProto_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_FieldDescriptorProto_serialize( + const google_protobuf_FieldDescriptorProto* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, + len); +} + +UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_name( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); +} +UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_extendee( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); +} +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)); +} +UPB_INLINE google_protobuf_FieldDescriptorProto_Label +google_protobuf_FieldDescriptorProto_label( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Label, + UPB_SIZE(8, 8)); +} +UPB_INLINE google_protobuf_FieldDescriptorProto_Type +google_protobuf_FieldDescriptorProto_type( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Type, + UPB_SIZE(16, 16)); +} +UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_type_name( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); +} +UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_default_value( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)); +} +UPB_INLINE const google_protobuf_FieldOptions* +google_protobuf_FieldDescriptorProto_options( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const google_protobuf_FieldOptions*, + UPB_SIZE(72, 112)); +} +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)); +} +UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_json_name( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)); +} + +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name( + google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee( + google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number( + google_protobuf_FieldDescriptorProto* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label( + google_protobuf_FieldDescriptorProto* msg, + google_protobuf_FieldDescriptorProto_Label value) { + UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Label, + UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type( + google_protobuf_FieldDescriptorProto* msg, + google_protobuf_FieldDescriptorProto_Type value) { + UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Type, + UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name( + google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value( + google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options( + google_protobuf_FieldDescriptorProto* msg, + google_protobuf_FieldOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_FieldOptions*, UPB_SIZE(72, 112)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index( + google_protobuf_FieldDescriptorProto* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name( + google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)) = value; +} + +/* google.protobuf.OneofDescriptorProto */ + +extern const upb_msglayout google_protobuf_OneofDescriptorProto_msginit; +UPB_INLINE google_protobuf_OneofDescriptorProto* +google_protobuf_OneofDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_OneofDescriptorProto* +google_protobuf_OneofDescriptorProto_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_OneofDescriptorProto* ret = + google_protobuf_OneofDescriptorProto_new(arena); + return (ret && + upb_decode(buf, ret, &google_protobuf_OneofDescriptorProto_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_OneofDescriptorProto_serialize( + const google_protobuf_OneofDescriptorProto* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_OneofDescriptorProto_msginit, arena, + len); +} + +UPB_INLINE upb_stringview google_protobuf_OneofDescriptorProto_name( + const google_protobuf_OneofDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE const google_protobuf_OneofOptions* +google_protobuf_OneofDescriptorProto_options( + const google_protobuf_OneofDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const google_protobuf_OneofOptions*, + UPB_SIZE(16, 32)); +} + +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name( + google_protobuf_OneofDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options( + google_protobuf_OneofDescriptorProto* msg, + google_protobuf_OneofOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_OneofOptions*, UPB_SIZE(16, 32)) = value; +} + +/* google.protobuf.EnumDescriptorProto */ + +extern const upb_msglayout google_protobuf_EnumDescriptorProto_msginit; +UPB_INLINE google_protobuf_EnumDescriptorProto* +google_protobuf_EnumDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_EnumDescriptorProto* +google_protobuf_EnumDescriptorProto_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_EnumDescriptorProto* ret = + google_protobuf_EnumDescriptorProto_new(arena); + return (ret && + upb_decode(buf, ret, &google_protobuf_EnumDescriptorProto_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_EnumDescriptorProto_serialize( + const google_protobuf_EnumDescriptorProto* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_EnumDescriptorProto_msginit, arena, + len); +} + +UPB_INLINE upb_stringview google_protobuf_EnumDescriptorProto_name( + const google_protobuf_EnumDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_value( + const google_protobuf_EnumDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); +} +UPB_INLINE const google_protobuf_EnumOptions* +google_protobuf_EnumDescriptorProto_options( + const google_protobuf_EnumDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const google_protobuf_EnumOptions*, + UPB_SIZE(16, 32)); +} +UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_reserved_range( + const google_protobuf_EnumDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); +} +UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_reserved_name( + const google_protobuf_EnumDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); +} + +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_name( + google_protobuf_EnumDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_value( + google_protobuf_EnumDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options( + google_protobuf_EnumDescriptorProto* msg, + google_protobuf_EnumOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_EnumOptions*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_reserved_range( + google_protobuf_EnumDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_reserved_name( + google_protobuf_EnumDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; +} + +/* google.protobuf.EnumDescriptorProto.EnumReservedRange */ + +extern const upb_msglayout + google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit; +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* +google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_arena* arena) { + return upb_msg_new( + &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena); +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* +google_protobuf_EnumDescriptorProto_EnumReservedRange_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_EnumDescriptorProto_EnumReservedRange* ret = + google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); + return (ret && + upb_decode( + buf, ret, + &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* +google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize( + const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, + upb_arena* arena, size_t* len) { + return upb_encode( + msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, + arena, len); +} + +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start( + const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); +} +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end( + const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); +} + +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start( + google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end( + google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + +/* google.protobuf.EnumValueDescriptorProto */ + +extern const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit; +UPB_INLINE google_protobuf_EnumValueDescriptorProto* +google_protobuf_EnumValueDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto* +google_protobuf_EnumValueDescriptorProto_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_EnumValueDescriptorProto* ret = + google_protobuf_EnumValueDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, + &google_protobuf_EnumValueDescriptorProto_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_EnumValueDescriptorProto_serialize( + const google_protobuf_EnumValueDescriptorProto* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, + arena, len); +} + +UPB_INLINE upb_stringview google_protobuf_EnumValueDescriptorProto_name( + const google_protobuf_EnumValueDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number( + const google_protobuf_EnumValueDescriptorProto* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); +} +UPB_INLINE const google_protobuf_EnumValueOptions* +google_protobuf_EnumValueDescriptorProto_options( + const google_protobuf_EnumValueDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const google_protobuf_EnumValueOptions*, + UPB_SIZE(16, 32)); +} + +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name( + google_protobuf_EnumValueDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number( + google_protobuf_EnumValueDescriptorProto* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options( + google_protobuf_EnumValueDescriptorProto* msg, + google_protobuf_EnumValueOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_EnumValueOptions*, UPB_SIZE(16, 32)) = + value; +} + +/* google.protobuf.ServiceDescriptorProto */ + +extern const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit; +UPB_INLINE google_protobuf_ServiceDescriptorProto* +google_protobuf_ServiceDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_ServiceDescriptorProto* +google_protobuf_ServiceDescriptorProto_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_ServiceDescriptorProto* ret = + google_protobuf_ServiceDescriptorProto_new(arena); + return (ret && + upb_decode(buf, ret, &google_protobuf_ServiceDescriptorProto_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_ServiceDescriptorProto_serialize( + const google_protobuf_ServiceDescriptorProto* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, arena, + len); +} + +UPB_INLINE upb_stringview google_protobuf_ServiceDescriptorProto_name( + const google_protobuf_ServiceDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE const upb_array* google_protobuf_ServiceDescriptorProto_method( + const google_protobuf_ServiceDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); +} +UPB_INLINE const google_protobuf_ServiceOptions* +google_protobuf_ServiceDescriptorProto_options( + const google_protobuf_ServiceDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const google_protobuf_ServiceOptions*, + UPB_SIZE(16, 32)); +} + +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name( + google_protobuf_ServiceDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_method( + google_protobuf_ServiceDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options( + google_protobuf_ServiceDescriptorProto* msg, + google_protobuf_ServiceOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_ServiceOptions*, UPB_SIZE(16, 32)) = value; +} + +/* google.protobuf.MethodDescriptorProto */ + +extern const upb_msglayout google_protobuf_MethodDescriptorProto_msginit; +UPB_INLINE google_protobuf_MethodDescriptorProto* +google_protobuf_MethodDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_MethodDescriptorProto* +google_protobuf_MethodDescriptorProto_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_MethodDescriptorProto* ret = + google_protobuf_MethodDescriptorProto_new(arena); + return (ret && + upb_decode(buf, ret, &google_protobuf_MethodDescriptorProto_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_MethodDescriptorProto_serialize( + const google_protobuf_MethodDescriptorProto* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_MethodDescriptorProto_msginit, arena, + len); +} + +UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_name( + const google_protobuf_MethodDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_input_type( + const google_protobuf_MethodDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); +} +UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_output_type( + const google_protobuf_MethodDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)); +} +UPB_INLINE const google_protobuf_MethodOptions* +google_protobuf_MethodDescriptorProto_options( + const google_protobuf_MethodDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const google_protobuf_MethodOptions*, + UPB_SIZE(32, 64)); +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming( + const google_protobuf_MethodDescriptorProto* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming( + const google_protobuf_MethodDescriptorProto* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); +} + +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name( + google_protobuf_MethodDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type( + google_protobuf_MethodDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type( + google_protobuf_MethodDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options( + google_protobuf_MethodDescriptorProto* msg, + google_protobuf_MethodOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_MethodOptions*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming( + google_protobuf_MethodDescriptorProto* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming( + google_protobuf_MethodDescriptorProto* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} + +/* google.protobuf.FileOptions */ + +extern const upb_msglayout google_protobuf_FileOptions_msginit; +UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_FileOptions_msginit, arena); +} +UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_FileOptions* ret = google_protobuf_FileOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FileOptions_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_FileOptions_serialize( + const google_protobuf_FileOptions* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_FileOptions_msginit, arena, len); +} + +UPB_INLINE upb_stringview google_protobuf_FileOptions_java_package( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_java_outer_classname( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); +} +UPB_INLINE google_protobuf_FileOptions_OptimizeMode +google_protobuf_FileOptions_optimize_for( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, google_protobuf_FileOptions_OptimizeMode, + UPB_SIZE(8, 8)); +} +UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); +} +UPB_INLINE upb_stringview +google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); +} +UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)); +} +UPB_INLINE bool google_protobuf_FileOptions_java_generic_services( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)); +} +UPB_INLINE bool google_protobuf_FileOptions_py_generic_services( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)); +} +UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)); +} +UPB_INLINE bool google_protobuf_FileOptions_deprecated( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)); +} +UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)); +} +UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_objc_class_prefix( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_csharp_namespace( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_swift_prefix( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(72, 112)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_php_class_prefix( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(80, 128)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_php_namespace( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(88, 144)); +} +UPB_INLINE bool google_protobuf_FileOptions_php_generic_services( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_php_metadata_namespace( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(96, 160)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_ruby_package( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(104, 176)); +} +UPB_INLINE const upb_array* google_protobuf_FileOptions_uninterpreted_option( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(112, 192)); +} + +UPB_INLINE void google_protobuf_FileOptions_set_java_package( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_optimize_for( + google_protobuf_FileOptions* msg, + google_protobuf_FileOptions_OptimizeMode value) { + UPB_FIELD_AT(msg, google_protobuf_FileOptions_OptimizeMode, UPB_SIZE(8, 8)) = + value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files( + google_protobuf_FileOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_go_package( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services( + google_protobuf_FileOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services( + google_protobuf_FileOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services( + google_protobuf_FileOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash( + google_protobuf_FileOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_deprecated( + google_protobuf_FileOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8( + google_protobuf_FileOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas( + google_protobuf_FileOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(72, 112)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(80, 128)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_namespace( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(88, 144)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services( + google_protobuf_FileOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(96, 160)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_ruby_package( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(104, 176)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_uninterpreted_option( + google_protobuf_FileOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(112, 192)) = value; +} + +/* google.protobuf.MessageOptions */ + +extern const upb_msglayout google_protobuf_MessageOptions_msginit; +UPB_INLINE google_protobuf_MessageOptions* google_protobuf_MessageOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); +} +UPB_INLINE google_protobuf_MessageOptions* +google_protobuf_MessageOptions_parsenew(upb_stringview buf, upb_arena* arena) { + google_protobuf_MessageOptions* ret = + google_protobuf_MessageOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_MessageOptions_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_MessageOptions_serialize( + const google_protobuf_MessageOptions* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_MessageOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format( + const google_protobuf_MessageOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); +} +UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor( + const google_protobuf_MessageOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); +} +UPB_INLINE bool google_protobuf_MessageOptions_deprecated( + const google_protobuf_MessageOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)); +} +UPB_INLINE bool google_protobuf_MessageOptions_map_entry( + const google_protobuf_MessageOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)); +} +UPB_INLINE const upb_array* google_protobuf_MessageOptions_uninterpreted_option( + const google_protobuf_MessageOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(8, 8)); +} + +UPB_INLINE void google_protobuf_MessageOptions_set_message_set_wire_format( + google_protobuf_MessageOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void +google_protobuf_MessageOptions_set_no_standard_descriptor_accessor( + google_protobuf_MessageOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_deprecated( + google_protobuf_MessageOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_map_entry( + google_protobuf_MessageOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_uninterpreted_option( + google_protobuf_MessageOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(8, 8)) = value; +} + +/* google.protobuf.FieldOptions */ + +extern const upb_msglayout google_protobuf_FieldOptions_msginit; +UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); +} +UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_FieldOptions* ret = google_protobuf_FieldOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FieldOptions_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_FieldOptions_serialize( + const google_protobuf_FieldOptions* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_FieldOptions_msginit, arena, len); +} + +UPB_INLINE google_protobuf_FieldOptions_CType +google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions* msg) { + return UPB_FIELD_AT(msg, google_protobuf_FieldOptions_CType, UPB_SIZE(8, 8)); +} +UPB_INLINE bool google_protobuf_FieldOptions_packed( + const google_protobuf_FieldOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); +} +UPB_INLINE bool google_protobuf_FieldOptions_deprecated( + const google_protobuf_FieldOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)); +} +UPB_INLINE bool google_protobuf_FieldOptions_lazy( + const google_protobuf_FieldOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)); +} +UPB_INLINE google_protobuf_FieldOptions_JSType +google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions* msg) { + return UPB_FIELD_AT(msg, google_protobuf_FieldOptions_JSType, + UPB_SIZE(16, 16)); +} +UPB_INLINE bool google_protobuf_FieldOptions_weak( + const google_protobuf_FieldOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)); +} +UPB_INLINE const upb_array* google_protobuf_FieldOptions_uninterpreted_option( + const google_protobuf_FieldOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 32)); +} + +UPB_INLINE void google_protobuf_FieldOptions_set_ctype( + google_protobuf_FieldOptions* msg, + google_protobuf_FieldOptions_CType value) { + UPB_FIELD_AT(msg, google_protobuf_FieldOptions_CType, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_packed( + google_protobuf_FieldOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_deprecated( + google_protobuf_FieldOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_lazy( + google_protobuf_FieldOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_jstype( + google_protobuf_FieldOptions* msg, + google_protobuf_FieldOptions_JSType value) { + UPB_FIELD_AT(msg, google_protobuf_FieldOptions_JSType, UPB_SIZE(16, 16)) = + value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_weak( + google_protobuf_FieldOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_uninterpreted_option( + google_protobuf_FieldOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 32)) = value; +} + +/* google.protobuf.OneofOptions */ + +extern const upb_msglayout google_protobuf_OneofOptions_msginit; +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); +} +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_OneofOptions* ret = google_protobuf_OneofOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_OneofOptions_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_OneofOptions_serialize( + const google_protobuf_OneofOptions* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_OneofOptions_msginit, arena, len); +} + +UPB_INLINE const upb_array* google_protobuf_OneofOptions_uninterpreted_option( + const google_protobuf_OneofOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_OneofOptions_set_uninterpreted_option( + google_protobuf_OneofOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.EnumOptions */ + +extern const upb_msglayout google_protobuf_EnumOptions_msginit; +UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); +} +UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_EnumOptions* ret = google_protobuf_EnumOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_EnumOptions_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_EnumOptions_serialize( + const google_protobuf_EnumOptions* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_EnumOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_EnumOptions_allow_alias( + const google_protobuf_EnumOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); +} +UPB_INLINE bool google_protobuf_EnumOptions_deprecated( + const google_protobuf_EnumOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); +} +UPB_INLINE const upb_array* google_protobuf_EnumOptions_uninterpreted_option( + const google_protobuf_EnumOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); +} + +UPB_INLINE void google_protobuf_EnumOptions_set_allow_alias( + google_protobuf_EnumOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void google_protobuf_EnumOptions_set_deprecated( + google_protobuf_EnumOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} +UPB_INLINE void google_protobuf_EnumOptions_set_uninterpreted_option( + google_protobuf_EnumOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; +} + +/* google.protobuf.EnumValueOptions */ + +extern const upb_msglayout google_protobuf_EnumValueOptions_msginit; +UPB_INLINE google_protobuf_EnumValueOptions* +google_protobuf_EnumValueOptions_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); +} +UPB_INLINE google_protobuf_EnumValueOptions* +google_protobuf_EnumValueOptions_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_EnumValueOptions* ret = + google_protobuf_EnumValueOptions_new(arena); + return (ret && + upb_decode(buf, ret, &google_protobuf_EnumValueOptions_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_EnumValueOptions_serialize( + const google_protobuf_EnumValueOptions* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_EnumValueOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated( + const google_protobuf_EnumValueOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); +} +UPB_INLINE const upb_array* +google_protobuf_EnumValueOptions_uninterpreted_option( + const google_protobuf_EnumValueOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); +} + +UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated( + google_protobuf_EnumValueOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void google_protobuf_EnumValueOptions_set_uninterpreted_option( + google_protobuf_EnumValueOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; +} + +/* google.protobuf.ServiceOptions */ + +extern const upb_msglayout google_protobuf_ServiceOptions_msginit; +UPB_INLINE google_protobuf_ServiceOptions* google_protobuf_ServiceOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); +} +UPB_INLINE google_protobuf_ServiceOptions* +google_protobuf_ServiceOptions_parsenew(upb_stringview buf, upb_arena* arena) { + google_protobuf_ServiceOptions* ret = + google_protobuf_ServiceOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_ServiceOptions_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_ServiceOptions_serialize( + const google_protobuf_ServiceOptions* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_ServiceOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_ServiceOptions_deprecated( + const google_protobuf_ServiceOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); +} +UPB_INLINE const upb_array* google_protobuf_ServiceOptions_uninterpreted_option( + const google_protobuf_ServiceOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); +} + +UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated( + google_protobuf_ServiceOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void google_protobuf_ServiceOptions_set_uninterpreted_option( + google_protobuf_ServiceOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; +} + +/* google.protobuf.MethodOptions */ + +extern const upb_msglayout google_protobuf_MethodOptions_msginit; +UPB_INLINE google_protobuf_MethodOptions* google_protobuf_MethodOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); +} +UPB_INLINE google_protobuf_MethodOptions* +google_protobuf_MethodOptions_parsenew(upb_stringview buf, upb_arena* arena) { + google_protobuf_MethodOptions* ret = google_protobuf_MethodOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_MethodOptions_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_MethodOptions_serialize( + const google_protobuf_MethodOptions* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_MethodOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_MethodOptions_deprecated( + const google_protobuf_MethodOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); +} +UPB_INLINE google_protobuf_MethodOptions_IdempotencyLevel +google_protobuf_MethodOptions_idempotency_level( + const google_protobuf_MethodOptions* msg) { + return UPB_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, + UPB_SIZE(8, 8)); +} +UPB_INLINE const upb_array* google_protobuf_MethodOptions_uninterpreted_option( + const google_protobuf_MethodOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 24)); +} + +UPB_INLINE void google_protobuf_MethodOptions_set_deprecated( + google_protobuf_MethodOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level( + google_protobuf_MethodOptions* msg, + google_protobuf_MethodOptions_IdempotencyLevel value) { + UPB_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, + UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_MethodOptions_set_uninterpreted_option( + google_protobuf_MethodOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 24)) = value; +} + +/* google.protobuf.UninterpretedOption */ + +extern const upb_msglayout google_protobuf_UninterpretedOption_msginit; +UPB_INLINE google_protobuf_UninterpretedOption* +google_protobuf_UninterpretedOption_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); +} +UPB_INLINE google_protobuf_UninterpretedOption* +google_protobuf_UninterpretedOption_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_UninterpretedOption* ret = + google_protobuf_UninterpretedOption_new(arena); + return (ret && + upb_decode(buf, ret, &google_protobuf_UninterpretedOption_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_UninterpretedOption_serialize( + const google_protobuf_UninterpretedOption* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_UninterpretedOption_msginit, arena, + len); +} + +UPB_INLINE const upb_array* google_protobuf_UninterpretedOption_name( + const google_protobuf_UninterpretedOption* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(56, 80)); +} +UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_identifier_value( + const google_protobuf_UninterpretedOption* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); +} +UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value( + const google_protobuf_UninterpretedOption* msg) { + return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); +} +UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value( + const google_protobuf_UninterpretedOption* msg) { + return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); +} +UPB_INLINE double google_protobuf_UninterpretedOption_double_value( + const google_protobuf_UninterpretedOption* msg) { + return UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)); +} +UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_string_value( + const google_protobuf_UninterpretedOption* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); +} +UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_aggregate_value( + const google_protobuf_UninterpretedOption* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); +} + +UPB_INLINE void google_protobuf_UninterpretedOption_set_name( + google_protobuf_UninterpretedOption* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(56, 80)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value( + google_protobuf_UninterpretedOption* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value( + google_protobuf_UninterpretedOption* msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_negative_int_value( + google_protobuf_UninterpretedOption* msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value( + google_protobuf_UninterpretedOption* msg, double value) { + UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value( + google_protobuf_UninterpretedOption* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value( + google_protobuf_UninterpretedOption* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; +} + +/* google.protobuf.UninterpretedOption.NamePart */ + +extern const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit; +UPB_INLINE google_protobuf_UninterpretedOption_NamePart* +google_protobuf_UninterpretedOption_NamePart_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, + arena); +} +UPB_INLINE google_protobuf_UninterpretedOption_NamePart* +google_protobuf_UninterpretedOption_NamePart_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_UninterpretedOption_NamePart* ret = + google_protobuf_UninterpretedOption_NamePart_new(arena); + return (ret && + upb_decode(buf, ret, + &google_protobuf_UninterpretedOption_NamePart_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_UninterpretedOption_NamePart_serialize( + const google_protobuf_UninterpretedOption_NamePart* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, + arena, len); +} + +UPB_INLINE upb_stringview +google_protobuf_UninterpretedOption_NamePart_name_part( + const google_protobuf_UninterpretedOption_NamePart* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension( + const google_protobuf_UninterpretedOption_NamePart* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); +} + +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part( + google_protobuf_UninterpretedOption_NamePart* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension( + google_protobuf_UninterpretedOption_NamePart* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} + +/* google.protobuf.SourceCodeInfo */ + +extern const upb_msglayout google_protobuf_SourceCodeInfo_msginit; +UPB_INLINE google_protobuf_SourceCodeInfo* google_protobuf_SourceCodeInfo_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena); +} +UPB_INLINE google_protobuf_SourceCodeInfo* +google_protobuf_SourceCodeInfo_parsenew(upb_stringview buf, upb_arena* arena) { + google_protobuf_SourceCodeInfo* ret = + google_protobuf_SourceCodeInfo_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_SourceCodeInfo_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_SourceCodeInfo_serialize( + const google_protobuf_SourceCodeInfo* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, arena, len); +} + +UPB_INLINE const upb_array* google_protobuf_SourceCodeInfo_location( + const google_protobuf_SourceCodeInfo* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_SourceCodeInfo_set_location( + google_protobuf_SourceCodeInfo* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.SourceCodeInfo.Location */ + +extern const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit; +UPB_INLINE google_protobuf_SourceCodeInfo_Location* +google_protobuf_SourceCodeInfo_Location_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena); +} +UPB_INLINE google_protobuf_SourceCodeInfo_Location* +google_protobuf_SourceCodeInfo_Location_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_SourceCodeInfo_Location* ret = + google_protobuf_SourceCodeInfo_Location_new(arena); + return (ret && upb_decode(buf, ret, + &google_protobuf_SourceCodeInfo_Location_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_SourceCodeInfo_Location_serialize( + const google_protobuf_SourceCodeInfo_Location* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_SourceCodeInfo_Location_msginit, + arena, len); +} + +UPB_INLINE const upb_array* google_protobuf_SourceCodeInfo_Location_path( + const google_protobuf_SourceCodeInfo_Location* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); +} +UPB_INLINE const upb_array* google_protobuf_SourceCodeInfo_Location_span( + const google_protobuf_SourceCodeInfo_Location* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); +} +UPB_INLINE upb_stringview +google_protobuf_SourceCodeInfo_Location_leading_comments( + const google_protobuf_SourceCodeInfo_Location* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE upb_stringview +google_protobuf_SourceCodeInfo_Location_trailing_comments( + const google_protobuf_SourceCodeInfo_Location* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); +} +UPB_INLINE const upb_array* +google_protobuf_SourceCodeInfo_Location_leading_detached_comments( + const google_protobuf_SourceCodeInfo_Location* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(32, 64)); +} + +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_path( + google_protobuf_SourceCodeInfo_Location* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_span( + google_protobuf_SourceCodeInfo_Location* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments( + google_protobuf_SourceCodeInfo_Location* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments( + google_protobuf_SourceCodeInfo_Location* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void +google_protobuf_SourceCodeInfo_Location_set_leading_detached_comments( + google_protobuf_SourceCodeInfo_Location* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(32, 64)) = value; +} + +/* google.protobuf.GeneratedCodeInfo */ + +extern const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit; +UPB_INLINE google_protobuf_GeneratedCodeInfo* +google_protobuf_GeneratedCodeInfo_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_GeneratedCodeInfo_msginit, arena); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo* +google_protobuf_GeneratedCodeInfo_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_GeneratedCodeInfo* ret = + google_protobuf_GeneratedCodeInfo_new(arena); + return (ret && + upb_decode(buf, ret, &google_protobuf_GeneratedCodeInfo_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_GeneratedCodeInfo_serialize( + const google_protobuf_GeneratedCodeInfo* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, arena, + len); +} + +UPB_INLINE const upb_array* google_protobuf_GeneratedCodeInfo_annotation( + const google_protobuf_GeneratedCodeInfo* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_GeneratedCodeInfo_set_annotation( + google_protobuf_GeneratedCodeInfo* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.GeneratedCodeInfo.Annotation */ + +extern const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit; +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* +google_protobuf_GeneratedCodeInfo_Annotation_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, + arena); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* +google_protobuf_GeneratedCodeInfo_Annotation_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_GeneratedCodeInfo_Annotation* ret = + google_protobuf_GeneratedCodeInfo_Annotation_new(arena); + return (ret && + upb_decode(buf, ret, + &google_protobuf_GeneratedCodeInfo_Annotation_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_GeneratedCodeInfo_Annotation_serialize( + const google_protobuf_GeneratedCodeInfo_Annotation* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, + arena, len); +} + +UPB_INLINE const upb_array* google_protobuf_GeneratedCodeInfo_Annotation_path( + const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 32)); +} +UPB_INLINE upb_stringview +google_protobuf_GeneratedCodeInfo_Annotation_source_file( + const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 16)); +} +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin( + const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); +} +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end( + const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); +} + +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_path( + google_protobuf_GeneratedCodeInfo_Annotation* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 32)) = value; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file( + google_protobuf_GeneratedCodeInfo_Annotation* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin( + google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end( + google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + +UPB_END_EXTERN_C + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/duration.upb.c b/src/core/ext/upb-generated/google/protobuf/duration.upb.c new file mode 100644 index 00000000000..b057ce5e4aa --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/duration.upb.c @@ -0,0 +1,24 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/duration.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include "google/protobuf/duration.upb.h" +#include +#include "upb/msg.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field google_protobuf_Duration__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_Duration_msginit = { + NULL, &google_protobuf_Duration__fields[0], UPB_SIZE(16, 16), 2, false, +}; + +#include "upb/port_undef.inc" diff --git a/src/core/ext/upb-generated/google/protobuf/duration.upb.h b/src/core/ext/upb-generated/google/protobuf/duration.upb.h new file mode 100644 index 00000000000..1f40b3aed24 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/duration.upb.h @@ -0,0 +1,65 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/duration.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +UPB_BEGIN_EXTERN_C + +struct google_protobuf_Duration; +typedef struct google_protobuf_Duration google_protobuf_Duration; + +/* Enums */ + +/* google.protobuf.Duration */ + +extern const upb_msglayout google_protobuf_Duration_msginit; +UPB_INLINE google_protobuf_Duration* google_protobuf_Duration_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_Duration_msginit, arena); +} +UPB_INLINE google_protobuf_Duration* google_protobuf_Duration_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_Duration* ret = google_protobuf_Duration_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Duration_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_Duration_serialize( + const google_protobuf_Duration* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_Duration_msginit, arena, len); +} + +UPB_INLINE int64_t +google_protobuf_Duration_seconds(const google_protobuf_Duration* msg) { + return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); +} +UPB_INLINE int32_t +google_protobuf_Duration_nanos(const google_protobuf_Duration* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); +} + +UPB_INLINE void google_protobuf_Duration_set_seconds( + google_protobuf_Duration* msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Duration_set_nanos( + google_protobuf_Duration* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + +UPB_END_EXTERN_C + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/struct.upb.c b/src/core/ext/upb-generated/google/protobuf/struct.upb.c new file mode 100644 index 00000000000..a0820e722a6 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/struct.upb.c @@ -0,0 +1,88 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/struct.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include "google/protobuf/struct.upb.h" +#include +#include "upb/msg.h" + +#include "upb/port_def.inc" + +static const upb_msglayout* const google_protobuf_Struct_submsgs[1] = { + &google_protobuf_Struct_FieldsEntry_msginit, +}; + +static const upb_msglayout_field google_protobuf_Struct__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_Struct_msginit = { + &google_protobuf_Struct_submsgs[0], + &google_protobuf_Struct__fields[0], + UPB_SIZE(4, 8), + 1, + false, +}; + +static const upb_msglayout* const + google_protobuf_Struct_FieldsEntry_submsgs[1] = { + &google_protobuf_Value_msginit, +}; + +static const upb_msglayout_field google_protobuf_Struct_FieldsEntry__fields[2] = + { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit = { + &google_protobuf_Struct_FieldsEntry_submsgs[0], + &google_protobuf_Struct_FieldsEntry__fields[0], + UPB_SIZE(16, 32), + 2, + false, +}; + +static const upb_msglayout* const google_protobuf_Value_submsgs[2] = { + &google_protobuf_ListValue_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field google_protobuf_Value__fields[6] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 14, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 1, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {4, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 8, 1}, + {5, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 1, 11, 1}, + {6, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_Value_msginit = { + &google_protobuf_Value_submsgs[0], + &google_protobuf_Value__fields[0], + UPB_SIZE(16, 32), + 6, + false, +}; + +static const upb_msglayout* const google_protobuf_ListValue_submsgs[1] = { + &google_protobuf_Value_msginit, +}; + +static const upb_msglayout_field google_protobuf_ListValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_ListValue_msginit = { + &google_protobuf_ListValue_submsgs[0], + &google_protobuf_ListValue__fields[0], + UPB_SIZE(4, 8), + 1, + false, +}; + +#include "upb/port_undef.inc" diff --git a/src/core/ext/upb-generated/google/protobuf/struct.upb.h b/src/core/ext/upb-generated/google/protobuf/struct.upb.h new file mode 100644 index 00000000000..5493794f0e6 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/struct.upb.h @@ -0,0 +1,226 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/struct.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +UPB_BEGIN_EXTERN_C + +struct google_protobuf_Struct; +struct google_protobuf_Struct_FieldsEntry; +struct google_protobuf_Value; +struct google_protobuf_ListValue; +typedef struct google_protobuf_Struct google_protobuf_Struct; +typedef struct google_protobuf_Struct_FieldsEntry + google_protobuf_Struct_FieldsEntry; +typedef struct google_protobuf_Value google_protobuf_Value; +typedef struct google_protobuf_ListValue google_protobuf_ListValue; + +/* Enums */ + +typedef enum { google_protobuf_NULL_VALUE = 0 } google_protobuf_NullValue; + +/* google.protobuf.Struct */ + +extern const upb_msglayout google_protobuf_Struct_msginit; +UPB_INLINE google_protobuf_Struct* google_protobuf_Struct_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_Struct_msginit, arena); +} +UPB_INLINE google_protobuf_Struct* google_protobuf_Struct_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_Struct* ret = google_protobuf_Struct_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Struct_msginit)) ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_Struct_serialize( + const google_protobuf_Struct* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_Struct_msginit, arena, len); +} + +UPB_INLINE const upb_array* google_protobuf_Struct_fields( + const google_protobuf_Struct* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_Struct_set_fields(google_protobuf_Struct* msg, + upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.Struct.FieldsEntry */ + +extern const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit; +UPB_INLINE google_protobuf_Struct_FieldsEntry* +google_protobuf_Struct_FieldsEntry_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_Struct_FieldsEntry_msginit, arena); +} +UPB_INLINE google_protobuf_Struct_FieldsEntry* +google_protobuf_Struct_FieldsEntry_parsenew(upb_stringview buf, + upb_arena* arena) { + google_protobuf_Struct_FieldsEntry* ret = + google_protobuf_Struct_FieldsEntry_new(arena); + return (ret && + upb_decode(buf, ret, &google_protobuf_Struct_FieldsEntry_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_Struct_FieldsEntry_serialize( + const google_protobuf_Struct_FieldsEntry* msg, upb_arena* arena, + size_t* len) { + return upb_encode(msg, &google_protobuf_Struct_FieldsEntry_msginit, arena, + len); +} + +UPB_INLINE upb_stringview google_protobuf_Struct_FieldsEntry_key( + const google_protobuf_Struct_FieldsEntry* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); +} +UPB_INLINE const google_protobuf_Value* +google_protobuf_Struct_FieldsEntry_value( + const google_protobuf_Struct_FieldsEntry* msg) { + return UPB_FIELD_AT(msg, const google_protobuf_Value*, UPB_SIZE(8, 16)); +} + +UPB_INLINE void google_protobuf_Struct_FieldsEntry_set_key( + google_protobuf_Struct_FieldsEntry* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Struct_FieldsEntry_set_value( + google_protobuf_Struct_FieldsEntry* msg, google_protobuf_Value* value) { + UPB_FIELD_AT(msg, google_protobuf_Value*, UPB_SIZE(8, 16)) = value; +} + +/* google.protobuf.Value */ + +extern const upb_msglayout google_protobuf_Value_msginit; +UPB_INLINE google_protobuf_Value* google_protobuf_Value_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_Value_msginit, arena); +} +UPB_INLINE google_protobuf_Value* google_protobuf_Value_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_Value* ret = google_protobuf_Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Value_msginit)) ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_Value_serialize( + const google_protobuf_Value* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_Value_msginit, arena, len); +} + +typedef enum { + google_protobuf_Value_kind_null_value = 1, + google_protobuf_Value_kind_number_value = 2, + google_protobuf_Value_kind_string_value = 3, + google_protobuf_Value_kind_bool_value = 4, + google_protobuf_Value_kind_struct_value = 5, + google_protobuf_Value_kind_list_value = 6, + google_protobuf_Value_kind_NOT_SET = 0, +} google_protobuf_Value_kind_oneofcases; +UPB_INLINE google_protobuf_Value_kind_oneofcases +google_protobuf_Value_kind_case(const google_protobuf_Value* msg) { + return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); +} + +UPB_INLINE google_protobuf_NullValue +google_protobuf_Value_null_value(const google_protobuf_Value* msg) { + return UPB_READ_ONEOF(msg, google_protobuf_NullValue, UPB_SIZE(0, 0), + UPB_SIZE(8, 16), 1, google_protobuf_NULL_VALUE); +} +UPB_INLINE double google_protobuf_Value_number_value( + const google_protobuf_Value* msg) { + return UPB_READ_ONEOF(msg, double, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, 0); +} +UPB_INLINE upb_stringview +google_protobuf_Value_string_value(const google_protobuf_Value* msg) { + return UPB_READ_ONEOF(msg, upb_stringview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, + upb_stringview_make("", strlen(""))); +} +UPB_INLINE bool google_protobuf_Value_bool_value( + const google_protobuf_Value* msg) { + return UPB_READ_ONEOF(msg, bool, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 4, false); +} +UPB_INLINE const google_protobuf_Struct* google_protobuf_Value_struct_value( + const google_protobuf_Value* msg) { + return UPB_READ_ONEOF(msg, const google_protobuf_Struct*, UPB_SIZE(0, 0), + UPB_SIZE(8, 16), 5, NULL); +} +UPB_INLINE const google_protobuf_ListValue* google_protobuf_Value_list_value( + const google_protobuf_Value* msg) { + return UPB_READ_ONEOF(msg, const google_protobuf_ListValue*, UPB_SIZE(0, 0), + UPB_SIZE(8, 16), 6, NULL); +} + +UPB_INLINE void google_protobuf_Value_set_null_value( + google_protobuf_Value* msg, google_protobuf_NullValue value) { + UPB_WRITE_ONEOF(msg, google_protobuf_NullValue, UPB_SIZE(0, 0), value, + UPB_SIZE(8, 16), 1); +} +UPB_INLINE void google_protobuf_Value_set_number_value( + google_protobuf_Value* msg, double value) { + UPB_WRITE_ONEOF(msg, double, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); +} +UPB_INLINE void google_protobuf_Value_set_string_value( + google_protobuf_Value* msg, upb_stringview value) { + UPB_WRITE_ONEOF(msg, upb_stringview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), + 3); +} +UPB_INLINE void google_protobuf_Value_set_bool_value(google_protobuf_Value* msg, + bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 4); +} +UPB_INLINE void google_protobuf_Value_set_struct_value( + google_protobuf_Value* msg, google_protobuf_Struct* value) { + UPB_WRITE_ONEOF(msg, google_protobuf_Struct*, UPB_SIZE(0, 0), value, + UPB_SIZE(8, 16), 5); +} +UPB_INLINE void google_protobuf_Value_set_list_value( + google_protobuf_Value* msg, google_protobuf_ListValue* value) { + UPB_WRITE_ONEOF(msg, google_protobuf_ListValue*, UPB_SIZE(0, 0), value, + UPB_SIZE(8, 16), 6); +} + +/* google.protobuf.ListValue */ + +extern const upb_msglayout google_protobuf_ListValue_msginit; +UPB_INLINE google_protobuf_ListValue* google_protobuf_ListValue_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_ListValue_msginit, arena); +} +UPB_INLINE google_protobuf_ListValue* google_protobuf_ListValue_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_ListValue* ret = google_protobuf_ListValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_ListValue_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_ListValue_serialize( + const google_protobuf_ListValue* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_ListValue_msginit, arena, len); +} + +UPB_INLINE const upb_array* google_protobuf_ListValue_values( + const google_protobuf_ListValue* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_ListValue_set_values( + google_protobuf_ListValue* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +UPB_END_EXTERN_C + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c new file mode 100644 index 00000000000..90d0aed7664 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c @@ -0,0 +1,24 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/timestamp.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include "google/protobuf/timestamp.upb.h" +#include +#include "upb/msg.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field google_protobuf_Timestamp__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_Timestamp_msginit = { + NULL, &google_protobuf_Timestamp__fields[0], UPB_SIZE(16, 16), 2, false, +}; + +#include "upb/port_undef.inc" diff --git a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h new file mode 100644 index 00000000000..a524eb5b6d0 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h @@ -0,0 +1,65 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/timestamp.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +UPB_BEGIN_EXTERN_C + +struct google_protobuf_Timestamp; +typedef struct google_protobuf_Timestamp google_protobuf_Timestamp; + +/* Enums */ + +/* google.protobuf.Timestamp */ + +extern const upb_msglayout google_protobuf_Timestamp_msginit; +UPB_INLINE google_protobuf_Timestamp* google_protobuf_Timestamp_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_Timestamp_msginit, arena); +} +UPB_INLINE google_protobuf_Timestamp* google_protobuf_Timestamp_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_Timestamp* ret = google_protobuf_Timestamp_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Timestamp_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_Timestamp_serialize( + const google_protobuf_Timestamp* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_Timestamp_msginit, arena, len); +} + +UPB_INLINE int64_t +google_protobuf_Timestamp_seconds(const google_protobuf_Timestamp* msg) { + return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); +} +UPB_INLINE int32_t +google_protobuf_Timestamp_nanos(const google_protobuf_Timestamp* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); +} + +UPB_INLINE void google_protobuf_Timestamp_set_seconds( + google_protobuf_Timestamp* msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Timestamp_set_nanos( + google_protobuf_Timestamp* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + +UPB_END_EXTERN_C + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c new file mode 100644 index 00000000000..3fa3bea1dbc --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c @@ -0,0 +1,87 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/wrappers.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include "google/protobuf/wrappers.upb.h" +#include +#include "upb/msg.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field google_protobuf_DoubleValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 1, 1}, +}; + +const upb_msglayout google_protobuf_DoubleValue_msginit = { + NULL, &google_protobuf_DoubleValue__fields[0], UPB_SIZE(8, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_FloatValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 2, 1}, +}; + +const upb_msglayout google_protobuf_FloatValue_msginit = { + NULL, &google_protobuf_FloatValue__fields[0], UPB_SIZE(4, 4), 1, false, +}; + +static const upb_msglayout_field google_protobuf_Int64Value__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, +}; + +const upb_msglayout google_protobuf_Int64Value_msginit = { + NULL, &google_protobuf_Int64Value__fields[0], UPB_SIZE(8, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_UInt64Value__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 4, 1}, +}; + +const upb_msglayout google_protobuf_UInt64Value_msginit = { + NULL, &google_protobuf_UInt64Value__fields[0], UPB_SIZE(8, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_Int32Value__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_Int32Value_msginit = { + NULL, &google_protobuf_Int32Value__fields[0], UPB_SIZE(4, 4), 1, false, +}; + +static const upb_msglayout_field google_protobuf_UInt32Value__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 13, 1}, +}; + +const upb_msglayout google_protobuf_UInt32Value_msginit = { + NULL, &google_protobuf_UInt32Value__fields[0], UPB_SIZE(4, 4), 1, false, +}; + +static const upb_msglayout_field google_protobuf_BoolValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout google_protobuf_BoolValue_msginit = { + NULL, &google_protobuf_BoolValue__fields[0], UPB_SIZE(1, 1), 1, false, +}; + +static const upb_msglayout_field google_protobuf_StringValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_StringValue_msginit = { + NULL, &google_protobuf_StringValue__fields[0], UPB_SIZE(8, 16), 1, false, +}; + +static const upb_msglayout_field google_protobuf_BytesValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 12, 1}, +}; + +const upb_msglayout google_protobuf_BytesValue_msginit = { + NULL, &google_protobuf_BytesValue__fields[0], UPB_SIZE(8, 16), 1, false, +}; + +#include "upb/port_undef.inc" diff --git a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h new file mode 100644 index 00000000000..3ae5d3b16e3 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h @@ -0,0 +1,305 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/wrappers.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +UPB_BEGIN_EXTERN_C + +struct google_protobuf_DoubleValue; +struct google_protobuf_FloatValue; +struct google_protobuf_Int64Value; +struct google_protobuf_UInt64Value; +struct google_protobuf_Int32Value; +struct google_protobuf_UInt32Value; +struct google_protobuf_BoolValue; +struct google_protobuf_StringValue; +struct google_protobuf_BytesValue; +typedef struct google_protobuf_DoubleValue google_protobuf_DoubleValue; +typedef struct google_protobuf_FloatValue google_protobuf_FloatValue; +typedef struct google_protobuf_Int64Value google_protobuf_Int64Value; +typedef struct google_protobuf_UInt64Value google_protobuf_UInt64Value; +typedef struct google_protobuf_Int32Value google_protobuf_Int32Value; +typedef struct google_protobuf_UInt32Value google_protobuf_UInt32Value; +typedef struct google_protobuf_BoolValue google_protobuf_BoolValue; +typedef struct google_protobuf_StringValue google_protobuf_StringValue; +typedef struct google_protobuf_BytesValue google_protobuf_BytesValue; + +/* Enums */ + +/* google.protobuf.DoubleValue */ + +extern const upb_msglayout google_protobuf_DoubleValue_msginit; +UPB_INLINE google_protobuf_DoubleValue* google_protobuf_DoubleValue_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_DoubleValue_msginit, arena); +} +UPB_INLINE google_protobuf_DoubleValue* google_protobuf_DoubleValue_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_DoubleValue* ret = google_protobuf_DoubleValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_DoubleValue_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_DoubleValue_serialize( + const google_protobuf_DoubleValue* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_DoubleValue_msginit, arena, len); +} + +UPB_INLINE double google_protobuf_DoubleValue_value( + const google_protobuf_DoubleValue* msg) { + return UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_DoubleValue_set_value( + google_protobuf_DoubleValue* msg, double value) { + UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.FloatValue */ + +extern const upb_msglayout google_protobuf_FloatValue_msginit; +UPB_INLINE google_protobuf_FloatValue* google_protobuf_FloatValue_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_FloatValue_msginit, arena); +} +UPB_INLINE google_protobuf_FloatValue* google_protobuf_FloatValue_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_FloatValue* ret = google_protobuf_FloatValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FloatValue_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_FloatValue_serialize( + const google_protobuf_FloatValue* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_FloatValue_msginit, arena, len); +} + +UPB_INLINE float google_protobuf_FloatValue_value( + const google_protobuf_FloatValue* msg) { + return UPB_FIELD_AT(msg, float, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_FloatValue_set_value( + google_protobuf_FloatValue* msg, float value) { + UPB_FIELD_AT(msg, float, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.Int64Value */ + +extern const upb_msglayout google_protobuf_Int64Value_msginit; +UPB_INLINE google_protobuf_Int64Value* google_protobuf_Int64Value_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_Int64Value_msginit, arena); +} +UPB_INLINE google_protobuf_Int64Value* google_protobuf_Int64Value_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_Int64Value* ret = google_protobuf_Int64Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Int64Value_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_Int64Value_serialize( + const google_protobuf_Int64Value* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_Int64Value_msginit, arena, len); +} + +UPB_INLINE int64_t +google_protobuf_Int64Value_value(const google_protobuf_Int64Value* msg) { + return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_Int64Value_set_value( + google_protobuf_Int64Value* msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.UInt64Value */ + +extern const upb_msglayout google_protobuf_UInt64Value_msginit; +UPB_INLINE google_protobuf_UInt64Value* google_protobuf_UInt64Value_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_UInt64Value_msginit, arena); +} +UPB_INLINE google_protobuf_UInt64Value* google_protobuf_UInt64Value_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_UInt64Value* ret = google_protobuf_UInt64Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_UInt64Value_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_UInt64Value_serialize( + const google_protobuf_UInt64Value* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_UInt64Value_msginit, arena, len); +} + +UPB_INLINE uint64_t +google_protobuf_UInt64Value_value(const google_protobuf_UInt64Value* msg) { + return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_UInt64Value_set_value( + google_protobuf_UInt64Value* msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.Int32Value */ + +extern const upb_msglayout google_protobuf_Int32Value_msginit; +UPB_INLINE google_protobuf_Int32Value* google_protobuf_Int32Value_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_Int32Value_msginit, arena); +} +UPB_INLINE google_protobuf_Int32Value* google_protobuf_Int32Value_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_Int32Value* ret = google_protobuf_Int32Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Int32Value_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_Int32Value_serialize( + const google_protobuf_Int32Value* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_Int32Value_msginit, arena, len); +} + +UPB_INLINE int32_t +google_protobuf_Int32Value_value(const google_protobuf_Int32Value* msg) { + return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_Int32Value_set_value( + google_protobuf_Int32Value* msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.UInt32Value */ + +extern const upb_msglayout google_protobuf_UInt32Value_msginit; +UPB_INLINE google_protobuf_UInt32Value* google_protobuf_UInt32Value_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); +} +UPB_INLINE google_protobuf_UInt32Value* google_protobuf_UInt32Value_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_UInt32Value* ret = google_protobuf_UInt32Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_UInt32Value_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_UInt32Value_serialize( + const google_protobuf_UInt32Value* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_UInt32Value_msginit, arena, len); +} + +UPB_INLINE uint32_t +google_protobuf_UInt32Value_value(const google_protobuf_UInt32Value* msg) { + return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_UInt32Value_set_value( + google_protobuf_UInt32Value* msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.BoolValue */ + +extern const upb_msglayout google_protobuf_BoolValue_msginit; +UPB_INLINE google_protobuf_BoolValue* google_protobuf_BoolValue_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_BoolValue_msginit, arena); +} +UPB_INLINE google_protobuf_BoolValue* google_protobuf_BoolValue_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_BoolValue* ret = google_protobuf_BoolValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_BoolValue_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_BoolValue_serialize( + const google_protobuf_BoolValue* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_BoolValue_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_BoolValue_value( + const google_protobuf_BoolValue* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_BoolValue_set_value( + google_protobuf_BoolValue* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.StringValue */ + +extern const upb_msglayout google_protobuf_StringValue_msginit; +UPB_INLINE google_protobuf_StringValue* google_protobuf_StringValue_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_StringValue_msginit, arena); +} +UPB_INLINE google_protobuf_StringValue* google_protobuf_StringValue_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_StringValue* ret = google_protobuf_StringValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_StringValue_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_StringValue_serialize( + const google_protobuf_StringValue* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_StringValue_msginit, arena, len); +} + +UPB_INLINE upb_stringview +google_protobuf_StringValue_value(const google_protobuf_StringValue* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_StringValue_set_value( + google_protobuf_StringValue* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.BytesValue */ + +extern const upb_msglayout google_protobuf_BytesValue_msginit; +UPB_INLINE google_protobuf_BytesValue* google_protobuf_BytesValue_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_BytesValue_msginit, arena); +} +UPB_INLINE google_protobuf_BytesValue* google_protobuf_BytesValue_parsenew( + upb_stringview buf, upb_arena* arena) { + google_protobuf_BytesValue* ret = google_protobuf_BytesValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_BytesValue_msginit)) + ? ret + : NULL; +} +UPB_INLINE char* google_protobuf_BytesValue_serialize( + const google_protobuf_BytesValue* msg, upb_arena* arena, size_t* len) { + return upb_encode(msg, &google_protobuf_BytesValue_msginit, arena, len); +} + +UPB_INLINE upb_stringview +google_protobuf_BytesValue_value(const google_protobuf_BytesValue* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_BytesValue_set_value( + google_protobuf_BytesValue* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; +} + +UPB_END_EXTERN_C + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ */ diff --git a/src/upb/gen_build_yaml.py b/src/upb/gen_build_yaml.py new file mode 100755 index 00000000000..0dd7bfae109 --- /dev/null +++ b/src/upb/gen_build_yaml.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python2.7 + +# Copyright 2015 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. + +# TODO: This should ideally be in upb submodule to avoid hardcoding this here. + +import re +import os +import sys +import yaml + +srcs = [ + "third_party/upb/google/protobuf/descriptor.upb.c", + "third_party/upb/upb/decode.c", + "third_party/upb/upb/def.c", + "third_party/upb/upb/encode.c", + "third_party/upb/upb/handlers.c", + "third_party/upb/upb/msg.c", + "third_party/upb/upb/msgfactory.c", + "third_party/upb/upb/refcounted.c", + "third_party/upb/upb/sink.c", + "third_party/upb/upb/table.c", + "third_party/upb/upb/upb.c", +] + +hdrs = [ + "third_party/upb/google/protobuf/descriptor.upb.h", + "third_party/upb/upb/decode.h", + "third_party/upb/upb/def.h", + "third_party/upb/upb/encode.h", + "third_party/upb/upb/handlers.h", + "third_party/upb/upb/msg.h", + "third_party/upb/upb/msgfactory.h", + "third_party/upb/upb/refcounted.h", + "third_party/upb/upb/sink.h", + "third_party/upb/upb/upb.h", +] + +os.chdir(os.path.dirname(sys.argv[0])+'/../..') + +out = {} + +try: + out['libs'] = [{ + 'name': 'upb', + 'defaults': 'upb', + 'build': 'private', + 'language': 'c', + 'secure': 'no', + 'src': srcs, + 'headers': hdrs, + }] +except: + pass + +print yaml.dump(out) + diff --git a/tools/buildgen/generate_build_additions.sh b/tools/buildgen/generate_build_additions.sh index 5a1f4a598a7..c99ad6ee552 100755 --- a/tools/buildgen/generate_build_additions.sh +++ b/tools/buildgen/generate_build_additions.sh @@ -19,6 +19,7 @@ gen_build_yaml_dirs=" \ src/boringssl \ src/benchmark \ src/proto \ + src/upb \ src/zlib \ src/c-ares \ test/core/bad_client \ diff --git a/tools/codegen/core/gen_upb_api.sh b/tools/codegen/core/gen_upb_api.sh new file mode 100755 index 00000000000..9457e06f124 --- /dev/null +++ b/tools/codegen/core/gen_upb_api.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Copyright 2016 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# REQUIRES: Bazel +set -ex +rm -rf src/core/ext/upb-generated +mkdir src/core/ext/upb-generated +cd third_party +cd upb +bazel build :protoc-gen-upb + +cd ../.. + +proto_files=( \ + "google/protobuf/any.proto" \ + "google/protobuf/struct.proto" \ + "google/protobuf/wrappers.proto" \ + "google/protobuf/descriptor.proto" \ + "google/protobuf/duration.proto" \ + "google/protobuf/timestamp.proto" ) + +for i in "${proto_files[@]}" +do + protoc -I=$PWD/third_party/data-plane-api -I=$PWD/third_party/googleapis -I=$PWD/third_party/protobuf -I=$PWD/third_party/protoc-gen-validate $i --upb_out=./src/core/ext/upb-generated --plugin=protoc-gen-upb=third_party/upb/bazel-bin/protoc-gen-upb +done diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py index 787bef1778e..fd93cf31e05 100755 --- a/tools/distrib/check_copyright.py +++ b/tools/distrib/check_copyright.py @@ -104,6 +104,20 @@ _EXEMPT = frozenset(( # Designer-generated source 'examples/csharp/HelloworldXamarin/Droid/Resources/Resource.designer.cs', 'examples/csharp/HelloworldXamarin/iOS/ViewController.designer.cs', + + # Upb generated source + 'src/core/ext/upb-generated/google/protobuf/any.upb.h', + 'src/core/ext/upb-generated/google/protobuf/any.upb.c', + 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.h', + 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.c', + 'src/core/ext/upb-generated/google/protobuf/duration.upb.h', + 'src/core/ext/upb-generated/google/protobuf/duration.upb.c', + 'src/core/ext/upb-generated/google/protobuf/struct.upb.h', + 'src/core/ext/upb-generated/google/protobuf/struct.upb.c', + 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.h', + 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.c', + 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.h', + 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.c', )) RE_YEAR = r'Copyright (?P[0-9]+\-)?(?P[0-9]+) ([Tt]he )?gRPC [Aa]uthors(\.|)' diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py index b8d530cce06..15b3478e555 100755 --- a/tools/distrib/check_include_guards.py +++ b/tools/distrib/check_include_guards.py @@ -165,6 +165,20 @@ KNOWN_BAD = set([ 'src/core/tsi/alts/handshaker/transport_security_common.pb.h', 'include/grpc++/ext/reflection.grpc.pb.h', 'include/grpc++/ext/reflection.pb.h', + + # Upb generated code + 'src/core/ext/upb-generated/google/protobuf/any.upb.h', + 'src/core/ext/upb-generated/google/protobuf/any.upb.c', + 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.h', + 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.c', + 'src/core/ext/upb-generated/google/protobuf/duration.upb.h', + 'src/core/ext/upb-generated/google/protobuf/duration.upb.c', + 'src/core/ext/upb-generated/google/protobuf/struct.upb.h', + 'src/core/ext/upb-generated/google/protobuf/struct.upb.c', + 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.h', + 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.c', + 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.h', + 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.c', ]) grep_filter = r"grep -E '^(include|src/core)/.*\.h$'" diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index d4d5d14f079..2fea807bbb0 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8825,6 +8825,27 @@ "third_party": false, "type": "lib" }, + { + "deps": [], + "headers": [ + "third_party/upb/google/protobuf/descriptor.upb.h", + "third_party/upb/upb/decode.h", + "third_party/upb/upb/def.h", + "third_party/upb/upb/encode.h", + "third_party/upb/upb/handlers.h", + "third_party/upb/upb/msg.h", + "third_party/upb/upb/msgfactory.h", + "third_party/upb/upb/refcounted.h", + "third_party/upb/upb/sink.h", + "third_party/upb/upb/upb.h" + ], + "is_filegroup": false, + "language": "c", + "name": "upb", + "src": [], + "third_party": false, + "type": "lib" + }, { "deps": [], "headers": [ diff --git a/tools/run_tests/sanity/check_port_platform.py b/tools/run_tests/sanity/check_port_platform.py index fff828eaee8..8c412700e45 100755 --- a/tools/run_tests/sanity/check_port_platform.py +++ b/tools/run_tests/sanity/check_port_platform.py @@ -35,6 +35,9 @@ def check_port_platform_inclusion(directory_root): continue if filename.endswith('.pb.h') or filename.endswith('.pb.c'): continue + # Skip check for upb generated code + if filename.endswith('.upb.h') or filename.endswith('.upb.c'): + continue with open(path) as f: all_lines_in_file = f.readlines() for index, l in enumerate(all_lines_in_file): From f6ce4e361b12f48dd021c348379f51edff83d516 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 11 Dec 2018 16:28:06 -0800 Subject: [PATCH 264/534] Remove the ignore-pattern in .pylintrc-tests --- .pylintrc-tests | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.pylintrc-tests b/.pylintrc-tests index 0d408fbb565..8a66eec79a6 100644 --- a/.pylintrc-tests +++ b/.pylintrc-tests @@ -1,7 +1,3 @@ -[MASTER] -ignore-patterns= - .+?(beta|framework).+?\.py - [VARIABLES] # TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection From bdfb5691ad7703aee8b28febf45606917be9644e Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 11 Dec 2018 16:30:07 -0800 Subject: [PATCH 265/534] Strict check for $config && Enable SC2154 --- tools/run_tests/dockerize/docker_run_tests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh index 5214938208b..bdcbd88ff9a 100755 --- a/tools/run_tests/dockerize/docker_run_tests.sh +++ b/tools/run_tests/dockerize/docker_run_tests.sh @@ -18,8 +18,7 @@ set -e -# shellcheck disable=SC2154 -export CONFIG=$config +export CONFIG=${config:?} export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer export PATH=$PATH:/usr/bin/llvm-symbolizer From 8f64f9528f45935187485dacb47cdfc822b35149 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 11 Dec 2018 16:37:44 -0800 Subject: [PATCH 266/534] Add ignore to .pylintrc-tests --- .pylintrc-tests | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.pylintrc-tests b/.pylintrc-tests index 8a66eec79a6..d9cc4d107ef 100644 --- a/.pylintrc-tests +++ b/.pylintrc-tests @@ -1,3 +1,10 @@ +[MASTER] +ignore= + src/python/grpcio_tests/tests/unit/beta, + src/python/grpcio_tests/tests/unit/framework, + src/python/grpcio_tests/tests/unit/framework/common, + src/python/grpcio_tests/tests/unit/framework/foundation, + [VARIABLES] # TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection From d550af373cc993ee80e9e350d60f4ca662b1ec28 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 12 Dec 2018 04:09:42 +0100 Subject: [PATCH 267/534] Moving ::grpc::Alarm to ::grpc_impl::Alarm. --- BUILD | 1 + CMakeLists.txt | 3 + Makefile | 3 + build.yaml | 1 + gRPC-C++.podspec | 1 + include/grpcpp/alarm.h | 93 +------------- include/grpcpp/alarm_impl.h | 116 ++++++++++++++++++ src/cpp/common/alarm.cc | 13 +- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + .../generated/sources_and_headers.json | 2 + 11 files changed, 140 insertions(+), 95 deletions(-) create mode 100644 include/grpcpp/alarm_impl.h diff --git a/BUILD b/BUILD index 9a2c16c6012..cb03e560d5e 100644 --- a/BUILD +++ b/BUILD @@ -204,6 +204,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", "include/grpcpp/alarm.h", + "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 23b4bb77e75..e843397e008 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2985,6 +2985,7 @@ foreach(_hdr include/grpc++/support/sync_stream.h include/grpc++/support/time.h include/grpcpp/alarm.h + include/grpcpp/alarm_impl.h include/grpcpp/channel.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h @@ -3569,6 +3570,7 @@ foreach(_hdr include/grpc++/support/sync_stream.h include/grpc++/support/time.h include/grpcpp/alarm.h + include/grpcpp/alarm_impl.h include/grpcpp/channel.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h @@ -4504,6 +4506,7 @@ foreach(_hdr include/grpc++/support/sync_stream.h include/grpc++/support/time.h include/grpcpp/alarm.h + include/grpcpp/alarm_impl.h include/grpcpp/channel.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h diff --git a/Makefile b/Makefile index 4f7cd130120..438e5729d58 100644 --- a/Makefile +++ b/Makefile @@ -5340,6 +5340,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/support/sync_stream.h \ include/grpc++/support/time.h \ include/grpcpp/alarm.h \ + include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ @@ -5933,6 +5934,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/support/sync_stream.h \ include/grpc++/support/time.h \ include/grpcpp/alarm.h \ + include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ @@ -6835,6 +6837,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/support/sync_stream.h \ include/grpc++/support/time.h \ include/grpcpp/alarm.h \ + include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ diff --git a/build.yaml b/build.yaml index 381e649b392..74a5f5e6dca 100644 --- a/build.yaml +++ b/build.yaml @@ -1323,6 +1323,7 @@ filegroups: - include/grpc++/support/sync_stream.h - include/grpc++/support/time.h - include/grpcpp/alarm.h + - include/grpcpp/alarm_impl.h - include/grpcpp/channel.h - include/grpcpp/client_context.h - include/grpcpp/completion_queue.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 6647201714c..3da94dda4b2 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -78,6 +78,7 @@ Pod::Spec.new do |s| ss.header_mappings_dir = 'include/grpcpp' ss.source_files = 'include/grpcpp/alarm.h', + 'include/grpcpp/alarm_impl.h', 'include/grpcpp/channel.h', 'include/grpcpp/client_context.h', 'include/grpcpp/completion_queue.h', diff --git a/include/grpcpp/alarm.h b/include/grpcpp/alarm.h index 365feb4eb95..2343c1149c5 100644 --- a/include/grpcpp/alarm.h +++ b/include/grpcpp/alarm.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 gRPC authors. + * 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. @@ -16,99 +16,14 @@ * */ -/// An Alarm posts the user provided tag to its associated completion queue upon -/// expiry or cancellation. #ifndef GRPCPP_ALARM_H #define GRPCPP_ALARM_H -#include - -#include -#include -#include -#include -#include -#include +#include namespace grpc { -/// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h). -class Alarm : private GrpcLibraryCodegen { - public: - /// Create an unset completion queue alarm - Alarm(); - - /// Destroy the given completion queue alarm, cancelling it in the process. - ~Alarm(); - - /// DEPRECATED: Create and set a completion queue alarm instance associated to - /// \a cq. - /// This form is deprecated because it is inherently racy. - /// \internal We rely on the presence of \a cq for grpc initialization. If \a - /// cq were ever to be removed, a reference to a static - /// internal::GrpcLibraryInitializer instance would need to be introduced - /// here. \endinternal. - template - Alarm(CompletionQueue* cq, const T& deadline, void* tag) : Alarm() { - SetInternal(cq, TimePoint(deadline).raw_time(), tag); - } - - /// Trigger an alarm instance on completion queue \a cq at the specified time. - /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel), - /// an event with tag \a tag will be added to \a cq. If the alarm expired, the - /// event's success bit will be true, false otherwise (ie, upon cancellation). - template - void Set(CompletionQueue* cq, const T& deadline, void* tag) { - SetInternal(cq, TimePoint(deadline).raw_time(), tag); - } - - /// Alarms aren't copyable. - Alarm(const Alarm&) = delete; - Alarm& operator=(const Alarm&) = delete; - - /// Alarms are movable. - Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; } - Alarm& operator=(Alarm&& rhs) { - alarm_ = rhs.alarm_; - rhs.alarm_ = nullptr; - return *this; - } - - /// Cancel a completion queue alarm. Calling this function over an alarm that - /// has already fired has no effect. - void Cancel(); - - /// NOTE: class experimental_type is not part of the public API of this class - /// TODO(vjpai): Move these contents to the public API of Alarm when - /// they are no longer experimental - class experimental_type { - public: - explicit experimental_type(Alarm* alarm) : alarm_(alarm) {} - - /// Set an alarm to invoke callback \a f. The argument to the callback - /// states whether the alarm expired at \a deadline (true) or was cancelled - /// (false) - template - void Set(const T& deadline, std::function f) { - alarm_->SetInternal(TimePoint(deadline).raw_time(), std::move(f)); - } - - private: - Alarm* alarm_; - }; - - /// NOTE: The function experimental() is not stable public API. It is a view - /// to the experimental components of this class. It may be changed or removed - /// at any time. - experimental_type experimental() { return experimental_type(this); } - - private: - void SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag); - void SetInternal(gpr_timespec deadline, std::function f); - - internal::CompletionQueueTag* alarm_; -}; - -} // namespace grpc +typedef ::grpc_impl::Alarm Alarm; +} #endif // GRPCPP_ALARM_H diff --git a/include/grpcpp/alarm_impl.h b/include/grpcpp/alarm_impl.h new file mode 100644 index 00000000000..7844e7c8866 --- /dev/null +++ b/include/grpcpp/alarm_impl.h @@ -0,0 +1,116 @@ +/* + * + * Copyright 2015 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. + * + */ + +/// An Alarm posts the user provided tag to its associated completion queue upon +/// expiry or cancellation. +#ifndef GRPCPP_ALARM_IMPL_H +#define GRPCPP_ALARM_IMPL_H + +#include + +#include +#include +#include +#include +#include +#include + +namespace grpc_impl { + +/// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h). +class Alarm : private ::grpc::GrpcLibraryCodegen { + public: + /// Create an unset completion queue alarm + Alarm(); + + /// Destroy the given completion queue alarm, cancelling it in the process. + ~Alarm(); + + /// DEPRECATED: Create and set a completion queue alarm instance associated to + /// \a cq. + /// This form is deprecated because it is inherently racy. + /// \internal We rely on the presence of \a cq for grpc initialization. If \a + /// cq were ever to be removed, a reference to a static + /// internal::GrpcLibraryInitializer instance would need to be introduced + /// here. \endinternal. + template + Alarm(::grpc::CompletionQueue* cq, const T& deadline, void* tag) : Alarm() { + SetInternal(cq, ::grpc::TimePoint(deadline).raw_time(), tag); + } + + /// Trigger an alarm instance on completion queue \a cq at the specified time. + /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel), + /// an event with tag \a tag will be added to \a cq. If the alarm expired, the + /// event's success bit will be true, false otherwise (ie, upon cancellation). + template + void Set(::grpc::CompletionQueue* cq, const T& deadline, void* tag) { + SetInternal(cq, ::grpc::TimePoint(deadline).raw_time(), tag); + } + + /// Alarms aren't copyable. + Alarm(const Alarm&) = delete; + Alarm& operator=(const Alarm&) = delete; + + /// Alarms are movable. + Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; } + Alarm& operator=(Alarm&& rhs) { + alarm_ = rhs.alarm_; + rhs.alarm_ = nullptr; + return *this; + } + + /// Cancel a completion queue alarm. Calling this function over an alarm that + /// has already fired has no effect. + void Cancel(); + + /// NOTE: class experimental_type is not part of the public API of this class + /// TODO(vjpai): Move these contents to the public API of Alarm when + /// they are no longer experimental + class experimental_type { + public: + explicit experimental_type(Alarm* alarm) : alarm_(alarm) {} + + /// Set an alarm to invoke callback \a f. The argument to the callback + /// states whether the alarm expired at \a deadline (true) or was cancelled + /// (false) + template + void Set(const T& deadline, std::function f) { + alarm_->SetInternal(::grpc::TimePoint(deadline).raw_time(), + std::move(f)); + } + + private: + Alarm* alarm_; + }; + + /// NOTE: The function experimental() is not stable public API. It is a view + /// to the experimental components of this class. It may be changed or removed + /// at any time. + experimental_type experimental() { return experimental_type(this); } + + private: + void SetInternal(::grpc::CompletionQueue* cq, gpr_timespec deadline, + void* tag); + void SetInternal(gpr_timespec deadline, std::function f); + + ::grpc::internal::CompletionQueueTag* alarm_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_ALARM_IMPL_H diff --git a/src/cpp/common/alarm.cc b/src/cpp/common/alarm.cc index 5819a4210bd..148f0b9bc94 100644 --- a/src/cpp/common/alarm.cc +++ b/src/cpp/common/alarm.cc @@ -31,10 +31,10 @@ #include #include "src/core/lib/debug/trace.h" -namespace grpc { +namespace grpc_impl { namespace internal { -class AlarmImpl : public CompletionQueueTag { +class AlarmImpl : public ::grpc::internal::CompletionQueueTag { public: AlarmImpl() : cq_(nullptr), tag_(nullptr) { gpr_ref_init(&refs_, 1); @@ -51,7 +51,7 @@ class AlarmImpl : public CompletionQueueTag { Unref(); return true; } - void Set(CompletionQueue* cq, gpr_timespec deadline, void* tag) { + void Set(::grpc::CompletionQueue* cq, gpr_timespec deadline, void* tag) { grpc_core::ExecCtx exec_ctx; GRPC_CQ_INTERNAL_REF(cq->cq(), "alarm"); cq_ = cq->cq(); @@ -114,13 +114,14 @@ class AlarmImpl : public CompletionQueueTag { }; } // namespace internal -static internal::GrpcLibraryInitializer g_gli_initializer; +static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; Alarm::Alarm() : alarm_(new internal::AlarmImpl()) { g_gli_initializer.summon(); } -void Alarm::SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag) { +void Alarm::SetInternal(::grpc::CompletionQueue* cq, gpr_timespec deadline, + void* tag) { // Note that we know that alarm_ is actually an internal::AlarmImpl // but we declared it as the base pointer to avoid a forward declaration // or exposing core data structures in the C++ public headers. @@ -145,4 +146,4 @@ Alarm::~Alarm() { } void Alarm::Cancel() { static_cast(alarm_)->Cancel(); } -} // namespace grpc +} // namespace grpc_impl diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 5c19711ee91..a5f817997dc 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -925,6 +925,7 @@ include/grpc/support/thd_id.h \ include/grpc/support/time.h \ include/grpc/support/workaround_list.h \ include/grpcpp/alarm.h \ +include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 72b247c48da..7b10bdc699f 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -926,6 +926,7 @@ include/grpc/support/thd_id.h \ include/grpc/support/time.h \ include/grpc/support/workaround_list.h \ include/grpcpp/alarm.h \ +include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 4d9bbb0f09e..a72e574f1e4 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11431,6 +11431,7 @@ "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", "include/grpcpp/alarm.h", + "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", @@ -11536,6 +11537,7 @@ "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", "include/grpcpp/alarm.h", + "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", From f3caa01bf383077946f1dc2570d382f3aaf79155 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Wed, 12 Dec 2018 09:03:17 -0800 Subject: [PATCH 268/534] monthly update of grpc root certificates --- etc/roots.pem | 272 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 242 insertions(+), 30 deletions(-) diff --git a/etc/roots.pem b/etc/roots.pem index 3e6bbcd76ea..be598710ddd 100644 --- a/etc/roots.pem +++ b/etc/roots.pem @@ -329,36 +329,6 @@ OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS -----END CERTIFICATE----- -# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association -# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association -# Label: "Visa eCommerce Root" -# Serial: 25952180776285836048024890241505565794 -# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02 -# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62 -# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22 ------BEGIN CERTIFICATE----- -MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr -MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl -cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv -bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw -CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h -dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l -cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h -2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E -lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV -ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq -299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t -vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL -dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF -AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR -zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 -LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd -7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw -++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt -398znM/jra6O1I7mT1GvFpLgXPYHDw== ------END CERTIFICATE----- - # Issuer: CN=AAA Certificate Services O=Comodo CA Limited # Subject: CN=AAA Certificate Services O=Comodo CA Limited # Label: "Comodo AAA Services root" @@ -4340,3 +4310,245 @@ rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV 57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 -----END CERTIFICATE----- + +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 146587175971765017618439757810265552097 +# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85 +# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8 +# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX +mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 +zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P +fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc +vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 +Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp +zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO +Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW +k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ +DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF +lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW +Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 +d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z +XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR +gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 +d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv +J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg +DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM ++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy +F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 +SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws +E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R2 O=Google Trust Services LLC +# Subject: CN=GTS Root R2 O=Google Trust Services LLC +# Label: "GTS Root R2" +# Serial: 146587176055767053814479386953112547951 +# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b +# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d +# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg +GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu +XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd +re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu +PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 +mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K +8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj +x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR +nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 +kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok +twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp +8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT +vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT +z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA +pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb +pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB +R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R +RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk +0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC +5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF +izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn +yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC +# Subject: CN=GTS Root R3 O=Google Trust Services LLC +# Label: "GTS Root R3" +# Serial: 146587176140553309517047991083707763997 +# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25 +# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5 +# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5 +-----BEGIN CERTIFICATE----- +MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A +DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk +fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA +njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC +# Subject: CN=GTS Root R4 O=Google Trust Services LLC +# Label: "GTS Root R4" +# Serial: 146587176229350439916519468929765261721 +# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26 +# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb +# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd +-----BEGIN CERTIFICATE----- +MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l +xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 +CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx +sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Global G2 Root O=UniTrust +# Subject: CN=UCA Global G2 Root O=UniTrust +# Label: "UCA Global G2 Root" +# Serial: 124779693093741543919145257850076631279 +# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 +# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a +# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Extended Validation Root O=UniTrust +# Subject: CN=UCA Extended Validation Root O=UniTrust +# Label: "UCA Extended Validation Root" +# Serial: 106100277556486529736699587978573607008 +# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 +# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a +# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- + +# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Label: "Certigna Root CA" +# Serial: 269714418870597844693661054334862075617 +# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 +# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 +# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- From 91e5f7c6474fd3d3939571a9406115ac330821e9 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 12 Dec 2018 09:38:44 -0800 Subject: [PATCH 269/534] Update urllib3 to avoid security vulnerability --- requirements.bazel.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.bazel.txt b/requirements.bazel.txt index 61e529a6ec8..7794aec752e 100644 --- a/requirements.bazel.txt +++ b/requirements.bazel.txt @@ -9,7 +9,7 @@ futures>=2.2.0 google-auth>=1.0.0 oauth2client==4.1.0 requests>=2.14.2 -urllib3==1.22 +urllib3>=1.23 chardet==3.0.4 certifi==2017.4.17 idna==2.7 From ca728e2269ddc69c7aeddd279a9b5dff501c3cbf Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Dec 2018 10:11:43 -0800 Subject: [PATCH 270/534] Revert "Strict check for $config && Enable SC2154" This reverts commit bdfb5691ad7703aee8b28febf45606917be9644e. --- tools/run_tests/dockerize/docker_run_tests.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh index bdcbd88ff9a..5214938208b 100755 --- a/tools/run_tests/dockerize/docker_run_tests.sh +++ b/tools/run_tests/dockerize/docker_run_tests.sh @@ -18,7 +18,8 @@ set -e -export CONFIG=${config:?} +# shellcheck disable=SC2154 +export CONFIG=$config export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer export PATH=$PATH:/usr/bin/llvm-symbolizer From 3d7dce518dc048670cc22b5c19a0aaca69b479d7 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 12 Dec 2018 09:38:44 -0800 Subject: [PATCH 271/534] Update urllib3 to avoid security vulnerability --- requirements.bazel.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.bazel.txt b/requirements.bazel.txt index 61e529a6ec8..7794aec752e 100644 --- a/requirements.bazel.txt +++ b/requirements.bazel.txt @@ -9,7 +9,7 @@ futures>=2.2.0 google-auth>=1.0.0 oauth2client==4.1.0 requests>=2.14.2 -urllib3==1.22 +urllib3>=1.23 chardet==3.0.4 certifi==2017.4.17 idna==2.7 From dbbb38215847d84f7a5544077024d5a21aed5a8d Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Dec 2018 10:24:47 -0800 Subject: [PATCH 272/534] Set CONFIG default value 'opt' --- tools/run_tests/dockerize/docker_run_tests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh index 5214938208b..2a3b6f53efa 100755 --- a/tools/run_tests/dockerize/docker_run_tests.sh +++ b/tools/run_tests/dockerize/docker_run_tests.sh @@ -18,8 +18,7 @@ set -e -# shellcheck disable=SC2154 -export CONFIG=$config +export CONFIG=${config:-opt} export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer export PATH=$PATH:/usr/bin/llvm-symbolizer From 031dfd970384245209b9e6a3b526806f04fa9a59 Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Wed, 12 Dec 2018 11:29:51 -0800 Subject: [PATCH 273/534] Bump version to 1.17.1 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index fb87e824bec..eafa89bbaac 100644 --- a/BUILD +++ b/BUILD @@ -68,7 +68,7 @@ g_stands_for = "gizmo" core_version = "7.0.0" -version = "1.17.1-pre1" +version = "1.17.1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index df1fd85e050..946ffb34ecc 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gizmo - version: 1.17.1-pre1 + version: 1.17.1 filegroups: - name: alts_proto headers: From ac6795a57e05523b8fa220bc5cef26abb876aae5 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 12 Dec 2018 11:40:25 -0800 Subject: [PATCH 274/534] Revert "Changes add a script for generating C code and build rule for protobuf" This reverts commit 62027b7e14624283f758a7785a0a1347eda0a147. --- BUILD | 25 - CMakeLists.txt | 53 - Makefile | 38 +- bazel/grpc_build_system.bzl | 1 - bazel/grpc_deps.bzl | 6 +- build.yaml | 2 - grpc.gyp | 19 - .../upb-generated/google/protobuf/any.upb.c | 24 - .../upb-generated/google/protobuf/any.upb.h | 63 - .../google/protobuf/descriptor.upb.c | 549 ----- .../google/protobuf/descriptor.upb.h | 1879 ----------------- .../google/protobuf/duration.upb.c | 24 - .../google/protobuf/duration.upb.h | 65 - .../google/protobuf/struct.upb.c | 88 - .../google/protobuf/struct.upb.h | 226 -- .../google/protobuf/timestamp.upb.c | 24 - .../google/protobuf/timestamp.upb.h | 65 - .../google/protobuf/wrappers.upb.c | 87 - .../google/protobuf/wrappers.upb.h | 305 --- src/upb/gen_build_yaml.py | 69 - tools/buildgen/generate_build_additions.sh | 1 - tools/codegen/core/gen_upb_api.sh | 38 - tools/distrib/check_copyright.py | 14 - tools/distrib/check_include_guards.py | 14 - .../generated/sources_and_headers.json | 21 - tools/run_tests/sanity/check_port_platform.py | 3 - 26 files changed, 4 insertions(+), 3699 deletions(-) delete mode 100644 src/core/ext/upb-generated/google/protobuf/any.upb.c delete mode 100644 src/core/ext/upb-generated/google/protobuf/any.upb.h delete mode 100644 src/core/ext/upb-generated/google/protobuf/descriptor.upb.c delete mode 100644 src/core/ext/upb-generated/google/protobuf/descriptor.upb.h delete mode 100644 src/core/ext/upb-generated/google/protobuf/duration.upb.c delete mode 100644 src/core/ext/upb-generated/google/protobuf/duration.upb.h delete mode 100644 src/core/ext/upb-generated/google/protobuf/struct.upb.c delete mode 100644 src/core/ext/upb-generated/google/protobuf/struct.upb.h delete mode 100644 src/core/ext/upb-generated/google/protobuf/timestamp.upb.c delete mode 100644 src/core/ext/upb-generated/google/protobuf/timestamp.upb.h delete mode 100644 src/core/ext/upb-generated/google/protobuf/wrappers.upb.c delete mode 100644 src/core/ext/upb-generated/google/protobuf/wrappers.upb.h delete mode 100755 src/upb/gen_build_yaml.py delete mode 100755 tools/codegen/core/gen_upb_api.sh diff --git a/BUILD b/BUILD index 034e47d1a92..5550e583a87 100644 --- a/BUILD +++ b/BUILD @@ -2274,29 +2274,4 @@ grpc_cc_library( ], ) -# TODO: Get this into build.yaml once we start using it. -grpc_cc_library( - name = "google_protobuf", - srcs = [ - "src/core/ext/upb-generated/google/protobuf/any.upb.c", - "src/core/ext/upb-generated/google/protobuf/descriptor.upb.c", - "src/core/ext/upb-generated/google/protobuf/duration.upb.c", - "src/core/ext/upb-generated/google/protobuf/struct.upb.c", - "src/core/ext/upb-generated/google/protobuf/timestamp.upb.c", - "src/core/ext/upb-generated/google/protobuf/wrappers.upb.c", - ], - hdrs = [ - "src/core/ext/upb-generated/google/protobuf/any.upb.h", - "src/core/ext/upb-generated/google/protobuf/descriptor.upb.h", - "src/core/ext/upb-generated/google/protobuf/duration.upb.h", - "src/core/ext/upb-generated/google/protobuf/struct.upb.h", - "src/core/ext/upb-generated/google/protobuf/timestamp.upb.h", - "src/core/ext/upb-generated/google/protobuf/wrappers.upb.h", - ], - language = "c++", - external_deps = [ - "upb_lib", - ], -) - grpc_generate_one_off_targets() diff --git a/CMakeLists.txt b/CMakeLists.txt index 08240fe82b4..9c660c77012 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5478,59 +5478,6 @@ endif() endif (gRPC_BUILD_CSHARP_EXT) if (gRPC_BUILD_TESTS) -add_library(upb - third_party/upb/google/protobuf/descriptor.upb.c - third_party/upb/upb/decode.c - third_party/upb/upb/def.c - third_party/upb/upb/encode.c - third_party/upb/upb/handlers.c - third_party/upb/upb/msg.c - third_party/upb/upb/msgfactory.c - third_party/upb/upb/refcounted.c - third_party/upb/upb/sink.c - third_party/upb/upb/table.c - third_party/upb/upb/upb.c -) - -if(WIN32 AND MSVC) - set_target_properties(upb PROPERTIES COMPILE_PDB_NAME "upb" - COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" - ) - if (gRPC_INSTALL) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/upb.pdb - DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL - ) - endif() -endif() - - -target_include_directories(upb - PUBLIC $ $ - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${_gRPC_SSL_INCLUDE_DIR} - PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} - PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} - PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} - PRIVATE ${_gRPC_CARES_INCLUDE_DIR} - PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} - PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} -) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(upb PROPERTIES LINKER_LANGUAGE C) - # only use the flags for C++ source files - target_compile_options(upb PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() -target_link_libraries(upb - ${_gRPC_SSL_LIBRARIES} - ${_gRPC_ALLTARGETS_LIBRARIES} -) - - -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - add_library(bad_client_test test/core/bad_client/bad_client.cc ) diff --git a/Makefile b/Makefile index 950ac75695d..0163dc414a5 100644 --- a/Makefile +++ b/Makefile @@ -1411,7 +1411,7 @@ plugins: $(PROTOC_PLUGINS) privatelibs: privatelibs_c privatelibs_cxx -privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libupb.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a +privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc @@ -10117,42 +10117,6 @@ ifneq ($(NO_DEPS),true) endif -LIBUPB_SRC = \ - third_party/upb/google/protobuf/descriptor.upb.c \ - third_party/upb/upb/decode.c \ - third_party/upb/upb/def.c \ - third_party/upb/upb/encode.c \ - third_party/upb/upb/handlers.c \ - third_party/upb/upb/msg.c \ - third_party/upb/upb/msgfactory.c \ - third_party/upb/upb/refcounted.c \ - third_party/upb/upb/sink.c \ - third_party/upb/upb/table.c \ - third_party/upb/upb/upb.c \ - -PUBLIC_HEADERS_C += \ - -LIBUPB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBUPB_SRC)))) - -$(LIBUPB_OBJS): CFLAGS += -Ithird_party/upb -Wno-sign-conversion -Wno-shadow -Wno-conversion -Wno-implicit-fallthrough - -$(LIBDIR)/$(CONFIG)/libupb.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(LIBUPB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libupb.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libupb.a $(LIBUPB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libupb.a -endif - - - - -ifneq ($(NO_DEPS),true) --include $(LIBUPB_OBJS:.o=.dep) -endif - - LIBZ_SRC = \ third_party/zlib/adler32.c \ third_party/zlib/compress.c \ diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 06b05f79525..65fe5a10aa2 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -99,7 +99,6 @@ def grpc_cc_library( linkopts = if_not_windows(["-pthread"]), includes = [ "include", - "src/core/ext/upb-generated", ], alwayslink = alwayslink, data = data, diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 2738e39abf7..3eacd2b0475 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -12,7 +12,7 @@ def grpc_deps(): ) native.bind( - name = "upb_lib", + name = "upblib", actual = "@upb//:upb", ) @@ -195,8 +195,8 @@ def grpc_deps(): if "upb" not in native.existing_rules(): http_archive( name = "upb", - strip_prefix = "upb-fb6f7e96895c3a9a8ae2e66516160937e7ac1779", - url = "https://github.com/google/upb/archive/fb6f7e96895c3a9a8ae2e66516160937e7ac1779.tar.gz", + strip_prefix = "upb-9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3", + url = "https://github.com/google/upb/archive/9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3.tar.gz", ) diff --git a/build.yaml b/build.yaml index b8c2fa6b020..4521169e6c1 100644 --- a/build.yaml +++ b/build.yaml @@ -5896,8 +5896,6 @@ defaults: -Wno-deprecated-declarations -Ithird_party/nanopb -DPB_FIELD_32BIT CXXFLAGS: -Wnon-virtual-dtor LDFLAGS: -g - upb: - CFLAGS: -Ithird_party/upb -Wno-sign-conversion -Wno-shadow -Wno-conversion -Wno-implicit-fallthrough zlib: CFLAGS: -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration -Wno-implicit-fallthrough $(W_NO_SHIFT_NEGATIVE_VALUE) -fvisibility=hidden diff --git a/grpc.gyp b/grpc.gyp index d03c74d8dc1..00f06a1e54e 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -2640,25 +2640,6 @@ 'third_party/benchmark/src/timers.cc', ], }, - { - 'target_name': 'upb', - 'type': 'static_library', - 'dependencies': [ - ], - 'sources': [ - 'third_party/upb/google/protobuf/descriptor.upb.c', - 'third_party/upb/upb/decode.c', - 'third_party/upb/upb/def.c', - 'third_party/upb/upb/encode.c', - 'third_party/upb/upb/handlers.c', - 'third_party/upb/upb/msg.c', - 'third_party/upb/upb/msgfactory.c', - 'third_party/upb/upb/refcounted.c', - 'third_party/upb/upb/sink.c', - 'third_party/upb/upb/table.c', - 'third_party/upb/upb/upb.c', - ], - }, { 'target_name': 'z', 'type': 'static_library', diff --git a/src/core/ext/upb-generated/google/protobuf/any.upb.c b/src/core/ext/upb-generated/google/protobuf/any.upb.c deleted file mode 100644 index 1005a48e909..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/any.upb.c +++ /dev/null @@ -1,24 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/any.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#include "google/protobuf/any.upb.h" -#include -#include "upb/msg.h" - -#include "upb/port_def.inc" - -static const upb_msglayout_field google_protobuf_Any__fields[2] = { - {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, - {2, UPB_SIZE(8, 16), 0, 0, 12, 1}, -}; - -const upb_msglayout google_protobuf_Any_msginit = { - NULL, &google_protobuf_Any__fields[0], UPB_SIZE(16, 32), 2, false, -}; - -#include "upb/port_undef.inc" diff --git a/src/core/ext/upb-generated/google/protobuf/any.upb.h b/src/core/ext/upb-generated/google/protobuf/any.upb.h deleted file mode 100644 index d29265553f7..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/any.upb.h +++ /dev/null @@ -1,63 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/any.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#ifndef GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ -#define GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ - -#include "upb/msg.h" - -#include "upb/decode.h" -#include "upb/encode.h" -#include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C - -struct google_protobuf_Any; -typedef struct google_protobuf_Any google_protobuf_Any; - -/* Enums */ - -/* google.protobuf.Any */ - -extern const upb_msglayout google_protobuf_Any_msginit; -UPB_INLINE google_protobuf_Any* google_protobuf_Any_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_Any_msginit, arena); -} -UPB_INLINE google_protobuf_Any* google_protobuf_Any_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_Any* ret = google_protobuf_Any_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_Any_msginit)) ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_Any_serialize(const google_protobuf_Any* msg, - upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_Any_msginit, arena, len); -} - -UPB_INLINE upb_stringview -google_protobuf_Any_type_url(const google_protobuf_Any* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); -} -UPB_INLINE upb_stringview -google_protobuf_Any_value(const google_protobuf_Any* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} - -UPB_INLINE void google_protobuf_Any_set_type_url(google_protobuf_Any* msg, - upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; -} -UPB_INLINE void google_protobuf_Any_set_value(google_protobuf_Any* msg, - upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} - -UPB_END_EXTERN_C - -#include "upb/port_undef.inc" - -#endif /* GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c deleted file mode 100644 index f774873d614..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c +++ /dev/null @@ -1,549 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/descriptor.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#include "google/protobuf/descriptor.upb.h" -#include -#include "upb/msg.h" - -#include "upb/port_def.inc" - -static const upb_msglayout* const google_protobuf_FileDescriptorSet_submsgs[1] = - { - &google_protobuf_FileDescriptorProto_msginit, -}; - -static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = - { - {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_FileDescriptorSet_msginit = { - &google_protobuf_FileDescriptorSet_submsgs[0], - &google_protobuf_FileDescriptorSet__fields[0], - UPB_SIZE(4, 8), - 1, - false, -}; - -static const upb_msglayout* const - google_protobuf_FileDescriptorProto_submsgs[6] = { - &google_protobuf_DescriptorProto_msginit, - &google_protobuf_EnumDescriptorProto_msginit, - &google_protobuf_FieldDescriptorProto_msginit, - &google_protobuf_FileOptions_msginit, - &google_protobuf_ServiceDescriptorProto_msginit, - &google_protobuf_SourceCodeInfo_msginit, -}; - -static const upb_msglayout_field - google_protobuf_FileDescriptorProto__fields[12] = { - {1, UPB_SIZE(8, 16), 1, 0, 9, 1}, - {2, UPB_SIZE(16, 32), 2, 0, 9, 1}, - {3, UPB_SIZE(40, 80), 0, 0, 9, 3}, - {4, UPB_SIZE(44, 88), 0, 0, 11, 3}, - {5, UPB_SIZE(48, 96), 0, 1, 11, 3}, - {6, UPB_SIZE(52, 104), 0, 4, 11, 3}, - {7, UPB_SIZE(56, 112), 0, 2, 11, 3}, - {8, UPB_SIZE(32, 64), 4, 3, 11, 1}, - {9, UPB_SIZE(36, 72), 5, 5, 11, 1}, - {10, UPB_SIZE(60, 120), 0, 0, 5, 3}, - {11, UPB_SIZE(64, 128), 0, 0, 5, 3}, - {12, UPB_SIZE(24, 48), 3, 0, 9, 1}, -}; - -const upb_msglayout google_protobuf_FileDescriptorProto_msginit = { - &google_protobuf_FileDescriptorProto_submsgs[0], - &google_protobuf_FileDescriptorProto__fields[0], - UPB_SIZE(72, 144), - 12, - false, -}; - -static const upb_msglayout* const google_protobuf_DescriptorProto_submsgs[8] = { - &google_protobuf_DescriptorProto_msginit, - &google_protobuf_DescriptorProto_ExtensionRange_msginit, - &google_protobuf_DescriptorProto_ReservedRange_msginit, - &google_protobuf_EnumDescriptorProto_msginit, - &google_protobuf_FieldDescriptorProto_msginit, - &google_protobuf_MessageOptions_msginit, - &google_protobuf_OneofDescriptorProto_msginit, -}; - -static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = { - {1, UPB_SIZE(8, 16), 1, 0, 9, 1}, {2, UPB_SIZE(20, 40), 0, 4, 11, 3}, - {3, UPB_SIZE(24, 48), 0, 0, 11, 3}, {4, UPB_SIZE(28, 56), 0, 3, 11, 3}, - {5, UPB_SIZE(32, 64), 0, 1, 11, 3}, {6, UPB_SIZE(36, 72), 0, 4, 11, 3}, - {7, UPB_SIZE(16, 32), 2, 5, 11, 1}, {8, UPB_SIZE(40, 80), 0, 6, 11, 3}, - {9, UPB_SIZE(44, 88), 0, 2, 11, 3}, {10, UPB_SIZE(48, 96), 0, 0, 9, 3}, -}; - -const upb_msglayout google_protobuf_DescriptorProto_msginit = { - &google_protobuf_DescriptorProto_submsgs[0], - &google_protobuf_DescriptorProto__fields[0], - UPB_SIZE(56, 112), - 10, - false, -}; - -static const upb_msglayout* const - google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = { - &google_protobuf_ExtensionRangeOptions_msginit, -}; - -static const upb_msglayout_field - google_protobuf_DescriptorProto_ExtensionRange__fields[3] = { - {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, - {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, - {3, UPB_SIZE(12, 16), 3, 0, 11, 1}, -}; - -const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = { - &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0], - &google_protobuf_DescriptorProto_ExtensionRange__fields[0], - UPB_SIZE(16, 24), - 3, - false, -}; - -static const upb_msglayout_field - google_protobuf_DescriptorProto_ReservedRange__fields[2] = { - {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, - {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, -}; - -const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = { - NULL, - &google_protobuf_DescriptorProto_ReservedRange__fields[0], - UPB_SIZE(12, 12), - 2, - false, -}; - -static const upb_msglayout* const - google_protobuf_ExtensionRangeOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, -}; - -static const upb_msglayout_field - google_protobuf_ExtensionRangeOptions__fields[1] = { - {999, UPB_SIZE(0, 0), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = { - &google_protobuf_ExtensionRangeOptions_submsgs[0], - &google_protobuf_ExtensionRangeOptions__fields[0], - UPB_SIZE(4, 8), - 1, - false, -}; - -static const upb_msglayout* const - google_protobuf_FieldDescriptorProto_submsgs[1] = { - &google_protobuf_FieldOptions_msginit, -}; - -static const upb_msglayout_field - google_protobuf_FieldDescriptorProto__fields[10] = { - {1, UPB_SIZE(32, 32), 5, 0, 9, 1}, - {2, UPB_SIZE(40, 48), 6, 0, 9, 1}, - {3, UPB_SIZE(24, 24), 3, 0, 5, 1}, - {4, UPB_SIZE(8, 8), 1, 0, 14, 1}, - {5, UPB_SIZE(16, 16), 2, 0, 14, 1}, - {6, UPB_SIZE(48, 64), 7, 0, 9, 1}, - {7, UPB_SIZE(56, 80), 8, 0, 9, 1}, - {8, UPB_SIZE(72, 112), 10, 0, 11, 1}, - {9, UPB_SIZE(28, 28), 4, 0, 5, 1}, - {10, UPB_SIZE(64, 96), 9, 0, 9, 1}, -}; - -const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = { - &google_protobuf_FieldDescriptorProto_submsgs[0], - &google_protobuf_FieldDescriptorProto__fields[0], - UPB_SIZE(80, 128), - 10, - false, -}; - -static const upb_msglayout* const - google_protobuf_OneofDescriptorProto_submsgs[1] = { - &google_protobuf_OneofOptions_msginit, -}; - -static const upb_msglayout_field - google_protobuf_OneofDescriptorProto__fields[2] = { - {1, UPB_SIZE(8, 16), 1, 0, 9, 1}, - {2, UPB_SIZE(16, 32), 2, 0, 11, 1}, -}; - -const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = { - &google_protobuf_OneofDescriptorProto_submsgs[0], - &google_protobuf_OneofDescriptorProto__fields[0], - UPB_SIZE(24, 48), - 2, - false, -}; - -static const upb_msglayout* const - google_protobuf_EnumDescriptorProto_submsgs[3] = { - &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, - &google_protobuf_EnumOptions_msginit, - &google_protobuf_EnumValueDescriptorProto_msginit, -}; - -static const upb_msglayout_field - google_protobuf_EnumDescriptorProto__fields[5] = { - {1, UPB_SIZE(8, 16), 1, 0, 9, 1}, {2, UPB_SIZE(20, 40), 0, 2, 11, 3}, - {3, UPB_SIZE(16, 32), 2, 1, 11, 1}, {4, UPB_SIZE(24, 48), 0, 0, 11, 3}, - {5, UPB_SIZE(28, 56), 0, 0, 9, 3}, -}; - -const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = { - &google_protobuf_EnumDescriptorProto_submsgs[0], - &google_protobuf_EnumDescriptorProto__fields[0], - UPB_SIZE(32, 64), - 5, - false, -}; - -static const upb_msglayout_field - google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = { - {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, - {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, -}; - -const upb_msglayout - google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = { - NULL, - &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0], - UPB_SIZE(12, 12), - 2, - false, -}; - -static const upb_msglayout* const - google_protobuf_EnumValueDescriptorProto_submsgs[1] = { - &google_protobuf_EnumValueOptions_msginit, -}; - -static const upb_msglayout_field - google_protobuf_EnumValueDescriptorProto__fields[3] = { - {1, UPB_SIZE(8, 16), 2, 0, 9, 1}, - {2, UPB_SIZE(4, 4), 1, 0, 5, 1}, - {3, UPB_SIZE(16, 32), 3, 0, 11, 1}, -}; - -const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = { - &google_protobuf_EnumValueDescriptorProto_submsgs[0], - &google_protobuf_EnumValueDescriptorProto__fields[0], - UPB_SIZE(24, 48), - 3, - false, -}; - -static const upb_msglayout* const - google_protobuf_ServiceDescriptorProto_submsgs[2] = { - &google_protobuf_MethodDescriptorProto_msginit, - &google_protobuf_ServiceOptions_msginit, -}; - -static const upb_msglayout_field - google_protobuf_ServiceDescriptorProto__fields[3] = { - {1, UPB_SIZE(8, 16), 1, 0, 9, 1}, - {2, UPB_SIZE(20, 40), 0, 0, 11, 3}, - {3, UPB_SIZE(16, 32), 2, 1, 11, 1}, -}; - -const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = { - &google_protobuf_ServiceDescriptorProto_submsgs[0], - &google_protobuf_ServiceDescriptorProto__fields[0], - UPB_SIZE(24, 48), - 3, - false, -}; - -static const upb_msglayout* const - google_protobuf_MethodDescriptorProto_submsgs[1] = { - &google_protobuf_MethodOptions_msginit, -}; - -static const upb_msglayout_field - google_protobuf_MethodDescriptorProto__fields[6] = { - {1, UPB_SIZE(8, 16), 3, 0, 9, 1}, {2, UPB_SIZE(16, 32), 4, 0, 9, 1}, - {3, UPB_SIZE(24, 48), 5, 0, 9, 1}, {4, UPB_SIZE(32, 64), 6, 0, 11, 1}, - {5, UPB_SIZE(1, 1), 1, 0, 8, 1}, {6, UPB_SIZE(2, 2), 2, 0, 8, 1}, -}; - -const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = { - &google_protobuf_MethodDescriptorProto_submsgs[0], - &google_protobuf_MethodDescriptorProto__fields[0], - UPB_SIZE(40, 80), - 6, - false, -}; - -static const upb_msglayout* const google_protobuf_FileOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, -}; - -static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = { - {1, UPB_SIZE(32, 32), 11, 0, 9, 1}, - {8, UPB_SIZE(40, 48), 12, 0, 9, 1}, - {9, UPB_SIZE(8, 8), 1, 0, 14, 1}, - {10, UPB_SIZE(16, 16), 2, 0, 8, 1}, - {11, UPB_SIZE(48, 64), 13, 0, 9, 1}, - {16, UPB_SIZE(17, 17), 3, 0, 8, 1}, - {17, UPB_SIZE(18, 18), 4, 0, 8, 1}, - {18, UPB_SIZE(19, 19), 5, 0, 8, 1}, - {20, UPB_SIZE(20, 20), 6, 0, 8, 1}, - {23, UPB_SIZE(21, 21), 7, 0, 8, 1}, - {27, UPB_SIZE(22, 22), 8, 0, 8, 1}, - {31, UPB_SIZE(23, 23), 9, 0, 8, 1}, - {36, UPB_SIZE(56, 80), 14, 0, 9, 1}, - {37, UPB_SIZE(64, 96), 15, 0, 9, 1}, - {39, UPB_SIZE(72, 112), 16, 0, 9, 1}, - {40, UPB_SIZE(80, 128), 17, 0, 9, 1}, - {41, UPB_SIZE(88, 144), 18, 0, 9, 1}, - {42, UPB_SIZE(24, 24), 10, 0, 8, 1}, - {44, UPB_SIZE(96, 160), 19, 0, 9, 1}, - {45, UPB_SIZE(104, 176), 20, 0, 9, 1}, - {999, UPB_SIZE(112, 192), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_FileOptions_msginit = { - &google_protobuf_FileOptions_submsgs[0], - &google_protobuf_FileOptions__fields[0], - UPB_SIZE(120, 208), - 21, - false, -}; - -static const upb_msglayout* const google_protobuf_MessageOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, -}; - -static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = { - {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, {2, UPB_SIZE(2, 2), 2, 0, 8, 1}, - {3, UPB_SIZE(3, 3), 3, 0, 8, 1}, {7, UPB_SIZE(4, 4), 4, 0, 8, 1}, - {999, UPB_SIZE(8, 8), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_MessageOptions_msginit = { - &google_protobuf_MessageOptions_submsgs[0], - &google_protobuf_MessageOptions__fields[0], - UPB_SIZE(12, 16), - 5, - false, -}; - -static const upb_msglayout* const google_protobuf_FieldOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, -}; - -static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = { - {1, UPB_SIZE(8, 8), 1, 0, 14, 1}, {2, UPB_SIZE(24, 24), 3, 0, 8, 1}, - {3, UPB_SIZE(25, 25), 4, 0, 8, 1}, {5, UPB_SIZE(26, 26), 5, 0, 8, 1}, - {6, UPB_SIZE(16, 16), 2, 0, 14, 1}, {10, UPB_SIZE(27, 27), 6, 0, 8, 1}, - {999, UPB_SIZE(28, 32), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_FieldOptions_msginit = { - &google_protobuf_FieldOptions_submsgs[0], - &google_protobuf_FieldOptions__fields[0], - UPB_SIZE(32, 40), - 7, - false, -}; - -static const upb_msglayout* const google_protobuf_OneofOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, -}; - -static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = { - {999, UPB_SIZE(0, 0), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_OneofOptions_msginit = { - &google_protobuf_OneofOptions_submsgs[0], - &google_protobuf_OneofOptions__fields[0], - UPB_SIZE(4, 8), - 1, - false, -}; - -static const upb_msglayout* const google_protobuf_EnumOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, -}; - -static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = { - {2, UPB_SIZE(1, 1), 1, 0, 8, 1}, - {3, UPB_SIZE(2, 2), 2, 0, 8, 1}, - {999, UPB_SIZE(4, 8), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_EnumOptions_msginit = { - &google_protobuf_EnumOptions_submsgs[0], - &google_protobuf_EnumOptions__fields[0], - UPB_SIZE(8, 16), - 3, - false, -}; - -static const upb_msglayout* const google_protobuf_EnumValueOptions_submsgs[1] = - { - &google_protobuf_UninterpretedOption_msginit, -}; - -static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = { - {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, - {999, UPB_SIZE(4, 8), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_EnumValueOptions_msginit = { - &google_protobuf_EnumValueOptions_submsgs[0], - &google_protobuf_EnumValueOptions__fields[0], - UPB_SIZE(8, 16), - 2, - false, -}; - -static const upb_msglayout* const google_protobuf_ServiceOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, -}; - -static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = { - {33, UPB_SIZE(1, 1), 1, 0, 8, 1}, - {999, UPB_SIZE(4, 8), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_ServiceOptions_msginit = { - &google_protobuf_ServiceOptions_submsgs[0], - &google_protobuf_ServiceOptions__fields[0], - UPB_SIZE(8, 16), - 2, - false, -}; - -static const upb_msglayout* const google_protobuf_MethodOptions_submsgs[1] = { - &google_protobuf_UninterpretedOption_msginit, -}; - -static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = { - {33, UPB_SIZE(16, 16), 2, 0, 8, 1}, - {34, UPB_SIZE(8, 8), 1, 0, 14, 1}, - {999, UPB_SIZE(20, 24), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_MethodOptions_msginit = { - &google_protobuf_MethodOptions_submsgs[0], - &google_protobuf_MethodOptions__fields[0], - UPB_SIZE(24, 32), - 3, - false, -}; - -static const upb_msglayout* const - google_protobuf_UninterpretedOption_submsgs[1] = { - &google_protobuf_UninterpretedOption_NamePart_msginit, -}; - -static const upb_msglayout_field - google_protobuf_UninterpretedOption__fields[7] = { - {2, UPB_SIZE(56, 80), 0, 0, 11, 3}, {3, UPB_SIZE(32, 32), 4, 0, 9, 1}, - {4, UPB_SIZE(8, 8), 1, 0, 4, 1}, {5, UPB_SIZE(16, 16), 2, 0, 3, 1}, - {6, UPB_SIZE(24, 24), 3, 0, 1, 1}, {7, UPB_SIZE(40, 48), 5, 0, 12, 1}, - {8, UPB_SIZE(48, 64), 6, 0, 9, 1}, -}; - -const upb_msglayout google_protobuf_UninterpretedOption_msginit = { - &google_protobuf_UninterpretedOption_submsgs[0], - &google_protobuf_UninterpretedOption__fields[0], - UPB_SIZE(64, 96), - 7, - false, -}; - -static const upb_msglayout_field - google_protobuf_UninterpretedOption_NamePart__fields[2] = { - {1, UPB_SIZE(8, 16), 2, 0, 9, 2}, - {2, UPB_SIZE(1, 1), 1, 0, 8, 2}, -}; - -const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = { - NULL, - &google_protobuf_UninterpretedOption_NamePart__fields[0], - UPB_SIZE(16, 32), - 2, - false, -}; - -static const upb_msglayout* const google_protobuf_SourceCodeInfo_submsgs[1] = { - &google_protobuf_SourceCodeInfo_Location_msginit, -}; - -static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_SourceCodeInfo_msginit = { - &google_protobuf_SourceCodeInfo_submsgs[0], - &google_protobuf_SourceCodeInfo__fields[0], - UPB_SIZE(4, 8), - 1, - false, -}; - -static const upb_msglayout_field - google_protobuf_SourceCodeInfo_Location__fields[5] = { - {1, UPB_SIZE(24, 48), 0, 0, 5, 3}, {2, UPB_SIZE(28, 56), 0, 0, 5, 3}, - {3, UPB_SIZE(8, 16), 1, 0, 9, 1}, {4, UPB_SIZE(16, 32), 2, 0, 9, 1}, - {6, UPB_SIZE(32, 64), 0, 0, 9, 3}, -}; - -const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = { - NULL, - &google_protobuf_SourceCodeInfo_Location__fields[0], - UPB_SIZE(40, 80), - 5, - false, -}; - -static const upb_msglayout* const google_protobuf_GeneratedCodeInfo_submsgs[1] = - { - &google_protobuf_GeneratedCodeInfo_Annotation_msginit, -}; - -static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = - { - {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = { - &google_protobuf_GeneratedCodeInfo_submsgs[0], - &google_protobuf_GeneratedCodeInfo__fields[0], - UPB_SIZE(4, 8), - 1, - false, -}; - -static const upb_msglayout_field - google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = { - {1, UPB_SIZE(24, 32), 0, 0, 5, 3}, - {2, UPB_SIZE(16, 16), 3, 0, 9, 1}, - {3, UPB_SIZE(4, 4), 1, 0, 5, 1}, - {4, UPB_SIZE(8, 8), 2, 0, 5, 1}, -}; - -const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = { - NULL, - &google_protobuf_GeneratedCodeInfo_Annotation__fields[0], - UPB_SIZE(32, 48), - 4, - false, -}; - -#include "upb/port_undef.inc" diff --git a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h deleted file mode 100644 index 37f0139ce32..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h +++ /dev/null @@ -1,1879 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/descriptor.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ -#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ - -#include "upb/msg.h" - -#include "upb/decode.h" -#include "upb/encode.h" -#include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C - -struct google_protobuf_FileDescriptorSet; -struct google_protobuf_FileDescriptorProto; -struct google_protobuf_DescriptorProto; -struct google_protobuf_DescriptorProto_ExtensionRange; -struct google_protobuf_DescriptorProto_ReservedRange; -struct google_protobuf_ExtensionRangeOptions; -struct google_protobuf_FieldDescriptorProto; -struct google_protobuf_OneofDescriptorProto; -struct google_protobuf_EnumDescriptorProto; -struct google_protobuf_EnumDescriptorProto_EnumReservedRange; -struct google_protobuf_EnumValueDescriptorProto; -struct google_protobuf_ServiceDescriptorProto; -struct google_protobuf_MethodDescriptorProto; -struct google_protobuf_FileOptions; -struct google_protobuf_MessageOptions; -struct google_protobuf_FieldOptions; -struct google_protobuf_OneofOptions; -struct google_protobuf_EnumOptions; -struct google_protobuf_EnumValueOptions; -struct google_protobuf_ServiceOptions; -struct google_protobuf_MethodOptions; -struct google_protobuf_UninterpretedOption; -struct google_protobuf_UninterpretedOption_NamePart; -struct google_protobuf_SourceCodeInfo; -struct google_protobuf_SourceCodeInfo_Location; -struct google_protobuf_GeneratedCodeInfo; -struct google_protobuf_GeneratedCodeInfo_Annotation; -typedef struct google_protobuf_FileDescriptorSet - google_protobuf_FileDescriptorSet; -typedef struct google_protobuf_FileDescriptorProto - google_protobuf_FileDescriptorProto; -typedef struct google_protobuf_DescriptorProto google_protobuf_DescriptorProto; -typedef struct google_protobuf_DescriptorProto_ExtensionRange - google_protobuf_DescriptorProto_ExtensionRange; -typedef struct google_protobuf_DescriptorProto_ReservedRange - google_protobuf_DescriptorProto_ReservedRange; -typedef struct google_protobuf_ExtensionRangeOptions - google_protobuf_ExtensionRangeOptions; -typedef struct google_protobuf_FieldDescriptorProto - google_protobuf_FieldDescriptorProto; -typedef struct google_protobuf_OneofDescriptorProto - google_protobuf_OneofDescriptorProto; -typedef struct google_protobuf_EnumDescriptorProto - google_protobuf_EnumDescriptorProto; -typedef struct google_protobuf_EnumDescriptorProto_EnumReservedRange - google_protobuf_EnumDescriptorProto_EnumReservedRange; -typedef struct google_protobuf_EnumValueDescriptorProto - google_protobuf_EnumValueDescriptorProto; -typedef struct google_protobuf_ServiceDescriptorProto - google_protobuf_ServiceDescriptorProto; -typedef struct google_protobuf_MethodDescriptorProto - google_protobuf_MethodDescriptorProto; -typedef struct google_protobuf_FileOptions google_protobuf_FileOptions; -typedef struct google_protobuf_MessageOptions google_protobuf_MessageOptions; -typedef struct google_protobuf_FieldOptions google_protobuf_FieldOptions; -typedef struct google_protobuf_OneofOptions google_protobuf_OneofOptions; -typedef struct google_protobuf_EnumOptions google_protobuf_EnumOptions; -typedef struct google_protobuf_EnumValueOptions - google_protobuf_EnumValueOptions; -typedef struct google_protobuf_ServiceOptions google_protobuf_ServiceOptions; -typedef struct google_protobuf_MethodOptions google_protobuf_MethodOptions; -typedef struct google_protobuf_UninterpretedOption - google_protobuf_UninterpretedOption; -typedef struct google_protobuf_UninterpretedOption_NamePart - google_protobuf_UninterpretedOption_NamePart; -typedef struct google_protobuf_SourceCodeInfo google_protobuf_SourceCodeInfo; -typedef struct google_protobuf_SourceCodeInfo_Location - google_protobuf_SourceCodeInfo_Location; -typedef struct google_protobuf_GeneratedCodeInfo - google_protobuf_GeneratedCodeInfo; -typedef struct google_protobuf_GeneratedCodeInfo_Annotation - google_protobuf_GeneratedCodeInfo_Annotation; - -/* Enums */ - -typedef enum { - google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, - google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2, - google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3 -} google_protobuf_FieldDescriptorProto_Label; - -typedef enum { - google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1, - google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2, - google_protobuf_FieldDescriptorProto_TYPE_INT64 = 3, - google_protobuf_FieldDescriptorProto_TYPE_UINT64 = 4, - google_protobuf_FieldDescriptorProto_TYPE_INT32 = 5, - google_protobuf_FieldDescriptorProto_TYPE_FIXED64 = 6, - google_protobuf_FieldDescriptorProto_TYPE_FIXED32 = 7, - google_protobuf_FieldDescriptorProto_TYPE_BOOL = 8, - google_protobuf_FieldDescriptorProto_TYPE_STRING = 9, - google_protobuf_FieldDescriptorProto_TYPE_GROUP = 10, - google_protobuf_FieldDescriptorProto_TYPE_MESSAGE = 11, - google_protobuf_FieldDescriptorProto_TYPE_BYTES = 12, - google_protobuf_FieldDescriptorProto_TYPE_UINT32 = 13, - google_protobuf_FieldDescriptorProto_TYPE_ENUM = 14, - google_protobuf_FieldDescriptorProto_TYPE_SFIXED32 = 15, - google_protobuf_FieldDescriptorProto_TYPE_SFIXED64 = 16, - google_protobuf_FieldDescriptorProto_TYPE_SINT32 = 17, - google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18 -} google_protobuf_FieldDescriptorProto_Type; - -typedef enum { - google_protobuf_FieldOptions_STRING = 0, - google_protobuf_FieldOptions_CORD = 1, - google_protobuf_FieldOptions_STRING_PIECE = 2 -} google_protobuf_FieldOptions_CType; - -typedef enum { - google_protobuf_FieldOptions_JS_NORMAL = 0, - google_protobuf_FieldOptions_JS_STRING = 1, - google_protobuf_FieldOptions_JS_NUMBER = 2 -} google_protobuf_FieldOptions_JSType; - -typedef enum { - google_protobuf_FileOptions_SPEED = 1, - google_protobuf_FileOptions_CODE_SIZE = 2, - google_protobuf_FileOptions_LITE_RUNTIME = 3 -} google_protobuf_FileOptions_OptimizeMode; - -typedef enum { - google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0, - google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1, - google_protobuf_MethodOptions_IDEMPOTENT = 2 -} google_protobuf_MethodOptions_IdempotencyLevel; - -/* google.protobuf.FileDescriptorSet */ - -extern const upb_msglayout google_protobuf_FileDescriptorSet_msginit; -UPB_INLINE google_protobuf_FileDescriptorSet* -google_protobuf_FileDescriptorSet_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_FileDescriptorSet_msginit, arena); -} -UPB_INLINE google_protobuf_FileDescriptorSet* -google_protobuf_FileDescriptorSet_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_FileDescriptorSet* ret = - google_protobuf_FileDescriptorSet_new(arena); - return (ret && - upb_decode(buf, ret, &google_protobuf_FileDescriptorSet_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_FileDescriptorSet_serialize( - const google_protobuf_FileDescriptorSet* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, arena, - len); -} - -UPB_INLINE const upb_array* google_protobuf_FileDescriptorSet_file( - const google_protobuf_FileDescriptorSet* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_FileDescriptorSet_set_file( - google_protobuf_FileDescriptorSet* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.FileDescriptorProto */ - -extern const upb_msglayout google_protobuf_FileDescriptorProto_msginit; -UPB_INLINE google_protobuf_FileDescriptorProto* -google_protobuf_FileDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_FileDescriptorProto* -google_protobuf_FileDescriptorProto_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_FileDescriptorProto* ret = - google_protobuf_FileDescriptorProto_new(arena); - return (ret && - upb_decode(buf, ret, &google_protobuf_FileDescriptorProto_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_FileDescriptorProto_serialize( - const google_protobuf_FileDescriptorProto* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_FileDescriptorProto_msginit, arena, - len); -} - -UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_name( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_package( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); -} -UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_dependency( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(40, 80)); -} -UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_message_type( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(44, 88)); -} -UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_enum_type( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(48, 96)); -} -UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_service( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(52, 104)); -} -UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_extension( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(56, 112)); -} -UPB_INLINE const google_protobuf_FileOptions* -google_protobuf_FileDescriptorProto_options( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const google_protobuf_FileOptions*, - UPB_SIZE(32, 64)); -} -UPB_INLINE const google_protobuf_SourceCodeInfo* -google_protobuf_FileDescriptorProto_source_code_info( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const google_protobuf_SourceCodeInfo*, - UPB_SIZE(36, 72)); -} -UPB_INLINE const upb_array* -google_protobuf_FileDescriptorProto_public_dependency( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(60, 120)); -} -UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_weak_dependency( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(64, 128)); -} -UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_syntax( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)); -} - -UPB_INLINE void google_protobuf_FileDescriptorProto_set_name( - google_protobuf_FileDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_package( - google_protobuf_FileDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_dependency( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(40, 80)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_message_type( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(44, 88)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_enum_type( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(48, 96)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_service( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(52, 104)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_extension( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(56, 112)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_options( - google_protobuf_FileDescriptorProto* msg, - google_protobuf_FileOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_FileOptions*, UPB_SIZE(32, 64)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info( - google_protobuf_FileDescriptorProto* msg, - google_protobuf_SourceCodeInfo* value) { - UPB_FIELD_AT(msg, google_protobuf_SourceCodeInfo*, UPB_SIZE(36, 72)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_public_dependency( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(60, 120)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_weak_dependency( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(64, 128)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax( - google_protobuf_FileDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)) = value; -} - -/* google.protobuf.DescriptorProto */ - -extern const upb_msglayout google_protobuf_DescriptorProto_msginit; -UPB_INLINE google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_DescriptorProto* -google_protobuf_DescriptorProto_parsenew(upb_stringview buf, upb_arena* arena) { - google_protobuf_DescriptorProto* ret = - google_protobuf_DescriptorProto_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_DescriptorProto_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_DescriptorProto_serialize( - const google_protobuf_DescriptorProto* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_DescriptorProto_msginit, arena, len); -} - -UPB_INLINE upb_stringview google_protobuf_DescriptorProto_name( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_field( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_nested_type( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_enum_type( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_extension_range( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(32, 64)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_extension( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(36, 72)); -} -UPB_INLINE const google_protobuf_MessageOptions* -google_protobuf_DescriptorProto_options( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const google_protobuf_MessageOptions*, - UPB_SIZE(16, 32)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_oneof_decl( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(40, 80)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_reserved_range( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(44, 88)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_reserved_name( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(48, 96)); -} - -UPB_INLINE void google_protobuf_DescriptorProto_set_name( - google_protobuf_DescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_field( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_nested_type( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_enum_type( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_extension_range( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(32, 64)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_extension( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(36, 72)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_options( - google_protobuf_DescriptorProto* msg, - google_protobuf_MessageOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_MessageOptions*, UPB_SIZE(16, 32)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_oneof_decl( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(40, 80)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_reserved_range( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(44, 88)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_reserved_name( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(48, 96)) = value; -} - -/* google.protobuf.DescriptorProto.ExtensionRange */ - -extern const upb_msglayout - google_protobuf_DescriptorProto_ExtensionRange_msginit; -UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* -google_protobuf_DescriptorProto_ExtensionRange_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, - arena); -} -UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* -google_protobuf_DescriptorProto_ExtensionRange_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_DescriptorProto_ExtensionRange* ret = - google_protobuf_DescriptorProto_ExtensionRange_new(arena); - return (ret && - upb_decode(buf, ret, - &google_protobuf_DescriptorProto_ExtensionRange_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_DescriptorProto_ExtensionRange_serialize( - const google_protobuf_DescriptorProto_ExtensionRange* msg, upb_arena* arena, - size_t* len) { - return upb_encode( - msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, len); -} - -UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start( - const google_protobuf_DescriptorProto_ExtensionRange* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); -} -UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end( - const google_protobuf_DescriptorProto_ExtensionRange* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); -} -UPB_INLINE const google_protobuf_ExtensionRangeOptions* -google_protobuf_DescriptorProto_ExtensionRange_options( - const google_protobuf_DescriptorProto_ExtensionRange* msg) { - return UPB_FIELD_AT(msg, const google_protobuf_ExtensionRangeOptions*, - UPB_SIZE(12, 16)); -} - -UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_start( - google_protobuf_DescriptorProto_ExtensionRange* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_end( - google_protobuf_DescriptorProto_ExtensionRange* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_options( - google_protobuf_DescriptorProto_ExtensionRange* msg, - google_protobuf_ExtensionRangeOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)) = - value; -} - -/* google.protobuf.DescriptorProto.ReservedRange */ - -extern const upb_msglayout - google_protobuf_DescriptorProto_ReservedRange_msginit; -UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* -google_protobuf_DescriptorProto_ReservedRange_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, - arena); -} -UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* -google_protobuf_DescriptorProto_ReservedRange_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_DescriptorProto_ReservedRange* ret = - google_protobuf_DescriptorProto_ReservedRange_new(arena); - return (ret && - upb_decode(buf, ret, - &google_protobuf_DescriptorProto_ReservedRange_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_DescriptorProto_ReservedRange_serialize( - const google_protobuf_DescriptorProto_ReservedRange* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, - arena, len); -} - -UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start( - const google_protobuf_DescriptorProto_ReservedRange* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); -} -UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end( - const google_protobuf_DescriptorProto_ReservedRange* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); -} - -UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_start( - google_protobuf_DescriptorProto_ReservedRange* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_end( - google_protobuf_DescriptorProto_ReservedRange* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; -} - -/* google.protobuf.ExtensionRangeOptions */ - -extern const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit; -UPB_INLINE google_protobuf_ExtensionRangeOptions* -google_protobuf_ExtensionRangeOptions_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena); -} -UPB_INLINE google_protobuf_ExtensionRangeOptions* -google_protobuf_ExtensionRangeOptions_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_ExtensionRangeOptions* ret = - google_protobuf_ExtensionRangeOptions_new(arena); - return (ret && - upb_decode(buf, ret, &google_protobuf_ExtensionRangeOptions_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_ExtensionRangeOptions_serialize( - const google_protobuf_ExtensionRangeOptions* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, arena, - len); -} - -UPB_INLINE const upb_array* -google_protobuf_ExtensionRangeOptions_uninterpreted_option( - const google_protobuf_ExtensionRangeOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_ExtensionRangeOptions_set_uninterpreted_option( - google_protobuf_ExtensionRangeOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.FieldDescriptorProto */ - -extern const upb_msglayout google_protobuf_FieldDescriptorProto_msginit; -UPB_INLINE google_protobuf_FieldDescriptorProto* -google_protobuf_FieldDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_FieldDescriptorProto* -google_protobuf_FieldDescriptorProto_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_FieldDescriptorProto* ret = - google_protobuf_FieldDescriptorProto_new(arena); - return (ret && - upb_decode(buf, ret, &google_protobuf_FieldDescriptorProto_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_FieldDescriptorProto_serialize( - const google_protobuf_FieldDescriptorProto* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, - len); -} - -UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_name( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); -} -UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_extendee( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); -} -UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)); -} -UPB_INLINE google_protobuf_FieldDescriptorProto_Label -google_protobuf_FieldDescriptorProto_label( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Label, - UPB_SIZE(8, 8)); -} -UPB_INLINE google_protobuf_FieldDescriptorProto_Type -google_protobuf_FieldDescriptorProto_type( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Type, - UPB_SIZE(16, 16)); -} -UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_type_name( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); -} -UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_default_value( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)); -} -UPB_INLINE const google_protobuf_FieldOptions* -google_protobuf_FieldDescriptorProto_options( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const google_protobuf_FieldOptions*, - UPB_SIZE(72, 112)); -} -UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)); -} -UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_json_name( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)); -} - -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name( - google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee( - google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number( - google_protobuf_FieldDescriptorProto* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label( - google_protobuf_FieldDescriptorProto* msg, - google_protobuf_FieldDescriptorProto_Label value) { - UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Label, - UPB_SIZE(8, 8)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type( - google_protobuf_FieldDescriptorProto* msg, - google_protobuf_FieldDescriptorProto_Type value) { - UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Type, - UPB_SIZE(16, 16)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name( - google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value( - google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options( - google_protobuf_FieldDescriptorProto* msg, - google_protobuf_FieldOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_FieldOptions*, UPB_SIZE(72, 112)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index( - google_protobuf_FieldDescriptorProto* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name( - google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)) = value; -} - -/* google.protobuf.OneofDescriptorProto */ - -extern const upb_msglayout google_protobuf_OneofDescriptorProto_msginit; -UPB_INLINE google_protobuf_OneofDescriptorProto* -google_protobuf_OneofDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_OneofDescriptorProto* -google_protobuf_OneofDescriptorProto_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_OneofDescriptorProto* ret = - google_protobuf_OneofDescriptorProto_new(arena); - return (ret && - upb_decode(buf, ret, &google_protobuf_OneofDescriptorProto_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_OneofDescriptorProto_serialize( - const google_protobuf_OneofDescriptorProto* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_OneofDescriptorProto_msginit, arena, - len); -} - -UPB_INLINE upb_stringview google_protobuf_OneofDescriptorProto_name( - const google_protobuf_OneofDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE const google_protobuf_OneofOptions* -google_protobuf_OneofDescriptorProto_options( - const google_protobuf_OneofDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const google_protobuf_OneofOptions*, - UPB_SIZE(16, 32)); -} - -UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name( - google_protobuf_OneofDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options( - google_protobuf_OneofDescriptorProto* msg, - google_protobuf_OneofOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_OneofOptions*, UPB_SIZE(16, 32)) = value; -} - -/* google.protobuf.EnumDescriptorProto */ - -extern const upb_msglayout google_protobuf_EnumDescriptorProto_msginit; -UPB_INLINE google_protobuf_EnumDescriptorProto* -google_protobuf_EnumDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_EnumDescriptorProto* -google_protobuf_EnumDescriptorProto_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_EnumDescriptorProto* ret = - google_protobuf_EnumDescriptorProto_new(arena); - return (ret && - upb_decode(buf, ret, &google_protobuf_EnumDescriptorProto_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_EnumDescriptorProto_serialize( - const google_protobuf_EnumDescriptorProto* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_EnumDescriptorProto_msginit, arena, - len); -} - -UPB_INLINE upb_stringview google_protobuf_EnumDescriptorProto_name( - const google_protobuf_EnumDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_value( - const google_protobuf_EnumDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); -} -UPB_INLINE const google_protobuf_EnumOptions* -google_protobuf_EnumDescriptorProto_options( - const google_protobuf_EnumDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const google_protobuf_EnumOptions*, - UPB_SIZE(16, 32)); -} -UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_reserved_range( - const google_protobuf_EnumDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); -} -UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_reserved_name( - const google_protobuf_EnumDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); -} - -UPB_INLINE void google_protobuf_EnumDescriptorProto_set_name( - google_protobuf_EnumDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_EnumDescriptorProto_set_value( - google_protobuf_EnumDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; -} -UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options( - google_protobuf_EnumDescriptorProto* msg, - google_protobuf_EnumOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_EnumOptions*, UPB_SIZE(16, 32)) = value; -} -UPB_INLINE void google_protobuf_EnumDescriptorProto_set_reserved_range( - google_protobuf_EnumDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; -} -UPB_INLINE void google_protobuf_EnumDescriptorProto_set_reserved_name( - google_protobuf_EnumDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; -} - -/* google.protobuf.EnumDescriptorProto.EnumReservedRange */ - -extern const upb_msglayout - google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit; -UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* -google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_arena* arena) { - return upb_msg_new( - &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena); -} -UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* -google_protobuf_EnumDescriptorProto_EnumReservedRange_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_EnumDescriptorProto_EnumReservedRange* ret = - google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); - return (ret && - upb_decode( - buf, ret, - &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* -google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize( - const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, - upb_arena* arena, size_t* len) { - return upb_encode( - msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, - arena, len); -} - -UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start( - const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); -} -UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end( - const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); -} - -UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start( - google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; -} -UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end( - google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; -} - -/* google.protobuf.EnumValueDescriptorProto */ - -extern const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit; -UPB_INLINE google_protobuf_EnumValueDescriptorProto* -google_protobuf_EnumValueDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_EnumValueDescriptorProto* -google_protobuf_EnumValueDescriptorProto_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_EnumValueDescriptorProto* ret = - google_protobuf_EnumValueDescriptorProto_new(arena); - return (ret && upb_decode(buf, ret, - &google_protobuf_EnumValueDescriptorProto_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_EnumValueDescriptorProto_serialize( - const google_protobuf_EnumValueDescriptorProto* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, - arena, len); -} - -UPB_INLINE upb_stringview google_protobuf_EnumValueDescriptorProto_name( - const google_protobuf_EnumValueDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number( - const google_protobuf_EnumValueDescriptorProto* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); -} -UPB_INLINE const google_protobuf_EnumValueOptions* -google_protobuf_EnumValueDescriptorProto_options( - const google_protobuf_EnumValueDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const google_protobuf_EnumValueOptions*, - UPB_SIZE(16, 32)); -} - -UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name( - google_protobuf_EnumValueDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number( - google_protobuf_EnumValueDescriptorProto* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; -} -UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options( - google_protobuf_EnumValueDescriptorProto* msg, - google_protobuf_EnumValueOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_EnumValueOptions*, UPB_SIZE(16, 32)) = - value; -} - -/* google.protobuf.ServiceDescriptorProto */ - -extern const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit; -UPB_INLINE google_protobuf_ServiceDescriptorProto* -google_protobuf_ServiceDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_ServiceDescriptorProto* -google_protobuf_ServiceDescriptorProto_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_ServiceDescriptorProto* ret = - google_protobuf_ServiceDescriptorProto_new(arena); - return (ret && - upb_decode(buf, ret, &google_protobuf_ServiceDescriptorProto_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_ServiceDescriptorProto_serialize( - const google_protobuf_ServiceDescriptorProto* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, arena, - len); -} - -UPB_INLINE upb_stringview google_protobuf_ServiceDescriptorProto_name( - const google_protobuf_ServiceDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE const upb_array* google_protobuf_ServiceDescriptorProto_method( - const google_protobuf_ServiceDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); -} -UPB_INLINE const google_protobuf_ServiceOptions* -google_protobuf_ServiceDescriptorProto_options( - const google_protobuf_ServiceDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const google_protobuf_ServiceOptions*, - UPB_SIZE(16, 32)); -} - -UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name( - google_protobuf_ServiceDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_method( - google_protobuf_ServiceDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; -} -UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options( - google_protobuf_ServiceDescriptorProto* msg, - google_protobuf_ServiceOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_ServiceOptions*, UPB_SIZE(16, 32)) = value; -} - -/* google.protobuf.MethodDescriptorProto */ - -extern const upb_msglayout google_protobuf_MethodDescriptorProto_msginit; -UPB_INLINE google_protobuf_MethodDescriptorProto* -google_protobuf_MethodDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_MethodDescriptorProto* -google_protobuf_MethodDescriptorProto_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_MethodDescriptorProto* ret = - google_protobuf_MethodDescriptorProto_new(arena); - return (ret && - upb_decode(buf, ret, &google_protobuf_MethodDescriptorProto_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_MethodDescriptorProto_serialize( - const google_protobuf_MethodDescriptorProto* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_MethodDescriptorProto_msginit, arena, - len); -} - -UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_name( - const google_protobuf_MethodDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_input_type( - const google_protobuf_MethodDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); -} -UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_output_type( - const google_protobuf_MethodDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)); -} -UPB_INLINE const google_protobuf_MethodOptions* -google_protobuf_MethodDescriptorProto_options( - const google_protobuf_MethodDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const google_protobuf_MethodOptions*, - UPB_SIZE(32, 64)); -} -UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming( - const google_protobuf_MethodDescriptorProto* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); -} -UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming( - const google_protobuf_MethodDescriptorProto* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); -} - -UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name( - google_protobuf_MethodDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type( - google_protobuf_MethodDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; -} -UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type( - google_protobuf_MethodDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)) = value; -} -UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options( - google_protobuf_MethodDescriptorProto* msg, - google_protobuf_MethodOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_MethodOptions*, UPB_SIZE(32, 64)) = value; -} -UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming( - google_protobuf_MethodDescriptorProto* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; -} -UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming( - google_protobuf_MethodDescriptorProto* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; -} - -/* google.protobuf.FileOptions */ - -extern const upb_msglayout google_protobuf_FileOptions_msginit; -UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_FileOptions_msginit, arena); -} -UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_FileOptions* ret = google_protobuf_FileOptions_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_FileOptions_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_FileOptions_serialize( - const google_protobuf_FileOptions* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_FileOptions_msginit, arena, len); -} - -UPB_INLINE upb_stringview google_protobuf_FileOptions_java_package( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_java_outer_classname( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); -} -UPB_INLINE google_protobuf_FileOptions_OptimizeMode -google_protobuf_FileOptions_optimize_for( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, google_protobuf_FileOptions_OptimizeMode, - UPB_SIZE(8, 8)); -} -UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); -} -UPB_INLINE upb_stringview -google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); -} -UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)); -} -UPB_INLINE bool google_protobuf_FileOptions_java_generic_services( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)); -} -UPB_INLINE bool google_protobuf_FileOptions_py_generic_services( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)); -} -UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)); -} -UPB_INLINE bool google_protobuf_FileOptions_deprecated( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)); -} -UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)); -} -UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_objc_class_prefix( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_csharp_namespace( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_swift_prefix( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(72, 112)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_php_class_prefix( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(80, 128)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_php_namespace( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(88, 144)); -} -UPB_INLINE bool google_protobuf_FileOptions_php_generic_services( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_php_metadata_namespace( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(96, 160)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_ruby_package( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(104, 176)); -} -UPB_INLINE const upb_array* google_protobuf_FileOptions_uninterpreted_option( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(112, 192)); -} - -UPB_INLINE void google_protobuf_FileOptions_set_java_package( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_optimize_for( - google_protobuf_FileOptions* msg, - google_protobuf_FileOptions_OptimizeMode value) { - UPB_FIELD_AT(msg, google_protobuf_FileOptions_OptimizeMode, UPB_SIZE(8, 8)) = - value; -} -UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files( - google_protobuf_FileOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_go_package( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services( - google_protobuf_FileOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services( - google_protobuf_FileOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services( - google_protobuf_FileOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash( - google_protobuf_FileOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_deprecated( - google_protobuf_FileOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8( - google_protobuf_FileOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas( - google_protobuf_FileOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(72, 112)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(80, 128)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_php_namespace( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(88, 144)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services( - google_protobuf_FileOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(96, 160)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_ruby_package( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(104, 176)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_uninterpreted_option( - google_protobuf_FileOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(112, 192)) = value; -} - -/* google.protobuf.MessageOptions */ - -extern const upb_msglayout google_protobuf_MessageOptions_msginit; -UPB_INLINE google_protobuf_MessageOptions* google_protobuf_MessageOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); -} -UPB_INLINE google_protobuf_MessageOptions* -google_protobuf_MessageOptions_parsenew(upb_stringview buf, upb_arena* arena) { - google_protobuf_MessageOptions* ret = - google_protobuf_MessageOptions_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_MessageOptions_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_MessageOptions_serialize( - const google_protobuf_MessageOptions* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_MessageOptions_msginit, arena, len); -} - -UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format( - const google_protobuf_MessageOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); -} -UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor( - const google_protobuf_MessageOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); -} -UPB_INLINE bool google_protobuf_MessageOptions_deprecated( - const google_protobuf_MessageOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)); -} -UPB_INLINE bool google_protobuf_MessageOptions_map_entry( - const google_protobuf_MessageOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)); -} -UPB_INLINE const upb_array* google_protobuf_MessageOptions_uninterpreted_option( - const google_protobuf_MessageOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(8, 8)); -} - -UPB_INLINE void google_protobuf_MessageOptions_set_message_set_wire_format( - google_protobuf_MessageOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; -} -UPB_INLINE void -google_protobuf_MessageOptions_set_no_standard_descriptor_accessor( - google_protobuf_MessageOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; -} -UPB_INLINE void google_protobuf_MessageOptions_set_deprecated( - google_protobuf_MessageOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)) = value; -} -UPB_INLINE void google_protobuf_MessageOptions_set_map_entry( - google_protobuf_MessageOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)) = value; -} -UPB_INLINE void google_protobuf_MessageOptions_set_uninterpreted_option( - google_protobuf_MessageOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(8, 8)) = value; -} - -/* google.protobuf.FieldOptions */ - -extern const upb_msglayout google_protobuf_FieldOptions_msginit; -UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); -} -UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_FieldOptions* ret = google_protobuf_FieldOptions_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_FieldOptions_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_FieldOptions_serialize( - const google_protobuf_FieldOptions* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_FieldOptions_msginit, arena, len); -} - -UPB_INLINE google_protobuf_FieldOptions_CType -google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions* msg) { - return UPB_FIELD_AT(msg, google_protobuf_FieldOptions_CType, UPB_SIZE(8, 8)); -} -UPB_INLINE bool google_protobuf_FieldOptions_packed( - const google_protobuf_FieldOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); -} -UPB_INLINE bool google_protobuf_FieldOptions_deprecated( - const google_protobuf_FieldOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)); -} -UPB_INLINE bool google_protobuf_FieldOptions_lazy( - const google_protobuf_FieldOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)); -} -UPB_INLINE google_protobuf_FieldOptions_JSType -google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions* msg) { - return UPB_FIELD_AT(msg, google_protobuf_FieldOptions_JSType, - UPB_SIZE(16, 16)); -} -UPB_INLINE bool google_protobuf_FieldOptions_weak( - const google_protobuf_FieldOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)); -} -UPB_INLINE const upb_array* google_protobuf_FieldOptions_uninterpreted_option( - const google_protobuf_FieldOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 32)); -} - -UPB_INLINE void google_protobuf_FieldOptions_set_ctype( - google_protobuf_FieldOptions* msg, - google_protobuf_FieldOptions_CType value) { - UPB_FIELD_AT(msg, google_protobuf_FieldOptions_CType, UPB_SIZE(8, 8)) = value; -} -UPB_INLINE void google_protobuf_FieldOptions_set_packed( - google_protobuf_FieldOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; -} -UPB_INLINE void google_protobuf_FieldOptions_set_deprecated( - google_protobuf_FieldOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)) = value; -} -UPB_INLINE void google_protobuf_FieldOptions_set_lazy( - google_protobuf_FieldOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)) = value; -} -UPB_INLINE void google_protobuf_FieldOptions_set_jstype( - google_protobuf_FieldOptions* msg, - google_protobuf_FieldOptions_JSType value) { - UPB_FIELD_AT(msg, google_protobuf_FieldOptions_JSType, UPB_SIZE(16, 16)) = - value; -} -UPB_INLINE void google_protobuf_FieldOptions_set_weak( - google_protobuf_FieldOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)) = value; -} -UPB_INLINE void google_protobuf_FieldOptions_set_uninterpreted_option( - google_protobuf_FieldOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 32)) = value; -} - -/* google.protobuf.OneofOptions */ - -extern const upb_msglayout google_protobuf_OneofOptions_msginit; -UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); -} -UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_OneofOptions* ret = google_protobuf_OneofOptions_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_OneofOptions_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_OneofOptions_serialize( - const google_protobuf_OneofOptions* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_OneofOptions_msginit, arena, len); -} - -UPB_INLINE const upb_array* google_protobuf_OneofOptions_uninterpreted_option( - const google_protobuf_OneofOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_OneofOptions_set_uninterpreted_option( - google_protobuf_OneofOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.EnumOptions */ - -extern const upb_msglayout google_protobuf_EnumOptions_msginit; -UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); -} -UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_EnumOptions* ret = google_protobuf_EnumOptions_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_EnumOptions_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_EnumOptions_serialize( - const google_protobuf_EnumOptions* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_EnumOptions_msginit, arena, len); -} - -UPB_INLINE bool google_protobuf_EnumOptions_allow_alias( - const google_protobuf_EnumOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); -} -UPB_INLINE bool google_protobuf_EnumOptions_deprecated( - const google_protobuf_EnumOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); -} -UPB_INLINE const upb_array* google_protobuf_EnumOptions_uninterpreted_option( - const google_protobuf_EnumOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); -} - -UPB_INLINE void google_protobuf_EnumOptions_set_allow_alias( - google_protobuf_EnumOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; -} -UPB_INLINE void google_protobuf_EnumOptions_set_deprecated( - google_protobuf_EnumOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; -} -UPB_INLINE void google_protobuf_EnumOptions_set_uninterpreted_option( - google_protobuf_EnumOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; -} - -/* google.protobuf.EnumValueOptions */ - -extern const upb_msglayout google_protobuf_EnumValueOptions_msginit; -UPB_INLINE google_protobuf_EnumValueOptions* -google_protobuf_EnumValueOptions_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); -} -UPB_INLINE google_protobuf_EnumValueOptions* -google_protobuf_EnumValueOptions_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_EnumValueOptions* ret = - google_protobuf_EnumValueOptions_new(arena); - return (ret && - upb_decode(buf, ret, &google_protobuf_EnumValueOptions_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_EnumValueOptions_serialize( - const google_protobuf_EnumValueOptions* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_EnumValueOptions_msginit, arena, len); -} - -UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated( - const google_protobuf_EnumValueOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); -} -UPB_INLINE const upb_array* -google_protobuf_EnumValueOptions_uninterpreted_option( - const google_protobuf_EnumValueOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); -} - -UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated( - google_protobuf_EnumValueOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; -} -UPB_INLINE void google_protobuf_EnumValueOptions_set_uninterpreted_option( - google_protobuf_EnumValueOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; -} - -/* google.protobuf.ServiceOptions */ - -extern const upb_msglayout google_protobuf_ServiceOptions_msginit; -UPB_INLINE google_protobuf_ServiceOptions* google_protobuf_ServiceOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); -} -UPB_INLINE google_protobuf_ServiceOptions* -google_protobuf_ServiceOptions_parsenew(upb_stringview buf, upb_arena* arena) { - google_protobuf_ServiceOptions* ret = - google_protobuf_ServiceOptions_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_ServiceOptions_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_ServiceOptions_serialize( - const google_protobuf_ServiceOptions* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_ServiceOptions_msginit, arena, len); -} - -UPB_INLINE bool google_protobuf_ServiceOptions_deprecated( - const google_protobuf_ServiceOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); -} -UPB_INLINE const upb_array* google_protobuf_ServiceOptions_uninterpreted_option( - const google_protobuf_ServiceOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); -} - -UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated( - google_protobuf_ServiceOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; -} -UPB_INLINE void google_protobuf_ServiceOptions_set_uninterpreted_option( - google_protobuf_ServiceOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; -} - -/* google.protobuf.MethodOptions */ - -extern const upb_msglayout google_protobuf_MethodOptions_msginit; -UPB_INLINE google_protobuf_MethodOptions* google_protobuf_MethodOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); -} -UPB_INLINE google_protobuf_MethodOptions* -google_protobuf_MethodOptions_parsenew(upb_stringview buf, upb_arena* arena) { - google_protobuf_MethodOptions* ret = google_protobuf_MethodOptions_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_MethodOptions_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_MethodOptions_serialize( - const google_protobuf_MethodOptions* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_MethodOptions_msginit, arena, len); -} - -UPB_INLINE bool google_protobuf_MethodOptions_deprecated( - const google_protobuf_MethodOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); -} -UPB_INLINE google_protobuf_MethodOptions_IdempotencyLevel -google_protobuf_MethodOptions_idempotency_level( - const google_protobuf_MethodOptions* msg) { - return UPB_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, - UPB_SIZE(8, 8)); -} -UPB_INLINE const upb_array* google_protobuf_MethodOptions_uninterpreted_option( - const google_protobuf_MethodOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 24)); -} - -UPB_INLINE void google_protobuf_MethodOptions_set_deprecated( - google_protobuf_MethodOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; -} -UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level( - google_protobuf_MethodOptions* msg, - google_protobuf_MethodOptions_IdempotencyLevel value) { - UPB_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, - UPB_SIZE(8, 8)) = value; -} -UPB_INLINE void google_protobuf_MethodOptions_set_uninterpreted_option( - google_protobuf_MethodOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 24)) = value; -} - -/* google.protobuf.UninterpretedOption */ - -extern const upb_msglayout google_protobuf_UninterpretedOption_msginit; -UPB_INLINE google_protobuf_UninterpretedOption* -google_protobuf_UninterpretedOption_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); -} -UPB_INLINE google_protobuf_UninterpretedOption* -google_protobuf_UninterpretedOption_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_UninterpretedOption* ret = - google_protobuf_UninterpretedOption_new(arena); - return (ret && - upb_decode(buf, ret, &google_protobuf_UninterpretedOption_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_UninterpretedOption_serialize( - const google_protobuf_UninterpretedOption* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_UninterpretedOption_msginit, arena, - len); -} - -UPB_INLINE const upb_array* google_protobuf_UninterpretedOption_name( - const google_protobuf_UninterpretedOption* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(56, 80)); -} -UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_identifier_value( - const google_protobuf_UninterpretedOption* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); -} -UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value( - const google_protobuf_UninterpretedOption* msg) { - return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); -} -UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value( - const google_protobuf_UninterpretedOption* msg) { - return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); -} -UPB_INLINE double google_protobuf_UninterpretedOption_double_value( - const google_protobuf_UninterpretedOption* msg) { - return UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)); -} -UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_string_value( - const google_protobuf_UninterpretedOption* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); -} -UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_aggregate_value( - const google_protobuf_UninterpretedOption* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); -} - -UPB_INLINE void google_protobuf_UninterpretedOption_set_name( - google_protobuf_UninterpretedOption* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(56, 80)) = value; -} -UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value( - google_protobuf_UninterpretedOption* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; -} -UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value( - google_protobuf_UninterpretedOption* msg, uint64_t value) { - UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; -} -UPB_INLINE void google_protobuf_UninterpretedOption_set_negative_int_value( - google_protobuf_UninterpretedOption* msg, int64_t value) { - UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value; -} -UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value( - google_protobuf_UninterpretedOption* msg, double value) { - UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)) = value; -} -UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value( - google_protobuf_UninterpretedOption* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; -} -UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value( - google_protobuf_UninterpretedOption* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; -} - -/* google.protobuf.UninterpretedOption.NamePart */ - -extern const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit; -UPB_INLINE google_protobuf_UninterpretedOption_NamePart* -google_protobuf_UninterpretedOption_NamePart_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, - arena); -} -UPB_INLINE google_protobuf_UninterpretedOption_NamePart* -google_protobuf_UninterpretedOption_NamePart_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_UninterpretedOption_NamePart* ret = - google_protobuf_UninterpretedOption_NamePart_new(arena); - return (ret && - upb_decode(buf, ret, - &google_protobuf_UninterpretedOption_NamePart_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_UninterpretedOption_NamePart_serialize( - const google_protobuf_UninterpretedOption_NamePart* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, - arena, len); -} - -UPB_INLINE upb_stringview -google_protobuf_UninterpretedOption_NamePart_name_part( - const google_protobuf_UninterpretedOption_NamePart* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension( - const google_protobuf_UninterpretedOption_NamePart* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); -} - -UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part( - google_protobuf_UninterpretedOption_NamePart* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension( - google_protobuf_UninterpretedOption_NamePart* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; -} - -/* google.protobuf.SourceCodeInfo */ - -extern const upb_msglayout google_protobuf_SourceCodeInfo_msginit; -UPB_INLINE google_protobuf_SourceCodeInfo* google_protobuf_SourceCodeInfo_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena); -} -UPB_INLINE google_protobuf_SourceCodeInfo* -google_protobuf_SourceCodeInfo_parsenew(upb_stringview buf, upb_arena* arena) { - google_protobuf_SourceCodeInfo* ret = - google_protobuf_SourceCodeInfo_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_SourceCodeInfo_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_SourceCodeInfo_serialize( - const google_protobuf_SourceCodeInfo* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, arena, len); -} - -UPB_INLINE const upb_array* google_protobuf_SourceCodeInfo_location( - const google_protobuf_SourceCodeInfo* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_SourceCodeInfo_set_location( - google_protobuf_SourceCodeInfo* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.SourceCodeInfo.Location */ - -extern const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit; -UPB_INLINE google_protobuf_SourceCodeInfo_Location* -google_protobuf_SourceCodeInfo_Location_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena); -} -UPB_INLINE google_protobuf_SourceCodeInfo_Location* -google_protobuf_SourceCodeInfo_Location_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_SourceCodeInfo_Location* ret = - google_protobuf_SourceCodeInfo_Location_new(arena); - return (ret && upb_decode(buf, ret, - &google_protobuf_SourceCodeInfo_Location_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_SourceCodeInfo_Location_serialize( - const google_protobuf_SourceCodeInfo_Location* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_SourceCodeInfo_Location_msginit, - arena, len); -} - -UPB_INLINE const upb_array* google_protobuf_SourceCodeInfo_Location_path( - const google_protobuf_SourceCodeInfo_Location* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); -} -UPB_INLINE const upb_array* google_protobuf_SourceCodeInfo_Location_span( - const google_protobuf_SourceCodeInfo_Location* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); -} -UPB_INLINE upb_stringview -google_protobuf_SourceCodeInfo_Location_leading_comments( - const google_protobuf_SourceCodeInfo_Location* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE upb_stringview -google_protobuf_SourceCodeInfo_Location_trailing_comments( - const google_protobuf_SourceCodeInfo_Location* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); -} -UPB_INLINE const upb_array* -google_protobuf_SourceCodeInfo_Location_leading_detached_comments( - const google_protobuf_SourceCodeInfo_Location* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(32, 64)); -} - -UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_path( - google_protobuf_SourceCodeInfo_Location* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; -} -UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_span( - google_protobuf_SourceCodeInfo_Location* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; -} -UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments( - google_protobuf_SourceCodeInfo_Location* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments( - google_protobuf_SourceCodeInfo_Location* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; -} -UPB_INLINE void -google_protobuf_SourceCodeInfo_Location_set_leading_detached_comments( - google_protobuf_SourceCodeInfo_Location* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(32, 64)) = value; -} - -/* google.protobuf.GeneratedCodeInfo */ - -extern const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit; -UPB_INLINE google_protobuf_GeneratedCodeInfo* -google_protobuf_GeneratedCodeInfo_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_GeneratedCodeInfo_msginit, arena); -} -UPB_INLINE google_protobuf_GeneratedCodeInfo* -google_protobuf_GeneratedCodeInfo_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_GeneratedCodeInfo* ret = - google_protobuf_GeneratedCodeInfo_new(arena); - return (ret && - upb_decode(buf, ret, &google_protobuf_GeneratedCodeInfo_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_GeneratedCodeInfo_serialize( - const google_protobuf_GeneratedCodeInfo* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, arena, - len); -} - -UPB_INLINE const upb_array* google_protobuf_GeneratedCodeInfo_annotation( - const google_protobuf_GeneratedCodeInfo* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_GeneratedCodeInfo_set_annotation( - google_protobuf_GeneratedCodeInfo* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.GeneratedCodeInfo.Annotation */ - -extern const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit; -UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* -google_protobuf_GeneratedCodeInfo_Annotation_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, - arena); -} -UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* -google_protobuf_GeneratedCodeInfo_Annotation_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_GeneratedCodeInfo_Annotation* ret = - google_protobuf_GeneratedCodeInfo_Annotation_new(arena); - return (ret && - upb_decode(buf, ret, - &google_protobuf_GeneratedCodeInfo_Annotation_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_GeneratedCodeInfo_Annotation_serialize( - const google_protobuf_GeneratedCodeInfo_Annotation* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, - arena, len); -} - -UPB_INLINE const upb_array* google_protobuf_GeneratedCodeInfo_Annotation_path( - const google_protobuf_GeneratedCodeInfo_Annotation* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 32)); -} -UPB_INLINE upb_stringview -google_protobuf_GeneratedCodeInfo_Annotation_source_file( - const google_protobuf_GeneratedCodeInfo_Annotation* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 16)); -} -UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin( - const google_protobuf_GeneratedCodeInfo_Annotation* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); -} -UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end( - const google_protobuf_GeneratedCodeInfo_Annotation* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); -} - -UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_path( - google_protobuf_GeneratedCodeInfo_Annotation* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 32)) = value; -} -UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file( - google_protobuf_GeneratedCodeInfo_Annotation* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 16)) = value; -} -UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin( - google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; -} -UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end( - google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; -} - -UPB_END_EXTERN_C - -#include "upb/port_undef.inc" - -#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/duration.upb.c b/src/core/ext/upb-generated/google/protobuf/duration.upb.c deleted file mode 100644 index b057ce5e4aa..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/duration.upb.c +++ /dev/null @@ -1,24 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/duration.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#include "google/protobuf/duration.upb.h" -#include -#include "upb/msg.h" - -#include "upb/port_def.inc" - -static const upb_msglayout_field google_protobuf_Duration__fields[2] = { - {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, - {2, UPB_SIZE(8, 8), 0, 0, 5, 1}, -}; - -const upb_msglayout google_protobuf_Duration_msginit = { - NULL, &google_protobuf_Duration__fields[0], UPB_SIZE(16, 16), 2, false, -}; - -#include "upb/port_undef.inc" diff --git a/src/core/ext/upb-generated/google/protobuf/duration.upb.h b/src/core/ext/upb-generated/google/protobuf/duration.upb.h deleted file mode 100644 index 1f40b3aed24..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/duration.upb.h +++ /dev/null @@ -1,65 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/duration.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#ifndef GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ -#define GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ - -#include "upb/msg.h" - -#include "upb/decode.h" -#include "upb/encode.h" -#include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C - -struct google_protobuf_Duration; -typedef struct google_protobuf_Duration google_protobuf_Duration; - -/* Enums */ - -/* google.protobuf.Duration */ - -extern const upb_msglayout google_protobuf_Duration_msginit; -UPB_INLINE google_protobuf_Duration* google_protobuf_Duration_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_Duration_msginit, arena); -} -UPB_INLINE google_protobuf_Duration* google_protobuf_Duration_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_Duration* ret = google_protobuf_Duration_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_Duration_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_Duration_serialize( - const google_protobuf_Duration* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_Duration_msginit, arena, len); -} - -UPB_INLINE int64_t -google_protobuf_Duration_seconds(const google_protobuf_Duration* msg) { - return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); -} -UPB_INLINE int32_t -google_protobuf_Duration_nanos(const google_protobuf_Duration* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); -} - -UPB_INLINE void google_protobuf_Duration_set_seconds( - google_protobuf_Duration* msg, int64_t value) { - UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; -} -UPB_INLINE void google_protobuf_Duration_set_nanos( - google_protobuf_Duration* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; -} - -UPB_END_EXTERN_C - -#include "upb/port_undef.inc" - -#endif /* GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/struct.upb.c b/src/core/ext/upb-generated/google/protobuf/struct.upb.c deleted file mode 100644 index a0820e722a6..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/struct.upb.c +++ /dev/null @@ -1,88 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/struct.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#include "google/protobuf/struct.upb.h" -#include -#include "upb/msg.h" - -#include "upb/port_def.inc" - -static const upb_msglayout* const google_protobuf_Struct_submsgs[1] = { - &google_protobuf_Struct_FieldsEntry_msginit, -}; - -static const upb_msglayout_field google_protobuf_Struct__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_Struct_msginit = { - &google_protobuf_Struct_submsgs[0], - &google_protobuf_Struct__fields[0], - UPB_SIZE(4, 8), - 1, - false, -}; - -static const upb_msglayout* const - google_protobuf_Struct_FieldsEntry_submsgs[1] = { - &google_protobuf_Value_msginit, -}; - -static const upb_msglayout_field google_protobuf_Struct_FieldsEntry__fields[2] = - { - {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, - {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, -}; - -const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit = { - &google_protobuf_Struct_FieldsEntry_submsgs[0], - &google_protobuf_Struct_FieldsEntry__fields[0], - UPB_SIZE(16, 32), - 2, - false, -}; - -static const upb_msglayout* const google_protobuf_Value_submsgs[2] = { - &google_protobuf_ListValue_msginit, - &google_protobuf_Struct_msginit, -}; - -static const upb_msglayout_field google_protobuf_Value__fields[6] = { - {1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 14, 1}, - {2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 1, 1}, - {3, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, - {4, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 8, 1}, - {5, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 1, 11, 1}, - {6, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 11, 1}, -}; - -const upb_msglayout google_protobuf_Value_msginit = { - &google_protobuf_Value_submsgs[0], - &google_protobuf_Value__fields[0], - UPB_SIZE(16, 32), - 6, - false, -}; - -static const upb_msglayout* const google_protobuf_ListValue_submsgs[1] = { - &google_protobuf_Value_msginit, -}; - -static const upb_msglayout_field google_protobuf_ListValue__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_ListValue_msginit = { - &google_protobuf_ListValue_submsgs[0], - &google_protobuf_ListValue__fields[0], - UPB_SIZE(4, 8), - 1, - false, -}; - -#include "upb/port_undef.inc" diff --git a/src/core/ext/upb-generated/google/protobuf/struct.upb.h b/src/core/ext/upb-generated/google/protobuf/struct.upb.h deleted file mode 100644 index 5493794f0e6..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/struct.upb.h +++ /dev/null @@ -1,226 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/struct.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#ifndef GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ -#define GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ - -#include "upb/msg.h" - -#include "upb/decode.h" -#include "upb/encode.h" -#include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C - -struct google_protobuf_Struct; -struct google_protobuf_Struct_FieldsEntry; -struct google_protobuf_Value; -struct google_protobuf_ListValue; -typedef struct google_protobuf_Struct google_protobuf_Struct; -typedef struct google_protobuf_Struct_FieldsEntry - google_protobuf_Struct_FieldsEntry; -typedef struct google_protobuf_Value google_protobuf_Value; -typedef struct google_protobuf_ListValue google_protobuf_ListValue; - -/* Enums */ - -typedef enum { google_protobuf_NULL_VALUE = 0 } google_protobuf_NullValue; - -/* google.protobuf.Struct */ - -extern const upb_msglayout google_protobuf_Struct_msginit; -UPB_INLINE google_protobuf_Struct* google_protobuf_Struct_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_Struct_msginit, arena); -} -UPB_INLINE google_protobuf_Struct* google_protobuf_Struct_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_Struct* ret = google_protobuf_Struct_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_Struct_msginit)) ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_Struct_serialize( - const google_protobuf_Struct* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_Struct_msginit, arena, len); -} - -UPB_INLINE const upb_array* google_protobuf_Struct_fields( - const google_protobuf_Struct* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_Struct_set_fields(google_protobuf_Struct* msg, - upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.Struct.FieldsEntry */ - -extern const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit; -UPB_INLINE google_protobuf_Struct_FieldsEntry* -google_protobuf_Struct_FieldsEntry_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_Struct_FieldsEntry_msginit, arena); -} -UPB_INLINE google_protobuf_Struct_FieldsEntry* -google_protobuf_Struct_FieldsEntry_parsenew(upb_stringview buf, - upb_arena* arena) { - google_protobuf_Struct_FieldsEntry* ret = - google_protobuf_Struct_FieldsEntry_new(arena); - return (ret && - upb_decode(buf, ret, &google_protobuf_Struct_FieldsEntry_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_Struct_FieldsEntry_serialize( - const google_protobuf_Struct_FieldsEntry* msg, upb_arena* arena, - size_t* len) { - return upb_encode(msg, &google_protobuf_Struct_FieldsEntry_msginit, arena, - len); -} - -UPB_INLINE upb_stringview google_protobuf_Struct_FieldsEntry_key( - const google_protobuf_Struct_FieldsEntry* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); -} -UPB_INLINE const google_protobuf_Value* -google_protobuf_Struct_FieldsEntry_value( - const google_protobuf_Struct_FieldsEntry* msg) { - return UPB_FIELD_AT(msg, const google_protobuf_Value*, UPB_SIZE(8, 16)); -} - -UPB_INLINE void google_protobuf_Struct_FieldsEntry_set_key( - google_protobuf_Struct_FieldsEntry* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; -} -UPB_INLINE void google_protobuf_Struct_FieldsEntry_set_value( - google_protobuf_Struct_FieldsEntry* msg, google_protobuf_Value* value) { - UPB_FIELD_AT(msg, google_protobuf_Value*, UPB_SIZE(8, 16)) = value; -} - -/* google.protobuf.Value */ - -extern const upb_msglayout google_protobuf_Value_msginit; -UPB_INLINE google_protobuf_Value* google_protobuf_Value_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_Value_msginit, arena); -} -UPB_INLINE google_protobuf_Value* google_protobuf_Value_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_Value* ret = google_protobuf_Value_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_Value_msginit)) ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_Value_serialize( - const google_protobuf_Value* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_Value_msginit, arena, len); -} - -typedef enum { - google_protobuf_Value_kind_null_value = 1, - google_protobuf_Value_kind_number_value = 2, - google_protobuf_Value_kind_string_value = 3, - google_protobuf_Value_kind_bool_value = 4, - google_protobuf_Value_kind_struct_value = 5, - google_protobuf_Value_kind_list_value = 6, - google_protobuf_Value_kind_NOT_SET = 0, -} google_protobuf_Value_kind_oneofcases; -UPB_INLINE google_protobuf_Value_kind_oneofcases -google_protobuf_Value_kind_case(const google_protobuf_Value* msg) { - return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); -} - -UPB_INLINE google_protobuf_NullValue -google_protobuf_Value_null_value(const google_protobuf_Value* msg) { - return UPB_READ_ONEOF(msg, google_protobuf_NullValue, UPB_SIZE(0, 0), - UPB_SIZE(8, 16), 1, google_protobuf_NULL_VALUE); -} -UPB_INLINE double google_protobuf_Value_number_value( - const google_protobuf_Value* msg) { - return UPB_READ_ONEOF(msg, double, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, 0); -} -UPB_INLINE upb_stringview -google_protobuf_Value_string_value(const google_protobuf_Value* msg) { - return UPB_READ_ONEOF(msg, upb_stringview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, - upb_stringview_make("", strlen(""))); -} -UPB_INLINE bool google_protobuf_Value_bool_value( - const google_protobuf_Value* msg) { - return UPB_READ_ONEOF(msg, bool, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 4, false); -} -UPB_INLINE const google_protobuf_Struct* google_protobuf_Value_struct_value( - const google_protobuf_Value* msg) { - return UPB_READ_ONEOF(msg, const google_protobuf_Struct*, UPB_SIZE(0, 0), - UPB_SIZE(8, 16), 5, NULL); -} -UPB_INLINE const google_protobuf_ListValue* google_protobuf_Value_list_value( - const google_protobuf_Value* msg) { - return UPB_READ_ONEOF(msg, const google_protobuf_ListValue*, UPB_SIZE(0, 0), - UPB_SIZE(8, 16), 6, NULL); -} - -UPB_INLINE void google_protobuf_Value_set_null_value( - google_protobuf_Value* msg, google_protobuf_NullValue value) { - UPB_WRITE_ONEOF(msg, google_protobuf_NullValue, UPB_SIZE(0, 0), value, - UPB_SIZE(8, 16), 1); -} -UPB_INLINE void google_protobuf_Value_set_number_value( - google_protobuf_Value* msg, double value) { - UPB_WRITE_ONEOF(msg, double, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); -} -UPB_INLINE void google_protobuf_Value_set_string_value( - google_protobuf_Value* msg, upb_stringview value) { - UPB_WRITE_ONEOF(msg, upb_stringview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), - 3); -} -UPB_INLINE void google_protobuf_Value_set_bool_value(google_protobuf_Value* msg, - bool value) { - UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 4); -} -UPB_INLINE void google_protobuf_Value_set_struct_value( - google_protobuf_Value* msg, google_protobuf_Struct* value) { - UPB_WRITE_ONEOF(msg, google_protobuf_Struct*, UPB_SIZE(0, 0), value, - UPB_SIZE(8, 16), 5); -} -UPB_INLINE void google_protobuf_Value_set_list_value( - google_protobuf_Value* msg, google_protobuf_ListValue* value) { - UPB_WRITE_ONEOF(msg, google_protobuf_ListValue*, UPB_SIZE(0, 0), value, - UPB_SIZE(8, 16), 6); -} - -/* google.protobuf.ListValue */ - -extern const upb_msglayout google_protobuf_ListValue_msginit; -UPB_INLINE google_protobuf_ListValue* google_protobuf_ListValue_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_ListValue_msginit, arena); -} -UPB_INLINE google_protobuf_ListValue* google_protobuf_ListValue_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_ListValue* ret = google_protobuf_ListValue_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_ListValue_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_ListValue_serialize( - const google_protobuf_ListValue* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_ListValue_msginit, arena, len); -} - -UPB_INLINE const upb_array* google_protobuf_ListValue_values( - const google_protobuf_ListValue* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_ListValue_set_values( - google_protobuf_ListValue* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -UPB_END_EXTERN_C - -#include "upb/port_undef.inc" - -#endif /* GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c deleted file mode 100644 index 90d0aed7664..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c +++ /dev/null @@ -1,24 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/timestamp.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#include "google/protobuf/timestamp.upb.h" -#include -#include "upb/msg.h" - -#include "upb/port_def.inc" - -static const upb_msglayout_field google_protobuf_Timestamp__fields[2] = { - {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, - {2, UPB_SIZE(8, 8), 0, 0, 5, 1}, -}; - -const upb_msglayout google_protobuf_Timestamp_msginit = { - NULL, &google_protobuf_Timestamp__fields[0], UPB_SIZE(16, 16), 2, false, -}; - -#include "upb/port_undef.inc" diff --git a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h deleted file mode 100644 index a524eb5b6d0..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h +++ /dev/null @@ -1,65 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/timestamp.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#ifndef GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ -#define GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ - -#include "upb/msg.h" - -#include "upb/decode.h" -#include "upb/encode.h" -#include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C - -struct google_protobuf_Timestamp; -typedef struct google_protobuf_Timestamp google_protobuf_Timestamp; - -/* Enums */ - -/* google.protobuf.Timestamp */ - -extern const upb_msglayout google_protobuf_Timestamp_msginit; -UPB_INLINE google_protobuf_Timestamp* google_protobuf_Timestamp_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_Timestamp_msginit, arena); -} -UPB_INLINE google_protobuf_Timestamp* google_protobuf_Timestamp_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_Timestamp* ret = google_protobuf_Timestamp_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_Timestamp_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_Timestamp_serialize( - const google_protobuf_Timestamp* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_Timestamp_msginit, arena, len); -} - -UPB_INLINE int64_t -google_protobuf_Timestamp_seconds(const google_protobuf_Timestamp* msg) { - return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); -} -UPB_INLINE int32_t -google_protobuf_Timestamp_nanos(const google_protobuf_Timestamp* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); -} - -UPB_INLINE void google_protobuf_Timestamp_set_seconds( - google_protobuf_Timestamp* msg, int64_t value) { - UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; -} -UPB_INLINE void google_protobuf_Timestamp_set_nanos( - google_protobuf_Timestamp* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; -} - -UPB_END_EXTERN_C - -#include "upb/port_undef.inc" - -#endif /* GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c deleted file mode 100644 index 3fa3bea1dbc..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c +++ /dev/null @@ -1,87 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/wrappers.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#include "google/protobuf/wrappers.upb.h" -#include -#include "upb/msg.h" - -#include "upb/port_def.inc" - -static const upb_msglayout_field google_protobuf_DoubleValue__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 1, 1}, -}; - -const upb_msglayout google_protobuf_DoubleValue_msginit = { - NULL, &google_protobuf_DoubleValue__fields[0], UPB_SIZE(8, 8), 1, false, -}; - -static const upb_msglayout_field google_protobuf_FloatValue__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 2, 1}, -}; - -const upb_msglayout google_protobuf_FloatValue_msginit = { - NULL, &google_protobuf_FloatValue__fields[0], UPB_SIZE(4, 4), 1, false, -}; - -static const upb_msglayout_field google_protobuf_Int64Value__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, -}; - -const upb_msglayout google_protobuf_Int64Value_msginit = { - NULL, &google_protobuf_Int64Value__fields[0], UPB_SIZE(8, 8), 1, false, -}; - -static const upb_msglayout_field google_protobuf_UInt64Value__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 4, 1}, -}; - -const upb_msglayout google_protobuf_UInt64Value_msginit = { - NULL, &google_protobuf_UInt64Value__fields[0], UPB_SIZE(8, 8), 1, false, -}; - -static const upb_msglayout_field google_protobuf_Int32Value__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 5, 1}, -}; - -const upb_msglayout google_protobuf_Int32Value_msginit = { - NULL, &google_protobuf_Int32Value__fields[0], UPB_SIZE(4, 4), 1, false, -}; - -static const upb_msglayout_field google_protobuf_UInt32Value__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 13, 1}, -}; - -const upb_msglayout google_protobuf_UInt32Value_msginit = { - NULL, &google_protobuf_UInt32Value__fields[0], UPB_SIZE(4, 4), 1, false, -}; - -static const upb_msglayout_field google_protobuf_BoolValue__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 8, 1}, -}; - -const upb_msglayout google_protobuf_BoolValue_msginit = { - NULL, &google_protobuf_BoolValue__fields[0], UPB_SIZE(1, 1), 1, false, -}; - -static const upb_msglayout_field google_protobuf_StringValue__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, -}; - -const upb_msglayout google_protobuf_StringValue_msginit = { - NULL, &google_protobuf_StringValue__fields[0], UPB_SIZE(8, 16), 1, false, -}; - -static const upb_msglayout_field google_protobuf_BytesValue__fields[1] = { - {1, UPB_SIZE(0, 0), 0, 0, 12, 1}, -}; - -const upb_msglayout google_protobuf_BytesValue_msginit = { - NULL, &google_protobuf_BytesValue__fields[0], UPB_SIZE(8, 16), 1, false, -}; - -#include "upb/port_undef.inc" diff --git a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h deleted file mode 100644 index 3ae5d3b16e3..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h +++ /dev/null @@ -1,305 +0,0 @@ -/* This file was generated by upbc (the upb compiler) from the input - * file: - * - * google/protobuf/wrappers.proto - * - * Do not edit -- your changes will be discarded when the file is - * regenerated. */ - -#ifndef GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ -#define GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ - -#include "upb/msg.h" - -#include "upb/decode.h" -#include "upb/encode.h" -#include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C - -struct google_protobuf_DoubleValue; -struct google_protobuf_FloatValue; -struct google_protobuf_Int64Value; -struct google_protobuf_UInt64Value; -struct google_protobuf_Int32Value; -struct google_protobuf_UInt32Value; -struct google_protobuf_BoolValue; -struct google_protobuf_StringValue; -struct google_protobuf_BytesValue; -typedef struct google_protobuf_DoubleValue google_protobuf_DoubleValue; -typedef struct google_protobuf_FloatValue google_protobuf_FloatValue; -typedef struct google_protobuf_Int64Value google_protobuf_Int64Value; -typedef struct google_protobuf_UInt64Value google_protobuf_UInt64Value; -typedef struct google_protobuf_Int32Value google_protobuf_Int32Value; -typedef struct google_protobuf_UInt32Value google_protobuf_UInt32Value; -typedef struct google_protobuf_BoolValue google_protobuf_BoolValue; -typedef struct google_protobuf_StringValue google_protobuf_StringValue; -typedef struct google_protobuf_BytesValue google_protobuf_BytesValue; - -/* Enums */ - -/* google.protobuf.DoubleValue */ - -extern const upb_msglayout google_protobuf_DoubleValue_msginit; -UPB_INLINE google_protobuf_DoubleValue* google_protobuf_DoubleValue_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_DoubleValue_msginit, arena); -} -UPB_INLINE google_protobuf_DoubleValue* google_protobuf_DoubleValue_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_DoubleValue* ret = google_protobuf_DoubleValue_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_DoubleValue_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_DoubleValue_serialize( - const google_protobuf_DoubleValue* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_DoubleValue_msginit, arena, len); -} - -UPB_INLINE double google_protobuf_DoubleValue_value( - const google_protobuf_DoubleValue* msg) { - return UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_DoubleValue_set_value( - google_protobuf_DoubleValue* msg, double value) { - UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.FloatValue */ - -extern const upb_msglayout google_protobuf_FloatValue_msginit; -UPB_INLINE google_protobuf_FloatValue* google_protobuf_FloatValue_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_FloatValue_msginit, arena); -} -UPB_INLINE google_protobuf_FloatValue* google_protobuf_FloatValue_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_FloatValue* ret = google_protobuf_FloatValue_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_FloatValue_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_FloatValue_serialize( - const google_protobuf_FloatValue* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_FloatValue_msginit, arena, len); -} - -UPB_INLINE float google_protobuf_FloatValue_value( - const google_protobuf_FloatValue* msg) { - return UPB_FIELD_AT(msg, float, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_FloatValue_set_value( - google_protobuf_FloatValue* msg, float value) { - UPB_FIELD_AT(msg, float, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.Int64Value */ - -extern const upb_msglayout google_protobuf_Int64Value_msginit; -UPB_INLINE google_protobuf_Int64Value* google_protobuf_Int64Value_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_Int64Value_msginit, arena); -} -UPB_INLINE google_protobuf_Int64Value* google_protobuf_Int64Value_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_Int64Value* ret = google_protobuf_Int64Value_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_Int64Value_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_Int64Value_serialize( - const google_protobuf_Int64Value* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_Int64Value_msginit, arena, len); -} - -UPB_INLINE int64_t -google_protobuf_Int64Value_value(const google_protobuf_Int64Value* msg) { - return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_Int64Value_set_value( - google_protobuf_Int64Value* msg, int64_t value) { - UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.UInt64Value */ - -extern const upb_msglayout google_protobuf_UInt64Value_msginit; -UPB_INLINE google_protobuf_UInt64Value* google_protobuf_UInt64Value_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_UInt64Value_msginit, arena); -} -UPB_INLINE google_protobuf_UInt64Value* google_protobuf_UInt64Value_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_UInt64Value* ret = google_protobuf_UInt64Value_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_UInt64Value_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_UInt64Value_serialize( - const google_protobuf_UInt64Value* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_UInt64Value_msginit, arena, len); -} - -UPB_INLINE uint64_t -google_protobuf_UInt64Value_value(const google_protobuf_UInt64Value* msg) { - return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_UInt64Value_set_value( - google_protobuf_UInt64Value* msg, uint64_t value) { - UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.Int32Value */ - -extern const upb_msglayout google_protobuf_Int32Value_msginit; -UPB_INLINE google_protobuf_Int32Value* google_protobuf_Int32Value_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_Int32Value_msginit, arena); -} -UPB_INLINE google_protobuf_Int32Value* google_protobuf_Int32Value_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_Int32Value* ret = google_protobuf_Int32Value_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_Int32Value_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_Int32Value_serialize( - const google_protobuf_Int32Value* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_Int32Value_msginit, arena, len); -} - -UPB_INLINE int32_t -google_protobuf_Int32Value_value(const google_protobuf_Int32Value* msg) { - return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_Int32Value_set_value( - google_protobuf_Int32Value* msg, int32_t value) { - UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.UInt32Value */ - -extern const upb_msglayout google_protobuf_UInt32Value_msginit; -UPB_INLINE google_protobuf_UInt32Value* google_protobuf_UInt32Value_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); -} -UPB_INLINE google_protobuf_UInt32Value* google_protobuf_UInt32Value_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_UInt32Value* ret = google_protobuf_UInt32Value_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_UInt32Value_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_UInt32Value_serialize( - const google_protobuf_UInt32Value* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_UInt32Value_msginit, arena, len); -} - -UPB_INLINE uint32_t -google_protobuf_UInt32Value_value(const google_protobuf_UInt32Value* msg) { - return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_UInt32Value_set_value( - google_protobuf_UInt32Value* msg, uint32_t value) { - UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.BoolValue */ - -extern const upb_msglayout google_protobuf_BoolValue_msginit; -UPB_INLINE google_protobuf_BoolValue* google_protobuf_BoolValue_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_BoolValue_msginit, arena); -} -UPB_INLINE google_protobuf_BoolValue* google_protobuf_BoolValue_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_BoolValue* ret = google_protobuf_BoolValue_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_BoolValue_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_BoolValue_serialize( - const google_protobuf_BoolValue* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_BoolValue_msginit, arena, len); -} - -UPB_INLINE bool google_protobuf_BoolValue_value( - const google_protobuf_BoolValue* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_BoolValue_set_value( - google_protobuf_BoolValue* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.StringValue */ - -extern const upb_msglayout google_protobuf_StringValue_msginit; -UPB_INLINE google_protobuf_StringValue* google_protobuf_StringValue_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_StringValue_msginit, arena); -} -UPB_INLINE google_protobuf_StringValue* google_protobuf_StringValue_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_StringValue* ret = google_protobuf_StringValue_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_StringValue_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_StringValue_serialize( - const google_protobuf_StringValue* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_StringValue_msginit, arena, len); -} - -UPB_INLINE upb_stringview -google_protobuf_StringValue_value(const google_protobuf_StringValue* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_StringValue_set_value( - google_protobuf_StringValue* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.BytesValue */ - -extern const upb_msglayout google_protobuf_BytesValue_msginit; -UPB_INLINE google_protobuf_BytesValue* google_protobuf_BytesValue_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_BytesValue_msginit, arena); -} -UPB_INLINE google_protobuf_BytesValue* google_protobuf_BytesValue_parsenew( - upb_stringview buf, upb_arena* arena) { - google_protobuf_BytesValue* ret = google_protobuf_BytesValue_new(arena); - return (ret && upb_decode(buf, ret, &google_protobuf_BytesValue_msginit)) - ? ret - : NULL; -} -UPB_INLINE char* google_protobuf_BytesValue_serialize( - const google_protobuf_BytesValue* msg, upb_arena* arena, size_t* len) { - return upb_encode(msg, &google_protobuf_BytesValue_msginit, arena, len); -} - -UPB_INLINE upb_stringview -google_protobuf_BytesValue_value(const google_protobuf_BytesValue* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_BytesValue_set_value( - google_protobuf_BytesValue* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; -} - -UPB_END_EXTERN_C - -#include "upb/port_undef.inc" - -#endif /* GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ */ diff --git a/src/upb/gen_build_yaml.py b/src/upb/gen_build_yaml.py deleted file mode 100755 index 0dd7bfae109..00000000000 --- a/src/upb/gen_build_yaml.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python2.7 - -# Copyright 2015 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. - -# TODO: This should ideally be in upb submodule to avoid hardcoding this here. - -import re -import os -import sys -import yaml - -srcs = [ - "third_party/upb/google/protobuf/descriptor.upb.c", - "third_party/upb/upb/decode.c", - "third_party/upb/upb/def.c", - "third_party/upb/upb/encode.c", - "third_party/upb/upb/handlers.c", - "third_party/upb/upb/msg.c", - "third_party/upb/upb/msgfactory.c", - "third_party/upb/upb/refcounted.c", - "third_party/upb/upb/sink.c", - "third_party/upb/upb/table.c", - "third_party/upb/upb/upb.c", -] - -hdrs = [ - "third_party/upb/google/protobuf/descriptor.upb.h", - "third_party/upb/upb/decode.h", - "third_party/upb/upb/def.h", - "third_party/upb/upb/encode.h", - "third_party/upb/upb/handlers.h", - "third_party/upb/upb/msg.h", - "third_party/upb/upb/msgfactory.h", - "third_party/upb/upb/refcounted.h", - "third_party/upb/upb/sink.h", - "third_party/upb/upb/upb.h", -] - -os.chdir(os.path.dirname(sys.argv[0])+'/../..') - -out = {} - -try: - out['libs'] = [{ - 'name': 'upb', - 'defaults': 'upb', - 'build': 'private', - 'language': 'c', - 'secure': 'no', - 'src': srcs, - 'headers': hdrs, - }] -except: - pass - -print yaml.dump(out) - diff --git a/tools/buildgen/generate_build_additions.sh b/tools/buildgen/generate_build_additions.sh index c99ad6ee552..5a1f4a598a7 100755 --- a/tools/buildgen/generate_build_additions.sh +++ b/tools/buildgen/generate_build_additions.sh @@ -19,7 +19,6 @@ gen_build_yaml_dirs=" \ src/boringssl \ src/benchmark \ src/proto \ - src/upb \ src/zlib \ src/c-ares \ test/core/bad_client \ diff --git a/tools/codegen/core/gen_upb_api.sh b/tools/codegen/core/gen_upb_api.sh deleted file mode 100755 index 9457e06f124..00000000000 --- a/tools/codegen/core/gen_upb_api.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# Copyright 2016 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# REQUIRES: Bazel -set -ex -rm -rf src/core/ext/upb-generated -mkdir src/core/ext/upb-generated -cd third_party -cd upb -bazel build :protoc-gen-upb - -cd ../.. - -proto_files=( \ - "google/protobuf/any.proto" \ - "google/protobuf/struct.proto" \ - "google/protobuf/wrappers.proto" \ - "google/protobuf/descriptor.proto" \ - "google/protobuf/duration.proto" \ - "google/protobuf/timestamp.proto" ) - -for i in "${proto_files[@]}" -do - protoc -I=$PWD/third_party/data-plane-api -I=$PWD/third_party/googleapis -I=$PWD/third_party/protobuf -I=$PWD/third_party/protoc-gen-validate $i --upb_out=./src/core/ext/upb-generated --plugin=protoc-gen-upb=third_party/upb/bazel-bin/protoc-gen-upb -done diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py index fd93cf31e05..787bef1778e 100755 --- a/tools/distrib/check_copyright.py +++ b/tools/distrib/check_copyright.py @@ -104,20 +104,6 @@ _EXEMPT = frozenset(( # Designer-generated source 'examples/csharp/HelloworldXamarin/Droid/Resources/Resource.designer.cs', 'examples/csharp/HelloworldXamarin/iOS/ViewController.designer.cs', - - # Upb generated source - 'src/core/ext/upb-generated/google/protobuf/any.upb.h', - 'src/core/ext/upb-generated/google/protobuf/any.upb.c', - 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.h', - 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.c', - 'src/core/ext/upb-generated/google/protobuf/duration.upb.h', - 'src/core/ext/upb-generated/google/protobuf/duration.upb.c', - 'src/core/ext/upb-generated/google/protobuf/struct.upb.h', - 'src/core/ext/upb-generated/google/protobuf/struct.upb.c', - 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.h', - 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.c', - 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.h', - 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.c', )) RE_YEAR = r'Copyright (?P[0-9]+\-)?(?P[0-9]+) ([Tt]he )?gRPC [Aa]uthors(\.|)' diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py index 15b3478e555..b8d530cce06 100755 --- a/tools/distrib/check_include_guards.py +++ b/tools/distrib/check_include_guards.py @@ -165,20 +165,6 @@ KNOWN_BAD = set([ 'src/core/tsi/alts/handshaker/transport_security_common.pb.h', 'include/grpc++/ext/reflection.grpc.pb.h', 'include/grpc++/ext/reflection.pb.h', - - # Upb generated code - 'src/core/ext/upb-generated/google/protobuf/any.upb.h', - 'src/core/ext/upb-generated/google/protobuf/any.upb.c', - 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.h', - 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.c', - 'src/core/ext/upb-generated/google/protobuf/duration.upb.h', - 'src/core/ext/upb-generated/google/protobuf/duration.upb.c', - 'src/core/ext/upb-generated/google/protobuf/struct.upb.h', - 'src/core/ext/upb-generated/google/protobuf/struct.upb.c', - 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.h', - 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.c', - 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.h', - 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.c', ]) grep_filter = r"grep -E '^(include|src/core)/.*\.h$'" diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 5b0041a250d..2451101f58d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8831,27 +8831,6 @@ "third_party": false, "type": "lib" }, - { - "deps": [], - "headers": [ - "third_party/upb/google/protobuf/descriptor.upb.h", - "third_party/upb/upb/decode.h", - "third_party/upb/upb/def.h", - "third_party/upb/upb/encode.h", - "third_party/upb/upb/handlers.h", - "third_party/upb/upb/msg.h", - "third_party/upb/upb/msgfactory.h", - "third_party/upb/upb/refcounted.h", - "third_party/upb/upb/sink.h", - "third_party/upb/upb/upb.h" - ], - "is_filegroup": false, - "language": "c", - "name": "upb", - "src": [], - "third_party": false, - "type": "lib" - }, { "deps": [], "headers": [ diff --git a/tools/run_tests/sanity/check_port_platform.py b/tools/run_tests/sanity/check_port_platform.py index 8c412700e45..fff828eaee8 100755 --- a/tools/run_tests/sanity/check_port_platform.py +++ b/tools/run_tests/sanity/check_port_platform.py @@ -35,9 +35,6 @@ def check_port_platform_inclusion(directory_root): continue if filename.endswith('.pb.h') or filename.endswith('.pb.c'): continue - # Skip check for upb generated code - if filename.endswith('.upb.h') or filename.endswith('.upb.c'): - continue with open(path) as f: all_lines_in_file = f.readlines() for index, l in enumerate(all_lines_in_file): From b15758ab371ced8ee541dc62869b63bc247773ea Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 12 Dec 2018 12:25:11 -0800 Subject: [PATCH 275/534] Fix alignment in memory counters. --- test/core/util/memory_counters.cc | 32 +++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index 4960fe07572..d0da05d9b4d 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -22,6 +22,7 @@ #include #include +#include "src/core/lib/gpr/alloc.h" #include "test/core/util/memory_counters.h" static struct grpc_memory_counters g_memory_counters; @@ -42,19 +43,18 @@ static void guard_free(void* vptr); #endif static void* guard_malloc(size_t size) { - size_t* ptr; if (!size) return nullptr; NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, (gpr_atm)1); - ptr = static_cast(g_old_allocs.malloc_fn(size + sizeof(size))); - *ptr++ = size; - return ptr; + void* ptr = g_old_allocs.malloc_fn( + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); + *static_cast(ptr) = size; + return static_cast(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); } static void* guard_realloc(void* vptr, size_t size) { - size_t* ptr = static_cast(vptr); if (vptr == nullptr) { return guard_malloc(size); } @@ -62,21 +62,25 @@ static void* guard_realloc(void* vptr, size_t size) { guard_free(vptr); return nullptr; } - --ptr; + void* ptr = + static_cast(vptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, + -*static_cast(ptr)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); - ptr = static_cast(g_old_allocs.realloc_fn(ptr, size + sizeof(size))); - *ptr++ = size; - return ptr; + ptr = g_old_allocs.realloc_fn( + ptr, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); + *static_cast(ptr) = size; + return static_cast(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); } static void guard_free(void* vptr) { - size_t* ptr = static_cast(vptr); - if (!vptr) return; - --ptr; - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr); + if (vptr == nullptr) return; + void* ptr = + static_cast(vptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size_t)); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, + -*static_cast(ptr)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, -(gpr_atm)1); g_old_allocs.free_fn(ptr); } From a31ccd49e685b26514514f282798a9464433650b Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Wed, 12 Dec 2018 12:45:00 -0800 Subject: [PATCH 276/534] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 8 ++++---- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 2 +- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 28 files changed, 34 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c199696a9b..b39e6f8e885 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.17.1-pre1") +set(PACKAGE_VERSION "1.17.1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 18f49301d76..736583fd936 100644 --- a/Makefile +++ b/Makefile @@ -438,8 +438,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.17.1-pre1 -CSHARP_VERSION = 1.17.1-pre1 +CPP_VERSION = 1.17.1 +CSHARP_VERSION = 1.17.1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index ba26e3979d6..65a3f5584d1 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.17.1-pre1' - version = '0.0.6-pre1' + # version = '1.17.1' + version = '0.0.6' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.17.1-pre1' + grpc_version = '1.17.1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 4b499208f5c..bf0d33ca3cc 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.17.1-pre1' + version = '1.17.1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 5d5bd6c47f5..c781ac12117 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.17.1-pre1' + version = '1.17.1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 9c453f0b192..e9a07fe0c0b 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.17.1-pre1' + version = '1.17.1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 83c7fceef1a..54420ae5cc8 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.17.1-pre1' + version = '1.17.1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 3e3d0c354c3..f1cfe0f6231 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.17.1RC1 - 1.17.1RC1 + 1.17.1 + 1.17.1 - beta - beta + stable + stable Apache 2.0 diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index af717f9934f..94d10196ebb 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.17.1-pre1"; } +grpc::string Version() { return "1.17.1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 1935ab77e4f..64a38f3f2d3 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.17.1-pre1 + 1.17.1 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 1209c509d03..3b7a76557da 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.17.1-pre1"; + public const string CurrentVersion = "1.17.1"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 996700b3e1e..42ed94f20a2 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.17.1-pre1 +set VERSION=1.17.1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 2fec12ddf89..a3a096588ad 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.17.1-pre1 +set VERSION=1.17.1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 65524edad29..b68dde831bb 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.17.1-pre1' + v = '1.17.1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 02d2c58a7d0..8da4d65a838 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.17.1-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.17.1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 8c3e0da603f..65f9ad4912a 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.17.1-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.17.1" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 9e79442157f..3ae5450748a 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.17.1RC1" +#define PHP_GRPC_VERSION "1.17.1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 63e56efa6b1..effc73ed79f 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.17.1rc1""" +__version__ = """1.17.1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 03f7db3b2fe..382ed461715 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.17.1rc1' +VERSION = '1.17.1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index c0817d51dce..62f4f394fce 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.17.1rc1' +VERSION = '1.17.1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 445513c6045..ab82077c478 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.17.1rc1' +VERSION = '1.17.1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 0c89e08dfbf..096f1d30fd3 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.17.1rc1' +VERSION = '1.17.1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 5b861bc0c83..b3ec30934ab 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.17.1rc1' +VERSION = '1.17.1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 3af5e94a7d0..2d7b867937a 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.17.1.pre1' + VERSION = '1.17.1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index e27237158e0..68fba45b9b4 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.17.1.pre1' + VERSION = '1.17.1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 628315ad26e..a43a6ace9ee 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.17.1rc1' +VERSION = '1.17.1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index c32e6b34519..73658d16b7b 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.17.1-pre1 +PROJECT_NUMBER = 1.17.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index d62f540ce84..02c9e75e819 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.17.1-pre1 +PROJECT_NUMBER = 1.17.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 7dc330f298154571163603a8b568015412767cad Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 12 Oct 2018 11:56:29 -0700 Subject: [PATCH 277/534] Disable SRV and TXT lookups for localhost --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 9 ++++-- .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 29 +++++++++++++++++++ .../dns_resolver_connectivity_test.cc | 5 +++- test/core/end2end/fuzzers/api_fuzzer.cc | 5 +++- test/core/iomgr/resolve_address_posix_test.cc | 13 +++++++-- 5 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index c8425ae3365..fc83fc44889 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -465,11 +465,16 @@ static grpc_error* blocking_resolve_address_ares( static grpc_address_resolver_vtable ares_resolver = { grpc_resolve_address_ares, blocking_resolve_address_ares}; +static bool should_use_ares(const char* resolver_env) { + return resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0; +} + void grpc_resolver_dns_ares_init() { char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); /* TODO(zyc): Turn on c-ares based resolver by default after the address sorter and the CNAME support are added. */ - if (resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0) { + if (should_use_ares(resolver_env)) { + gpr_log(GPR_DEBUG, "Using ares dns resolver"); address_sorting_init(); grpc_error* error = grpc_ares_init(); if (error != GRPC_ERROR_NONE) { @@ -489,7 +494,7 @@ void grpc_resolver_dns_ares_init() { void grpc_resolver_dns_ares_shutdown() { char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0) { + if (should_use_ares(resolver_env)) { address_sorting_shutdown(); grpc_ares_cleanup(); } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index 1b1c2303da3..68977567694 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -510,6 +510,28 @@ static bool resolve_as_ip_literal_locked( return out; } +static bool target_matches_localhost_inner(const char* name, char** host, + char** port) { + if (!gpr_split_host_port(name, host, port)) { + gpr_log(GPR_INFO, "Unable to split host and port for name: %s", name); + return false; + } + if (gpr_stricmp(*host, "localhost") == 0) { + return true; + } else { + return false; + } +} + +static bool target_matches_localhost(const char* name) { + char* host = nullptr; + char* port = nullptr; + bool out = target_matches_localhost_inner(name, &host, &port); + gpr_free(host); + gpr_free(port); + return out; +} + static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, @@ -536,6 +558,13 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); return r; } + // Don't query for SRV and TXT records if the target is "localhost", so + // as to cut down on lookups over the network, especially in tests: + // https://github.com/grpc/proposal/pull/79 + if (target_matches_localhost(name)) { + check_grpclb = false; + r->service_config_json_out = nullptr; + } // Look up name using c-ares lib. grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( r, dns_server, name, default_port, interested_parties, check_grpclb, diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc index 1a7a7c9ccc9..0cf549d01da 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -76,7 +76,10 @@ static grpc_ares_request* my_dns_lookup_ares_locked( } else { gpr_mu_unlock(&g_mu); *addresses = grpc_core::MakeUnique(); - (*addresses)->emplace_back(nullptr, 0, nullptr); + grpc_resolved_address dummy_resolved_address; + memset(&dummy_resolved_address, 0, sizeof(dummy_resolved_address)); + dummy_resolved_address.len = 123; + (*addresses)->emplace_back(dummy_resolved_address, nullptr); } GRPC_CLOSURE_SCHED(on_done, error); return nullptr; diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index fe471279841..a0b82904753 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -342,7 +342,10 @@ static void finish_resolve(void* arg, grpc_error* error) { *r->addrs = addrs; } else if (r->addresses != nullptr) { *r->addresses = grpc_core::MakeUnique(); - (*r->addresses)->emplace_back(nullptr, 0, nullptr); + grpc_resolved_address dummy_resolved_address; + memset(&dummy_resolved_address, 0, sizeof(dummy_resolved_address)); + dummy_resolved_address.len = 0; + (*r->addresses)->emplace_back(dummy_resolved_address, nullptr); } GRPC_CLOSURE_SCHED(r->on_done, GRPC_ERROR_NONE); } else { diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc index ceeb70a1086..5785c73e225 100644 --- a/test/core/iomgr/resolve_address_posix_test.cc +++ b/test/core/iomgr/resolve_address_posix_test.cc @@ -27,6 +27,8 @@ #include #include +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/executor.h" @@ -163,8 +165,15 @@ int main(int argc, char** argv) { { grpc_core::ExecCtx exec_ctx; - test_unix_socket(); - test_unix_socket_path_name_too_long(); + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + // c-ares resolver doesn't support UDS (ability for native DNS resolver + // to handle this is only expected to be used by servers, which + // unconditionally use the native DNS resolver). + if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) { + test_unix_socket(); + test_unix_socket_path_name_too_long(); + } + gpr_free(resolver_env); } grpc_shutdown(); From 1334f8d2009eba9cf9a00bb2469e514a43cd5f22 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 12 Dec 2018 13:27:29 -0800 Subject: [PATCH 278/534] Revert alignment hack in New<> and Delete<>. --- src/core/lib/gprpp/memory.h | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/core/lib/gprpp/memory.h b/src/core/lib/gprpp/memory.h index e90bedcd9b4..b4b63ae771a 100644 --- a/src/core/lib/gprpp/memory.h +++ b/src/core/lib/gprpp/memory.h @@ -40,15 +40,10 @@ namespace grpc_core { -// The alignment of memory returned by gpr_malloc(). -constexpr size_t kAlignmentForDefaultAllocationInBytes = 8; - // Alternative to new, since we cannot use it (for fear of libstdc++) template inline T* New(Args&&... args) { - void* p = alignof(T) > kAlignmentForDefaultAllocationInBytes - ? gpr_malloc_aligned(sizeof(T), alignof(T)) - : gpr_malloc(sizeof(T)); + void* p = gpr_malloc(sizeof(T)); return new (p) T(std::forward(args)...); } @@ -57,11 +52,7 @@ template inline void Delete(T* p) { if (p == nullptr) return; p->~T(); - if (alignof(T) > kAlignmentForDefaultAllocationInBytes) { - gpr_free_aligned(p); - } else { - gpr_free(p); - } + gpr_free(p); } template From fd74fcf2a07a40cd18b5795614c9f71a0e463e87 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Dec 2018 13:48:39 -0800 Subject: [PATCH 279/534] New abort with grpc.Status API * Add `abort_with_status` method in ServicerContext * Add `Status` interface similar to the design of Details in interceptor * Add 3 unit test cases for abort mechanism --- src/python/grpcio/grpc/__init__.py | 36 +++++ src/python/grpcio/grpc/_server.py | 4 + .../grpc_testing/_server/_servicer_context.py | 3 + src/python/grpcio_tests/tests/tests.json | 1 + .../grpcio_tests/tests/unit/BUILD.bazel | 1 + .../grpcio_tests/tests/unit/_abort_test.py | 124 ++++++++++++++++++ .../grpcio_tests/tests/unit/_api_test.py | 1 + 7 files changed, 170 insertions(+) create mode 100644 src/python/grpcio_tests/tests/unit/_abort_test.py diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 6022fc3ef21..441f4ac8132 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -266,6 +266,23 @@ class StatusCode(enum.Enum): UNAUTHENTICATED = (_cygrpc.StatusCode.unauthenticated, 'unauthenticated') +############################# gRPC Status ################################ + + +class Status(six.with_metaclass(abc.ABCMeta)): + """Describes the status of an RPC. + + This is an EXPERIMENTAL API. + + Attributes: + code: A StatusCode object to be sent to the client. + It must not be StatusCode.OK. + details: An ASCII-encodable string to be sent to the client upon + termination of the RPC. + trailing_metadata: The trailing :term:`metadata` in the RPC. + """ + + ############################# gRPC Exceptions ################################ @@ -1118,6 +1135,24 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): """ raise NotImplementedError() + @abc.abstractmethod + def abort_with_status(self, status): + """Raises an exception to terminate the RPC with a non-OK status. + + The status passed as argument will supercede any existing status code, + status message and trailing metadata. + + This is an EXPERIMENTAL API. + + Args: + status: A grpc.Status object. + + Raises: + Exception: An exception is always raised to signal the abortion the + RPC to the gRPC runtime. + """ + raise NotImplementedError() + @abc.abstractmethod def set_code(self, code): """Sets the value to be used as status code upon RPC completion. @@ -1747,6 +1782,7 @@ __all__ = ( 'Future', 'ChannelConnectivity', 'StatusCode', + 'Status', 'RpcError', 'RpcContext', 'Call', diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index e939f615dfd..3bbfa47da53 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -291,6 +291,10 @@ class _Context(grpc.ServicerContext): self._state.abortion = Exception() raise self._state.abortion + def abort_with_status(self, status): + self._state.trailing_metadata = status.trailing_metadata + self.abort(status.code, status.details) + def set_code(self, code): with self._state.condition: self._state.code = code diff --git a/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py b/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py index 90eeb130d30..5b1dfeacdf5 100644 --- a/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py +++ b/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py @@ -70,6 +70,9 @@ class ServicerContext(grpc.ServicerContext): def abort(self, code, details): raise NotImplementedError() + def abort_with_status(self, status): + raise NotImplementedError() + def set_code(self, code): self._rpc.set_code(code) diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index 9cffd3df197..44700e979e9 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -19,6 +19,7 @@ "testing._server_test.FirstServiceServicerTest", "testing._time_test.StrictFakeTimeTest", "testing._time_test.StrictRealTimeTest", + "unit._abort_test.AbortTest", "unit._api_test.AllTest", "unit._api_test.ChannelConnectivityTest", "unit._api_test.ChannelTest", diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index de33b81e325..4f850220f8f 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -3,6 +3,7 @@ load("@grpc_python_dependencies//:requirements.bzl", "requirement") package(default_visibility = ["//visibility:public"]) GRPCIO_TESTS_UNIT = [ + "_abort_test.py", "_api_test.py", "_auth_context_test.py", "_auth_test.py", diff --git a/src/python/grpcio_tests/tests/unit/_abort_test.py b/src/python/grpcio_tests/tests/unit/_abort_test.py new file mode 100644 index 00000000000..6438f6897a0 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_abort_test.py @@ -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. +"""Tests server context abort mechanism""" + +import unittest +import collections +import logging + +import grpc + +from tests.unit import test_common +from tests.unit.framework.common import test_constants + +_ABORT = '/test/abort' +_ABORT_WITH_STATUS = '/test/AbortWithStatus' +_INVALID_CODE = '/test/InvalidCode' + +_REQUEST = b'\x00\x00\x00' +_RESPONSE = b'\x00\x00\x00' + +_ABORT_DETAILS = 'Abandon ship!' +_ABORT_METADATA = (('a-trailing-metadata', '42'),) + + +class _Status( + collections.namedtuple( + '_Status', ('code', 'details', 'trailing_metadata')), grpc.Status): + pass + + +def abort_unary_unary(request, servicer_context): + servicer_context.abort( + grpc.StatusCode.INTERNAL, + _ABORT_DETAILS, + ) + raise Exception('This line should not be executed!') + + +def abort_with_status_unary_unary(request, servicer_context): + servicer_context.abort_with_status( + _Status( + code=grpc.StatusCode.INTERNAL, + details=_ABORT_DETAILS, + trailing_metadata=_ABORT_METADATA, + )) + raise Exception('This line should not be executed!') + + +def invalid_code_unary_unary(request, servicer_context): + servicer_context.abort( + 42, + _ABORT_DETAILS, + ) + + +class _GenericHandler(grpc.GenericRpcHandler): + + def service(self, handler_call_details): + if handler_call_details.method == _ABORT: + return grpc.unary_unary_rpc_method_handler(abort_unary_unary) + elif handler_call_details.method == _ABORT_WITH_STATUS: + return grpc.unary_unary_rpc_method_handler( + abort_with_status_unary_unary) + elif handler_call_details.method == _INVALID_CODE: + return grpc.stream_stream_rpc_method_handler( + invalid_code_unary_unary) + else: + return None + + +class AbortTest(unittest.TestCase): + + def setUp(self): + self._server = test_common.test_server() + port = self._server.add_insecure_port('[::]:0') + self._server.add_generic_rpc_handlers((_GenericHandler(),)) + self._server.start() + + self._channel = grpc.insecure_channel('localhost:%d' % port) + + def tearDown(self): + self._channel.close() + self._server.stop(0) + + def test_abort(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_ABORT)(_REQUEST) + rpc_error = exception_context.exception + + self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) + self.assertEqual(rpc_error.details(), _ABORT_DETAILS) + + def test_abort_with_status(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_ABORT_WITH_STATUS)(_REQUEST) + rpc_error = exception_context.exception + + self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) + self.assertEqual(rpc_error.details(), _ABORT_DETAILS) + self.assertEqual(rpc_error.trailing_metadata(), _ABORT_METADATA) + + def test_invalid_code(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_INVALID_CODE)(_REQUEST) + rpc_error = exception_context.exception + + self.assertEqual(rpc_error.code(), grpc.StatusCode.UNKNOWN) + self.assertEqual(rpc_error.details(), _ABORT_DETAILS) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py index 38072861a49..427894bfe9f 100644 --- a/src/python/grpcio_tests/tests/unit/_api_test.py +++ b/src/python/grpcio_tests/tests/unit/_api_test.py @@ -32,6 +32,7 @@ class AllTest(unittest.TestCase): 'Future', 'ChannelConnectivity', 'StatusCode', + 'Status', 'RpcError', 'RpcContext', 'Call', From 3fc5ca0c75aae97e9201df000a5afd5f628403b8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 12 Dec 2018 14:30:12 -0800 Subject: [PATCH 280/534] batch fix --- .../GRPCClient/private/GRPCInsecureChannelFactory.m | 2 +- src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m | 2 +- src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index b802137c13a..8ad1e848f55 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -33,7 +33,7 @@ } - (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { - grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); + grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); GRPCFreeChannelArgs(coreChannelArgs); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 3ccc70a7448..96998895364 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -119,7 +119,7 @@ if (host.length == 0) { return NULL; } - grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); + grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); GRPCFreeChannelArgs(coreChannelArgs); diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 4edd9d3e378..1a848a4b7c3 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -307,6 +307,10 @@ - (void)channelDisconnected { @synchronized(self) { if (_call != NULL) { + // Unreference the call will lead to its cancellation in the core. Note that since + // this function is only called with a network state change, any existing GRPCCall object will + // also receive the same notification and cancel themselves with GRPCErrorCodeUnavailable, so + // the user gets GRPCErrorCodeUnavailable in this case. grpc_call_unref(_call); _call = NULL; } From 087d48a8bd74f39eabea96b495d132e3332b5927 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Dec 2018 14:31:52 -0800 Subject: [PATCH 281/534] Update the documentation about the status code constraint --- src/python/grpcio/grpc/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 441f4ac8132..daf869b1563 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -276,7 +276,6 @@ class Status(six.with_metaclass(abc.ABCMeta)): Attributes: code: A StatusCode object to be sent to the client. - It must not be StatusCode.OK. details: An ASCII-encodable string to be sent to the client upon termination of the RPC. trailing_metadata: The trailing :term:`metadata` in the RPC. @@ -1145,7 +1144,8 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): This is an EXPERIMENTAL API. Args: - status: A grpc.Status object. + status: A grpc.Status object. The status code in it must not be + StatusCode.OK. Raises: Exception: An exception is always raised to signal the abortion the From bd142d6c46ff97ccd17031d8cd272b6d2ea1206e Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 12 Dec 2018 14:19:05 -0800 Subject: [PATCH 282/534] Actually build CensusContext --- src/python/grpcio/grpc/_channel.py | 40 +++++++++++++++++++----------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 35fa82d56bd..96118badada 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -499,6 +499,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._context = cygrpc.build_context() def _prepare(self, request, timeout, metadata, wait_for_ready): deadline, serialized_request, rendezvous = _start_unary_request( @@ -528,11 +529,12 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): raise rendezvous else: call = self._channel.segregated_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, + self._method, None, deadline, metadata, None if credentials is None else credentials._credentials, (( operations, None, - ),)) + ),), self._context) event = call.next_event() _handle_event(event, state, self._response_deserializer) return state, call, @@ -570,9 +572,10 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): else: event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, + self._method, None, deadline, metadata, None if credentials is None else credentials._credentials, - (operations,), event_handler) + (operations,), event_handler, self._context) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -587,6 +590,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._context = cygrpc.build_context() def __call__(self, request, @@ -615,9 +619,10 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): ) event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, + self._method, None, deadline, metadata, None if credentials is None else credentials._credentials, - operationses, event_handler) + operationses, event_handler, self._context) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -632,6 +637,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._context = cygrpc.build_context() def _blocking(self, request_iterator, timeout, metadata, credentials, wait_for_ready): @@ -640,10 +646,11 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) call = self._channel.segregated_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, deadline, metadata, None if credentials is None else credentials._credentials, _stream_unary_invocation_operationses_and_tags( - metadata, initial_metadata_flags)) + metadata, initial_metadata_flags), self._context) _consume_request_iterator(request_iterator, state, call, self._request_serializer, None) while True: @@ -687,10 +694,11 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) call = self._managed_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, deadline, metadata, None if credentials is None else credentials._credentials, _stream_unary_invocation_operationses( - metadata, initial_metadata_flags), event_handler) + metadata, initial_metadata_flags), event_handler, self._context) _consume_request_iterator(request_iterator, state, call, self._request_serializer, event_handler) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -706,6 +714,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._context = cygrpc.build_context() def __call__(self, request_iterator, @@ -727,9 +736,10 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): ) event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, deadline, metadata, None if credentials is None else credentials._credentials, operationses, - event_handler) + event_handler, self._context) _consume_request_iterator(request_iterator, state, call, self._request_serializer, event_handler) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -789,7 +799,7 @@ def _channel_managed_call_management(state): # pylint: disable=too-many-arguments def create(flags, method, host, deadline, metadata, credentials, - operationses, event_handler): + operationses, event_handler, context): """Creates a cygrpc.IntegratedCall. Args: @@ -804,7 +814,7 @@ def _channel_managed_call_management(state): started on the call. event_handler: A behavior to call to handle the events resultant from the operations on the call. - + context: Context object for distributed tracing. Returns: A cygrpc.IntegratedCall with which to conduct an RPC. """ @@ -815,7 +825,7 @@ def _channel_managed_call_management(state): with state.lock: call = state.channel.integrated_call(flags, method, host, deadline, metadata, credentials, - operationses_and_tags) + operationses_and_tags, context) if state.managed_calls == 0: state.managed_calls = 1 _run_channel_spin_thread(state) From 7fd68349e3ac2dbf642cb1c7907901ad51b5d6c6 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Dec 2018 14:50:32 -0800 Subject: [PATCH 283/534] Add gRPC Python Example: Metadata --- examples/python/metadata/README.md | 6 + examples/python/metadata/helloworld_pb2.py | 134 ++++++++++++++++++ .../python/metadata/helloworld_pb2_grpc.py | 46 ++++++ examples/python/metadata/metadata_client.py | 48 +++++++ examples/python/metadata/metadata_server.py | 56 ++++++++ 5 files changed, 290 insertions(+) create mode 100644 examples/python/metadata/README.md create mode 100644 examples/python/metadata/helloworld_pb2.py create mode 100644 examples/python/metadata/helloworld_pb2_grpc.py create mode 100644 examples/python/metadata/metadata_client.py create mode 100644 examples/python/metadata/metadata_server.py diff --git a/examples/python/metadata/README.md b/examples/python/metadata/README.md new file mode 100644 index 00000000000..5aa75d504a8 --- /dev/null +++ b/examples/python/metadata/README.md @@ -0,0 +1,6 @@ +An example showing how to add custom HTTP2 headers (or [metadata](https://grpc.io/grpc/python/glossary.html) in gRPC glossary) + +HTTP2 supports initial headers and trailing headers, which gRPC utilizes both of them ([learn more](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md)). + +More complete documentation lives at [grpc.io](https://grpc.io/docs/tutorials/basic/python.html). +For API reference please see [API](https://grpc.io/grpc/python/grpc.html). diff --git a/examples/python/metadata/helloworld_pb2.py b/examples/python/metadata/helloworld_pb2.py new file mode 100644 index 00000000000..e18ab9acc7a --- /dev/null +++ b/examples/python/metadata/helloworld_pb2.py @@ -0,0 +1,134 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: helloworld.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='helloworld.proto', + package='helloworld', + syntax='proto3', + serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3') +) + + + + +_HELLOREQUEST = _descriptor.Descriptor( + name='HelloRequest', + full_name='helloworld.HelloRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='helloworld.HelloRequest.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=32, + serialized_end=60, +) + + +_HELLOREPLY = _descriptor.Descriptor( + name='HelloReply', + full_name='helloworld.HelloReply', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='helloworld.HelloReply.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=62, + serialized_end=91, +) + +DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST +DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict( + DESCRIPTOR = _HELLOREQUEST, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + )) +_sym_db.RegisterMessage(HelloRequest) + +HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict( + DESCRIPTOR = _HELLOREPLY, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloReply) + )) +_sym_db.RegisterMessage(HelloReply) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW')) + +_GREETER = _descriptor.ServiceDescriptor( + name='Greeter', + full_name='helloworld.Greeter', + file=DESCRIPTOR, + index=0, + options=None, + serialized_start=93, + serialized_end=166, + methods=[ + _descriptor.MethodDescriptor( + name='SayHello', + full_name='helloworld.Greeter.SayHello', + index=0, + containing_service=None, + input_type=_HELLOREQUEST, + output_type=_HELLOREPLY, + options=None, + ), +]) +_sym_db.RegisterServiceDescriptor(_GREETER) + +DESCRIPTOR.services_by_name['Greeter'] = _GREETER + +# @@protoc_insertion_point(module_scope) diff --git a/examples/python/metadata/helloworld_pb2_grpc.py b/examples/python/metadata/helloworld_pb2_grpc.py new file mode 100644 index 00000000000..18e07d16797 --- /dev/null +++ b/examples/python/metadata/helloworld_pb2_grpc.py @@ -0,0 +1,46 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +import grpc + +import helloworld_pb2 as helloworld__pb2 + + +class GreeterStub(object): + """The greeting service definition. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.SayHello = channel.unary_unary( + '/helloworld.Greeter/SayHello', + request_serializer=helloworld__pb2.HelloRequest.SerializeToString, + response_deserializer=helloworld__pb2.HelloReply.FromString, + ) + + +class GreeterServicer(object): + """The greeting service definition. + """ + + def SayHello(self, request, context): + """Sends a greeting + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_GreeterServicer_to_server(servicer, server): + rpc_method_handlers = { + 'SayHello': grpc.unary_unary_rpc_method_handler( + servicer.SayHello, + request_deserializer=helloworld__pb2.HelloRequest.FromString, + response_serializer=helloworld__pb2.HelloReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'helloworld.Greeter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) diff --git a/examples/python/metadata/metadata_client.py b/examples/python/metadata/metadata_client.py new file mode 100644 index 00000000000..f2a8e37cc21 --- /dev/null +++ b/examples/python/metadata/metadata_client.py @@ -0,0 +1,48 @@ +# Copyright 2018 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. +"""Example gRPC client that gets/sets metadata (HTTP2 headers)""" + +from __future__ import print_function +import logging + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + + +def run(): + # NOTE(gRPC Python Team): .close() is possible on a channel and should be + # used in circumstances in which the with statement does not fit the needs + # of the code. + with grpc.insecure_channel('localhost:50051') as channel: + stub = helloworld_pb2_grpc.GreeterStub(channel) + response, call = stub.SayHello.with_call( + helloworld_pb2.HelloRequest(name='you'), + metadata=( + ('initial-metadata-1', 'The value should be str'), + ('binary-metadata-bin', + b'With -bin surffix, the value can be bytes'), + ('accesstoken', 'gRPC Python is great'), + )) + + print("Greeter client received: " + response.message) + for key, value in call.trailing_metadata(): + print('Greeter client received trailing metadata: key=%s value=%s' % + (key, value)) + + +if __name__ == '__main__': + logging.basicConfig() + run() diff --git a/examples/python/metadata/metadata_server.py b/examples/python/metadata/metadata_server.py new file mode 100644 index 00000000000..a4329df79aa --- /dev/null +++ b/examples/python/metadata/metadata_server.py @@ -0,0 +1,56 @@ +# Copyright 2018 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. +"""Example gRPC server that gets/sets metadata (HTTP2 headers)""" + +from __future__ import print_function +from concurrent import futures +import time +import logging + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +class Greeter(helloworld_pb2_grpc.GreeterServicer): + + def SayHello(self, request, context): + for key, value in context.invocation_metadata(): + print('Received initial metadata: key=%s value=%s' % (key, value)) + + context.set_trailing_metadata(( + ('checksum-bin', b'I agree'), + ('retry', 'false'), + )) + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def serve(): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) + server.add_insecure_port('[::]:50051') + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop(0) + + +if __name__ == '__main__': + logging.basicConfig() + serve() From a69fa16dfdb7795f4918c50f607c4306e598d4d9 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 12 Dec 2018 15:06:12 -0800 Subject: [PATCH 284/534] Add compression example --- examples/cpp/compression/Makefile | 110 +++++++++++++++++++++ examples/cpp/compression/README.md | 84 ++++++++++++++++ examples/cpp/compression/greeter_client.cc | 93 +++++++++++++++++ examples/cpp/compression/greeter_server.cc | 76 ++++++++++++++ 4 files changed, 363 insertions(+) create mode 100644 examples/cpp/compression/Makefile create mode 100644 examples/cpp/compression/README.md create mode 100644 examples/cpp/compression/greeter_client.cc create mode 100644 examples/cpp/compression/greeter_server.cc diff --git a/examples/cpp/compression/Makefile b/examples/cpp/compression/Makefile new file mode 100644 index 00000000000..47211886ff6 --- /dev/null +++ b/examples/cpp/compression/Makefile @@ -0,0 +1,110 @@ +# +# 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. +# + +HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) +CXX = g++ +CPPFLAGS += `pkg-config --cflags protobuf grpc` +CXXFLAGS += -std=c++11 +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -lgrpc++_reflection\ + -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ + -ldl +endif +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check greeter_client greeter_server + +greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + +greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + +.PRECIOUS: %.grpc.pb.cc +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + +.PRECIOUS: %.pb.cc +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + +clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/examples/cpp/compression/README.md b/examples/cpp/compression/README.md new file mode 100644 index 00000000000..13988f2c0c5 --- /dev/null +++ b/examples/cpp/compression/README.md @@ -0,0 +1,84 @@ +# gRPC C++ Message Compression Tutorial + +### Prerequisite +Make sure you have run the [hello world example](../helloworld) or understood the basics of gRPC. We will not dive into the details that have been discussed in the hello world example. + +### Get the tutorial source code + +The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: + + +```sh +$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc +``` + +Change your current directory to examples/cpp/compression + +```sh +$ cd examples/cpp/compression/ +``` + +### Generating gRPC code + +To generate the client and server side interfaces: + +```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` + +### Writing a client and a server + +The client and the server can be based on the hello world example. + +Additionally, we can configure the compression settings. + +In the client, set the default compression algorithm of the channel via the channel arg. + +```cpp + ChannelArguments args; + // Set the default compression algorithm for the channel. + args.SetCompressionAlgorithm(GRPC_COMPRESS_GZIP); + GreeterClient greeter(grpc::CreateCustomChannel( + "localhost:50051", grpc::InsecureChannelCredentials(), args)); +``` + +Each call's compression configuration can be overwritten by client context. + +```cpp + // Overwrite the call's compression algorithm to DEFLATE. + context.set_compression_algorithm(GRPC_COMPRESS_DEFLATE); +``` + +In the server, set the default compression algorithm via the server builder. + +```cpp + ServerBuilder builder; + // Set the default compression algorithm for the server. + builder.SetDefaultCompressionAlgorithm(GRPC_COMPRESS_GZIP); +``` + +Each call's compression configuration can be overwritten by server context. + +```cpp + // Overwrite the call's compression algorithm to DEFLATE. + context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE); +``` + +For a working example, refer to [greeter_client.cc](greeter_client.cc) and [greeter_server.cc](greeter_server.cc). + +Build and run the (compressing) client and the server by the following commands. + +```sh +make +./greeter_server +``` + +```sh +./greeter_client +``` diff --git a/examples/cpp/compression/greeter_client.cc b/examples/cpp/compression/greeter_client.cc new file mode 100644 index 00000000000..a8428174644 --- /dev/null +++ b/examples/cpp/compression/greeter_client.cc @@ -0,0 +1,93 @@ +/* + * + * 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + + // Overwrite the call's compression algorithm to DEFLATE. + context.set_compression_algorithm(GRPC_COMPRESS_DEFLATE); + + // The actual RPC. + Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. + if (status.ok()) { + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureChannelCredentials()). + ChannelArguments args; + // Set the default compression algorithm for the channel. + args.SetCompressionAlgorithm(GRPC_COMPRESS_GZIP); + GreeterClient greeter(grpc::CreateCustomChannel( + "localhost:50051", grpc::InsecureChannelCredentials(), args)); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + return 0; +} diff --git a/examples/cpp/compression/greeter_server.cc b/examples/cpp/compression/greeter_server.cc new file mode 100644 index 00000000000..7399017afb7 --- /dev/null +++ b/examples/cpp/compression/greeter_server.cc @@ -0,0 +1,76 @@ +/* + * + * 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + // Overwrite the call's compression algorithm to DEFLATE. + context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE); + std::string prefix("Hello "); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + // Set the default compression algorithm for the server. + builder.SetDefaultCompressionAlgorithm(GRPC_COMPRESS_GZIP); + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} From a050ae8ddc3a64151b344fd1a4d438db9dea2acb Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 13 Dec 2018 00:29:10 +0100 Subject: [PATCH 285/534] Revert "better slice management for win_read" This reverts commit b0139e15425196be518b251dbdfa3b86648b4740. --- src/core/lib/iomgr/tcp_windows.cc | 57 +++++++++---------------------- 1 file changed, 16 insertions(+), 41 deletions(-) diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 86ee1010cf7..aaf9fb4ea8a 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -113,10 +113,7 @@ typedef struct grpc_tcp { grpc_closure* read_cb; grpc_closure* write_cb; - - /* garbage after the last read */ - grpc_slice_buffer last_read_buffer; - + grpc_slice read_slice; grpc_slice_buffer* write_slices; grpc_slice_buffer* read_slices; @@ -135,7 +132,6 @@ static void tcp_free(grpc_tcp* tcp) { grpc_winsocket_destroy(tcp->socket); gpr_mu_destroy(&tcp->mu); gpr_free(tcp->peer_string); - grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); if (tcp->shutting_down) GRPC_ERROR_UNREF(tcp->shutdown_error); gpr_free(tcp); @@ -184,6 +180,7 @@ static void on_read(void* tcpp, grpc_error* error) { grpc_tcp* tcp = (grpc_tcp*)tcpp; grpc_closure* cb = tcp->read_cb; grpc_winsocket* socket = tcp->socket; + grpc_slice sub; grpc_winsocket_callback_info* info = &socket->read_info; if (grpc_tcp_trace.enabled()) { @@ -197,19 +194,11 @@ static void on_read(void* tcpp, grpc_error* error) { char* utf8_message = gpr_format_message(info->wsa_error); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(utf8_message); gpr_free(utf8_message); - grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); + grpc_slice_unref_internal(tcp->read_slice); } else { if (info->bytes_transfered != 0 && !tcp->shutting_down) { - GPR_ASSERT((size_t)info->bytes_transfered <= tcp->read_slices->length); - if (static_cast(info->bytes_transfered) != - tcp->read_slices->length) { - grpc_slice_buffer_trim_end( - tcp->read_slices, - tcp->read_slices->length - - static_cast(info->bytes_transfered), - &tcp->last_read_buffer); - } - GPR_ASSERT((size_t)info->bytes_transfered == tcp->read_slices->length); + sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); + grpc_slice_buffer_add(tcp->read_slices, sub); if (grpc_tcp_trace.enabled()) { size_t i; @@ -225,7 +214,7 @@ static void on_read(void* tcpp, grpc_error* error) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp); } - grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); + grpc_slice_unref_internal(tcp->read_slice); error = tcp->shutting_down ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "TCP stream shutting down", &tcp->shutdown_error, 1) @@ -239,8 +228,6 @@ static void on_read(void* tcpp, grpc_error* error) { GRPC_CLOSURE_SCHED(cb, error); } -#define DEFAULT_TARGET_READ_SIZE 8192 -#define MAX_WSABUF_COUNT 16 static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, grpc_closure* cb) { grpc_tcp* tcp = (grpc_tcp*)ep; @@ -249,8 +236,7 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, int status; DWORD bytes_read = 0; DWORD flags = 0; - WSABUF buffers[MAX_WSABUF_COUNT]; - size_t i; + WSABUF buffer; if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p win_read", tcp); @@ -266,27 +252,18 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, tcp->read_cb = cb; tcp->read_slices = read_slices; grpc_slice_buffer_reset_and_unref_internal(read_slices); - grpc_slice_buffer_swap(read_slices, &tcp->last_read_buffer); - if (tcp->read_slices->length < DEFAULT_TARGET_READ_SIZE / 2 && - tcp->read_slices->count < MAX_WSABUF_COUNT) { - // TODO(jtattermusch): slice should be allocated using resource quota - grpc_slice_buffer_add(tcp->read_slices, - GRPC_SLICE_MALLOC(DEFAULT_TARGET_READ_SIZE)); - } + tcp->read_slice = GRPC_SLICE_MALLOC(8192); - GPR_ASSERT(tcp->read_slices->count <= MAX_WSABUF_COUNT); - for (i = 0; i < tcp->read_slices->count; i++) { - buffers[i].len = (ULONG)GRPC_SLICE_LENGTH( - tcp->read_slices->slices[i]); // we know slice size fits in 32bit. - buffers[i].buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slices->slices[i]); - } + buffer.len = (ULONG)GRPC_SLICE_LENGTH( + tcp->read_slice); // we know slice size fits in 32bit. + buffer.buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slice); TCP_REF(tcp, "read"); /* First let's try a synchronous, non-blocking read. */ - status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count, - &bytes_read, &flags, NULL, NULL); + status = + WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, NULL, NULL); info->wsa_error = status == 0 ? 0 : WSAGetLastError(); /* Did we get data immediately ? Yay. */ @@ -298,8 +275,8 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, /* Otherwise, let's retry, by queuing a read. */ memset(&tcp->socket->read_info.overlapped, 0, sizeof(OVERLAPPED)); - status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count, - &bytes_read, &flags, &info->overlapped, NULL); + status = WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, + &info->overlapped, NULL); if (status != 0) { int wsa_error = WSAGetLastError(); @@ -353,7 +330,7 @@ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, unsigned i; DWORD bytes_sent; int status; - WSABUF local_buffers[MAX_WSABUF_COUNT]; + WSABUF local_buffers[16]; WSABUF* allocated = NULL; WSABUF* buffers = local_buffers; size_t len; @@ -472,7 +449,6 @@ static void win_shutdown(grpc_endpoint* ep, grpc_error* why) { static void win_destroy(grpc_endpoint* ep) { grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = (grpc_tcp*)ep; - grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); TCP_UNREF(tcp, "destroy"); } @@ -524,7 +500,6 @@ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, GRPC_CLOSURE_INIT(&tcp->on_read, on_read, tcp, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&tcp->on_write, on_write, tcp, grpc_schedule_on_exec_ctx); tcp->peer_string = gpr_strdup(peer_string); - grpc_slice_buffer_init(&tcp->last_read_buffer); tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string); /* Tell network status tracking code about the new endpoint */ grpc_network_status_register_endpoint(&tcp->base); From f438d72e6c5e5bd839a255322fb91c416822f629 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 13 Dec 2018 00:29:23 +0100 Subject: [PATCH 286/534] Revert "basic tcp_trace support for windows" This reverts commit 5861f082607344ed42215ac341e97e4b4bbf0abc. --- src/core/lib/iomgr/tcp_windows.cc | 37 ------------------------------- 1 file changed, 37 deletions(-) diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index aaf9fb4ea8a..4b5250803d1 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -42,7 +42,6 @@ #include "src/core/lib/iomgr/tcp_windows.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/slice/slice_string_helpers.h" #if defined(__MSYS__) && defined(GPR_ARCH_64) /* Nasty workaround for nasty bug when using the 64 bits msys compiler @@ -183,10 +182,6 @@ static void on_read(void* tcpp, grpc_error* error) { grpc_slice sub; grpc_winsocket_callback_info* info = &socket->read_info; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_INFO, "TCP:%p on_read", tcp); - } - GRPC_ERROR_REF(error); if (error == GRPC_ERROR_NONE) { @@ -199,21 +194,7 @@ static void on_read(void* tcpp, grpc_error* error) { if (info->bytes_transfered != 0 && !tcp->shutting_down) { sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); grpc_slice_buffer_add(tcp->read_slices, sub); - - if (grpc_tcp_trace.enabled()) { - size_t i; - for (i = 0; i < tcp->read_slices->count; i++) { - char* dump = grpc_dump_slice(tcp->read_slices->slices[i], - GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_INFO, "READ %p (peer=%s): %s", tcp, tcp->peer_string, - dump); - gpr_free(dump); - } - } } else { - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp); - } grpc_slice_unref_internal(tcp->read_slice); error = tcp->shutting_down ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -238,10 +219,6 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, DWORD flags = 0; WSABUF buffer; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_INFO, "TCP:%p win_read", tcp); - } - if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -298,10 +275,6 @@ static void on_write(void* tcpp, grpc_error* error) { grpc_winsocket_callback_info* info = &handle->write_info; grpc_closure* cb; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_INFO, "TCP:%p on_write", tcp); - } - GRPC_ERROR_REF(error); gpr_mu_lock(&tcp->mu); @@ -335,16 +308,6 @@ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, WSABUF* buffers = local_buffers; size_t len; - if (grpc_tcp_trace.enabled()) { - size_t i; - for (i = 0; i < slices->count; i++) { - char* data = - grpc_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_INFO, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data); - gpr_free(data); - } - } - if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( From 0f4d465452552cfaf16367241c8894034d1f575a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 12 Dec 2018 15:52:54 -0800 Subject: [PATCH 287/534] nit fix --- src/objective-c/GRPCClient/private/GRPCHost.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h index f1d57196424..ca3c52ea177 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.h +++ b/src/objective-c/GRPCClient/private/GRPCHost.h @@ -64,7 +64,7 @@ struct grpc_channel_credentials; withCertChain:(nullable NSString *)pemCertChain error:(NSError **)errorPtr; -@property(atomic, readwrite) GRPCTransportType transportType; +@property(atomic) GRPCTransportType transportType; + (GRPCCallOptions *)callOptionsForHost:(NSString *)host; From 827e84d0a4165e3e64d9ae0a1b8fbbaecdde0fa6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 12 Dec 2018 17:21:30 -0800 Subject: [PATCH 288/534] Fix unused variable error --- src/objective-c/tests/Podfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 12112f95e14..8e5f588906b 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -150,7 +150,9 @@ post_install do |installer| end # Enable NSAssert on gRPC - if target.name == 'gRPC' || target.name == 'ProtoRPC' || target.name == 'RxLibrary' + if target.name == 'gRPC' || target.name.start_with?('gRPC.') || + target.name == 'ProtoRPC' || target.name.start_with?('ProtoRPC.') || + target.name == 'RxLibrary' || target.name.start_with?('RxLibrary.') target.build_configurations.each do |config| if config.name != 'Release' config.build_settings['ENABLE_NS_ASSERTIONS'] = 'YES' From 6f083e112c509e4ef964b90eb1c3654033123878 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 12 Dec 2018 17:43:52 -0800 Subject: [PATCH 289/534] revert pb files --- .../lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c | 4 ++-- src/core/tsi/alts/handshaker/altscontext.pb.c | 4 ++-- src/core/tsi/alts/handshaker/handshaker.pb.c | 4 ++-- src/core/tsi/alts/handshaker/transport_security_common.pb.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c index a7b072420ec..f6538e1349f 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c @@ -75,14 +75,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_32BIT +/* If you get an error here, it means that you need to define PB_FIELD_16BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server) +PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server) #endif diff --git a/src/core/tsi/alts/handshaker/altscontext.pb.c b/src/core/tsi/alts/handshaker/altscontext.pb.c index 2320edb1eff..5fb152a558e 100644 --- a/src/core/tsi/alts/handshaker/altscontext.pb.c +++ b/src/core/tsi/alts/handshaker/altscontext.pb.c @@ -33,14 +33,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 65536 #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_32BIT +/* If you get an error here, it means that you need to define PB_FIELD_16BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_AltsContext) +PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_AltsContext) #endif diff --git a/src/core/tsi/alts/handshaker/handshaker.pb.c b/src/core/tsi/alts/handshaker/handshaker.pb.c index 8eda290e123..5450b1602d4 100644 --- a/src/core/tsi/alts/handshaker/handshaker.pb.c +++ b/src/core/tsi/alts/handshaker/handshaker.pb.c @@ -108,14 +108,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identit #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_32BIT +/* If you get an error here, it means that you need to define PB_FIELD_16BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identities) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_identity) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_ServerHandshakeParameters, local_identities) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, handshake_parameters[0]) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry, value) < 256 && pb_membersize(grpc_gcp_HandshakerReq, client_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, server_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, next) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, local_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_rpc_versions) < 256 && pb_membersize(grpc_gcp_HandshakerResp, result) < 256 && pb_membersize(grpc_gcp_HandshakerResp, status) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_Endpoint_grpc_gcp_Identity_grpc_gcp_StartClientHandshakeReq_grpc_gcp_ServerHandshakeParameters_grpc_gcp_StartServerHandshakeReq_grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_grpc_gcp_NextHandshakeMessageReq_grpc_gcp_HandshakerReq_grpc_gcp_HandshakerResult_grpc_gcp_HandshakerStatus_grpc_gcp_HandshakerResp) +PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identities) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_identity) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_ServerHandshakeParameters, local_identities) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, handshake_parameters[0]) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry, value) < 256 && pb_membersize(grpc_gcp_HandshakerReq, client_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, server_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, next) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, local_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_rpc_versions) < 256 && pb_membersize(grpc_gcp_HandshakerResp, result) < 256 && pb_membersize(grpc_gcp_HandshakerResp, status) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_Endpoint_grpc_gcp_Identity_grpc_gcp_StartClientHandshakeReq_grpc_gcp_ServerHandshakeParameters_grpc_gcp_StartServerHandshakeReq_grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_grpc_gcp_NextHandshakeMessageReq_grpc_gcp_HandshakerReq_grpc_gcp_HandshakerResult_grpc_gcp_HandshakerStatus_grpc_gcp_HandshakerResp) #endif diff --git a/src/core/tsi/alts/handshaker/transport_security_common.pb.c b/src/core/tsi/alts/handshaker/transport_security_common.pb.c index aac699314e7..326b1b10ab7 100644 --- a/src/core/tsi/alts/handshaker/transport_security_common.pb.c +++ b/src/core/tsi/alts/handshaker/transport_security_common.pb.c @@ -35,14 +35,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_32BIT +/* If you get an error here, it means that you need to define PB_FIELD_16BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < 256 && pb_membersize(grpc_gcp_RpcProtocolVersions, min_rpc_version) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_RpcProtocolVersions_grpc_gcp_RpcProtocolVersions_Version) +PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < 256 && pb_membersize(grpc_gcp_RpcProtocolVersions, min_rpc_version) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_RpcProtocolVersions_grpc_gcp_RpcProtocolVersions_Version) #endif From e8d6d4785410154a64554651898807063ce41e20 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 12 Dec 2018 17:58:52 -0800 Subject: [PATCH 290/534] Update README for #16821 --- src/objective-c/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/objective-c/README.md b/src/objective-c/README.md index 32e3956a1ef..83775f86e17 100644 --- a/src/objective-c/README.md +++ b/src/objective-c/README.md @@ -242,3 +242,12 @@ pod `gRPC-Core`, :podspec => "." # assuming gRPC-Core.podspec is in the same dir These steps should allow gRPC to use OpenSSL and drop BoringSSL dependency. If you see any issue, file an issue to us. + +## Upgrade issue with BoringSSL +If you were using an old version of gRPC (<= v1.14) which depended on pod `BoringSSL` rather than +`BoringSSL-GRPC` and meet issue with the library like: +``` +ld: framework not found openssl +``` +updating `-framework openssl` in Other Linker Flags to `-framework openssl_grpc` in your project +may resolve this issue (see [#16821](https://github.com/grpc/grpc/issues/16821)). From e1c78993becfde9006fde8397474da4679367b29 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 11 Dec 2018 14:41:38 -0800 Subject: [PATCH 291/534] re-enable unit._exit_test.ExitTest --- src/python/grpcio_tests/commands.py | 8 ++++++++ src/python/grpcio_tests/tests/unit/_exit_test.py | 15 ++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 65e9a99950e..18413abab02 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -133,6 +133,14 @@ class TestGevent(setuptools.Command): # TODO(https://github.com/grpc/grpc/issues/15411) unpin gevent version # This test will stuck while running higher version of gevent 'unit._auth_context_test.AuthContextTest.testSessionResumption', + # TODO(https://github.com/grpc/grpc/issues/15411) enable these tests + 'unit._exit_test.ExitTest.test_in_flight_unary_unary_call', + 'unit._exit_test.ExitTest.test_in_flight_unary_stream_call', + 'unit._exit_test.ExitTest.test_in_flight_stream_unary_call', + 'unit._exit_test.ExitTest.test_in_flight_stream_stream_call', + 'unit._exit_test.ExitTest.test_in_flight_partial_unary_stream_call', + 'unit._exit_test.ExitTest.test_in_flight_partial_stream_unary_call', + 'unit._exit_test.ExitTest.test_in_flight_partial_stream_stream_call', # TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels', 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels_and_sockets', diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py index 52265375799..b429ee089f7 100644 --- a/src/python/grpcio_tests/tests/unit/_exit_test.py +++ b/src/python/grpcio_tests/tests/unit/_exit_test.py @@ -71,7 +71,6 @@ def wait(process): process.wait() -@unittest.skip('https://github.com/grpc/grpc/issues/7311') class ExitTest(unittest.TestCase): def test_unstarted_server(self): @@ -130,6 +129,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_unary_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_UNARY_CALL], @@ -138,6 +139,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_STREAM_CALL], @@ -145,6 +148,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_UNARY_CALL], @@ -153,6 +158,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_STREAM_CALL], @@ -161,6 +168,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -169,6 +178,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -178,6 +189,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + From 9decf48632e2106a56515e67c4147e1a6506b47d Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 6 Dec 2018 01:17:51 -0500 Subject: [PATCH 292/534] Move security credentials, connectors, and auth context to C++ This is to use `grpc_core::RefCount` to improve performnace. This commit also replaces explicit C vtables, with C++ vtable with its own compile time assertions and performance benefits. It also makes use of `RefCountedPtr` wherever possible. --- .../lb_policy/grpclb/grpclb_channel_secure.cc | 10 +- .../lb_policy/xds/xds_channel_secure.cc | 10 +- .../client/secure/secure_channel_create.cc | 17 +- .../server/secure/server_secure_chttp2.cc | 19 +- src/core/lib/gprpp/ref_counted_ptr.h | 8 +- .../lib/http/httpcli_security_connector.cc | 195 ++--- src/core/lib/http/parser.h | 10 +- .../lib/security/context/security_context.cc | 183 ++--- .../lib/security/context/security_context.h | 94 ++- .../credentials/alts/alts_credentials.cc | 84 +- .../credentials/alts/alts_credentials.h | 47 +- .../composite/composite_credentials.cc | 297 ++++---- .../composite/composite_credentials.h | 111 ++- .../lib/security/credentials/credentials.cc | 160 +--- .../lib/security/credentials/credentials.h | 214 +++--- .../credentials/fake/fake_credentials.cc | 117 ++- .../credentials/fake/fake_credentials.h | 28 +- .../google_default_credentials.cc | 83 +- .../google_default_credentials.h | 33 +- .../credentials/iam/iam_credentials.cc | 62 +- .../credentials/iam/iam_credentials.h | 22 +- .../credentials/jwt/jwt_credentials.cc | 129 ++-- .../credentials/jwt/jwt_credentials.h | 39 +- .../credentials/local/local_credentials.cc | 51 +- .../credentials/local/local_credentials.h | 43 +- .../credentials/oauth2/oauth2_credentials.cc | 279 ++++--- .../credentials/oauth2/oauth2_credentials.h | 103 ++- .../credentials/plugin/plugin_credentials.cc | 136 ++-- .../credentials/plugin/plugin_credentials.h | 57 +- .../credentials/ssl/ssl_credentials.cc | 149 ++-- .../credentials/ssl/ssl_credentials.h | 73 +- .../alts/alts_security_connector.cc | 329 ++++---- .../alts/alts_security_connector.h | 22 +- .../fake/fake_security_connector.cc | 424 +++++------ .../fake/fake_security_connector.h | 15 +- .../local/local_security_connector.cc | 278 +++---- .../local/local_security_connector.h | 19 +- .../security_connector/security_connector.cc | 165 +--- .../security_connector/security_connector.h | 206 +++-- .../ssl/ssl_security_connector.cc | 718 +++++++++--------- .../ssl/ssl_security_connector.h | 26 +- .../security/security_connector/ssl_utils.cc | 22 +- .../security/security_connector/ssl_utils.h | 4 +- .../security/transport/client_auth_filter.cc | 100 +-- .../security/transport/security_handshaker.cc | 147 ++-- .../security/transport/server_auth_filter.cc | 28 +- src/cpp/client/secure_credentials.cc | 6 +- src/cpp/client/secure_credentials.h | 9 +- src/cpp/common/secure_auth_context.cc | 38 +- src/cpp/common/secure_auth_context.h | 11 +- src/cpp/common/secure_create_auth_context.cc | 5 +- src/cpp/server/secure_server_credentials.cc | 2 +- .../security/alts_security_connector_test.cc | 41 +- test/core/security/auth_context_test.cc | 116 +-- test/core/security/credentials_test.cc | 232 +++--- test/core/security/oauth2_utils.cc | 5 +- .../print_google_default_creds_token.cc | 9 +- test/core/security/security_connector_test.cc | 95 +-- test/core/security/ssl_server_fuzzer.cc | 11 +- .../surface/secure_channel_create_test.cc | 2 +- .../cpp/common/auth_property_iterator_test.cc | 17 +- test/cpp/common/secure_auth_context_test.cc | 14 +- test/cpp/end2end/grpclb_end2end_test.cc | 4 +- 63 files changed, 2940 insertions(+), 3043 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc index 6e8fbdcab77..657ff693126 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc @@ -88,22 +88,18 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( // bearer token credentials. grpc_channel_credentials* channel_credentials = grpc_channel_credentials_find_in_args(args); - grpc_channel_credentials* creds_sans_call_creds = nullptr; + grpc_core::RefCountedPtr creds_sans_call_creds; if (channel_credentials != nullptr) { creds_sans_call_creds = - grpc_channel_credentials_duplicate_without_call_credentials( - channel_credentials); + channel_credentials->duplicate_without_call_credentials(); GPR_ASSERT(creds_sans_call_creds != nullptr); args_to_remove[num_args_to_remove++] = GRPC_ARG_CHANNEL_CREDENTIALS; args_to_add[num_args_to_add++] = - grpc_channel_credentials_to_arg(creds_sans_call_creds); + grpc_channel_credentials_to_arg(creds_sans_call_creds.get()); } grpc_channel_args* result = grpc_channel_args_copy_and_add_and_remove( args, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add); // Clean up. grpc_channel_args_destroy(args); - if (creds_sans_call_creds != nullptr) { - grpc_channel_credentials_unref(creds_sans_call_creds); - } return result; } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc index 9a11f8e39fd..55c646e6eed 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc @@ -87,22 +87,18 @@ grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args( // bearer token credentials. grpc_channel_credentials* channel_credentials = grpc_channel_credentials_find_in_args(args); - grpc_channel_credentials* creds_sans_call_creds = nullptr; + grpc_core::RefCountedPtr creds_sans_call_creds; if (channel_credentials != nullptr) { creds_sans_call_creds = - grpc_channel_credentials_duplicate_without_call_credentials( - channel_credentials); + channel_credentials->duplicate_without_call_credentials(); GPR_ASSERT(creds_sans_call_creds != nullptr); args_to_remove[num_args_to_remove++] = GRPC_ARG_CHANNEL_CREDENTIALS; args_to_add[num_args_to_add++] = - grpc_channel_credentials_to_arg(creds_sans_call_creds); + grpc_channel_credentials_to_arg(creds_sans_call_creds.get()); } grpc_channel_args* result = grpc_channel_args_copy_and_add_and_remove( args, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add); // Clean up. grpc_channel_args_destroy(args); - if (creds_sans_call_creds != nullptr) { - grpc_channel_credentials_unref(creds_sans_call_creds); - } return result; } diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc index e73eee43537..9612698e967 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc @@ -110,14 +110,14 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( grpc_channel_args* args_with_authority = grpc_channel_args_copy_and_add(args->args, args_to_add, num_args_to_add); grpc_uri_destroy(server_uri); - grpc_channel_security_connector* subchannel_security_connector = nullptr; // Create the security connector using the credentials and target name. grpc_channel_args* new_args_from_connector = nullptr; - const grpc_security_status security_status = - grpc_channel_credentials_create_security_connector( - channel_credentials, authority.get(), args_with_authority, - &subchannel_security_connector, &new_args_from_connector); - if (security_status != GRPC_SECURITY_OK) { + grpc_core::RefCountedPtr + subchannel_security_connector = + channel_credentials->create_security_connector( + /*call_creds=*/nullptr, authority.get(), args_with_authority, + &new_args_from_connector); + if (subchannel_security_connector == nullptr) { gpr_log(GPR_ERROR, "Failed to create secure subchannel for secure name '%s'", authority.get()); @@ -125,15 +125,14 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( return nullptr; } grpc_arg new_security_connector_arg = - grpc_security_connector_to_arg(&subchannel_security_connector->base); + grpc_security_connector_to_arg(subchannel_security_connector.get()); grpc_channel_args* new_args = grpc_channel_args_copy_and_add( new_args_from_connector != nullptr ? new_args_from_connector : args_with_authority, &new_security_connector_arg, 1); - GRPC_SECURITY_CONNECTOR_UNREF(&subchannel_security_connector->base, - "lb_channel_create"); + subchannel_security_connector.reset(DEBUG_LOCATION, "lb_channel_create"); if (new_args_from_connector != nullptr) { grpc_channel_args_destroy(new_args_from_connector); } diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc index 6689a17da63..98fdb620704 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc @@ -31,6 +31,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/surface/api_trace.h" @@ -40,9 +41,8 @@ int grpc_server_add_secure_http2_port(grpc_server* server, const char* addr, grpc_server_credentials* creds) { grpc_core::ExecCtx exec_ctx; grpc_error* err = GRPC_ERROR_NONE; - grpc_server_security_connector* sc = nullptr; + grpc_core::RefCountedPtr sc; int port_num = 0; - grpc_security_status status; grpc_channel_args* args = nullptr; GRPC_API_TRACE( "grpc_server_add_secure_http2_port(" @@ -54,30 +54,27 @@ int grpc_server_add_secure_http2_port(grpc_server* server, const char* addr, "No credentials specified for secure server port (creds==NULL)"); goto done; } - status = grpc_server_credentials_create_security_connector(creds, &sc); - if (status != GRPC_SECURITY_OK) { + sc = creds->create_security_connector(); + if (sc == nullptr) { char* msg; gpr_asprintf(&msg, "Unable to create secure server with credentials of type %s.", - creds->type); - err = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg), - GRPC_ERROR_INT_SECURITY_STATUS, status); + creds->type()); + err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); goto done; } // Create channel args. grpc_arg args_to_add[2]; args_to_add[0] = grpc_server_credentials_to_arg(creds); - args_to_add[1] = grpc_security_connector_to_arg(&sc->base); + args_to_add[1] = grpc_security_connector_to_arg(sc.get()); args = grpc_channel_args_copy_and_add(grpc_server_get_channel_args(server), args_to_add, GPR_ARRAY_SIZE(args_to_add)); // Add server port. err = grpc_chttp2_server_add_port(server, addr, args, &port_num); done: - if (sc != nullptr) { - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server"); - } + sc.reset(DEBUG_LOCATION, "server"); if (err != GRPC_ERROR_NONE) { const char* msg = grpc_error_string(err); diff --git a/src/core/lib/gprpp/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h index 1ed5d584c70..19f38d7f013 100644 --- a/src/core/lib/gprpp/ref_counted_ptr.h +++ b/src/core/lib/gprpp/ref_counted_ptr.h @@ -50,7 +50,7 @@ class RefCountedPtr { } template RefCountedPtr(RefCountedPtr&& other) { - value_ = other.value_; + value_ = static_cast(other.value_); other.value_ = nullptr; } @@ -77,7 +77,7 @@ class RefCountedPtr { static_assert(std::has_virtual_destructor::value, "T does not have a virtual dtor"); if (other.value_ != nullptr) other.value_->IncrementRefCount(); - value_ = other.value_; + value_ = static_cast(other.value_); } // Copy assignment. @@ -118,7 +118,7 @@ class RefCountedPtr { static_assert(std::has_virtual_destructor::value, "T does not have a virtual dtor"); if (value_ != nullptr) value_->Unref(); - value_ = value; + value_ = static_cast(value); } template void reset(const DebugLocation& location, const char* reason, @@ -126,7 +126,7 @@ class RefCountedPtr { static_assert(std::has_virtual_destructor::value, "T does not have a virtual dtor"); if (value_ != nullptr) value_->Unref(location, reason); - value_ = value; + value_ = static_cast(value); } // TODO(roth): This method exists solely as a transition mechanism to allow diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 1c798d368b0..6802851392c 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -29,119 +29,125 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "src/core/lib/security/transport/security_handshaker.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/tsi/ssl_transport_security.h" -typedef struct { - grpc_channel_security_connector base; - tsi_ssl_client_handshaker_factory* handshaker_factory; - char* secure_peer_name; -} grpc_httpcli_ssl_channel_security_connector; - -static void httpcli_ssl_destroy(grpc_security_connector* sc) { - grpc_httpcli_ssl_channel_security_connector* c = - reinterpret_cast(sc); - if (c->handshaker_factory != nullptr) { - tsi_ssl_client_handshaker_factory_unref(c->handshaker_factory); - c->handshaker_factory = nullptr; +class grpc_httpcli_ssl_channel_security_connector final + : public grpc_channel_security_connector { + public: + explicit grpc_httpcli_ssl_channel_security_connector(char* secure_peer_name) + : grpc_channel_security_connector( + /*url_scheme=*/nullptr, + /*channel_creds=*/nullptr, + /*request_metadata_creds=*/nullptr), + secure_peer_name_(secure_peer_name) {} + + ~grpc_httpcli_ssl_channel_security_connector() override { + if (handshaker_factory_ != nullptr) { + tsi_ssl_client_handshaker_factory_unref(handshaker_factory_); + } + if (secure_peer_name_ != nullptr) { + gpr_free(secure_peer_name_); + } + } + + tsi_result InitHandshakerFactory(const char* pem_root_certs, + const tsi_ssl_root_certs_store* root_store) { + tsi_ssl_client_handshaker_options options; + memset(&options, 0, sizeof(options)); + options.pem_root_certs = pem_root_certs; + options.root_store = root_store; + return tsi_create_ssl_client_handshaker_factory_with_options( + &options, &handshaker_factory_); } - if (c->secure_peer_name != nullptr) gpr_free(c->secure_peer_name); - gpr_free(sc); -} -static void httpcli_ssl_add_handshakers(grpc_channel_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_httpcli_ssl_channel_security_connector* c = - reinterpret_cast(sc); - tsi_handshaker* handshaker = nullptr; - if (c->handshaker_factory != nullptr) { - tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( - c->handshaker_factory, c->secure_peer_name, &handshaker); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) override { + tsi_handshaker* handshaker = nullptr; + if (handshaker_factory_ != nullptr) { + tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( + handshaker_factory_, secure_peer_name_, &handshaker); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + } } + grpc_handshake_manager_add( + handshake_mgr, grpc_security_handshaker_create(handshaker, this)); } - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(handshaker, &sc->base)); -} -static void httpcli_ssl_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_httpcli_ssl_channel_security_connector* c = - reinterpret_cast(sc); - grpc_error* error = GRPC_ERROR_NONE; - - /* Check the peer name. */ - if (c->secure_peer_name != nullptr && - !tsi_ssl_peer_matches_name(&peer, c->secure_peer_name)) { - char* msg; - gpr_asprintf(&msg, "Peer name %s is not in peer certificate", - c->secure_peer_name); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); + tsi_ssl_client_handshaker_factory* handshaker_factory() const { + return handshaker_factory_; } - GRPC_CLOSURE_SCHED(on_peer_checked, error); - tsi_peer_destruct(&peer); -} -static int httpcli_ssl_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_httpcli_ssl_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_httpcli_ssl_channel_security_connector* c2 = - reinterpret_cast(sc2); - return strcmp(c1->secure_peer_name, c2->secure_peer_name); -} + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* /*auth_context*/, + grpc_closure* on_peer_checked) override { + grpc_error* error = GRPC_ERROR_NONE; + + /* Check the peer name. */ + if (secure_peer_name_ != nullptr && + !tsi_ssl_peer_matches_name(&peer, secure_peer_name_)) { + char* msg; + gpr_asprintf(&msg, "Peer name %s is not in peer certificate", + secure_peer_name_); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + } + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); + } -static grpc_security_connector_vtable httpcli_ssl_vtable = { - httpcli_ssl_destroy, httpcli_ssl_check_peer, httpcli_ssl_cmp}; + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast( + other_sc); + return strcmp(secure_peer_name_, other->secure_peer_name_); + } -static grpc_security_status httpcli_ssl_channel_security_connector_create( - const char* pem_root_certs, const tsi_ssl_root_certs_store* root_store, - const char* secure_peer_name, grpc_channel_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_httpcli_ssl_channel_security_connector* c; + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + *error = GRPC_ERROR_NONE; + return true; + } - if (secure_peer_name != nullptr && pem_root_certs == nullptr) { - gpr_log(GPR_ERROR, - "Cannot assert a secure peer name without a trust root."); - return GRPC_SECURITY_ERROR; + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); } - c = static_cast( - gpr_zalloc(sizeof(grpc_httpcli_ssl_channel_security_connector))); + const char* secure_peer_name() const { return secure_peer_name_; } - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &httpcli_ssl_vtable; - if (secure_peer_name != nullptr) { - c->secure_peer_name = gpr_strdup(secure_peer_name); + private: + tsi_ssl_client_handshaker_factory* handshaker_factory_ = nullptr; + char* secure_peer_name_; +}; + +static grpc_core::RefCountedPtr +httpcli_ssl_channel_security_connector_create( + const char* pem_root_certs, const tsi_ssl_root_certs_store* root_store, + const char* secure_peer_name) { + if (secure_peer_name != nullptr && pem_root_certs == nullptr) { + gpr_log(GPR_ERROR, + "Cannot assert a secure peer name without a trust root."); + return nullptr; } - tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); - options.pem_root_certs = pem_root_certs; - options.root_store = root_store; - result = tsi_create_ssl_client_handshaker_factory_with_options( - &options, &c->handshaker_factory); + grpc_core::RefCountedPtr c = + grpc_core::MakeRefCounted( + secure_peer_name == nullptr ? nullptr : gpr_strdup(secure_peer_name)); + tsi_result result = c->InitHandshakerFactory(pem_root_certs, root_store); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", tsi_result_to_string(result)); - httpcli_ssl_destroy(&c->base.base); - *sc = nullptr; - return GRPC_SECURITY_ERROR; + return nullptr; } - // We don't actually need a channel credentials object in this case, - // but we set it to a non-nullptr address so that we don't trigger - // assertions in grpc_channel_security_connector_cmp(). - c->base.channel_creds = (grpc_channel_credentials*)1; - c->base.add_handshakers = httpcli_ssl_add_handshakers; - *sc = &c->base; - return GRPC_SECURITY_OK; + return c; } /* handshaker */ @@ -186,10 +192,11 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host, } c->func = on_done; c->arg = arg; - grpc_channel_security_connector* sc = nullptr; - GPR_ASSERT(httpcli_ssl_channel_security_connector_create( - pem_root_certs, root_store, host, &sc) == GRPC_SECURITY_OK); - grpc_arg channel_arg = grpc_security_connector_to_arg(&sc->base); + grpc_core::RefCountedPtr sc = + httpcli_ssl_channel_security_connector_create(pem_root_certs, root_store, + host); + GPR_ASSERT(sc != nullptr); + grpc_arg channel_arg = grpc_security_connector_to_arg(sc.get()); grpc_channel_args args = {1, &channel_arg}; c->handshake_mgr = grpc_handshake_manager_create(); grpc_handshakers_add(HANDSHAKER_CLIENT, &args, @@ -197,7 +204,7 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host, grpc_handshake_manager_do_handshake( c->handshake_mgr, tcp, nullptr /* channel_args */, deadline, nullptr /* acceptor */, on_handshake_done, c /* user_data */); - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); + sc.reset(DEBUG_LOCATION, "httpcli"); } const grpc_httpcli_handshaker grpc_httpcli_ssl = {"https", ssl_handshake}; diff --git a/src/core/lib/http/parser.h b/src/core/lib/http/parser.h index 1d2e13e8317..a8f47c96c85 100644 --- a/src/core/lib/http/parser.h +++ b/src/core/lib/http/parser.h @@ -70,13 +70,13 @@ typedef struct grpc_http_request { /* A response */ typedef struct grpc_http_response { /* HTTP status code */ - int status; + int status = 0; /* Headers: count and key/values */ - size_t hdr_count; - grpc_http_header* hdrs; + size_t hdr_count = 0; + grpc_http_header* hdrs = nullptr; /* Body: length and contents; contents are NOT null-terminated */ - size_t body_length; - char* body; + size_t body_length = 0; + char* body = nullptr; } grpc_http_response; typedef struct { diff --git a/src/core/lib/security/context/security_context.cc b/src/core/lib/security/context/security_context.cc index 16f40b4f55d..8443ee0695a 100644 --- a/src/core/lib/security/context/security_context.cc +++ b/src/core/lib/security/context/security_context.cc @@ -23,6 +23,8 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/arena.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/call.h" @@ -50,13 +52,11 @@ grpc_call_error grpc_call_set_credentials(grpc_call* call, ctx = static_cast( grpc_call_context_get(call, GRPC_CONTEXT_SECURITY)); if (ctx == nullptr) { - ctx = grpc_client_security_context_create(grpc_call_get_arena(call)); - ctx->creds = grpc_call_credentials_ref(creds); + ctx = grpc_client_security_context_create(grpc_call_get_arena(call), creds); grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx, grpc_client_security_context_destroy); } else { - grpc_call_credentials_unref(ctx->creds); - ctx->creds = grpc_call_credentials_ref(creds); + ctx->creds = creds != nullptr ? creds->Ref() : nullptr; } return GRPC_CALL_OK; @@ -66,33 +66,45 @@ grpc_auth_context* grpc_call_auth_context(grpc_call* call) { void* sec_ctx = grpc_call_context_get(call, GRPC_CONTEXT_SECURITY); GRPC_API_TRACE("grpc_call_auth_context(call=%p)", 1, (call)); if (sec_ctx == nullptr) return nullptr; - return grpc_call_is_client(call) - ? GRPC_AUTH_CONTEXT_REF( - ((grpc_client_security_context*)sec_ctx)->auth_context, - "grpc_call_auth_context client") - : GRPC_AUTH_CONTEXT_REF( - ((grpc_server_security_context*)sec_ctx)->auth_context, - "grpc_call_auth_context server"); + if (grpc_call_is_client(call)) { + auto* sc = static_cast(sec_ctx); + if (sc->auth_context == nullptr) { + return nullptr; + } else { + return sc->auth_context + ->Ref(DEBUG_LOCATION, "grpc_call_auth_context client") + .release(); + } + } else { + auto* sc = static_cast(sec_ctx); + if (sc->auth_context == nullptr) { + return nullptr; + } else { + return sc->auth_context + ->Ref(DEBUG_LOCATION, "grpc_call_auth_context server") + .release(); + } + } } void grpc_auth_context_release(grpc_auth_context* context) { GRPC_API_TRACE("grpc_auth_context_release(context=%p)", 1, (context)); - GRPC_AUTH_CONTEXT_UNREF(context, "grpc_auth_context_unref"); + if (context == nullptr) return; + context->Unref(DEBUG_LOCATION, "grpc_auth_context_unref"); } /* --- grpc_client_security_context --- */ grpc_client_security_context::~grpc_client_security_context() { - grpc_call_credentials_unref(creds); - GRPC_AUTH_CONTEXT_UNREF(auth_context, "client_security_context"); + auth_context.reset(DEBUG_LOCATION, "client_security_context"); if (extension.instance != nullptr && extension.destroy != nullptr) { extension.destroy(extension.instance); } } grpc_client_security_context* grpc_client_security_context_create( - gpr_arena* arena) { + gpr_arena* arena, grpc_call_credentials* creds) { return new (gpr_arena_alloc(arena, sizeof(grpc_client_security_context))) - grpc_client_security_context(); + grpc_client_security_context(creds != nullptr ? creds->Ref() : nullptr); } void grpc_client_security_context_destroy(void* ctx) { @@ -104,7 +116,7 @@ void grpc_client_security_context_destroy(void* ctx) { /* --- grpc_server_security_context --- */ grpc_server_security_context::~grpc_server_security_context() { - GRPC_AUTH_CONTEXT_UNREF(auth_context, "server_security_context"); + auth_context.reset(DEBUG_LOCATION, "server_security_context"); if (extension.instance != nullptr && extension.destroy != nullptr) { extension.destroy(extension.instance); } @@ -126,69 +138,11 @@ void grpc_server_security_context_destroy(void* ctx) { static grpc_auth_property_iterator empty_iterator = {nullptr, 0, nullptr}; -grpc_auth_context* grpc_auth_context_create(grpc_auth_context* chained) { - grpc_auth_context* ctx = - static_cast(gpr_zalloc(sizeof(grpc_auth_context))); - gpr_ref_init(&ctx->refcount, 1); - if (chained != nullptr) { - ctx->chained = GRPC_AUTH_CONTEXT_REF(chained, "chained"); - ctx->peer_identity_property_name = - ctx->chained->peer_identity_property_name; - } - return ctx; -} - -#ifndef NDEBUG -grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* ctx, - const char* file, int line, - const char* reason) { - if (ctx == nullptr) return nullptr; - if (grpc_trace_auth_context_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&ctx->refcount.count); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "AUTH_CONTEXT:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", ctx, val, - val + 1, reason); - } -#else -grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* ctx) { - if (ctx == nullptr) return nullptr; -#endif - gpr_ref(&ctx->refcount); - return ctx; -} - -#ifndef NDEBUG -void grpc_auth_context_unref(grpc_auth_context* ctx, const char* file, int line, - const char* reason) { - if (ctx == nullptr) return; - if (grpc_trace_auth_context_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&ctx->refcount.count); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "AUTH_CONTEXT:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", ctx, val, - val - 1, reason); - } -#else -void grpc_auth_context_unref(grpc_auth_context* ctx) { - if (ctx == nullptr) return; -#endif - if (gpr_unref(&ctx->refcount)) { - size_t i; - GRPC_AUTH_CONTEXT_UNREF(ctx->chained, "chained"); - if (ctx->properties.array != nullptr) { - for (i = 0; i < ctx->properties.count; i++) { - grpc_auth_property_reset(&ctx->properties.array[i]); - } - gpr_free(ctx->properties.array); - } - gpr_free(ctx); - } -} - const char* grpc_auth_context_peer_identity_property_name( const grpc_auth_context* ctx) { GRPC_API_TRACE("grpc_auth_context_peer_identity_property_name(ctx=%p)", 1, (ctx)); - return ctx->peer_identity_property_name; + return ctx->peer_identity_property_name(); } int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context* ctx, @@ -204,13 +158,13 @@ int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context* ctx, name != nullptr ? name : "NULL"); return 0; } - ctx->peer_identity_property_name = prop->name; + ctx->set_peer_identity_property_name(prop->name); return 1; } int grpc_auth_context_peer_is_authenticated(const grpc_auth_context* ctx) { GRPC_API_TRACE("grpc_auth_context_peer_is_authenticated(ctx=%p)", 1, (ctx)); - return ctx->peer_identity_property_name == nullptr ? 0 : 1; + return ctx->is_authenticated(); } grpc_auth_property_iterator grpc_auth_context_property_iterator( @@ -226,16 +180,17 @@ const grpc_auth_property* grpc_auth_property_iterator_next( grpc_auth_property_iterator* it) { GRPC_API_TRACE("grpc_auth_property_iterator_next(it=%p)", 1, (it)); if (it == nullptr || it->ctx == nullptr) return nullptr; - while (it->index == it->ctx->properties.count) { - if (it->ctx->chained == nullptr) return nullptr; - it->ctx = it->ctx->chained; + while (it->index == it->ctx->properties().count) { + if (it->ctx->chained() == nullptr) return nullptr; + it->ctx = it->ctx->chained(); it->index = 0; } if (it->name == nullptr) { - return &it->ctx->properties.array[it->index++]; + return &it->ctx->properties().array[it->index++]; } else { - while (it->index < it->ctx->properties.count) { - const grpc_auth_property* prop = &it->ctx->properties.array[it->index++]; + while (it->index < it->ctx->properties().count) { + const grpc_auth_property* prop = + &it->ctx->properties().array[it->index++]; GPR_ASSERT(prop->name != nullptr); if (strcmp(it->name, prop->name) == 0) { return prop; @@ -262,49 +217,56 @@ grpc_auth_property_iterator grpc_auth_context_peer_identity( GRPC_API_TRACE("grpc_auth_context_peer_identity(ctx=%p)", 1, (ctx)); if (ctx == nullptr) return empty_iterator; return grpc_auth_context_find_properties_by_name( - ctx, ctx->peer_identity_property_name); + ctx, ctx->peer_identity_property_name()); } -static void ensure_auth_context_capacity(grpc_auth_context* ctx) { - if (ctx->properties.count == ctx->properties.capacity) { - ctx->properties.capacity = - GPR_MAX(ctx->properties.capacity + 8, ctx->properties.capacity * 2); - ctx->properties.array = static_cast( - gpr_realloc(ctx->properties.array, - ctx->properties.capacity * sizeof(grpc_auth_property))); +void grpc_auth_context::ensure_capacity() { + if (properties_.count == properties_.capacity) { + properties_.capacity = + GPR_MAX(properties_.capacity + 8, properties_.capacity * 2); + properties_.array = static_cast(gpr_realloc( + properties_.array, properties_.capacity * sizeof(grpc_auth_property))); } } +void grpc_auth_context::add_property(const char* name, const char* value, + size_t value_length) { + ensure_capacity(); + grpc_auth_property* prop = &properties_.array[properties_.count++]; + prop->name = gpr_strdup(name); + prop->value = static_cast(gpr_malloc(value_length + 1)); + memcpy(prop->value, value, value_length); + prop->value[value_length] = '\0'; + prop->value_length = value_length; +} + void grpc_auth_context_add_property(grpc_auth_context* ctx, const char* name, const char* value, size_t value_length) { - grpc_auth_property* prop; GRPC_API_TRACE( "grpc_auth_context_add_property(ctx=%p, name=%s, value=%*.*s, " "value_length=%lu)", 6, (ctx, name, (int)value_length, (int)value_length, value, (unsigned long)value_length)); - ensure_auth_context_capacity(ctx); - prop = &ctx->properties.array[ctx->properties.count++]; + ctx->add_property(name, value, value_length); +} + +void grpc_auth_context::add_cstring_property(const char* name, + const char* value) { + ensure_capacity(); + grpc_auth_property* prop = &properties_.array[properties_.count++]; prop->name = gpr_strdup(name); - prop->value = static_cast(gpr_malloc(value_length + 1)); - memcpy(prop->value, value, value_length); - prop->value[value_length] = '\0'; - prop->value_length = value_length; + prop->value = gpr_strdup(value); + prop->value_length = strlen(value); } void grpc_auth_context_add_cstring_property(grpc_auth_context* ctx, const char* name, const char* value) { - grpc_auth_property* prop; GRPC_API_TRACE( "grpc_auth_context_add_cstring_property(ctx=%p, name=%s, value=%s)", 3, (ctx, name, value)); - ensure_auth_context_capacity(ctx); - prop = &ctx->properties.array[ctx->properties.count++]; - prop->name = gpr_strdup(name); - prop->value = gpr_strdup(value); - prop->value_length = strlen(value); + ctx->add_cstring_property(name, value); } void grpc_auth_property_reset(grpc_auth_property* property) { @@ -314,12 +276,17 @@ void grpc_auth_property_reset(grpc_auth_property* property) { } static void auth_context_pointer_arg_destroy(void* p) { - GRPC_AUTH_CONTEXT_UNREF((grpc_auth_context*)p, "auth_context_pointer_arg"); + if (p != nullptr) { + static_cast(p)->Unref(DEBUG_LOCATION, + "auth_context_pointer_arg"); + } } static void* auth_context_pointer_arg_copy(void* p) { - return GRPC_AUTH_CONTEXT_REF((grpc_auth_context*)p, - "auth_context_pointer_arg"); + auto* ctx = static_cast(p); + return ctx == nullptr + ? nullptr + : ctx->Ref(DEBUG_LOCATION, "auth_context_pointer_arg").release(); } static int auth_context_pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); } diff --git a/src/core/lib/security/context/security_context.h b/src/core/lib/security/context/security_context.h index e45415f63b8..b43ee5e62d5 100644 --- a/src/core/lib/security/context/security_context.h +++ b/src/core/lib/security/context/security_context.h @@ -21,6 +21,8 @@ #include +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/security/credentials/credentials.h" @@ -40,39 +42,59 @@ struct grpc_auth_property_array { size_t capacity = 0; }; -struct grpc_auth_context { - grpc_auth_context() { gpr_ref_init(&refcount, 0); } +void grpc_auth_property_reset(grpc_auth_property* property); - struct grpc_auth_context* chained = nullptr; - grpc_auth_property_array properties; - gpr_refcount refcount; - const char* peer_identity_property_name = nullptr; - grpc_pollset* pollset = nullptr; +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_auth_context + : public grpc_core::RefCounted { + public: + explicit grpc_auth_context( + grpc_core::RefCountedPtr chained) + : grpc_core::RefCounted( + &grpc_trace_auth_context_refcount), + chained_(std::move(chained)) { + if (chained_ != nullptr) { + peer_identity_property_name_ = chained_->peer_identity_property_name_; + } + } + + ~grpc_auth_context() { + chained_.reset(DEBUG_LOCATION, "chained"); + if (properties_.array != nullptr) { + for (size_t i = 0; i < properties_.count; i++) { + grpc_auth_property_reset(&properties_.array[i]); + } + gpr_free(properties_.array); + } + } + + const grpc_auth_context* chained() const { return chained_.get(); } + const grpc_auth_property_array& properties() const { return properties_; } + + bool is_authenticated() const { + return peer_identity_property_name_ != nullptr; + } + const char* peer_identity_property_name() const { + return peer_identity_property_name_; + } + void set_peer_identity_property_name(const char* name) { + peer_identity_property_name_ = name; + } + + void ensure_capacity(); + void add_property(const char* name, const char* value, size_t value_length); + void add_cstring_property(const char* name, const char* value); + + private: + grpc_core::RefCountedPtr chained_; + grpc_auth_property_array properties_; + const char* peer_identity_property_name_ = nullptr; }; -/* Creation. */ -grpc_auth_context* grpc_auth_context_create(grpc_auth_context* chained); - -/* Refcounting. */ -#ifndef NDEBUG -#define GRPC_AUTH_CONTEXT_REF(p, r) \ - grpc_auth_context_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_AUTH_CONTEXT_UNREF(p, r) \ - grpc_auth_context_unref((p), __FILE__, __LINE__, (r)) -grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* policy, - const char* file, int line, - const char* reason); -void grpc_auth_context_unref(grpc_auth_context* policy, const char* file, - int line, const char* reason); -#else -#define GRPC_AUTH_CONTEXT_REF(p, r) grpc_auth_context_ref((p)) -#define GRPC_AUTH_CONTEXT_UNREF(p, r) grpc_auth_context_unref((p)) -grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* policy); -void grpc_auth_context_unref(grpc_auth_context* policy); -#endif - -void grpc_auth_property_reset(grpc_auth_property* property); - /* --- grpc_security_context_extension --- Extension to the security context that may be set in a filter and accessed @@ -88,16 +110,18 @@ struct grpc_security_context_extension { Internal client-side security context. */ struct grpc_client_security_context { - grpc_client_security_context() = default; + explicit grpc_client_security_context( + grpc_core::RefCountedPtr creds) + : creds(std::move(creds)) {} ~grpc_client_security_context(); - grpc_call_credentials* creds = nullptr; - grpc_auth_context* auth_context = nullptr; + grpc_core::RefCountedPtr creds; + grpc_core::RefCountedPtr auth_context; grpc_security_context_extension extension; }; grpc_client_security_context* grpc_client_security_context_create( - gpr_arena* arena); + gpr_arena* arena, grpc_call_credentials* creds); void grpc_client_security_context_destroy(void* ctx); /* --- grpc_server_security_context --- @@ -108,7 +132,7 @@ struct grpc_server_security_context { grpc_server_security_context() = default; ~grpc_server_security_context(); - grpc_auth_context* auth_context = nullptr; + grpc_core::RefCountedPtr auth_context; grpc_security_context_extension extension; }; diff --git a/src/core/lib/security/credentials/alts/alts_credentials.cc b/src/core/lib/security/credentials/alts/alts_credentials.cc index 1fbef4ae0c7..06546492bc7 100644 --- a/src/core/lib/security/credentials/alts/alts_credentials.cc +++ b/src/core/lib/security/credentials/alts/alts_credentials.cc @@ -33,40 +33,47 @@ #define GRPC_CREDENTIALS_TYPE_ALTS "Alts" #define GRPC_ALTS_HANDSHAKER_SERVICE_URL "metadata.google.internal:8080" -static void alts_credentials_destruct(grpc_channel_credentials* creds) { - grpc_alts_credentials* alts_creds = - reinterpret_cast(creds); - grpc_alts_credentials_options_destroy(alts_creds->options); - gpr_free(alts_creds->handshaker_service_url); -} - -static void alts_server_credentials_destruct(grpc_server_credentials* creds) { - grpc_alts_server_credentials* alts_creds = - reinterpret_cast(creds); - grpc_alts_credentials_options_destroy(alts_creds->options); - gpr_free(alts_creds->handshaker_service_url); +grpc_alts_credentials::grpc_alts_credentials( + const grpc_alts_credentials_options* options, + const char* handshaker_service_url) + : grpc_channel_credentials(GRPC_CREDENTIALS_TYPE_ALTS), + options_(grpc_alts_credentials_options_copy(options)), + handshaker_service_url_(handshaker_service_url == nullptr + ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) + : gpr_strdup(handshaker_service_url)) {} + +grpc_alts_credentials::~grpc_alts_credentials() { + grpc_alts_credentials_options_destroy(options_); + gpr_free(handshaker_service_url_); } -static grpc_security_status alts_create_security_connector( - grpc_channel_credentials* creds, - grpc_call_credentials* request_metadata_creds, const char* target_name, - const grpc_channel_args* args, grpc_channel_security_connector** sc, +grpc_core::RefCountedPtr +grpc_alts_credentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target_name, const grpc_channel_args* args, grpc_channel_args** new_args) { return grpc_alts_channel_security_connector_create( - creds, request_metadata_creds, target_name, sc); + this->Ref(), std::move(call_creds), target_name); } -static grpc_security_status alts_server_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc) { - return grpc_alts_server_security_connector_create(creds, sc); +grpc_alts_server_credentials::grpc_alts_server_credentials( + const grpc_alts_credentials_options* options, + const char* handshaker_service_url) + : grpc_server_credentials(GRPC_CREDENTIALS_TYPE_ALTS), + options_(grpc_alts_credentials_options_copy(options)), + handshaker_service_url_(handshaker_service_url == nullptr + ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) + : gpr_strdup(handshaker_service_url)) {} + +grpc_core::RefCountedPtr +grpc_alts_server_credentials::create_security_connector() { + return grpc_alts_server_security_connector_create(this->Ref()); } -static const grpc_channel_credentials_vtable alts_credentials_vtable = { - alts_credentials_destruct, alts_create_security_connector, - /*duplicate_without_call_credentials=*/nullptr}; - -static const grpc_server_credentials_vtable alts_server_credentials_vtable = { - alts_server_credentials_destruct, alts_server_create_security_connector}; +grpc_alts_server_credentials::~grpc_alts_server_credentials() { + grpc_alts_credentials_options_destroy(options_); + gpr_free(handshaker_service_url_); +} grpc_channel_credentials* grpc_alts_credentials_create_customized( const grpc_alts_credentials_options* options, @@ -74,17 +81,7 @@ grpc_channel_credentials* grpc_alts_credentials_create_customized( if (!enable_untrusted_alts && !grpc_alts_is_running_on_gcp()) { return nullptr; } - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_alts_credentials))); - creds->options = grpc_alts_credentials_options_copy(options); - creds->handshaker_service_url = - handshaker_service_url == nullptr - ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) - : gpr_strdup(handshaker_service_url); - creds->base.type = GRPC_CREDENTIALS_TYPE_ALTS; - creds->base.vtable = &alts_credentials_vtable; - gpr_ref_init(&creds->base.refcount, 1); - return &creds->base; + return grpc_core::New(options, handshaker_service_url); } grpc_server_credentials* grpc_alts_server_credentials_create_customized( @@ -93,17 +90,8 @@ grpc_server_credentials* grpc_alts_server_credentials_create_customized( if (!enable_untrusted_alts && !grpc_alts_is_running_on_gcp()) { return nullptr; } - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_alts_server_credentials))); - creds->options = grpc_alts_credentials_options_copy(options); - creds->handshaker_service_url = - handshaker_service_url == nullptr - ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) - : gpr_strdup(handshaker_service_url); - creds->base.type = GRPC_CREDENTIALS_TYPE_ALTS; - creds->base.vtable = &alts_server_credentials_vtable; - gpr_ref_init(&creds->base.refcount, 1); - return &creds->base; + return grpc_core::New(options, + handshaker_service_url); } grpc_channel_credentials* grpc_alts_credentials_create( diff --git a/src/core/lib/security/credentials/alts/alts_credentials.h b/src/core/lib/security/credentials/alts/alts_credentials.h index 810117f2bea..cc6d5222b16 100644 --- a/src/core/lib/security/credentials/alts/alts_credentials.h +++ b/src/core/lib/security/credentials/alts/alts_credentials.h @@ -27,18 +27,45 @@ #include "src/core/lib/security/credentials/credentials.h" /* Main struct for grpc ALTS channel credential. */ -typedef struct grpc_alts_credentials { - grpc_channel_credentials base; - grpc_alts_credentials_options* options; - char* handshaker_service_url; -} grpc_alts_credentials; +class grpc_alts_credentials final : public grpc_channel_credentials { + public: + grpc_alts_credentials(const grpc_alts_credentials_options* options, + const char* handshaker_service_url); + ~grpc_alts_credentials() override; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target_name, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + const grpc_alts_credentials_options* options() const { return options_; } + grpc_alts_credentials_options* mutable_options() { return options_; } + const char* handshaker_service_url() const { return handshaker_service_url_; } + + private: + grpc_alts_credentials_options* options_; + char* handshaker_service_url_; +}; /* Main struct for grpc ALTS server credential. */ -typedef struct grpc_alts_server_credentials { - grpc_server_credentials base; - grpc_alts_credentials_options* options; - char* handshaker_service_url; -} grpc_alts_server_credentials; +class grpc_alts_server_credentials final : public grpc_server_credentials { + public: + grpc_alts_server_credentials(const grpc_alts_credentials_options* options, + const char* handshaker_service_url); + ~grpc_alts_server_credentials() override; + + grpc_core::RefCountedPtr + create_security_connector() override; + + const grpc_alts_credentials_options* options() const { return options_; } + grpc_alts_credentials_options* mutable_options() { return options_; } + const char* handshaker_service_url() const { return handshaker_service_url_; } + + private: + grpc_alts_credentials_options* options_; + char* handshaker_service_url_; +}; /** * This method creates an ALTS channel credential object with customized diff --git a/src/core/lib/security/credentials/composite/composite_credentials.cc b/src/core/lib/security/credentials/composite/composite_credentials.cc index b8f409260f0..85dcd4693bc 100644 --- a/src/core/lib/security/credentials/composite/composite_credentials.cc +++ b/src/core/lib/security/credentials/composite/composite_credentials.cc @@ -20,8 +20,10 @@ #include "src/core/lib/security/credentials/composite/composite_credentials.h" -#include +#include +#include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/surface/api_trace.h" @@ -31,36 +33,83 @@ /* -- Composite call credentials. -- */ -typedef struct { +static void composite_call_metadata_cb(void* arg, grpc_error* error); + +grpc_call_credentials_array::~grpc_call_credentials_array() { + for (size_t i = 0; i < num_creds_; ++i) { + creds_array_[i].~RefCountedPtr(); + } + if (creds_array_ != nullptr) { + gpr_free(creds_array_); + } +} + +grpc_call_credentials_array::grpc_call_credentials_array( + const grpc_call_credentials_array& that) + : num_creds_(that.num_creds_) { + reserve(that.capacity_); + for (size_t i = 0; i < num_creds_; ++i) { + new (&creds_array_[i]) + grpc_core::RefCountedPtr(that.creds_array_[i]); + } +} + +void grpc_call_credentials_array::reserve(size_t capacity) { + if (capacity_ >= capacity) { + return; + } + grpc_core::RefCountedPtr* new_arr = + static_cast*>(gpr_malloc( + sizeof(grpc_core::RefCountedPtr) * capacity)); + if (creds_array_ != nullptr) { + for (size_t i = 0; i < num_creds_; ++i) { + new (&new_arr[i]) grpc_core::RefCountedPtr( + std::move(creds_array_[i])); + creds_array_[i].~RefCountedPtr(); + } + gpr_free(creds_array_); + } + creds_array_ = new_arr; + capacity_ = capacity; +} + +namespace { +struct grpc_composite_call_credentials_metadata_context { + grpc_composite_call_credentials_metadata_context( + grpc_composite_call_credentials* composite_creds, + grpc_polling_entity* pollent, grpc_auth_metadata_context auth_md_context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata) + : composite_creds(composite_creds), + pollent(pollent), + auth_md_context(auth_md_context), + md_array(md_array), + on_request_metadata(on_request_metadata) { + GRPC_CLOSURE_INIT(&internal_on_request_metadata, composite_call_metadata_cb, + this, grpc_schedule_on_exec_ctx); + } + grpc_composite_call_credentials* composite_creds; - size_t creds_index; + size_t creds_index = 0; grpc_polling_entity* pollent; grpc_auth_metadata_context auth_md_context; grpc_credentials_mdelem_array* md_array; grpc_closure* on_request_metadata; grpc_closure internal_on_request_metadata; -} grpc_composite_call_credentials_metadata_context; - -static void composite_call_destruct(grpc_call_credentials* creds) { - grpc_composite_call_credentials* c = - reinterpret_cast(creds); - for (size_t i = 0; i < c->inner.num_creds; i++) { - grpc_call_credentials_unref(c->inner.creds_array[i]); - } - gpr_free(c->inner.creds_array); -} +}; +} // namespace static void composite_call_metadata_cb(void* arg, grpc_error* error) { grpc_composite_call_credentials_metadata_context* ctx = static_cast(arg); if (error == GRPC_ERROR_NONE) { + const grpc_call_credentials_array& inner = ctx->composite_creds->inner(); /* See if we need to get some more metadata. */ - if (ctx->creds_index < ctx->composite_creds->inner.num_creds) { - grpc_call_credentials* inner_creds = - ctx->composite_creds->inner.creds_array[ctx->creds_index++]; - if (grpc_call_credentials_get_request_metadata( - inner_creds, ctx->pollent, ctx->auth_md_context, ctx->md_array, - &ctx->internal_on_request_metadata, &error)) { + if (ctx->creds_index < inner.size()) { + if (inner.get(ctx->creds_index++) + ->get_request_metadata( + ctx->pollent, ctx->auth_md_context, ctx->md_array, + &ctx->internal_on_request_metadata, &error)) { // Synchronous response, so call ourselves recursively. composite_call_metadata_cb(arg, error); GRPC_ERROR_UNREF(error); @@ -73,76 +122,86 @@ static void composite_call_metadata_cb(void* arg, grpc_error* error) { gpr_free(ctx); } -static bool composite_call_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context auth_md_context, +bool grpc_composite_call_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context auth_md_context, grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, grpc_error** error) { - grpc_composite_call_credentials* c = - reinterpret_cast(creds); grpc_composite_call_credentials_metadata_context* ctx; - ctx = static_cast( - gpr_zalloc(sizeof(grpc_composite_call_credentials_metadata_context))); - ctx->composite_creds = c; - ctx->pollent = pollent; - ctx->auth_md_context = auth_md_context; - ctx->md_array = md_array; - ctx->on_request_metadata = on_request_metadata; - GRPC_CLOSURE_INIT(&ctx->internal_on_request_metadata, - composite_call_metadata_cb, ctx, grpc_schedule_on_exec_ctx); + ctx = grpc_core::New( + this, pollent, auth_md_context, md_array, on_request_metadata); bool synchronous = true; - while (ctx->creds_index < ctx->composite_creds->inner.num_creds) { - grpc_call_credentials* inner_creds = - ctx->composite_creds->inner.creds_array[ctx->creds_index++]; - if (grpc_call_credentials_get_request_metadata( - inner_creds, ctx->pollent, ctx->auth_md_context, ctx->md_array, - &ctx->internal_on_request_metadata, error)) { + const grpc_call_credentials_array& inner = ctx->composite_creds->inner(); + while (ctx->creds_index < inner.size()) { + if (inner.get(ctx->creds_index++) + ->get_request_metadata(ctx->pollent, ctx->auth_md_context, + ctx->md_array, + &ctx->internal_on_request_metadata, error)) { if (*error != GRPC_ERROR_NONE) break; } else { synchronous = false; // Async return. break; } } - if (synchronous) gpr_free(ctx); + if (synchronous) grpc_core::Delete(ctx); return synchronous; } -static void composite_call_cancel_get_request_metadata( - grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { - grpc_composite_call_credentials* c = - reinterpret_cast(creds); - for (size_t i = 0; i < c->inner.num_creds; ++i) { - grpc_call_credentials_cancel_get_request_metadata( - c->inner.creds_array[i], md_array, GRPC_ERROR_REF(error)); +void grpc_composite_call_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { + for (size_t i = 0; i < inner_.size(); ++i) { + inner_.get(i)->cancel_get_request_metadata(md_array, GRPC_ERROR_REF(error)); } GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable composite_call_credentials_vtable = { - composite_call_destruct, composite_call_get_request_metadata, - composite_call_cancel_get_request_metadata}; +static size_t get_creds_array_size(const grpc_call_credentials* creds, + bool is_composite) { + return is_composite + ? static_cast(creds) + ->inner() + .size() + : 1; +} -static grpc_call_credentials_array get_creds_array( - grpc_call_credentials** creds_addr) { - grpc_call_credentials_array result; - grpc_call_credentials* creds = *creds_addr; - result.creds_array = creds_addr; - result.num_creds = 1; - if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) { - result = *grpc_composite_call_credentials_get_credentials(creds); +void grpc_composite_call_credentials::push_to_inner( + grpc_core::RefCountedPtr creds, bool is_composite) { + if (!is_composite) { + inner_.push_back(std::move(creds)); + return; } - return result; + auto composite_creds = + static_cast(creds.get()); + for (size_t i = 0; i < composite_creds->inner().size(); ++i) { + inner_.push_back(std::move(composite_creds->inner_.get_mutable(i))); + } +} + +grpc_composite_call_credentials::grpc_composite_call_credentials( + grpc_core::RefCountedPtr creds1, + grpc_core::RefCountedPtr creds2) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) { + const bool creds1_is_composite = + strcmp(creds1->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0; + const bool creds2_is_composite = + strcmp(creds2->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0; + const size_t size = get_creds_array_size(creds1.get(), creds1_is_composite) + + get_creds_array_size(creds2.get(), creds2_is_composite); + inner_.reserve(size); + push_to_inner(std::move(creds1), creds1_is_composite); + push_to_inner(std::move(creds2), creds2_is_composite); +} + +static grpc_core::RefCountedPtr +composite_call_credentials_create( + grpc_core::RefCountedPtr creds1, + grpc_core::RefCountedPtr creds2) { + return grpc_core::MakeRefCounted( + std::move(creds1), std::move(creds2)); } grpc_call_credentials* grpc_composite_call_credentials_create( grpc_call_credentials* creds1, grpc_call_credentials* creds2, void* reserved) { - size_t i; - size_t creds_array_byte_size; - grpc_call_credentials_array creds1_array; - grpc_call_credentials_array creds2_array; - grpc_composite_call_credentials* c; GRPC_API_TRACE( "grpc_composite_call_credentials_create(creds1=%p, creds2=%p, " "reserved=%p)", @@ -150,120 +209,40 @@ grpc_call_credentials* grpc_composite_call_credentials_create( GPR_ASSERT(reserved == nullptr); GPR_ASSERT(creds1 != nullptr); GPR_ASSERT(creds2 != nullptr); - c = static_cast( - gpr_zalloc(sizeof(grpc_composite_call_credentials))); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE; - c->base.vtable = &composite_call_credentials_vtable; - gpr_ref_init(&c->base.refcount, 1); - creds1_array = get_creds_array(&creds1); - creds2_array = get_creds_array(&creds2); - c->inner.num_creds = creds1_array.num_creds + creds2_array.num_creds; - creds_array_byte_size = c->inner.num_creds * sizeof(grpc_call_credentials*); - c->inner.creds_array = - static_cast(gpr_zalloc(creds_array_byte_size)); - for (i = 0; i < creds1_array.num_creds; i++) { - grpc_call_credentials* cur_creds = creds1_array.creds_array[i]; - c->inner.creds_array[i] = grpc_call_credentials_ref(cur_creds); - } - for (i = 0; i < creds2_array.num_creds; i++) { - grpc_call_credentials* cur_creds = creds2_array.creds_array[i]; - c->inner.creds_array[i + creds1_array.num_creds] = - grpc_call_credentials_ref(cur_creds); - } - return &c->base; -} -const grpc_call_credentials_array* -grpc_composite_call_credentials_get_credentials(grpc_call_credentials* creds) { - const grpc_composite_call_credentials* c = - reinterpret_cast(creds); - GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); - return &c->inner; -} - -grpc_call_credentials* grpc_credentials_contains_type( - grpc_call_credentials* creds, const char* type, - grpc_call_credentials** composite_creds) { - size_t i; - if (strcmp(creds->type, type) == 0) { - if (composite_creds != nullptr) *composite_creds = nullptr; - return creds; - } else if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) { - const grpc_call_credentials_array* inner_creds_array = - grpc_composite_call_credentials_get_credentials(creds); - for (i = 0; i < inner_creds_array->num_creds; i++) { - if (strcmp(type, inner_creds_array->creds_array[i]->type) == 0) { - if (composite_creds != nullptr) *composite_creds = creds; - return inner_creds_array->creds_array[i]; - } - } - } - return nullptr; + return composite_call_credentials_create(creds1->Ref(), creds2->Ref()) + .release(); } /* -- Composite channel credentials. -- */ -static void composite_channel_destruct(grpc_channel_credentials* creds) { - grpc_composite_channel_credentials* c = - reinterpret_cast(creds); - grpc_channel_credentials_unref(c->inner_creds); - grpc_call_credentials_unref(c->call_creds); -} - -static grpc_security_status composite_channel_create_security_connector( - grpc_channel_credentials* creds, grpc_call_credentials* call_creds, +grpc_core::RefCountedPtr +grpc_composite_channel_credentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - grpc_composite_channel_credentials* c = - reinterpret_cast(creds); - grpc_security_status status = GRPC_SECURITY_ERROR; - - GPR_ASSERT(c->inner_creds != nullptr && c->call_creds != nullptr && - c->inner_creds->vtable != nullptr && - c->inner_creds->vtable->create_security_connector != nullptr); + grpc_channel_args** new_args) { + GPR_ASSERT(inner_creds_ != nullptr && call_creds_ != nullptr); /* If we are passed a call_creds, create a call composite to pass it downstream. */ if (call_creds != nullptr) { - grpc_call_credentials* composite_call_creds = - grpc_composite_call_credentials_create(c->call_creds, call_creds, - nullptr); - status = c->inner_creds->vtable->create_security_connector( - c->inner_creds, composite_call_creds, target, args, sc, new_args); - grpc_call_credentials_unref(composite_call_creds); + return inner_creds_->create_security_connector( + composite_call_credentials_create(call_creds_, std::move(call_creds)), + target, args, new_args); } else { - status = c->inner_creds->vtable->create_security_connector( - c->inner_creds, c->call_creds, target, args, sc, new_args); + return inner_creds_->create_security_connector(call_creds_, target, args, + new_args); } - return status; -} - -static grpc_channel_credentials* -composite_channel_duplicate_without_call_credentials( - grpc_channel_credentials* creds) { - grpc_composite_channel_credentials* c = - reinterpret_cast(creds); - return grpc_channel_credentials_ref(c->inner_creds); } -static grpc_channel_credentials_vtable composite_channel_credentials_vtable = { - composite_channel_destruct, composite_channel_create_security_connector, - composite_channel_duplicate_without_call_credentials}; - grpc_channel_credentials* grpc_composite_channel_credentials_create( grpc_channel_credentials* channel_creds, grpc_call_credentials* call_creds, void* reserved) { - grpc_composite_channel_credentials* c = - static_cast(gpr_zalloc(sizeof(*c))); GPR_ASSERT(channel_creds != nullptr && call_creds != nullptr && reserved == nullptr); GRPC_API_TRACE( "grpc_composite_channel_credentials_create(channel_creds=%p, " "call_creds=%p, reserved=%p)", 3, (channel_creds, call_creds, reserved)); - c->base.type = channel_creds->type; - c->base.vtable = &composite_channel_credentials_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->inner_creds = grpc_channel_credentials_ref(channel_creds); - c->call_creds = grpc_call_credentials_ref(call_creds); - return &c->base; + return grpc_core::New( + channel_creds->Ref(), call_creds->Ref()); } diff --git a/src/core/lib/security/credentials/composite/composite_credentials.h b/src/core/lib/security/credentials/composite/composite_credentials.h index a952ad57f1e..6b7fca13708 100644 --- a/src/core/lib/security/credentials/composite/composite_credentials.h +++ b/src/core/lib/security/credentials/composite/composite_credentials.h @@ -21,39 +21,104 @@ #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/credentials/credentials.h" -typedef struct { - grpc_call_credentials** creds_array; - size_t num_creds; -} grpc_call_credentials_array; +// TODO(soheil): Replace this with InlinedVector once #16032 is resolved. +class grpc_call_credentials_array { + public: + grpc_call_credentials_array() = default; + grpc_call_credentials_array(const grpc_call_credentials_array& that); -const grpc_call_credentials_array* -grpc_composite_call_credentials_get_credentials( - grpc_call_credentials* composite_creds); + ~grpc_call_credentials_array(); -/* Returns creds if creds is of the specified type or the inner creds of the - specified type (if found), if the creds is of type COMPOSITE. - If composite_creds is not NULL, *composite_creds will point to creds if of - type COMPOSITE in case of success. */ -grpc_call_credentials* grpc_credentials_contains_type( - grpc_call_credentials* creds, const char* type, - grpc_call_credentials** composite_creds); + void reserve(size_t capacity); + + // Must reserve before pushing any data. + void push_back(grpc_core::RefCountedPtr cred) { + GPR_DEBUG_ASSERT(capacity_ > num_creds_); + new (&creds_array_[num_creds_++]) + grpc_core::RefCountedPtr(std::move(cred)); + } + + const grpc_core::RefCountedPtr& get(size_t i) const { + GPR_DEBUG_ASSERT(i < num_creds_); + return creds_array_[i]; + } + grpc_core::RefCountedPtr& get_mutable(size_t i) { + GPR_DEBUG_ASSERT(i < num_creds_); + return creds_array_[i]; + } + + size_t size() const { return num_creds_; } + + private: + grpc_core::RefCountedPtr* creds_array_ = nullptr; + size_t num_creds_ = 0; + size_t capacity_ = 0; +}; /* -- Composite channel credentials. -- */ -typedef struct { - grpc_channel_credentials base; - grpc_channel_credentials* inner_creds; - grpc_call_credentials* call_creds; -} grpc_composite_channel_credentials; +class grpc_composite_channel_credentials : public grpc_channel_credentials { + public: + grpc_composite_channel_credentials( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr call_creds) + : grpc_channel_credentials(channel_creds->type()), + inner_creds_(std::move(channel_creds)), + call_creds_(std::move(call_creds)) {} + + ~grpc_composite_channel_credentials() override = default; + + grpc_core::RefCountedPtr + duplicate_without_call_credentials() override { + return inner_creds_; + } + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + const grpc_channel_credentials* inner_creds() const { + return inner_creds_.get(); + } + const grpc_call_credentials* call_creds() const { return call_creds_.get(); } + grpc_call_credentials* mutable_call_creds() { return call_creds_.get(); } + + private: + grpc_core::RefCountedPtr inner_creds_; + grpc_core::RefCountedPtr call_creds_; +}; /* -- Composite call credentials. -- */ -typedef struct { - grpc_call_credentials base; - grpc_call_credentials_array inner; -} grpc_composite_call_credentials; +class grpc_composite_call_credentials : public grpc_call_credentials { + public: + grpc_composite_call_credentials( + grpc_core::RefCountedPtr creds1, + grpc_core::RefCountedPtr creds2); + ~grpc_composite_call_credentials() override = default; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + const grpc_call_credentials_array& inner() const { return inner_; } + + private: + void push_to_inner(grpc_core::RefCountedPtr creds, + bool is_composite); + + grpc_call_credentials_array inner_; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_COMPOSITE_COMPOSITE_CREDENTIALS_H \ */ diff --git a/src/core/lib/security/credentials/credentials.cc b/src/core/lib/security/credentials/credentials.cc index c43cb440ebf..90452d68d61 100644 --- a/src/core/lib/security/credentials/credentials.cc +++ b/src/core/lib/security/credentials/credentials.cc @@ -39,120 +39,24 @@ /* -- Common. -- */ -grpc_credentials_metadata_request* grpc_credentials_metadata_request_create( - grpc_call_credentials* creds) { - grpc_credentials_metadata_request* r = - static_cast( - gpr_zalloc(sizeof(grpc_credentials_metadata_request))); - r->creds = grpc_call_credentials_ref(creds); - return r; -} - -void grpc_credentials_metadata_request_destroy( - grpc_credentials_metadata_request* r) { - grpc_call_credentials_unref(r->creds); - grpc_http_response_destroy(&r->response); - gpr_free(r); -} - -grpc_channel_credentials* grpc_channel_credentials_ref( - grpc_channel_credentials* creds) { - if (creds == nullptr) return nullptr; - gpr_ref(&creds->refcount); - return creds; -} - -void grpc_channel_credentials_unref(grpc_channel_credentials* creds) { - if (creds == nullptr) return; - if (gpr_unref(&creds->refcount)) { - if (creds->vtable->destruct != nullptr) { - creds->vtable->destruct(creds); - } - gpr_free(creds); - } -} - void grpc_channel_credentials_release(grpc_channel_credentials* creds) { GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds)); grpc_core::ExecCtx exec_ctx; - grpc_channel_credentials_unref(creds); -} - -grpc_call_credentials* grpc_call_credentials_ref(grpc_call_credentials* creds) { - if (creds == nullptr) return nullptr; - gpr_ref(&creds->refcount); - return creds; -} - -void grpc_call_credentials_unref(grpc_call_credentials* creds) { - if (creds == nullptr) return; - if (gpr_unref(&creds->refcount)) { - if (creds->vtable->destruct != nullptr) { - creds->vtable->destruct(creds); - } - gpr_free(creds); - } + if (creds) creds->Unref(); } void grpc_call_credentials_release(grpc_call_credentials* creds) { GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds)); grpc_core::ExecCtx exec_ctx; - grpc_call_credentials_unref(creds); -} - -bool grpc_call_credentials_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error) { - if (creds == nullptr || creds->vtable->get_request_metadata == nullptr) { - return true; - } - return creds->vtable->get_request_metadata(creds, pollent, context, md_array, - on_request_metadata, error); -} - -void grpc_call_credentials_cancel_get_request_metadata( - grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { - if (creds == nullptr || - creds->vtable->cancel_get_request_metadata == nullptr) { - return; - } - creds->vtable->cancel_get_request_metadata(creds, md_array, error); -} - -grpc_security_status grpc_channel_credentials_create_security_connector( - grpc_channel_credentials* channel_creds, const char* target, - const grpc_channel_args* args, grpc_channel_security_connector** sc, - grpc_channel_args** new_args) { - *new_args = nullptr; - if (channel_creds == nullptr) { - return GRPC_SECURITY_ERROR; - } - GPR_ASSERT(channel_creds->vtable->create_security_connector != nullptr); - return channel_creds->vtable->create_security_connector( - channel_creds, nullptr, target, args, sc, new_args); -} - -grpc_channel_credentials* -grpc_channel_credentials_duplicate_without_call_credentials( - grpc_channel_credentials* channel_creds) { - if (channel_creds != nullptr && channel_creds->vtable != nullptr && - channel_creds->vtable->duplicate_without_call_credentials != nullptr) { - return channel_creds->vtable->duplicate_without_call_credentials( - channel_creds); - } else { - return grpc_channel_credentials_ref(channel_creds); - } + if (creds) creds->Unref(); } static void credentials_pointer_arg_destroy(void* p) { - grpc_channel_credentials_unref(static_cast(p)); + static_cast(p)->Unref(); } static void* credentials_pointer_arg_copy(void* p) { - return grpc_channel_credentials_ref( - static_cast(p)); + return static_cast(p)->Ref().release(); } static int credentials_pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); } @@ -191,63 +95,35 @@ grpc_channel_credentials* grpc_channel_credentials_find_in_args( return nullptr; } -grpc_server_credentials* grpc_server_credentials_ref( - grpc_server_credentials* creds) { - if (creds == nullptr) return nullptr; - gpr_ref(&creds->refcount); - return creds; -} - -void grpc_server_credentials_unref(grpc_server_credentials* creds) { - if (creds == nullptr) return; - if (gpr_unref(&creds->refcount)) { - if (creds->vtable->destruct != nullptr) { - creds->vtable->destruct(creds); - } - if (creds->processor.destroy != nullptr && - creds->processor.state != nullptr) { - creds->processor.destroy(creds->processor.state); - } - gpr_free(creds); - } -} - void grpc_server_credentials_release(grpc_server_credentials* creds) { GRPC_API_TRACE("grpc_server_credentials_release(creds=%p)", 1, (creds)); grpc_core::ExecCtx exec_ctx; - grpc_server_credentials_unref(creds); + if (creds) creds->Unref(); } -grpc_security_status grpc_server_credentials_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc) { - if (creds == nullptr || creds->vtable->create_security_connector == nullptr) { - gpr_log(GPR_ERROR, "Server credentials cannot create security context."); - return GRPC_SECURITY_ERROR; - } - return creds->vtable->create_security_connector(creds, sc); -} - -void grpc_server_credentials_set_auth_metadata_processor( - grpc_server_credentials* creds, grpc_auth_metadata_processor processor) { +void grpc_server_credentials::set_auth_metadata_processor( + const grpc_auth_metadata_processor& processor) { GRPC_API_TRACE( "grpc_server_credentials_set_auth_metadata_processor(" "creds=%p, " "processor=grpc_auth_metadata_processor { process: %p, state: %p })", - 3, (creds, (void*)(intptr_t)processor.process, processor.state)); - if (creds == nullptr) return; - if (creds->processor.destroy != nullptr && - creds->processor.state != nullptr) { - creds->processor.destroy(creds->processor.state); - } - creds->processor = processor; + 3, (this, (void*)(intptr_t)processor.process, processor.state)); + DestroyProcessor(); + processor_ = processor; +} + +void grpc_server_credentials_set_auth_metadata_processor( + grpc_server_credentials* creds, grpc_auth_metadata_processor processor) { + GPR_DEBUG_ASSERT(creds != nullptr); + creds->set_auth_metadata_processor(processor); } static void server_credentials_pointer_arg_destroy(void* p) { - grpc_server_credentials_unref(static_cast(p)); + static_cast(p)->Unref(); } static void* server_credentials_pointer_arg_copy(void* p) { - return grpc_server_credentials_ref(static_cast(p)); + return static_cast(p)->Ref().release(); } static int server_credentials_pointer_cmp(void* a, void* b) { diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h index 3878958b38b..4091ef3dfb5 100644 --- a/src/core/lib/security/credentials/credentials.h +++ b/src/core/lib/security/credentials/credentials.h @@ -26,6 +26,7 @@ #include #include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/http/httpcli.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/polling_entity.h" @@ -90,44 +91,46 @@ void grpc_override_well_known_credentials_path_getter( #define GRPC_ARG_CHANNEL_CREDENTIALS "grpc.channel_credentials" -typedef struct { - void (*destruct)(grpc_channel_credentials* c); - - grpc_security_status (*create_security_connector)( - grpc_channel_credentials* c, grpc_call_credentials* call_creds, +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_channel_credentials + : grpc_core::RefCounted { + public: + explicit grpc_channel_credentials(const char* type) : type_(type) {} + virtual ~grpc_channel_credentials() = default; + + // Creates a security connector for the channel. May also create new channel + // args for the channel to be used in place of the passed in const args if + // returned non NULL. In that case the caller is responsible for destroying + // new_args after channel creation. + virtual grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args); - - grpc_channel_credentials* (*duplicate_without_call_credentials)( - grpc_channel_credentials* c); -} grpc_channel_credentials_vtable; - -struct grpc_channel_credentials { - const grpc_channel_credentials_vtable* vtable; - const char* type; - gpr_refcount refcount; + grpc_channel_args** new_args) { + // Tell clang-tidy that call_creds cannot be passed as const-ref. + call_creds.reset(); + GRPC_ABSTRACT; + } + + // Creates a version of the channel credentials without any attached call + // credentials. This can be used in order to open a channel to a non-trusted + // gRPC load balancer. + virtual grpc_core::RefCountedPtr + duplicate_without_call_credentials() { + // By default we just increment the refcount. + return Ref(); + } + + const char* type() const { return type_; } + + GRPC_ABSTRACT_BASE_CLASS + + private: + const char* type_; }; -grpc_channel_credentials* grpc_channel_credentials_ref( - grpc_channel_credentials* creds); -void grpc_channel_credentials_unref(grpc_channel_credentials* creds); - -/* Creates a security connector for the channel. May also create new channel - args for the channel to be used in place of the passed in const args if - returned non NULL. In that case the caller is responsible for destroying - new_args after channel creation. */ -grpc_security_status grpc_channel_credentials_create_security_connector( - grpc_channel_credentials* creds, const char* target, - const grpc_channel_args* args, grpc_channel_security_connector** sc, - grpc_channel_args** new_args); - -/* Creates a version of the channel credentials without any attached call - credentials. This can be used in order to open a channel to a non-trusted - gRPC load balancer. */ -grpc_channel_credentials* -grpc_channel_credentials_duplicate_without_call_credentials( - grpc_channel_credentials* creds); - /* Util to encapsulate the channel credentials in a channel arg. */ grpc_arg grpc_channel_credentials_to_arg(grpc_channel_credentials* credentials); @@ -158,44 +161,39 @@ void grpc_credentials_mdelem_array_destroy(grpc_credentials_mdelem_array* list); /* --- grpc_call_credentials. --- */ -typedef struct { - void (*destruct)(grpc_call_credentials* c); - bool (*get_request_metadata)(grpc_call_credentials* c, - grpc_polling_entity* pollent, - grpc_auth_metadata_context context, - grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, - grpc_error** error); - void (*cancel_get_request_metadata)(grpc_call_credentials* c, - grpc_credentials_mdelem_array* md_array, - grpc_error* error); -} grpc_call_credentials_vtable; - -struct grpc_call_credentials { - const grpc_call_credentials_vtable* vtable; - const char* type; - gpr_refcount refcount; +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_call_credentials + : public grpc_core::RefCounted { + public: + explicit grpc_call_credentials(const char* type) : type_(type) {} + virtual ~grpc_call_credentials() = default; + + // Returns true if completed synchronously, in which case \a error will + // be set to indicate the result. Otherwise, \a on_request_metadata will + // be invoked asynchronously when complete. \a md_array will be populated + // with the resulting metadata once complete. + virtual bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) GRPC_ABSTRACT; + + // Cancels a pending asynchronous operation started by + // grpc_call_credentials_get_request_metadata() with the corresponding + // value of \a md_array. + virtual void cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) GRPC_ABSTRACT; + + const char* type() const { return type_; } + + GRPC_ABSTRACT_BASE_CLASS + + private: + const char* type_; }; -grpc_call_credentials* grpc_call_credentials_ref(grpc_call_credentials* creds); -void grpc_call_credentials_unref(grpc_call_credentials* creds); - -/// Returns true if completed synchronously, in which case \a error will -/// be set to indicate the result. Otherwise, \a on_request_metadata will -/// be invoked asynchronously when complete. \a md_array will be populated -/// with the resulting metadata once complete. -bool grpc_call_credentials_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error); - -/// Cancels a pending asynchronous operation started by -/// grpc_call_credentials_get_request_metadata() with the corresponding -/// value of \a md_array. -void grpc_call_credentials_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error); - /* Metadata-only credentials with the specified key and value where asynchronicity can be simulated for testing. */ grpc_call_credentials* grpc_md_only_test_credentials_create( @@ -203,26 +201,40 @@ grpc_call_credentials* grpc_md_only_test_credentials_create( /* --- grpc_server_credentials. --- */ -typedef struct { - void (*destruct)(grpc_server_credentials* c); - grpc_security_status (*create_security_connector)( - grpc_server_credentials* c, grpc_server_security_connector** sc); -} grpc_server_credentials_vtable; - -struct grpc_server_credentials { - const grpc_server_credentials_vtable* vtable; - const char* type; - gpr_refcount refcount; - grpc_auth_metadata_processor processor; -}; +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_server_credentials + : public grpc_core::RefCounted { + public: + explicit grpc_server_credentials(const char* type) : type_(type) {} -grpc_security_status grpc_server_credentials_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc); + virtual ~grpc_server_credentials() { DestroyProcessor(); } -grpc_server_credentials* grpc_server_credentials_ref( - grpc_server_credentials* creds); + virtual grpc_core::RefCountedPtr + create_security_connector() GRPC_ABSTRACT; -void grpc_server_credentials_unref(grpc_server_credentials* creds); + const char* type() const { return type_; } + + const grpc_auth_metadata_processor& auth_metadata_processor() const { + return processor_; + } + void set_auth_metadata_processor( + const grpc_auth_metadata_processor& processor); + + GRPC_ABSTRACT_BASE_CLASS + + private: + void DestroyProcessor() { + if (processor_.destroy != nullptr && processor_.state != nullptr) { + processor_.destroy(processor_.state); + } + } + + const char* type_; + grpc_auth_metadata_processor processor_ = + grpc_auth_metadata_processor(); // Zero-initialize the C struct. +}; #define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials" @@ -233,15 +245,27 @@ grpc_server_credentials* grpc_find_server_credentials_in_args( /* -- Credentials Metadata Request. -- */ -typedef struct { - grpc_call_credentials* creds; +struct grpc_credentials_metadata_request { + explicit grpc_credentials_metadata_request( + grpc_core::RefCountedPtr creds) + : creds(std::move(creds)) {} + ~grpc_credentials_metadata_request() { + grpc_http_response_destroy(&response); + } + + grpc_core::RefCountedPtr creds; grpc_http_response response; -} grpc_credentials_metadata_request; +}; -grpc_credentials_metadata_request* grpc_credentials_metadata_request_create( - grpc_call_credentials* creds); +inline grpc_credentials_metadata_request* +grpc_credentials_metadata_request_create( + grpc_core::RefCountedPtr creds) { + return grpc_core::New(std::move(creds)); +} -void grpc_credentials_metadata_request_destroy( - grpc_credentials_metadata_request* r); +inline void grpc_credentials_metadata_request_destroy( + grpc_credentials_metadata_request* r) { + grpc_core::Delete(r); +} #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/fake/fake_credentials.cc b/src/core/lib/security/credentials/fake/fake_credentials.cc index d3e0e8c8168..337dd7679fd 100644 --- a/src/core/lib/security/credentials/fake/fake_credentials.cc +++ b/src/core/lib/security/credentials/fake/fake_credentials.cc @@ -33,49 +33,45 @@ /* -- Fake transport security credentials. -- */ -static grpc_security_status fake_transport_security_create_security_connector( - grpc_channel_credentials* c, grpc_call_credentials* call_creds, - const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - *sc = - grpc_fake_channel_security_connector_create(c, call_creds, target, args); - return GRPC_SECURITY_OK; -} - -static grpc_security_status -fake_transport_security_server_create_security_connector( - grpc_server_credentials* c, grpc_server_security_connector** sc) { - *sc = grpc_fake_server_security_connector_create(c); - return GRPC_SECURITY_OK; -} +namespace { +class grpc_fake_channel_credentials final : public grpc_channel_credentials { + public: + grpc_fake_channel_credentials() + : grpc_channel_credentials( + GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) {} + ~grpc_fake_channel_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override { + return grpc_fake_channel_security_connector_create( + this->Ref(), std::move(call_creds), target, args); + } +}; + +class grpc_fake_server_credentials final : public grpc_server_credentials { + public: + grpc_fake_server_credentials() + : grpc_server_credentials( + GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) {} + ~grpc_fake_server_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector() override { + return grpc_fake_server_security_connector_create(this->Ref()); + } +}; +} // namespace -static grpc_channel_credentials_vtable - fake_transport_security_credentials_vtable = { - nullptr, fake_transport_security_create_security_connector, nullptr}; - -static grpc_server_credentials_vtable - fake_transport_security_server_credentials_vtable = { - nullptr, fake_transport_security_server_create_security_connector}; - -grpc_channel_credentials* grpc_fake_transport_security_credentials_create( - void) { - grpc_channel_credentials* c = static_cast( - gpr_zalloc(sizeof(grpc_channel_credentials))); - c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY; - c->vtable = &fake_transport_security_credentials_vtable; - gpr_ref_init(&c->refcount, 1); - return c; +grpc_channel_credentials* grpc_fake_transport_security_credentials_create() { + return grpc_core::New(); } -grpc_server_credentials* grpc_fake_transport_security_server_credentials_create( - void) { - grpc_server_credentials* c = static_cast( - gpr_malloc(sizeof(grpc_server_credentials))); - memset(c, 0, sizeof(grpc_server_credentials)); - c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY; - gpr_ref_init(&c->refcount, 1); - c->vtable = &fake_transport_security_server_credentials_vtable; - return c; +grpc_server_credentials* +grpc_fake_transport_security_server_credentials_create() { + return grpc_core::New(); } grpc_arg grpc_fake_transport_expected_targets_arg(char* expected_targets) { @@ -92,46 +88,25 @@ const char* grpc_fake_transport_get_expected_targets( /* -- Metadata-only test credentials. -- */ -static void md_only_test_destruct(grpc_call_credentials* creds) { - grpc_md_only_test_credentials* c = - reinterpret_cast(creds); - GRPC_MDELEM_UNREF(c->md); -} - -static bool md_only_test_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error) { - grpc_md_only_test_credentials* c = - reinterpret_cast(creds); - grpc_credentials_mdelem_array_add(md_array, c->md); - if (c->is_async) { +bool grpc_md_only_test_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { + grpc_credentials_mdelem_array_add(md_array, md_); + if (is_async_) { GRPC_CLOSURE_SCHED(on_request_metadata, GRPC_ERROR_NONE); return false; } return true; } -static void md_only_test_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { +void grpc_md_only_test_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable md_only_test_vtable = { - md_only_test_destruct, md_only_test_get_request_metadata, - md_only_test_cancel_get_request_metadata}; - grpc_call_credentials* grpc_md_only_test_credentials_create( const char* md_key, const char* md_value, bool is_async) { - grpc_md_only_test_credentials* c = - static_cast( - gpr_zalloc(sizeof(grpc_md_only_test_credentials))); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; - c->base.vtable = &md_only_test_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->md = grpc_mdelem_from_slices(grpc_slice_from_copied_string(md_key), - grpc_slice_from_copied_string(md_value)); - c->is_async = is_async; - return &c->base; + return grpc_core::New(md_key, md_value, + is_async); } diff --git a/src/core/lib/security/credentials/fake/fake_credentials.h b/src/core/lib/security/credentials/fake/fake_credentials.h index e89e6e24cca..b7f6a1909fc 100644 --- a/src/core/lib/security/credentials/fake/fake_credentials.h +++ b/src/core/lib/security/credentials/fake/fake_credentials.h @@ -55,10 +55,28 @@ const char* grpc_fake_transport_get_expected_targets( /* -- Metadata-only Test credentials. -- */ -typedef struct { - grpc_call_credentials base; - grpc_mdelem md; - bool is_async; -} grpc_md_only_test_credentials; +class grpc_md_only_test_credentials : public grpc_call_credentials { + public: + grpc_md_only_test_credentials(const char* md_key, const char* md_value, + bool is_async) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_OAUTH2), + md_(grpc_mdelem_from_slices(grpc_slice_from_copied_string(md_key), + grpc_slice_from_copied_string(md_value))), + is_async_(is_async) {} + ~grpc_md_only_test_credentials() override { GRPC_MDELEM_UNREF(md_); } + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + private: + grpc_mdelem md_; + bool is_async_; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_FAKE_FAKE_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc index 0674540d01c..a86a17d5864 100644 --- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc +++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/http/httpcli.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/load_file.h" @@ -72,20 +73,11 @@ typedef struct { grpc_http_response response; } metadata_server_detector; -static void google_default_credentials_destruct( - grpc_channel_credentials* creds) { - grpc_google_default_channel_credentials* c = - reinterpret_cast(creds); - grpc_channel_credentials_unref(c->alts_creds); - grpc_channel_credentials_unref(c->ssl_creds); -} - -static grpc_security_status google_default_create_security_connector( - grpc_channel_credentials* creds, grpc_call_credentials* call_creds, +grpc_core::RefCountedPtr +grpc_google_default_channel_credentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - grpc_google_default_channel_credentials* c = - reinterpret_cast(creds); + grpc_channel_args** new_args) { bool is_grpclb_load_balancer = grpc_channel_arg_get_bool( grpc_channel_args_find(args, GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER), false); @@ -95,22 +87,22 @@ static grpc_security_status google_default_create_security_connector( false); bool use_alts = is_grpclb_load_balancer || is_backend_from_grpclb_load_balancer; - grpc_security_status status = GRPC_SECURITY_ERROR; /* Return failure if ALTS is selected but not running on GCE. */ if (use_alts && !g_is_on_gce) { gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE."); - goto end; + return nullptr; } - status = use_alts ? c->alts_creds->vtable->create_security_connector( - c->alts_creds, call_creds, target, args, sc, new_args) - : c->ssl_creds->vtable->create_security_connector( - c->ssl_creds, call_creds, target, args, sc, new_args); -/* grpclb-specific channel args are removed from the channel args set - * to ensure backends and fallback adresses will have the same set of channel - * args. By doing that, it guarantees the connections to backends will not be - * torn down and re-connected when switching in and out of fallback mode. - */ -end: + + grpc_core::RefCountedPtr sc = + use_alts ? alts_creds_->create_security_connector(call_creds, target, + args, new_args) + : ssl_creds_->create_security_connector(call_creds, target, args, + new_args); + /* grpclb-specific channel args are removed from the channel args set + * to ensure backends and fallback adresses will have the same set of channel + * args. By doing that, it guarantees the connections to backends will not be + * torn down and re-connected when switching in and out of fallback mode. + */ if (use_alts) { static const char* args_to_remove[] = { GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER, @@ -119,13 +111,9 @@ end: *new_args = grpc_channel_args_copy_and_add_and_remove( args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), nullptr, 0); } - return status; + return sc; } -static grpc_channel_credentials_vtable google_default_credentials_vtable = { - google_default_credentials_destruct, - google_default_create_security_connector, nullptr}; - static void on_metadata_server_detection_http_response(void* user_data, grpc_error* error) { metadata_server_detector* detector = @@ -215,11 +203,11 @@ static int is_metadata_server_reachable() { /* Takes ownership of creds_path if not NULL. */ static grpc_error* create_default_creds_from_path( - char* creds_path, grpc_call_credentials** creds) { + char* creds_path, grpc_core::RefCountedPtr* creds) { grpc_json* json = nullptr; grpc_auth_json_key key; grpc_auth_refresh_token token; - grpc_call_credentials* result = nullptr; + grpc_core::RefCountedPtr result; grpc_slice creds_data = grpc_empty_slice(); grpc_error* error = GRPC_ERROR_NONE; if (creds_path == nullptr) { @@ -276,9 +264,9 @@ end: return error; } -grpc_channel_credentials* grpc_google_default_credentials_create(void) { +grpc_channel_credentials* grpc_google_default_credentials_create() { grpc_channel_credentials* result = nullptr; - grpc_call_credentials* call_creds = nullptr; + grpc_core::RefCountedPtr call_creds; grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Failed to create Google credentials"); grpc_error* err; @@ -316,7 +304,8 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) { gpr_mu_unlock(&g_state_mu); if (g_metadata_server_available) { - call_creds = grpc_google_compute_engine_credentials_create(nullptr); + call_creds = grpc_core::RefCountedPtr( + grpc_google_compute_engine_credentials_create(nullptr)); if (call_creds == nullptr) { error = grpc_error_add_child( error, GRPC_ERROR_CREATE_FROM_STATIC_STRING( @@ -327,23 +316,23 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) { end: if (call_creds != nullptr) { /* Create google default credentials. */ - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_google_default_channel_credentials))); - creds->base.vtable = &google_default_credentials_vtable; - creds->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_GOOGLE_DEFAULT; - gpr_ref_init(&creds->base.refcount, 1); - creds->ssl_creds = + grpc_channel_credentials* ssl_creds = grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr); - GPR_ASSERT(creds->ssl_creds != nullptr); + GPR_ASSERT(ssl_creds != nullptr); grpc_alts_credentials_options* options = grpc_alts_credentials_client_options_create(); - creds->alts_creds = grpc_alts_credentials_create(options); + grpc_channel_credentials* alts_creds = + grpc_alts_credentials_create(options); grpc_alts_credentials_options_destroy(options); - result = grpc_composite_channel_credentials_create(&creds->base, call_creds, - nullptr); + auto creds = + grpc_core::MakeRefCounted( + alts_creds != nullptr ? alts_creds->Ref() : nullptr, + ssl_creds != nullptr ? ssl_creds->Ref() : nullptr); + if (ssl_creds) ssl_creds->Unref(); + if (alts_creds) alts_creds->Unref(); + result = grpc_composite_channel_credentials_create( + creds.get(), call_creds.get(), nullptr); GPR_ASSERT(result != nullptr); - grpc_channel_credentials_unref(&creds->base); - grpc_call_credentials_unref(call_creds); } else { gpr_log(GPR_ERROR, "Could not create google default credentials: %s", grpc_error_string(error)); diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.h b/src/core/lib/security/credentials/google_default/google_default_credentials.h index b9e2efb04fa..bf00f7285ad 100644 --- a/src/core/lib/security/credentials/google_default/google_default_credentials.h +++ b/src/core/lib/security/credentials/google_default/google_default_credentials.h @@ -21,6 +21,7 @@ #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/credentials/credentials.h" #define GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY "gcloud" @@ -39,11 +40,33 @@ "/" GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE #endif -typedef struct { - grpc_channel_credentials base; - grpc_channel_credentials* alts_creds; - grpc_channel_credentials* ssl_creds; -} grpc_google_default_channel_credentials; +class grpc_google_default_channel_credentials + : public grpc_channel_credentials { + public: + grpc_google_default_channel_credentials( + grpc_core::RefCountedPtr alts_creds, + grpc_core::RefCountedPtr ssl_creds) + : grpc_channel_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_GOOGLE_DEFAULT), + alts_creds_(std::move(alts_creds)), + ssl_creds_(std::move(ssl_creds)) {} + + ~grpc_google_default_channel_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + const grpc_channel_credentials* alts_creds() const { + return alts_creds_.get(); + } + const grpc_channel_credentials* ssl_creds() const { return ssl_creds_.get(); } + + private: + grpc_core::RefCountedPtr alts_creds_; + grpc_core::RefCountedPtr ssl_creds_; +}; namespace grpc_core { namespace internal { diff --git a/src/core/lib/security/credentials/iam/iam_credentials.cc b/src/core/lib/security/credentials/iam/iam_credentials.cc index 5d92fa88c45..5cd561f676a 100644 --- a/src/core/lib/security/credentials/iam/iam_credentials.cc +++ b/src/core/lib/security/credentials/iam/iam_credentials.cc @@ -22,6 +22,7 @@ #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/surface/api_trace.h" #include @@ -29,32 +30,37 @@ #include #include -static void iam_destruct(grpc_call_credentials* creds) { - grpc_google_iam_credentials* c = - reinterpret_cast(creds); - grpc_credentials_mdelem_array_destroy(&c->md_array); +grpc_google_iam_credentials::~grpc_google_iam_credentials() { + grpc_credentials_mdelem_array_destroy(&md_array_); } -static bool iam_get_request_metadata(grpc_call_credentials* creds, - grpc_polling_entity* pollent, - grpc_auth_metadata_context context, - grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, - grpc_error** error) { - grpc_google_iam_credentials* c = - reinterpret_cast(creds); - grpc_credentials_mdelem_array_append(md_array, &c->md_array); +bool grpc_google_iam_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { + grpc_credentials_mdelem_array_append(md_array, &md_array_); return true; } -static void iam_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { +void grpc_google_iam_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable iam_vtable = { - iam_destruct, iam_get_request_metadata, iam_cancel_get_request_metadata}; +grpc_google_iam_credentials::grpc_google_iam_credentials( + const char* token, const char* authority_selector) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_IAM) { + grpc_mdelem md = grpc_mdelem_from_slices( + grpc_slice_from_static_string(GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY), + grpc_slice_from_copied_string(token)); + grpc_credentials_mdelem_array_add(&md_array_, md); + GRPC_MDELEM_UNREF(md); + md = grpc_mdelem_from_slices( + grpc_slice_from_static_string(GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY), + grpc_slice_from_copied_string(authority_selector)); + grpc_credentials_mdelem_array_add(&md_array_, md); + GRPC_MDELEM_UNREF(md); +} grpc_call_credentials* grpc_google_iam_credentials_create( const char* token, const char* authority_selector, void* reserved) { @@ -66,21 +72,7 @@ grpc_call_credentials* grpc_google_iam_credentials_create( GPR_ASSERT(reserved == nullptr); GPR_ASSERT(token != nullptr); GPR_ASSERT(authority_selector != nullptr); - grpc_google_iam_credentials* c = - static_cast(gpr_zalloc(sizeof(*c))); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_IAM; - c->base.vtable = &iam_vtable; - gpr_ref_init(&c->base.refcount, 1); - grpc_mdelem md = grpc_mdelem_from_slices( - grpc_slice_from_static_string(GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY), - grpc_slice_from_copied_string(token)); - grpc_credentials_mdelem_array_add(&c->md_array, md); - GRPC_MDELEM_UNREF(md); - md = grpc_mdelem_from_slices( - grpc_slice_from_static_string(GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY), - grpc_slice_from_copied_string(authority_selector)); - grpc_credentials_mdelem_array_add(&c->md_array, md); - GRPC_MDELEM_UNREF(md); - - return &c->base; + return grpc_core::MakeRefCounted( + token, authority_selector) + .release(); } diff --git a/src/core/lib/security/credentials/iam/iam_credentials.h b/src/core/lib/security/credentials/iam/iam_credentials.h index a45710fe0f8..36f5ee89307 100644 --- a/src/core/lib/security/credentials/iam/iam_credentials.h +++ b/src/core/lib/security/credentials/iam/iam_credentials.h @@ -23,9 +23,23 @@ #include "src/core/lib/security/credentials/credentials.h" -typedef struct { - grpc_call_credentials base; - grpc_credentials_mdelem_array md_array; -} grpc_google_iam_credentials; +class grpc_google_iam_credentials : public grpc_call_credentials { + public: + grpc_google_iam_credentials(const char* token, + const char* authority_selector); + ~grpc_google_iam_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + private: + grpc_credentials_mdelem_array md_array_; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_IAM_IAM_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.cc b/src/core/lib/security/credentials/jwt/jwt_credentials.cc index 05c08a68b01..f2591a1ea5e 100644 --- a/src/core/lib/security/credentials/jwt/jwt_credentials.cc +++ b/src/core/lib/security/credentials/jwt/jwt_credentials.cc @@ -23,6 +23,8 @@ #include #include +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/surface/api_trace.h" #include @@ -30,71 +32,66 @@ #include #include -static void jwt_reset_cache(grpc_service_account_jwt_access_credentials* c) { - GRPC_MDELEM_UNREF(c->cached.jwt_md); - c->cached.jwt_md = GRPC_MDNULL; - if (c->cached.service_url != nullptr) { - gpr_free(c->cached.service_url); - c->cached.service_url = nullptr; +void grpc_service_account_jwt_access_credentials::reset_cache() { + GRPC_MDELEM_UNREF(cached_.jwt_md); + cached_.jwt_md = GRPC_MDNULL; + if (cached_.service_url != nullptr) { + gpr_free(cached_.service_url); + cached_.service_url = nullptr; } - c->cached.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); + cached_.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); } -static void jwt_destruct(grpc_call_credentials* creds) { - grpc_service_account_jwt_access_credentials* c = - reinterpret_cast(creds); - grpc_auth_json_key_destruct(&c->key); - jwt_reset_cache(c); - gpr_mu_destroy(&c->cache_mu); +grpc_service_account_jwt_access_credentials:: + ~grpc_service_account_jwt_access_credentials() { + grpc_auth_json_key_destruct(&key_); + reset_cache(); + gpr_mu_destroy(&cache_mu_); } -static bool jwt_get_request_metadata(grpc_call_credentials* creds, - grpc_polling_entity* pollent, - grpc_auth_metadata_context context, - grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, - grpc_error** error) { - grpc_service_account_jwt_access_credentials* c = - reinterpret_cast(creds); +bool grpc_service_account_jwt_access_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { gpr_timespec refresh_threshold = gpr_time_from_seconds( GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN); /* See if we can return a cached jwt. */ grpc_mdelem jwt_md = GRPC_MDNULL; { - gpr_mu_lock(&c->cache_mu); - if (c->cached.service_url != nullptr && - strcmp(c->cached.service_url, context.service_url) == 0 && - !GRPC_MDISNULL(c->cached.jwt_md) && - (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, - gpr_now(GPR_CLOCK_REALTIME)), - refresh_threshold) > 0)) { - jwt_md = GRPC_MDELEM_REF(c->cached.jwt_md); + gpr_mu_lock(&cache_mu_); + if (cached_.service_url != nullptr && + strcmp(cached_.service_url, context.service_url) == 0 && + !GRPC_MDISNULL(cached_.jwt_md) && + (gpr_time_cmp( + gpr_time_sub(cached_.jwt_expiration, gpr_now(GPR_CLOCK_REALTIME)), + refresh_threshold) > 0)) { + jwt_md = GRPC_MDELEM_REF(cached_.jwt_md); } - gpr_mu_unlock(&c->cache_mu); + gpr_mu_unlock(&cache_mu_); } if (GRPC_MDISNULL(jwt_md)) { char* jwt = nullptr; /* Generate a new jwt. */ - gpr_mu_lock(&c->cache_mu); - jwt_reset_cache(c); - jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url, - c->jwt_lifetime, nullptr); + gpr_mu_lock(&cache_mu_); + reset_cache(); + jwt = grpc_jwt_encode_and_sign(&key_, context.service_url, jwt_lifetime_, + nullptr); if (jwt != nullptr) { char* md_value; gpr_asprintf(&md_value, "Bearer %s", jwt); gpr_free(jwt); - c->cached.jwt_expiration = - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime); - c->cached.service_url = gpr_strdup(context.service_url); - c->cached.jwt_md = grpc_mdelem_from_slices( + cached_.jwt_expiration = + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), jwt_lifetime_); + cached_.service_url = gpr_strdup(context.service_url); + cached_.jwt_md = grpc_mdelem_from_slices( grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY), grpc_slice_from_copied_string(md_value)); gpr_free(md_value); - jwt_md = GRPC_MDELEM_REF(c->cached.jwt_md); + jwt_md = GRPC_MDELEM_REF(cached_.jwt_md); } - gpr_mu_unlock(&c->cache_mu); + gpr_mu_unlock(&cache_mu_); } if (!GRPC_MDISNULL(jwt_md)) { @@ -106,29 +103,15 @@ static bool jwt_get_request_metadata(grpc_call_credentials* creds, return true; } -static void jwt_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { +void grpc_service_account_jwt_access_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable jwt_vtable = { - jwt_destruct, jwt_get_request_metadata, jwt_cancel_get_request_metadata}; - -grpc_call_credentials* -grpc_service_account_jwt_access_credentials_create_from_auth_json_key( - grpc_auth_json_key key, gpr_timespec token_lifetime) { - grpc_service_account_jwt_access_credentials* c; - if (!grpc_auth_json_key_is_valid(&key)) { - gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation"); - return nullptr; - } - c = static_cast( - gpr_zalloc(sizeof(grpc_service_account_jwt_access_credentials))); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_JWT; - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &jwt_vtable; - c->key = key; +grpc_service_account_jwt_access_credentials:: + grpc_service_account_jwt_access_credentials(grpc_auth_json_key key, + gpr_timespec token_lifetime) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_JWT), key_(key) { gpr_timespec max_token_lifetime = grpc_max_auth_token_lifetime(); if (gpr_time_cmp(token_lifetime, max_token_lifetime) > 0) { gpr_log(GPR_INFO, @@ -136,10 +119,20 @@ grpc_service_account_jwt_access_credentials_create_from_auth_json_key( static_cast(max_token_lifetime.tv_sec)); token_lifetime = grpc_max_auth_token_lifetime(); } - c->jwt_lifetime = token_lifetime; - gpr_mu_init(&c->cache_mu); - jwt_reset_cache(c); - return &c->base; + jwt_lifetime_ = token_lifetime; + gpr_mu_init(&cache_mu_); + reset_cache(); +} + +grpc_core::RefCountedPtr +grpc_service_account_jwt_access_credentials_create_from_auth_json_key( + grpc_auth_json_key key, gpr_timespec token_lifetime) { + if (!grpc_auth_json_key_is_valid(&key)) { + gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation"); + return nullptr; + } + return grpc_core::MakeRefCounted( + key, token_lifetime); } static char* redact_private_key(const char* json_key) { @@ -182,9 +175,7 @@ grpc_call_credentials* grpc_service_account_jwt_access_credentials_create( } GPR_ASSERT(reserved == nullptr); grpc_core::ExecCtx exec_ctx; - grpc_call_credentials* creds = - grpc_service_account_jwt_access_credentials_create_from_auth_json_key( - grpc_auth_json_key_create_from_string(json_key), token_lifetime); - - return creds; + return grpc_service_account_jwt_access_credentials_create_from_auth_json_key( + grpc_auth_json_key_create_from_string(json_key), token_lifetime) + .release(); } diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.h b/src/core/lib/security/credentials/jwt/jwt_credentials.h index 5c3d34aa566..5af909f44df 100644 --- a/src/core/lib/security/credentials/jwt/jwt_credentials.h +++ b/src/core/lib/security/credentials/jwt/jwt_credentials.h @@ -24,25 +24,44 @@ #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/jwt/json_token.h" -typedef struct { - grpc_call_credentials base; +class grpc_service_account_jwt_access_credentials + : public grpc_call_credentials { + public: + grpc_service_account_jwt_access_credentials(grpc_auth_json_key key, + gpr_timespec token_lifetime); + ~grpc_service_account_jwt_access_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + const gpr_timespec& jwt_lifetime() const { return jwt_lifetime_; } + const grpc_auth_json_key& key() const { return key_; } + + private: + void reset_cache(); // Have a simple cache for now with just 1 entry. We could have a map based on // the service_url for a more sophisticated one. - gpr_mu cache_mu; + gpr_mu cache_mu_; struct { - grpc_mdelem jwt_md; - char* service_url; + grpc_mdelem jwt_md = GRPC_MDNULL; + char* service_url = nullptr; gpr_timespec jwt_expiration; - } cached; + } cached_; - grpc_auth_json_key key; - gpr_timespec jwt_lifetime; -} grpc_service_account_jwt_access_credentials; + grpc_auth_json_key key_; + gpr_timespec jwt_lifetime_; +}; // Private constructor for jwt credentials from an already parsed json key. // Takes ownership of the key. -grpc_call_credentials* +grpc_core::RefCountedPtr grpc_service_account_jwt_access_credentials_create_from_auth_json_key( grpc_auth_json_key key, gpr_timespec token_lifetime); diff --git a/src/core/lib/security/credentials/local/local_credentials.cc b/src/core/lib/security/credentials/local/local_credentials.cc index 3ccfa2b9086..6f6f95a34a7 100644 --- a/src/core/lib/security/credentials/local/local_credentials.cc +++ b/src/core/lib/security/credentials/local/local_credentials.cc @@ -29,49 +29,36 @@ #define GRPC_CREDENTIALS_TYPE_LOCAL "Local" -static void local_credentials_destruct(grpc_channel_credentials* creds) {} - -static void local_server_credentials_destruct(grpc_server_credentials* creds) {} - -static grpc_security_status local_create_security_connector( - grpc_channel_credentials* creds, - grpc_call_credentials* request_metadata_creds, const char* target_name, - const grpc_channel_args* args, grpc_channel_security_connector** sc, +grpc_core::RefCountedPtr +grpc_local_credentials::create_security_connector( + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const grpc_channel_args* args, grpc_channel_args** new_args) { return grpc_local_channel_security_connector_create( - creds, request_metadata_creds, args, target_name, sc); + this->Ref(), std::move(request_metadata_creds), args, target_name); } -static grpc_security_status local_server_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc) { - return grpc_local_server_security_connector_create(creds, sc); +grpc_core::RefCountedPtr +grpc_local_server_credentials::create_security_connector() { + return grpc_local_server_security_connector_create(this->Ref()); } -static const grpc_channel_credentials_vtable local_credentials_vtable = { - local_credentials_destruct, local_create_security_connector, - /*duplicate_without_call_credentials=*/nullptr}; - -static const grpc_server_credentials_vtable local_server_credentials_vtable = { - local_server_credentials_destruct, local_server_create_security_connector}; +grpc_local_credentials::grpc_local_credentials( + grpc_local_connect_type connect_type) + : grpc_channel_credentials(GRPC_CREDENTIALS_TYPE_LOCAL), + connect_type_(connect_type) {} grpc_channel_credentials* grpc_local_credentials_create( grpc_local_connect_type connect_type) { - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_local_credentials))); - creds->connect_type = connect_type; - creds->base.type = GRPC_CREDENTIALS_TYPE_LOCAL; - creds->base.vtable = &local_credentials_vtable; - gpr_ref_init(&creds->base.refcount, 1); - return &creds->base; + return grpc_core::New(connect_type); } +grpc_local_server_credentials::grpc_local_server_credentials( + grpc_local_connect_type connect_type) + : grpc_server_credentials(GRPC_CREDENTIALS_TYPE_LOCAL), + connect_type_(connect_type) {} + grpc_server_credentials* grpc_local_server_credentials_create( grpc_local_connect_type connect_type) { - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_local_server_credentials))); - creds->connect_type = connect_type; - creds->base.type = GRPC_CREDENTIALS_TYPE_LOCAL; - creds->base.vtable = &local_server_credentials_vtable; - gpr_ref_init(&creds->base.refcount, 1); - return &creds->base; + return grpc_core::New(connect_type); } diff --git a/src/core/lib/security/credentials/local/local_credentials.h b/src/core/lib/security/credentials/local/local_credentials.h index 47358b04bc1..60a8a4f64ca 100644 --- a/src/core/lib/security/credentials/local/local_credentials.h +++ b/src/core/lib/security/credentials/local/local_credentials.h @@ -25,16 +25,37 @@ #include "src/core/lib/security/credentials/credentials.h" -/* Main struct for grpc local channel credential. */ -typedef struct grpc_local_credentials { - grpc_channel_credentials base; - grpc_local_connect_type connect_type; -} grpc_local_credentials; - -/* Main struct for grpc local server credential. */ -typedef struct grpc_local_server_credentials { - grpc_server_credentials base; - grpc_local_connect_type connect_type; -} grpc_local_server_credentials; +/* Main class for grpc local channel credential. */ +class grpc_local_credentials final : public grpc_channel_credentials { + public: + explicit grpc_local_credentials(grpc_local_connect_type connect_type); + ~grpc_local_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + grpc_local_connect_type connect_type() const { return connect_type_; } + + private: + grpc_local_connect_type connect_type_; +}; + +/* Main class for grpc local server credential. */ +class grpc_local_server_credentials final : public grpc_server_credentials { + public: + explicit grpc_local_server_credentials(grpc_local_connect_type connect_type); + ~grpc_local_server_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector() override; + + grpc_local_connect_type connect_type() const { return connect_type_; } + + private: + grpc_local_connect_type connect_type_; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_LOCAL_LOCAL_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc index 44b093557f3..ad63b01e754 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc @@ -22,6 +22,7 @@ #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/util/json_util.h" #include "src/core/lib/surface/api_trace.h" @@ -105,13 +106,12 @@ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token* refresh_token) { // Oauth2 Token Fetcher credentials. // -static void oauth2_token_fetcher_destruct(grpc_call_credentials* creds) { - grpc_oauth2_token_fetcher_credentials* c = - reinterpret_cast(creds); - GRPC_MDELEM_UNREF(c->access_token_md); - gpr_mu_destroy(&c->mu); - grpc_pollset_set_destroy(grpc_polling_entity_pollset_set(&c->pollent)); - grpc_httpcli_context_destroy(&c->httpcli_context); +grpc_oauth2_token_fetcher_credentials:: + ~grpc_oauth2_token_fetcher_credentials() { + GRPC_MDELEM_UNREF(access_token_md_); + gpr_mu_destroy(&mu_); + grpc_pollset_set_destroy(grpc_polling_entity_pollset_set(&pollent_)); + grpc_httpcli_context_destroy(&httpcli_context_); } grpc_credentials_status @@ -209,25 +209,29 @@ static void on_oauth2_token_fetcher_http_response(void* user_data, grpc_credentials_metadata_request* r = static_cast(user_data); grpc_oauth2_token_fetcher_credentials* c = - reinterpret_cast(r->creds); + reinterpret_cast(r->creds.get()); + c->on_http_response(r, error); +} + +void grpc_oauth2_token_fetcher_credentials::on_http_response( + grpc_credentials_metadata_request* r, grpc_error* error) { grpc_mdelem access_token_md = GRPC_MDNULL; grpc_millis token_lifetime; grpc_credentials_status status = grpc_oauth2_token_fetcher_credentials_parse_server_response( &r->response, &access_token_md, &token_lifetime); // Update cache and grab list of pending requests. - gpr_mu_lock(&c->mu); - c->token_fetch_pending = false; - c->access_token_md = GRPC_MDELEM_REF(access_token_md); - c->token_expiration = + gpr_mu_lock(&mu_); + token_fetch_pending_ = false; + access_token_md_ = GRPC_MDELEM_REF(access_token_md); + token_expiration_ = status == GRPC_CREDENTIALS_OK ? gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_millis(token_lifetime, GPR_TIMESPAN)) : gpr_inf_past(GPR_CLOCK_MONOTONIC); - grpc_oauth2_pending_get_request_metadata* pending_request = - c->pending_requests; - c->pending_requests = nullptr; - gpr_mu_unlock(&c->mu); + grpc_oauth2_pending_get_request_metadata* pending_request = pending_requests_; + pending_requests_ = nullptr; + gpr_mu_unlock(&mu_); // Invoke callbacks for all pending requests. while (pending_request != nullptr) { if (status == GRPC_CREDENTIALS_OK) { @@ -239,42 +243,40 @@ static void on_oauth2_token_fetcher_http_response(void* user_data, } GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, error); grpc_polling_entity_del_from_pollset_set( - pending_request->pollent, grpc_polling_entity_pollset_set(&c->pollent)); + pending_request->pollent, grpc_polling_entity_pollset_set(&pollent_)); grpc_oauth2_pending_get_request_metadata* prev = pending_request; pending_request = pending_request->next; gpr_free(prev); } GRPC_MDELEM_UNREF(access_token_md); - grpc_call_credentials_unref(r->creds); + Unref(); grpc_credentials_metadata_request_destroy(r); } -static bool oauth2_token_fetcher_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error) { - grpc_oauth2_token_fetcher_credentials* c = - reinterpret_cast(creds); +bool grpc_oauth2_token_fetcher_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { // Check if we can use the cached token. grpc_millis refresh_threshold = GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS * GPR_MS_PER_SEC; grpc_mdelem cached_access_token_md = GRPC_MDNULL; - gpr_mu_lock(&c->mu); - if (!GRPC_MDISNULL(c->access_token_md) && + gpr_mu_lock(&mu_); + if (!GRPC_MDISNULL(access_token_md_) && gpr_time_cmp( - gpr_time_sub(c->token_expiration, gpr_now(GPR_CLOCK_MONOTONIC)), + gpr_time_sub(token_expiration_, gpr_now(GPR_CLOCK_MONOTONIC)), gpr_time_from_seconds(GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN)) > 0) { - cached_access_token_md = GRPC_MDELEM_REF(c->access_token_md); + cached_access_token_md = GRPC_MDELEM_REF(access_token_md_); } if (!GRPC_MDISNULL(cached_access_token_md)) { - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&mu_); grpc_credentials_mdelem_array_add(md_array, cached_access_token_md); GRPC_MDELEM_UNREF(cached_access_token_md); return true; } // Couldn't get the token from the cache. - // Add request to c->pending_requests and start a new fetch if needed. + // Add request to pending_requests_ and start a new fetch if needed. grpc_oauth2_pending_get_request_metadata* pending_request = static_cast( gpr_malloc(sizeof(*pending_request))); @@ -282,41 +284,37 @@ static bool oauth2_token_fetcher_get_request_metadata( pending_request->on_request_metadata = on_request_metadata; pending_request->pollent = pollent; grpc_polling_entity_add_to_pollset_set( - pollent, grpc_polling_entity_pollset_set(&c->pollent)); - pending_request->next = c->pending_requests; - c->pending_requests = pending_request; + pollent, grpc_polling_entity_pollset_set(&pollent_)); + pending_request->next = pending_requests_; + pending_requests_ = pending_request; bool start_fetch = false; - if (!c->token_fetch_pending) { - c->token_fetch_pending = true; + if (!token_fetch_pending_) { + token_fetch_pending_ = true; start_fetch = true; } - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&mu_); if (start_fetch) { - grpc_call_credentials_ref(creds); - c->fetch_func(grpc_credentials_metadata_request_create(creds), - &c->httpcli_context, &c->pollent, - on_oauth2_token_fetcher_http_response, - grpc_core::ExecCtx::Get()->Now() + refresh_threshold); + Ref().release(); + fetch_oauth2(grpc_credentials_metadata_request_create(this->Ref()), + &httpcli_context_, &pollent_, + on_oauth2_token_fetcher_http_response, + grpc_core::ExecCtx::Get()->Now() + refresh_threshold); } return false; } -static void oauth2_token_fetcher_cancel_get_request_metadata( - grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { - grpc_oauth2_token_fetcher_credentials* c = - reinterpret_cast(creds); - gpr_mu_lock(&c->mu); +void grpc_oauth2_token_fetcher_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { + gpr_mu_lock(&mu_); grpc_oauth2_pending_get_request_metadata* prev = nullptr; - grpc_oauth2_pending_get_request_metadata* pending_request = - c->pending_requests; + grpc_oauth2_pending_get_request_metadata* pending_request = pending_requests_; while (pending_request != nullptr) { if (pending_request->md_array == md_array) { // Remove matching pending request from the list. if (prev != nullptr) { prev->next = pending_request->next; } else { - c->pending_requests = pending_request->next; + pending_requests_ = pending_request->next; } // Invoke the callback immediately with an error. GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, @@ -327,96 +325,89 @@ static void oauth2_token_fetcher_cancel_get_request_metadata( prev = pending_request; pending_request = pending_request->next; } - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&mu_); GRPC_ERROR_UNREF(error); } -static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials* c, - grpc_fetch_oauth2_func fetch_func) { - memset(c, 0, sizeof(grpc_oauth2_token_fetcher_credentials)); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; - gpr_ref_init(&c->base.refcount, 1); - gpr_mu_init(&c->mu); - c->token_expiration = gpr_inf_past(GPR_CLOCK_MONOTONIC); - c->fetch_func = fetch_func; - c->pollent = - grpc_polling_entity_create_from_pollset_set(grpc_pollset_set_create()); - grpc_httpcli_context_init(&c->httpcli_context); +grpc_oauth2_token_fetcher_credentials::grpc_oauth2_token_fetcher_credentials() + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_OAUTH2), + token_expiration_(gpr_inf_past(GPR_CLOCK_MONOTONIC)), + pollent_(grpc_polling_entity_create_from_pollset_set( + grpc_pollset_set_create())) { + gpr_mu_init(&mu_); + grpc_httpcli_context_init(&httpcli_context_); } // // Google Compute Engine credentials. // -static grpc_call_credentials_vtable compute_engine_vtable = { - oauth2_token_fetcher_destruct, oauth2_token_fetcher_get_request_metadata, - oauth2_token_fetcher_cancel_get_request_metadata}; +namespace { + +class grpc_compute_engine_token_fetcher_credentials + : public grpc_oauth2_token_fetcher_credentials { + public: + grpc_compute_engine_token_fetcher_credentials() = default; + ~grpc_compute_engine_token_fetcher_credentials() override = default; + + protected: + void fetch_oauth2(grpc_credentials_metadata_request* metadata_req, + grpc_httpcli_context* http_context, + grpc_polling_entity* pollent, + grpc_iomgr_cb_func response_cb, + grpc_millis deadline) override { + grpc_http_header header = {(char*)"Metadata-Flavor", (char*)"Google"}; + grpc_httpcli_request request; + memset(&request, 0, sizeof(grpc_httpcli_request)); + request.host = (char*)GRPC_COMPUTE_ENGINE_METADATA_HOST; + request.http.path = (char*)GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH; + request.http.hdr_count = 1; + request.http.hdrs = &header; + /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host + channel. This would allow us to cancel an authentication query when under + extreme memory pressure. */ + grpc_resource_quota* resource_quota = + grpc_resource_quota_create("oauth2_credentials"); + grpc_httpcli_get(http_context, pollent, resource_quota, &request, deadline, + GRPC_CLOSURE_CREATE(response_cb, metadata_req, + grpc_schedule_on_exec_ctx), + &metadata_req->response); + grpc_resource_quota_unref_internal(resource_quota); + } +}; -static void compute_engine_fetch_oauth2( - grpc_credentials_metadata_request* metadata_req, - grpc_httpcli_context* httpcli_context, grpc_polling_entity* pollent, - grpc_iomgr_cb_func response_cb, grpc_millis deadline) { - grpc_http_header header = {(char*)"Metadata-Flavor", (char*)"Google"}; - grpc_httpcli_request request; - memset(&request, 0, sizeof(grpc_httpcli_request)); - request.host = (char*)GRPC_COMPUTE_ENGINE_METADATA_HOST; - request.http.path = (char*)GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH; - request.http.hdr_count = 1; - request.http.hdrs = &header; - /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host - channel. This would allow us to cancel an authentication query when under - extreme memory pressure. */ - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("oauth2_credentials"); - grpc_httpcli_get( - httpcli_context, pollent, resource_quota, &request, deadline, - GRPC_CLOSURE_CREATE(response_cb, metadata_req, grpc_schedule_on_exec_ctx), - &metadata_req->response); - grpc_resource_quota_unref_internal(resource_quota); -} +} // namespace grpc_call_credentials* grpc_google_compute_engine_credentials_create( void* reserved) { - grpc_oauth2_token_fetcher_credentials* c = - static_cast( - gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials))); GRPC_API_TRACE("grpc_compute_engine_credentials_create(reserved=%p)", 1, (reserved)); GPR_ASSERT(reserved == nullptr); - init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2); - c->base.vtable = &compute_engine_vtable; - return &c->base; + return grpc_core::MakeRefCounted< + grpc_compute_engine_token_fetcher_credentials>() + .release(); } // // Google Refresh Token credentials. // -static void refresh_token_destruct(grpc_call_credentials* creds) { - grpc_google_refresh_token_credentials* c = - reinterpret_cast(creds); - grpc_auth_refresh_token_destruct(&c->refresh_token); - oauth2_token_fetcher_destruct(&c->base.base); +grpc_google_refresh_token_credentials:: + ~grpc_google_refresh_token_credentials() { + grpc_auth_refresh_token_destruct(&refresh_token_); } -static grpc_call_credentials_vtable refresh_token_vtable = { - refresh_token_destruct, oauth2_token_fetcher_get_request_metadata, - oauth2_token_fetcher_cancel_get_request_metadata}; - -static void refresh_token_fetch_oauth2( +void grpc_google_refresh_token_credentials::fetch_oauth2( grpc_credentials_metadata_request* metadata_req, grpc_httpcli_context* httpcli_context, grpc_polling_entity* pollent, grpc_iomgr_cb_func response_cb, grpc_millis deadline) { - grpc_google_refresh_token_credentials* c = - reinterpret_cast( - metadata_req->creds); grpc_http_header header = {(char*)"Content-Type", (char*)"application/x-www-form-urlencoded"}; grpc_httpcli_request request; char* body = nullptr; gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING, - c->refresh_token.client_id, c->refresh_token.client_secret, - c->refresh_token.refresh_token); + refresh_token_.client_id, refresh_token_.client_secret, + refresh_token_.refresh_token); memset(&request, 0, sizeof(grpc_httpcli_request)); request.host = (char*)GRPC_GOOGLE_OAUTH2_SERVICE_HOST; request.http.path = (char*)GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH; @@ -437,20 +428,19 @@ static void refresh_token_fetch_oauth2( gpr_free(body); } -grpc_call_credentials* +grpc_google_refresh_token_credentials::grpc_google_refresh_token_credentials( + grpc_auth_refresh_token refresh_token) + : refresh_token_(refresh_token) {} + +grpc_core::RefCountedPtr grpc_refresh_token_credentials_create_from_auth_refresh_token( grpc_auth_refresh_token refresh_token) { - grpc_google_refresh_token_credentials* c; if (!grpc_auth_refresh_token_is_valid(&refresh_token)) { gpr_log(GPR_ERROR, "Invalid input for refresh token credentials creation"); return nullptr; } - c = static_cast( - gpr_zalloc(sizeof(grpc_google_refresh_token_credentials))); - init_oauth2_token_fetcher(&c->base, refresh_token_fetch_oauth2); - c->base.base.vtable = &refresh_token_vtable; - c->refresh_token = refresh_token; - return &c->base.base; + return grpc_core::MakeRefCounted( + refresh_token); } static char* create_loggable_refresh_token(grpc_auth_refresh_token* token) { @@ -478,59 +468,50 @@ grpc_call_credentials* grpc_google_refresh_token_credentials_create( gpr_free(loggable_token); } GPR_ASSERT(reserved == nullptr); - return grpc_refresh_token_credentials_create_from_auth_refresh_token(token); + return grpc_refresh_token_credentials_create_from_auth_refresh_token(token) + .release(); } // // Oauth2 Access Token credentials. // -static void access_token_destruct(grpc_call_credentials* creds) { - grpc_access_token_credentials* c = - reinterpret_cast(creds); - GRPC_MDELEM_UNREF(c->access_token_md); +grpc_access_token_credentials::~grpc_access_token_credentials() { + GRPC_MDELEM_UNREF(access_token_md_); } -static bool access_token_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error) { - grpc_access_token_credentials* c = - reinterpret_cast(creds); - grpc_credentials_mdelem_array_add(md_array, c->access_token_md); +bool grpc_access_token_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { + grpc_credentials_mdelem_array_add(md_array, access_token_md_); return true; } -static void access_token_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { +void grpc_access_token_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable access_token_vtable = { - access_token_destruct, access_token_get_request_metadata, - access_token_cancel_get_request_metadata}; +grpc_access_token_credentials::grpc_access_token_credentials( + const char* access_token) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) { + char* token_md_value; + gpr_asprintf(&token_md_value, "Bearer %s", access_token); + grpc_core::ExecCtx exec_ctx; + access_token_md_ = grpc_mdelem_from_slices( + grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY), + grpc_slice_from_copied_string(token_md_value)); + gpr_free(token_md_value); +} grpc_call_credentials* grpc_access_token_credentials_create( const char* access_token, void* reserved) { - grpc_access_token_credentials* c = - static_cast( - gpr_zalloc(sizeof(grpc_access_token_credentials))); GRPC_API_TRACE( "grpc_access_token_credentials_create(access_token=, " "reserved=%p)", 1, (reserved)); GPR_ASSERT(reserved == nullptr); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; - c->base.vtable = &access_token_vtable; - gpr_ref_init(&c->base.refcount, 1); - char* token_md_value; - gpr_asprintf(&token_md_value, "Bearer %s", access_token); - grpc_core::ExecCtx exec_ctx; - c->access_token_md = grpc_mdelem_from_slices( - grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY), - grpc_slice_from_copied_string(token_md_value)); - - gpr_free(token_md_value); - return &c->base; + return grpc_core::MakeRefCounted(access_token) + .release(); } diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h index 12a1d4484fe..510a78b484a 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h @@ -54,46 +54,91 @@ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token* refresh_token); // This object is a base for credentials that need to acquire an oauth2 token // from an http service. -typedef void (*grpc_fetch_oauth2_func)(grpc_credentials_metadata_request* req, - grpc_httpcli_context* http_context, - grpc_polling_entity* pollent, - grpc_iomgr_cb_func cb, - grpc_millis deadline); - -typedef struct grpc_oauth2_pending_get_request_metadata { +struct grpc_oauth2_pending_get_request_metadata { grpc_credentials_mdelem_array* md_array; grpc_closure* on_request_metadata; grpc_polling_entity* pollent; struct grpc_oauth2_pending_get_request_metadata* next; -} grpc_oauth2_pending_get_request_metadata; - -typedef struct { - grpc_call_credentials base; - gpr_mu mu; - grpc_mdelem access_token_md; - gpr_timespec token_expiration; - bool token_fetch_pending; - grpc_oauth2_pending_get_request_metadata* pending_requests; - grpc_httpcli_context httpcli_context; - grpc_fetch_oauth2_func fetch_func; - grpc_polling_entity pollent; -} grpc_oauth2_token_fetcher_credentials; +}; + +class grpc_oauth2_token_fetcher_credentials : public grpc_call_credentials { + public: + grpc_oauth2_token_fetcher_credentials(); + ~grpc_oauth2_token_fetcher_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + void on_http_response(grpc_credentials_metadata_request* r, + grpc_error* error); + + GRPC_ABSTRACT_BASE_CLASS + + protected: + virtual void fetch_oauth2(grpc_credentials_metadata_request* req, + grpc_httpcli_context* httpcli_context, + grpc_polling_entity* pollent, grpc_iomgr_cb_func cb, + grpc_millis deadline) GRPC_ABSTRACT; + + private: + gpr_mu mu_; + grpc_mdelem access_token_md_ = GRPC_MDNULL; + gpr_timespec token_expiration_; + bool token_fetch_pending_ = false; + grpc_oauth2_pending_get_request_metadata* pending_requests_ = nullptr; + grpc_httpcli_context httpcli_context_; + grpc_polling_entity pollent_; +}; // Google refresh token credentials. -typedef struct { - grpc_oauth2_token_fetcher_credentials base; - grpc_auth_refresh_token refresh_token; -} grpc_google_refresh_token_credentials; +class grpc_google_refresh_token_credentials final + : public grpc_oauth2_token_fetcher_credentials { + public: + grpc_google_refresh_token_credentials(grpc_auth_refresh_token refresh_token); + ~grpc_google_refresh_token_credentials() override; + + const grpc_auth_refresh_token& refresh_token() const { + return refresh_token_; + } + + protected: + void fetch_oauth2(grpc_credentials_metadata_request* req, + grpc_httpcli_context* httpcli_context, + grpc_polling_entity* pollent, grpc_iomgr_cb_func cb, + grpc_millis deadline) override; + + private: + grpc_auth_refresh_token refresh_token_; +}; // Access token credentials. -typedef struct { - grpc_call_credentials base; - grpc_mdelem access_token_md; -} grpc_access_token_credentials; +class grpc_access_token_credentials final : public grpc_call_credentials { + public: + grpc_access_token_credentials(const char* access_token); + ~grpc_access_token_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + private: + grpc_mdelem access_token_md_; +}; // Private constructor for refresh token credentials from an already parsed // refresh token. Takes ownership of the refresh token. -grpc_call_credentials* +grpc_core::RefCountedPtr grpc_refresh_token_credentials_create_from_auth_refresh_token( grpc_auth_refresh_token token); diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.cc b/src/core/lib/security/credentials/plugin/plugin_credentials.cc index 4015124298b..52982fdb8f1 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.cc +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc @@ -35,20 +35,17 @@ grpc_core::TraceFlag grpc_plugin_credentials_trace(false, "plugin_credentials"); -static void plugin_destruct(grpc_call_credentials* creds) { - grpc_plugin_credentials* c = - reinterpret_cast(creds); - gpr_mu_destroy(&c->mu); - if (c->plugin.state != nullptr && c->plugin.destroy != nullptr) { - c->plugin.destroy(c->plugin.state); +grpc_plugin_credentials::~grpc_plugin_credentials() { + gpr_mu_destroy(&mu_); + if (plugin_.state != nullptr && plugin_.destroy != nullptr) { + plugin_.destroy(plugin_.state); } } -static void pending_request_remove_locked( - grpc_plugin_credentials* c, - grpc_plugin_credentials_pending_request* pending_request) { +void grpc_plugin_credentials::pending_request_remove_locked( + pending_request* pending_request) { if (pending_request->prev == nullptr) { - c->pending_requests = pending_request->next; + pending_requests_ = pending_request->next; } else { pending_request->prev->next = pending_request->next; } @@ -62,17 +59,17 @@ static void pending_request_remove_locked( // cancelled out from under us. // When this returns, r->cancelled indicates whether the request was // cancelled before completion. -static void pending_request_complete( - grpc_plugin_credentials_pending_request* r) { - gpr_mu_lock(&r->creds->mu); - if (!r->cancelled) pending_request_remove_locked(r->creds, r); - gpr_mu_unlock(&r->creds->mu); +void grpc_plugin_credentials::pending_request_complete(pending_request* r) { + GPR_DEBUG_ASSERT(r->creds == this); + gpr_mu_lock(&mu_); + if (!r->cancelled) pending_request_remove_locked(r); + gpr_mu_unlock(&mu_); // Ref to credentials not needed anymore. - grpc_call_credentials_unref(&r->creds->base); + Unref(); } static grpc_error* process_plugin_result( - grpc_plugin_credentials_pending_request* r, const grpc_metadata* md, + grpc_plugin_credentials::pending_request* r, const grpc_metadata* md, size_t num_md, grpc_status_code status, const char* error_details) { grpc_error* error = GRPC_ERROR_NONE; if (status != GRPC_STATUS_OK) { @@ -119,8 +116,8 @@ static void plugin_md_request_metadata_ready(void* request, /* called from application code */ grpc_core::ExecCtx exec_ctx(GRPC_EXEC_CTX_FLAG_IS_FINISHED | GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP); - grpc_plugin_credentials_pending_request* r = - static_cast(request); + grpc_plugin_credentials::pending_request* r = + static_cast(request); if (grpc_plugin_credentials_trace.enabled()) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin returned " @@ -128,7 +125,7 @@ static void plugin_md_request_metadata_ready(void* request, r->creds, r); } // Remove request from pending list if not previously cancelled. - pending_request_complete(r); + r->creds->pending_request_complete(r); // If it has not been cancelled, process it. if (!r->cancelled) { grpc_error* error = @@ -143,65 +140,59 @@ static void plugin_md_request_metadata_ready(void* request, gpr_free(r); } -static bool plugin_get_request_metadata(grpc_call_credentials* creds, - grpc_polling_entity* pollent, - grpc_auth_metadata_context context, - grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, - grpc_error** error) { - grpc_plugin_credentials* c = - reinterpret_cast(creds); +bool grpc_plugin_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { bool retval = true; // Synchronous return. - if (c->plugin.get_metadata != nullptr) { + if (plugin_.get_metadata != nullptr) { // Create pending_request object. - grpc_plugin_credentials_pending_request* pending_request = - static_cast( - gpr_zalloc(sizeof(*pending_request))); - pending_request->creds = c; - pending_request->md_array = md_array; - pending_request->on_request_metadata = on_request_metadata; + pending_request* request = + static_cast(gpr_zalloc(sizeof(*request))); + request->creds = this; + request->md_array = md_array; + request->on_request_metadata = on_request_metadata; // Add it to the pending list. - gpr_mu_lock(&c->mu); - if (c->pending_requests != nullptr) { - c->pending_requests->prev = pending_request; + gpr_mu_lock(&mu_); + if (pending_requests_ != nullptr) { + pending_requests_->prev = request; } - pending_request->next = c->pending_requests; - c->pending_requests = pending_request; - gpr_mu_unlock(&c->mu); + request->next = pending_requests_; + pending_requests_ = request; + gpr_mu_unlock(&mu_); // Invoke the plugin. The callback holds a ref to us. if (grpc_plugin_credentials_trace.enabled()) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: invoking plugin", - c, pending_request); + this, request); } - grpc_call_credentials_ref(creds); + Ref().release(); grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX]; size_t num_creds_md = 0; grpc_status_code status = GRPC_STATUS_OK; const char* error_details = nullptr; - if (!c->plugin.get_metadata(c->plugin.state, context, - plugin_md_request_metadata_ready, - pending_request, creds_md, &num_creds_md, - &status, &error_details)) { + if (!plugin_.get_metadata( + plugin_.state, context, plugin_md_request_metadata_ready, request, + creds_md, &num_creds_md, &status, &error_details)) { if (grpc_plugin_credentials_trace.enabled()) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin will return " "asynchronously", - c, pending_request); + this, request); } return false; // Asynchronous return. } // Returned synchronously. // Remove request from pending list if not previously cancelled. - pending_request_complete(pending_request); + request->creds->pending_request_complete(request); // If the request was cancelled, the error will have been returned // asynchronously by plugin_cancel_get_request_metadata(), so return // false. Otherwise, process the result. - if (pending_request->cancelled) { + if (request->cancelled) { if (grpc_plugin_credentials_trace.enabled()) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p was cancelled, error " "will be returned asynchronously", - c, pending_request); + this, request); } retval = false; } else { @@ -209,10 +200,10 @@ static bool plugin_get_request_metadata(grpc_call_credentials* creds, gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin returned " "synchronously", - c, pending_request); + this, request); } - *error = process_plugin_result(pending_request, creds_md, num_creds_md, - status, error_details); + *error = process_plugin_result(request, creds_md, num_creds_md, status, + error_details); } // Clean up. for (size_t i = 0; i < num_creds_md; ++i) { @@ -220,51 +211,42 @@ static bool plugin_get_request_metadata(grpc_call_credentials* creds, grpc_slice_unref_internal(creds_md[i].value); } gpr_free((void*)error_details); - gpr_free(pending_request); + gpr_free(request); } return retval; } -static void plugin_cancel_get_request_metadata( - grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { - grpc_plugin_credentials* c = - reinterpret_cast(creds); - gpr_mu_lock(&c->mu); - for (grpc_plugin_credentials_pending_request* pending_request = - c->pending_requests; +void grpc_plugin_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { + gpr_mu_lock(&mu_); + for (pending_request* pending_request = pending_requests_; pending_request != nullptr; pending_request = pending_request->next) { if (pending_request->md_array == md_array) { if (grpc_plugin_credentials_trace.enabled()) { - gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", c, + gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", this, pending_request); } pending_request->cancelled = true; GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, GRPC_ERROR_REF(error)); - pending_request_remove_locked(c, pending_request); + pending_request_remove_locked(pending_request); break; } } - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&mu_); GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable plugin_vtable = { - plugin_destruct, plugin_get_request_metadata, - plugin_cancel_get_request_metadata}; +grpc_plugin_credentials::grpc_plugin_credentials( + grpc_metadata_credentials_plugin plugin) + : grpc_call_credentials(plugin.type), plugin_(plugin) { + gpr_mu_init(&mu_); +} grpc_call_credentials* grpc_metadata_credentials_create_from_plugin( grpc_metadata_credentials_plugin plugin, void* reserved) { - grpc_plugin_credentials* c = - static_cast(gpr_zalloc(sizeof(*c))); GRPC_API_TRACE("grpc_metadata_credentials_create_from_plugin(reserved=%p)", 1, (reserved)); GPR_ASSERT(reserved == nullptr); - c->base.type = plugin.type; - c->base.vtable = &plugin_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->plugin = plugin; - gpr_mu_init(&c->mu); - return &c->base; + return grpc_core::New(plugin); } diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.h b/src/core/lib/security/credentials/plugin/plugin_credentials.h index caf990efa15..77a957e5137 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.h +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.h @@ -25,22 +25,45 @@ extern grpc_core::TraceFlag grpc_plugin_credentials_trace; -struct grpc_plugin_credentials; - -typedef struct grpc_plugin_credentials_pending_request { - bool cancelled; - struct grpc_plugin_credentials* creds; - grpc_credentials_mdelem_array* md_array; - grpc_closure* on_request_metadata; - struct grpc_plugin_credentials_pending_request* prev; - struct grpc_plugin_credentials_pending_request* next; -} grpc_plugin_credentials_pending_request; - -typedef struct grpc_plugin_credentials { - grpc_call_credentials base; - grpc_metadata_credentials_plugin plugin; - gpr_mu mu; - grpc_plugin_credentials_pending_request* pending_requests; -} grpc_plugin_credentials; +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_plugin_credentials final : public grpc_call_credentials { + public: + struct pending_request { + bool cancelled; + struct grpc_plugin_credentials* creds; + grpc_credentials_mdelem_array* md_array; + grpc_closure* on_request_metadata; + struct pending_request* prev; + struct pending_request* next; + }; + + explicit grpc_plugin_credentials(grpc_metadata_credentials_plugin plugin); + ~grpc_plugin_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + // Checks if the request has been cancelled. + // If not, removes it from the pending list, so that it cannot be + // cancelled out from under us. + // When this returns, r->cancelled indicates whether the request was + // cancelled before completion. + void pending_request_complete(pending_request* r); + + private: + void pending_request_remove_locked(pending_request* pending_request); + + grpc_metadata_credentials_plugin plugin_; + gpr_mu mu_; + pending_request* pending_requests_ = nullptr; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_PLUGIN_PLUGIN_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.cc b/src/core/lib/security/credentials/ssl/ssl_credentials.cc index 3d6f2f200a3..83db86f1eac 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.cc +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.cc @@ -44,22 +44,27 @@ void grpc_tsi_ssl_pem_key_cert_pairs_destroy(tsi_ssl_pem_key_cert_pair* kp, gpr_free(kp); } -static void ssl_destruct(grpc_channel_credentials* creds) { - grpc_ssl_credentials* c = reinterpret_cast(creds); - gpr_free(c->config.pem_root_certs); - grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pair, 1); - if (c->config.verify_options.verify_peer_destruct != nullptr) { - c->config.verify_options.verify_peer_destruct( - c->config.verify_options.verify_peer_callback_userdata); +grpc_ssl_credentials::grpc_ssl_credentials( + const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const verify_peer_options* verify_options) + : grpc_channel_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_SSL) { + build_config(pem_root_certs, pem_key_cert_pair, verify_options); +} + +grpc_ssl_credentials::~grpc_ssl_credentials() { + gpr_free(config_.pem_root_certs); + grpc_tsi_ssl_pem_key_cert_pairs_destroy(config_.pem_key_cert_pair, 1); + if (config_.verify_options.verify_peer_destruct != nullptr) { + config_.verify_options.verify_peer_destruct( + config_.verify_options.verify_peer_callback_userdata); } } -static grpc_security_status ssl_create_security_connector( - grpc_channel_credentials* creds, grpc_call_credentials* call_creds, +grpc_core::RefCountedPtr +grpc_ssl_credentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - grpc_ssl_credentials* c = reinterpret_cast(creds); - grpc_security_status status = GRPC_SECURITY_OK; + grpc_channel_args** new_args) { const char* overridden_target_name = nullptr; tsi_ssl_session_cache* ssl_session_cache = nullptr; for (size_t i = 0; args && i < args->num_args; i++) { @@ -74,52 +79,47 @@ static grpc_security_status ssl_create_security_connector( static_cast(arg->value.pointer.p); } } - status = grpc_ssl_channel_security_connector_create( - creds, call_creds, &c->config, target, overridden_target_name, - ssl_session_cache, sc); - if (status != GRPC_SECURITY_OK) { - return status; + grpc_core::RefCountedPtr sc = + grpc_ssl_channel_security_connector_create( + this->Ref(), std::move(call_creds), &config_, target, + overridden_target_name, ssl_session_cache); + if (sc == nullptr) { + return sc; } grpc_arg new_arg = grpc_channel_arg_string_create( (char*)GRPC_ARG_HTTP2_SCHEME, (char*)"https"); *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1); - return status; + return sc; } -static grpc_channel_credentials_vtable ssl_vtable = { - ssl_destruct, ssl_create_security_connector, nullptr}; - -static void ssl_build_config(const char* pem_root_certs, - grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, - const verify_peer_options* verify_options, - grpc_ssl_config* config) { - if (pem_root_certs != nullptr) { - config->pem_root_certs = gpr_strdup(pem_root_certs); - } +void grpc_ssl_credentials::build_config( + const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const verify_peer_options* verify_options) { + config_.pem_root_certs = gpr_strdup(pem_root_certs); if (pem_key_cert_pair != nullptr) { GPR_ASSERT(pem_key_cert_pair->private_key != nullptr); GPR_ASSERT(pem_key_cert_pair->cert_chain != nullptr); - config->pem_key_cert_pair = static_cast( + config_.pem_key_cert_pair = static_cast( gpr_zalloc(sizeof(tsi_ssl_pem_key_cert_pair))); - config->pem_key_cert_pair->cert_chain = + config_.pem_key_cert_pair->cert_chain = gpr_strdup(pem_key_cert_pair->cert_chain); - config->pem_key_cert_pair->private_key = + config_.pem_key_cert_pair->private_key = gpr_strdup(pem_key_cert_pair->private_key); + } else { + config_.pem_key_cert_pair = nullptr; } if (verify_options != nullptr) { - memcpy(&config->verify_options, verify_options, + memcpy(&config_.verify_options, verify_options, sizeof(verify_peer_options)); } else { // Otherwise set all options to default values - memset(&config->verify_options, 0, sizeof(verify_peer_options)); + memset(&config_.verify_options, 0, sizeof(verify_peer_options)); } } grpc_channel_credentials* grpc_ssl_credentials_create( const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, const verify_peer_options* verify_options, void* reserved) { - grpc_ssl_credentials* c = static_cast( - gpr_zalloc(sizeof(grpc_ssl_credentials))); GRPC_API_TRACE( "grpc_ssl_credentials_create(pem_root_certs=%s, " "pem_key_cert_pair=%p, " @@ -127,12 +127,9 @@ grpc_channel_credentials* grpc_ssl_credentials_create( "reserved=%p)", 4, (pem_root_certs, pem_key_cert_pair, verify_options, reserved)); GPR_ASSERT(reserved == nullptr); - c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; - c->base.vtable = &ssl_vtable; - gpr_ref_init(&c->base.refcount, 1); - ssl_build_config(pem_root_certs, pem_key_cert_pair, verify_options, - &c->config); - return &c->base; + + return grpc_core::New(pem_root_certs, pem_key_cert_pair, + verify_options); } // @@ -145,21 +142,29 @@ struct grpc_ssl_server_credentials_options { grpc_ssl_server_certificate_config_fetcher* certificate_config_fetcher; }; -static void ssl_server_destruct(grpc_server_credentials* creds) { - grpc_ssl_server_credentials* c = - reinterpret_cast(creds); - grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pairs, - c->config.num_key_cert_pairs); - gpr_free(c->config.pem_root_certs); +grpc_ssl_server_credentials::grpc_ssl_server_credentials( + const grpc_ssl_server_credentials_options& options) + : grpc_server_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_SSL) { + if (options.certificate_config_fetcher != nullptr) { + config_.client_certificate_request = options.client_certificate_request; + certificate_config_fetcher_ = *options.certificate_config_fetcher; + } else { + build_config(options.certificate_config->pem_root_certs, + options.certificate_config->pem_key_cert_pairs, + options.certificate_config->num_key_cert_pairs, + options.client_certificate_request); + } } -static grpc_security_status ssl_server_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc) { - return grpc_ssl_server_security_connector_create(creds, sc); +grpc_ssl_server_credentials::~grpc_ssl_server_credentials() { + grpc_tsi_ssl_pem_key_cert_pairs_destroy(config_.pem_key_cert_pairs, + config_.num_key_cert_pairs); + gpr_free(config_.pem_root_certs); +} +grpc_core::RefCountedPtr +grpc_ssl_server_credentials::create_security_connector() { + return grpc_ssl_server_security_connector_create(this->Ref()); } - -static grpc_server_credentials_vtable ssl_server_vtable = { - ssl_server_destruct, ssl_server_create_security_connector}; tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs( const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, @@ -179,18 +184,15 @@ tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs( return tsi_pairs; } -static void ssl_build_server_config( +void grpc_ssl_server_credentials::build_config( const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, size_t num_key_cert_pairs, - grpc_ssl_client_certificate_request_type client_certificate_request, - grpc_ssl_server_config* config) { - config->client_certificate_request = client_certificate_request; - if (pem_root_certs != nullptr) { - config->pem_root_certs = gpr_strdup(pem_root_certs); - } - config->pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( + grpc_ssl_client_certificate_request_type client_certificate_request) { + config_.client_certificate_request = client_certificate_request; + config_.pem_root_certs = gpr_strdup(pem_root_certs); + config_.pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( pem_key_cert_pairs, num_key_cert_pairs); - config->num_key_cert_pairs = num_key_cert_pairs; + config_.num_key_cert_pairs = num_key_cert_pairs; } grpc_ssl_server_certificate_config* grpc_ssl_server_certificate_config_create( @@ -200,9 +202,7 @@ grpc_ssl_server_certificate_config* grpc_ssl_server_certificate_config_create( grpc_ssl_server_certificate_config* config = static_cast( gpr_zalloc(sizeof(grpc_ssl_server_certificate_config))); - if (pem_root_certs != nullptr) { - config->pem_root_certs = gpr_strdup(pem_root_certs); - } + config->pem_root_certs = gpr_strdup(pem_root_certs); if (num_key_cert_pairs > 0) { GPR_ASSERT(pem_key_cert_pairs != nullptr); config->pem_key_cert_pairs = static_cast( @@ -311,7 +311,6 @@ grpc_server_credentials* grpc_ssl_server_credentials_create_ex( grpc_server_credentials* grpc_ssl_server_credentials_create_with_options( grpc_ssl_server_credentials_options* options) { grpc_server_credentials* retval = nullptr; - grpc_ssl_server_credentials* c = nullptr; if (options == nullptr) { gpr_log(GPR_ERROR, @@ -331,23 +330,7 @@ grpc_server_credentials* grpc_ssl_server_credentials_create_with_options( goto done; } - c = static_cast( - gpr_zalloc(sizeof(grpc_ssl_server_credentials))); - c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &ssl_server_vtable; - - if (options->certificate_config_fetcher != nullptr) { - c->config.client_certificate_request = options->client_certificate_request; - c->certificate_config_fetcher = *options->certificate_config_fetcher; - } else { - ssl_build_server_config(options->certificate_config->pem_root_certs, - options->certificate_config->pem_key_cert_pairs, - options->certificate_config->num_key_cert_pairs, - options->client_certificate_request, &c->config); - } - - retval = &c->base; + retval = grpc_core::New(*options); done: grpc_ssl_server_credentials_options_destroy(options); diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.h b/src/core/lib/security/credentials/ssl/ssl_credentials.h index 0fba413876e..e1174327b30 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.h +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.h @@ -24,27 +24,70 @@ #include "src/core/lib/security/security_connector/ssl/ssl_security_connector.h" -typedef struct { - grpc_channel_credentials base; - grpc_ssl_config config; -} grpc_ssl_credentials; +class grpc_ssl_credentials : public grpc_channel_credentials { + public: + grpc_ssl_credentials(const char* pem_root_certs, + grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const verify_peer_options* verify_options); + + ~grpc_ssl_credentials() override; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + private: + void build_config(const char* pem_root_certs, + grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const verify_peer_options* verify_options); + + grpc_ssl_config config_; +}; struct grpc_ssl_server_certificate_config { - grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs; - size_t num_key_cert_pairs; - char* pem_root_certs; + grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs = nullptr; + size_t num_key_cert_pairs = 0; + char* pem_root_certs = nullptr; }; -typedef struct { - grpc_ssl_server_certificate_config_callback cb; +struct grpc_ssl_server_certificate_config_fetcher { + grpc_ssl_server_certificate_config_callback cb = nullptr; void* user_data; -} grpc_ssl_server_certificate_config_fetcher; +}; + +class grpc_ssl_server_credentials final : public grpc_server_credentials { + public: + grpc_ssl_server_credentials( + const grpc_ssl_server_credentials_options& options); + ~grpc_ssl_server_credentials() override; -typedef struct { - grpc_server_credentials base; - grpc_ssl_server_config config; - grpc_ssl_server_certificate_config_fetcher certificate_config_fetcher; -} grpc_ssl_server_credentials; + grpc_core::RefCountedPtr + create_security_connector() override; + + bool has_cert_config_fetcher() const { + return certificate_config_fetcher_.cb != nullptr; + } + + grpc_ssl_certificate_config_reload_status FetchCertConfig( + grpc_ssl_server_certificate_config** config) { + GPR_DEBUG_ASSERT(has_cert_config_fetcher()); + return certificate_config_fetcher_.cb(certificate_config_fetcher_.user_data, + config); + } + + const grpc_ssl_server_config& config() const { return config_; } + + private: + void build_config( + const char* pem_root_certs, + grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, size_t num_key_cert_pairs, + grpc_ssl_client_certificate_request_type client_certificate_request); + + grpc_ssl_server_config config_; + grpc_ssl_server_certificate_config_fetcher certificate_config_fetcher_; +}; tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs( const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.cc b/src/core/lib/security/security_connector/alts/alts_security_connector.cc index dd71c8bc606..6db70ef1720 100644 --- a/src/core/lib/security/security_connector/alts/alts_security_connector.cc +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.cc @@ -28,6 +28,7 @@ #include #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/credentials/alts/alts_credentials.h" #include "src/core/lib/security/transport/security_handshaker.h" #include "src/core/lib/slice/slice_internal.h" @@ -35,64 +36,9 @@ #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" #include "src/core/tsi/transport_security.h" -typedef struct { - grpc_channel_security_connector base; - char* target_name; -} grpc_alts_channel_security_connector; +namespace { -typedef struct { - grpc_server_security_connector base; -} grpc_alts_server_security_connector; - -static void alts_channel_destroy(grpc_security_connector* sc) { - if (sc == nullptr) { - return; - } - auto c = reinterpret_cast(sc); - grpc_call_credentials_unref(c->base.request_metadata_creds); - grpc_channel_credentials_unref(c->base.channel_creds); - gpr_free(c->target_name); - gpr_free(sc); -} - -static void alts_server_destroy(grpc_security_connector* sc) { - if (sc == nullptr) { - return; - } - auto c = reinterpret_cast(sc); - grpc_server_credentials_unref(c->base.server_creds); - gpr_free(sc); -} - -static void alts_channel_add_handshakers( - grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) { - tsi_handshaker* handshaker = nullptr; - auto c = reinterpret_cast(sc); - grpc_alts_credentials* creds = - reinterpret_cast(c->base.channel_creds); - GPR_ASSERT(alts_tsi_handshaker_create( - creds->options, c->target_name, creds->handshaker_service_url, - true, interested_parties, &handshaker) == TSI_OK); - grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( - handshaker, &sc->base)); -} - -static void alts_server_add_handshakers( - grpc_server_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) { - tsi_handshaker* handshaker = nullptr; - auto c = reinterpret_cast(sc); - grpc_alts_server_credentials* creds = - reinterpret_cast(c->base.server_creds); - GPR_ASSERT(alts_tsi_handshaker_create( - creds->options, nullptr, creds->handshaker_service_url, false, - interested_parties, &handshaker) == TSI_OK); - grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( - handshaker, &sc->base)); -} - -static void alts_set_rpc_protocol_versions( +void alts_set_rpc_protocol_versions( grpc_gcp_rpc_protocol_versions* rpc_versions) { grpc_gcp_rpc_protocol_versions_set_max(rpc_versions, GRPC_PROTOCOL_VERSION_MAX_MAJOR, @@ -102,17 +48,131 @@ static void alts_set_rpc_protocol_versions( GRPC_PROTOCOL_VERSION_MIN_MINOR); } +void atls_check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { + *auth_context = + grpc_core::internal::grpc_alts_auth_context_from_tsi_peer(&peer); + tsi_peer_destruct(&peer); + grpc_error* error = + *auth_context != nullptr + ? GRPC_ERROR_NONE + : GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Could not get ALTS auth context from TSI peer"); + GRPC_CLOSURE_SCHED(on_peer_checked, error); +} + +class grpc_alts_channel_security_connector final + : public grpc_channel_security_connector { + public: + grpc_alts_channel_security_connector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name) + : grpc_channel_security_connector(/*url_scheme=*/nullptr, + std::move(channel_creds), + std::move(request_metadata_creds)), + target_name_(gpr_strdup(target_name)) { + grpc_alts_credentials* creds = + static_cast(mutable_channel_creds()); + alts_set_rpc_protocol_versions(&creds->mutable_options()->rpc_versions); + } + + ~grpc_alts_channel_security_connector() override { gpr_free(target_name_); } + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_manager) override { + tsi_handshaker* handshaker = nullptr; + const grpc_alts_credentials* creds = + static_cast(channel_creds()); + GPR_ASSERT(alts_tsi_handshaker_create(creds->options(), target_name_, + creds->handshaker_service_url(), true, + interested_parties, + &handshaker) == TSI_OK); + grpc_handshake_manager_add( + handshake_manager, grpc_security_handshaker_create(handshaker, this)); + } + + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + atls_check_peer(peer, auth_context, on_peer_checked); + } + + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast(other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) return c; + return strcmp(target_name_, other->target_name_); + } + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + if (host == nullptr || strcmp(host, target_name_) != 0) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "ALTS call host does not match target name"); + } + return true; + } + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + private: + char* target_name_; +}; + +class grpc_alts_server_security_connector final + : public grpc_server_security_connector { + public: + grpc_alts_server_security_connector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(/*url_scheme=*/nullptr, + std::move(server_creds)) { + grpc_alts_server_credentials* creds = + reinterpret_cast(mutable_server_creds()); + alts_set_rpc_protocol_versions(&creds->mutable_options()->rpc_versions); + } + ~grpc_alts_server_security_connector() override = default; + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_manager) override { + tsi_handshaker* handshaker = nullptr; + const grpc_alts_server_credentials* creds = + static_cast(server_creds()); + GPR_ASSERT(alts_tsi_handshaker_create( + creds->options(), nullptr, creds->handshaker_service_url(), + false, interested_parties, &handshaker) == TSI_OK); + grpc_handshake_manager_add( + handshake_manager, grpc_security_handshaker_create(handshaker, this)); + } + + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + atls_check_peer(peer, auth_context, on_peer_checked); + } + + int cmp(const grpc_security_connector* other) const override { + return server_security_connector_cmp( + static_cast(other)); + } +}; +} // namespace + namespace grpc_core { namespace internal { - -grpc_security_status grpc_alts_auth_context_from_tsi_peer( - const tsi_peer* peer, grpc_auth_context** ctx) { - if (peer == nullptr || ctx == nullptr) { +grpc_core::RefCountedPtr +grpc_alts_auth_context_from_tsi_peer(const tsi_peer* peer) { + if (peer == nullptr) { gpr_log(GPR_ERROR, "Invalid arguments to grpc_alts_auth_context_from_tsi_peer()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - *ctx = nullptr; /* Validate certificate type. */ const tsi_peer_property* cert_type_prop = tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY); @@ -120,14 +180,14 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer( strncmp(cert_type_prop->value.data, TSI_ALTS_CERTIFICATE_TYPE, cert_type_prop->value.length) != 0) { gpr_log(GPR_ERROR, "Invalid or missing certificate type property."); - return GRPC_SECURITY_ERROR; + return nullptr; } /* Validate RPC protocol versions. */ const tsi_peer_property* rpc_versions_prop = tsi_peer_get_property_by_name(peer, TSI_ALTS_RPC_VERSIONS); if (rpc_versions_prop == nullptr) { gpr_log(GPR_ERROR, "Missing rpc protocol versions property."); - return GRPC_SECURITY_ERROR; + return nullptr; } grpc_gcp_rpc_protocol_versions local_versions, peer_versions; alts_set_rpc_protocol_versions(&local_versions); @@ -138,19 +198,19 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer( grpc_slice_unref_internal(slice); if (!decode_result) { gpr_log(GPR_ERROR, "Invalid peer rpc protocol versions."); - return GRPC_SECURITY_ERROR; + return nullptr; } /* TODO: Pass highest common rpc protocol version to grpc caller. */ bool check_result = grpc_gcp_rpc_protocol_versions_check( &local_versions, &peer_versions, nullptr); if (!check_result) { gpr_log(GPR_ERROR, "Mismatch of local and peer rpc protocol versions."); - return GRPC_SECURITY_ERROR; + return nullptr; } /* Create auth context. */ - *ctx = grpc_auth_context_create(nullptr); + auto ctx = grpc_core::MakeRefCounted(nullptr); grpc_auth_context_add_cstring_property( - *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_ALTS_TRANSPORT_SECURITY_TYPE); size_t i = 0; for (i = 0; i < peer->property_count; i++) { @@ -158,132 +218,47 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer( /* Add service account to auth context. */ if (strcmp(tsi_prop->name, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 0) { grpc_auth_context_add_property( - *ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, tsi_prop->value.data, - tsi_prop->value.length); + ctx.get(), TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, + tsi_prop->value.data, tsi_prop->value.length); GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( - *ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 1); + ctx.get(), TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 1); } } - if (!grpc_auth_context_peer_is_authenticated(*ctx)) { + if (!grpc_auth_context_peer_is_authenticated(ctx.get())) { gpr_log(GPR_ERROR, "Invalid unauthenticated peer."); - GRPC_AUTH_CONTEXT_UNREF(*ctx, "test"); - *ctx = nullptr; - return GRPC_SECURITY_ERROR; + ctx.reset(DEBUG_LOCATION, "test"); + return nullptr; } - return GRPC_SECURITY_OK; + return ctx; } } // namespace internal } // namespace grpc_core -static void alts_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_security_status status; - status = grpc_core::internal::grpc_alts_auth_context_from_tsi_peer( - &peer, auth_context); - tsi_peer_destruct(&peer); - grpc_error* error = - status == GRPC_SECURITY_OK - ? GRPC_ERROR_NONE - : GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Could not get ALTS auth context from TSI peer"); - GRPC_CLOSURE_SCHED(on_peer_checked, error); -} - -static int alts_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_alts_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_alts_channel_security_connector* c2 = - reinterpret_cast(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - return strcmp(c1->target_name, c2->target_name); -} - -static int alts_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_alts_server_security_connector* c1 = - reinterpret_cast(sc1); - grpc_alts_server_security_connector* c2 = - reinterpret_cast(sc2); - return grpc_server_security_connector_cmp(&c1->base, &c2->base); -} - -static grpc_security_connector_vtable alts_channel_vtable = { - alts_channel_destroy, alts_check_peer, alts_channel_cmp}; - -static grpc_security_connector_vtable alts_server_vtable = { - alts_server_destroy, alts_check_peer, alts_server_cmp}; - -static bool alts_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_alts_channel_security_connector* alts_sc = - reinterpret_cast(sc); - if (host == nullptr || alts_sc == nullptr || - strcmp(host, alts_sc->target_name) != 0) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "ALTS call host does not match target name"); - } - return true; -} - -static void alts_cancel_check_call_host(grpc_channel_security_connector* sc, - grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} - -grpc_security_status grpc_alts_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target_name, - grpc_channel_security_connector** sc) { - if (channel_creds == nullptr || sc == nullptr || target_name == nullptr) { +grpc_core::RefCountedPtr +grpc_alts_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name) { + if (channel_creds == nullptr || target_name == nullptr) { gpr_log( GPR_ERROR, "Invalid arguments to grpc_alts_channel_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - auto c = static_cast( - gpr_zalloc(sizeof(grpc_alts_channel_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &alts_channel_vtable; - c->base.add_handshakers = alts_channel_add_handshakers; - c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = alts_check_call_host; - c->base.cancel_check_call_host = alts_cancel_check_call_host; - grpc_alts_credentials* creds = - reinterpret_cast(c->base.channel_creds); - alts_set_rpc_protocol_versions(&creds->options->rpc_versions); - c->target_name = gpr_strdup(target_name); - *sc = &c->base; - return GRPC_SECURITY_OK; + return grpc_core::MakeRefCounted( + std::move(channel_creds), std::move(request_metadata_creds), target_name); } -grpc_security_status grpc_alts_server_security_connector_create( - grpc_server_credentials* server_creds, - grpc_server_security_connector** sc) { - if (server_creds == nullptr || sc == nullptr) { +grpc_core::RefCountedPtr +grpc_alts_server_security_connector_create( + grpc_core::RefCountedPtr server_creds) { + if (server_creds == nullptr) { gpr_log( GPR_ERROR, "Invalid arguments to grpc_alts_server_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - auto c = static_cast( - gpr_zalloc(sizeof(grpc_alts_server_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &alts_server_vtable; - c->base.server_creds = grpc_server_credentials_ref(server_creds); - c->base.add_handshakers = alts_server_add_handshakers; - grpc_alts_server_credentials* creds = - reinterpret_cast(c->base.server_creds); - alts_set_rpc_protocol_versions(&creds->options->rpc_versions); - *sc = &c->base; - return GRPC_SECURITY_OK; + return grpc_core::MakeRefCounted( + std::move(server_creds)); } diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.h b/src/core/lib/security/security_connector/alts/alts_security_connector.h index d2e057a76aa..b96dc36b302 100644 --- a/src/core/lib/security/security_connector/alts/alts_security_connector.h +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.h @@ -36,12 +36,13 @@ * - sc: address of ALTS channel security connector instance to be returned from * the method. * - * It returns GRPC_SECURITY_OK on success, and an error stauts code on failure. + * It returns nullptr on failure. */ -grpc_security_status grpc_alts_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target_name, - grpc_channel_security_connector** sc); +grpc_core::RefCountedPtr +grpc_alts_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name); /** * This method creates an ALTS server security connector. @@ -50,17 +51,18 @@ grpc_security_status grpc_alts_channel_security_connector_create( * - sc: address of ALTS server security connector instance to be returned from * the method. * - * It returns GRPC_SECURITY_OK on success, and an error status code on failure. + * It returns nullptr on failure. */ -grpc_security_status grpc_alts_server_security_connector_create( - grpc_server_credentials* server_creds, grpc_server_security_connector** sc); +grpc_core::RefCountedPtr +grpc_alts_server_security_connector_create( + grpc_core::RefCountedPtr server_creds); namespace grpc_core { namespace internal { /* Exposed only for testing. */ -grpc_security_status grpc_alts_auth_context_from_tsi_peer( - const tsi_peer* peer, grpc_auth_context** ctx); +grpc_core::RefCountedPtr +grpc_alts_auth_context_from_tsi_peer(const tsi_peer* peer); } // namespace internal } // namespace grpc_core diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.cc b/src/core/lib/security/security_connector/fake/fake_security_connector.cc index 5c0c89b88f2..d2cdaaac77c 100644 --- a/src/core/lib/security/security_connector/fake/fake_security_connector.cc +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.cc @@ -31,6 +31,7 @@ #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" @@ -38,91 +39,183 @@ #include "src/core/lib/security/transport/target_authority_table.h" #include "src/core/tsi/fake_transport_security.h" -typedef struct { - grpc_channel_security_connector base; - char* target; - char* expected_targets; - bool is_lb_channel; - char* target_name_override; -} grpc_fake_channel_security_connector; +namespace { +class grpc_fake_channel_security_connector final + : public grpc_channel_security_connector { + public: + grpc_fake_channel_security_connector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target, const grpc_channel_args* args) + : grpc_channel_security_connector(GRPC_FAKE_SECURITY_URL_SCHEME, + std::move(channel_creds), + std::move(request_metadata_creds)), + target_(gpr_strdup(target)), + expected_targets_( + gpr_strdup(grpc_fake_transport_get_expected_targets(args))), + is_lb_channel_(grpc_core::FindTargetAuthorityTableInArgs(args) != + nullptr) { + const grpc_arg* target_name_override_arg = + grpc_channel_args_find(args, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); + if (target_name_override_arg != nullptr) { + target_name_override_ = + gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg)); + } else { + target_name_override_ = nullptr; + } + } -static void fake_channel_destroy(grpc_security_connector* sc) { - grpc_fake_channel_security_connector* c = - reinterpret_cast(sc); - grpc_call_credentials_unref(c->base.request_metadata_creds); - gpr_free(c->target); - gpr_free(c->expected_targets); - gpr_free(c->target_name_override); - gpr_free(c); -} + ~grpc_fake_channel_security_connector() override { + gpr_free(target_); + gpr_free(expected_targets_); + if (target_name_override_ != nullptr) gpr_free(target_name_override_); + } -static void fake_server_destroy(grpc_security_connector* sc) { gpr_free(sc); } + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override; -static bool fake_check_target(const char* target_type, const char* target, - const char* set_str) { - GPR_ASSERT(target_type != nullptr); - GPR_ASSERT(target != nullptr); - char** set = nullptr; - size_t set_size = 0; - gpr_string_split(set_str, ",", &set, &set_size); - bool found = false; - for (size_t i = 0; i < set_size; ++i) { - if (set[i] != nullptr && strcmp(target, set[i]) == 0) found = true; + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast(other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) return c; + c = strcmp(target_, other->target_); + if (c != 0) return c; + if (expected_targets_ == nullptr || other->expected_targets_ == nullptr) { + c = GPR_ICMP(expected_targets_, other->expected_targets_); + } else { + c = strcmp(expected_targets_, other->expected_targets_); + } + if (c != 0) return c; + return GPR_ICMP(is_lb_channel_, other->is_lb_channel_); } - for (size_t i = 0; i < set_size; ++i) { - gpr_free(set[i]); + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) override { + grpc_handshake_manager_add( + handshake_mgr, + grpc_security_handshaker_create( + tsi_create_fake_handshaker(/*is_client=*/true), this)); } - gpr_free(set); - return found; -} -static void fake_secure_name_check(const char* target, - const char* expected_targets, - bool is_lb_channel) { - if (expected_targets == nullptr) return; - char** lbs_and_backends = nullptr; - size_t lbs_and_backends_size = 0; - bool success = false; - gpr_string_split(expected_targets, ";", &lbs_and_backends, - &lbs_and_backends_size); - if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) { - gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'", - expected_targets); - goto done; + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + char* authority_hostname = nullptr; + char* authority_ignored_port = nullptr; + char* target_hostname = nullptr; + char* target_ignored_port = nullptr; + gpr_split_host_port(host, &authority_hostname, &authority_ignored_port); + gpr_split_host_port(target_, &target_hostname, &target_ignored_port); + if (target_name_override_ != nullptr) { + char* fake_security_target_name_override_hostname = nullptr; + char* fake_security_target_name_override_ignored_port = nullptr; + gpr_split_host_port(target_name_override_, + &fake_security_target_name_override_hostname, + &fake_security_target_name_override_ignored_port); + if (strcmp(authority_hostname, + fake_security_target_name_override_hostname) != 0) { + gpr_log(GPR_ERROR, + "Authority (host) '%s' != Fake Security Target override '%s'", + host, fake_security_target_name_override_hostname); + abort(); + } + gpr_free(fake_security_target_name_override_hostname); + gpr_free(fake_security_target_name_override_ignored_port); + } else if (strcmp(authority_hostname, target_hostname) != 0) { + gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", + authority_hostname, target_hostname); + abort(); + } + gpr_free(authority_hostname); + gpr_free(authority_ignored_port); + gpr_free(target_hostname); + gpr_free(target_ignored_port); + return true; } - if (is_lb_channel) { - if (lbs_and_backends_size != 2) { - gpr_log(GPR_ERROR, - "Invalid expected targets arg value: '%s'. Expectations for LB " - "channels must be of the form 'be1,be2,be3,...;lb1,lb2,...", - expected_targets); - goto done; + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + char* target() const { return target_; } + char* expected_targets() const { return expected_targets_; } + bool is_lb_channel() const { return is_lb_channel_; } + char* target_name_override() const { return target_name_override_; } + + private: + bool fake_check_target(const char* target_type, const char* target, + const char* set_str) const { + GPR_ASSERT(target_type != nullptr); + GPR_ASSERT(target != nullptr); + char** set = nullptr; + size_t set_size = 0; + gpr_string_split(set_str, ",", &set, &set_size); + bool found = false; + for (size_t i = 0; i < set_size; ++i) { + if (set[i] != nullptr && strcmp(target, set[i]) == 0) found = true; } - if (!fake_check_target("LB", target, lbs_and_backends[1])) { - gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'", - target, lbs_and_backends[1]); - goto done; + for (size_t i = 0; i < set_size; ++i) { + gpr_free(set[i]); } - success = true; - } else { - if (!fake_check_target("Backend", target, lbs_and_backends[0])) { - gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'", - target, lbs_and_backends[0]); + gpr_free(set); + return found; + } + + void fake_secure_name_check() const { + if (expected_targets_ == nullptr) return; + char** lbs_and_backends = nullptr; + size_t lbs_and_backends_size = 0; + bool success = false; + gpr_string_split(expected_targets_, ";", &lbs_and_backends, + &lbs_and_backends_size); + if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) { + gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'", + expected_targets_); goto done; } - success = true; - } -done: - for (size_t i = 0; i < lbs_and_backends_size; ++i) { - gpr_free(lbs_and_backends[i]); + if (is_lb_channel_) { + if (lbs_and_backends_size != 2) { + gpr_log(GPR_ERROR, + "Invalid expected targets arg value: '%s'. Expectations for LB " + "channels must be of the form 'be1,be2,be3,...;lb1,lb2,...", + expected_targets_); + goto done; + } + if (!fake_check_target("LB", target_, lbs_and_backends[1])) { + gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'", + target_, lbs_and_backends[1]); + goto done; + } + success = true; + } else { + if (!fake_check_target("Backend", target_, lbs_and_backends[0])) { + gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'", + target_, lbs_and_backends[0]); + goto done; + } + success = true; + } + done: + for (size_t i = 0; i < lbs_and_backends_size; ++i) { + gpr_free(lbs_and_backends[i]); + } + gpr_free(lbs_and_backends); + if (!success) abort(); } - gpr_free(lbs_and_backends); - if (!success) abort(); -} -static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { + char* target_; + char* expected_targets_; + bool is_lb_channel_; + char* target_name_override_; +}; + +static void fake_check_peer( + grpc_security_connector* sc, tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { const char* prop_name; grpc_error* error = GRPC_ERROR_NONE; *auth_context = nullptr; @@ -147,164 +240,65 @@ static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer, "Invalid value for cert type property."); goto end; } - *auth_context = grpc_auth_context_create(nullptr); + *auth_context = grpc_core::MakeRefCounted(nullptr); grpc_auth_context_add_cstring_property( - *auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + auth_context->get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_FAKE_TRANSPORT_SECURITY_TYPE); end: GRPC_CLOSURE_SCHED(on_peer_checked, error); tsi_peer_destruct(&peer); } -static void fake_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - fake_check_peer(sc, peer, auth_context, on_peer_checked); - grpc_fake_channel_security_connector* c = - reinterpret_cast(sc); - fake_secure_name_check(c->target, c->expected_targets, c->is_lb_channel); +void grpc_fake_channel_security_connector::check_peer( + tsi_peer peer, grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { + fake_check_peer(this, peer, auth_context, on_peer_checked); + fake_secure_name_check(); } -static void fake_server_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - fake_check_peer(sc, peer, auth_context, on_peer_checked); -} +class grpc_fake_server_security_connector + : public grpc_server_security_connector { + public: + grpc_fake_server_security_connector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(GRPC_FAKE_SECURITY_URL_SCHEME, + std::move(server_creds)) {} + ~grpc_fake_server_security_connector() override = default; -static int fake_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_fake_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_fake_channel_security_connector* c2 = - reinterpret_cast(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - c = strcmp(c1->target, c2->target); - if (c != 0) return c; - if (c1->expected_targets == nullptr || c2->expected_targets == nullptr) { - c = GPR_ICMP(c1->expected_targets, c2->expected_targets); - } else { - c = strcmp(c1->expected_targets, c2->expected_targets); + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + fake_check_peer(this, peer, auth_context, on_peer_checked); } - if (c != 0) return c; - return GPR_ICMP(c1->is_lb_channel, c2->is_lb_channel); -} -static int fake_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - return grpc_server_security_connector_cmp( - reinterpret_cast(sc1), - reinterpret_cast(sc2)); -} - -static bool fake_channel_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_fake_channel_security_connector* c = - reinterpret_cast(sc); - char* authority_hostname = nullptr; - char* authority_ignored_port = nullptr; - char* target_hostname = nullptr; - char* target_ignored_port = nullptr; - gpr_split_host_port(host, &authority_hostname, &authority_ignored_port); - gpr_split_host_port(c->target, &target_hostname, &target_ignored_port); - if (c->target_name_override != nullptr) { - char* fake_security_target_name_override_hostname = nullptr; - char* fake_security_target_name_override_ignored_port = nullptr; - gpr_split_host_port(c->target_name_override, - &fake_security_target_name_override_hostname, - &fake_security_target_name_override_ignored_port); - if (strcmp(authority_hostname, - fake_security_target_name_override_hostname) != 0) { - gpr_log(GPR_ERROR, - "Authority (host) '%s' != Fake Security Target override '%s'", - host, fake_security_target_name_override_hostname); - abort(); - } - gpr_free(fake_security_target_name_override_hostname); - gpr_free(fake_security_target_name_override_ignored_port); - } else if (strcmp(authority_hostname, target_hostname) != 0) { - gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", - authority_hostname, target_hostname); - abort(); + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) override { + grpc_handshake_manager_add( + handshake_mgr, + grpc_security_handshaker_create( + tsi_create_fake_handshaker(/*=is_client*/ false), this)); } - gpr_free(authority_hostname); - gpr_free(authority_ignored_port); - gpr_free(target_hostname); - gpr_free(target_ignored_port); - return true; -} -static void fake_channel_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} - -static void fake_channel_add_handshakers( - grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add( - handshake_mgr, - grpc_security_handshaker_create( - tsi_create_fake_handshaker(true /* is_client */), &sc->base)); -} - -static void fake_server_add_handshakers(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add( - handshake_mgr, - grpc_security_handshaker_create( - tsi_create_fake_handshaker(false /* is_client */), &sc->base)); -} - -static grpc_security_connector_vtable fake_channel_vtable = { - fake_channel_destroy, fake_channel_check_peer, fake_channel_cmp}; - -static grpc_security_connector_vtable fake_server_vtable = { - fake_server_destroy, fake_server_check_peer, fake_server_cmp}; - -grpc_channel_security_connector* grpc_fake_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target, - const grpc_channel_args* args) { - grpc_fake_channel_security_connector* c = - static_cast( - gpr_zalloc(sizeof(*c))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; - c->base.base.vtable = &fake_channel_vtable; - c->base.channel_creds = channel_creds; - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = fake_channel_check_call_host; - c->base.cancel_check_call_host = fake_channel_cancel_check_call_host; - c->base.add_handshakers = fake_channel_add_handshakers; - c->target = gpr_strdup(target); - const char* expected_targets = grpc_fake_transport_get_expected_targets(args); - c->expected_targets = gpr_strdup(expected_targets); - c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr; - const grpc_arg* target_name_override_arg = - grpc_channel_args_find(args, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); - if (target_name_override_arg != nullptr) { - c->target_name_override = - gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg)); + int cmp(const grpc_security_connector* other) const override { + return server_security_connector_cmp( + static_cast(other)); } - return &c->base; +}; +} // namespace + +grpc_core::RefCountedPtr +grpc_fake_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target, const grpc_channel_args* args) { + return grpc_core::MakeRefCounted( + std::move(channel_creds), std::move(request_metadata_creds), target, + args); } -grpc_server_security_connector* grpc_fake_server_security_connector_create( - grpc_server_credentials* server_creds) { - grpc_server_security_connector* c = - static_cast( - gpr_zalloc(sizeof(grpc_server_security_connector))); - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &fake_server_vtable; - c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; - c->server_creds = server_creds; - c->add_handshakers = fake_server_add_handshakers; - return c; +grpc_core::RefCountedPtr +grpc_fake_server_security_connector_create( + grpc_core::RefCountedPtr server_creds) { + return grpc_core::MakeRefCounted( + std::move(server_creds)); } diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.h b/src/core/lib/security/security_connector/fake/fake_security_connector.h index fdfe048c6e7..344a2349a49 100644 --- a/src/core/lib/security/security_connector/fake/fake_security_connector.h +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.h @@ -24,19 +24,22 @@ #include #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/security_connector/security_connector.h" #define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security" /* Creates a fake connector that emulates real channel security. */ -grpc_channel_security_connector* grpc_fake_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target, - const grpc_channel_args* args); +grpc_core::RefCountedPtr +grpc_fake_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target, const grpc_channel_args* args); /* Creates a fake connector that emulates real server security. */ -grpc_server_security_connector* grpc_fake_server_security_connector_create( - grpc_server_credentials* server_creds); +grpc_core::RefCountedPtr +grpc_fake_server_security_connector_create( + grpc_core::RefCountedPtr server_creds); #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_FAKE_FAKE_SECURITY_CONNECTOR_H \ */ diff --git a/src/core/lib/security/security_connector/local/local_security_connector.cc b/src/core/lib/security/security_connector/local/local_security_connector.cc index 008a98df281..7a59e54e9a7 100644 --- a/src/core/lib/security/security_connector/local/local_security_connector.cc +++ b/src/core/lib/security/security_connector/local/local_security_connector.cc @@ -30,6 +30,7 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/security/credentials/local/local_credentials.h" #include "src/core/lib/security/transport/security_handshaker.h" @@ -39,153 +40,145 @@ #define GRPC_UDS_URL_SCHEME "unix" #define GRPC_LOCAL_TRANSPORT_SECURITY_TYPE "local" -typedef struct { - grpc_channel_security_connector base; - char* target_name; -} grpc_local_channel_security_connector; +namespace { -typedef struct { - grpc_server_security_connector base; -} grpc_local_server_security_connector; - -static void local_channel_destroy(grpc_security_connector* sc) { - if (sc == nullptr) { - return; - } - auto c = reinterpret_cast(sc); - grpc_call_credentials_unref(c->base.request_metadata_creds); - grpc_channel_credentials_unref(c->base.channel_creds); - gpr_free(c->target_name); - gpr_free(sc); -} - -static void local_server_destroy(grpc_security_connector* sc) { - if (sc == nullptr) { - return; - } - auto c = reinterpret_cast(sc); - grpc_server_credentials_unref(c->base.server_creds); - gpr_free(sc); -} - -static void local_channel_add_handshakers( - grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) { - tsi_handshaker* handshaker = nullptr; - GPR_ASSERT(local_tsi_handshaker_create(true /* is_client */, &handshaker) == - TSI_OK); - grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( - handshaker, &sc->base)); -} - -static void local_server_add_handshakers( - grpc_server_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) { - tsi_handshaker* handshaker = nullptr; - GPR_ASSERT(local_tsi_handshaker_create(false /* is_client */, &handshaker) == - TSI_OK); - grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( - handshaker, &sc->base)); -} - -static int local_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_local_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_local_channel_security_connector* c2 = - reinterpret_cast(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - return strcmp(c1->target_name, c2->target_name); -} - -static int local_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_local_server_security_connector* c1 = - reinterpret_cast(sc1); - grpc_local_server_security_connector* c2 = - reinterpret_cast(sc2); - return grpc_server_security_connector_cmp(&c1->base, &c2->base); -} - -static grpc_security_status local_auth_context_create(grpc_auth_context** ctx) { - if (ctx == nullptr) { - gpr_log(GPR_ERROR, "Invalid arguments to local_auth_context_create()"); - return GRPC_SECURITY_ERROR; - } +grpc_core::RefCountedPtr local_auth_context_create() { /* Create auth context. */ - *ctx = grpc_auth_context_create(nullptr); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); grpc_auth_context_add_cstring_property( - *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_LOCAL_TRANSPORT_SECURITY_TYPE); GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( - *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME) == 1); - return GRPC_SECURITY_OK; + ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME) == 1); + return ctx; } -static void local_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_security_status status; +void local_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { /* Create an auth context which is necessary to pass the santiy check in - * {client, server}_auth_filter that verifies if the peer's auth context is + * {client, server}_auth_filter that verifies if the pepp's auth context is * obtained during handshakes. The auth context is only checked for its * existence and not actually used. */ - status = local_auth_context_create(auth_context); - grpc_error* error = status == GRPC_SECURITY_OK + *auth_context = local_auth_context_create(); + grpc_error* error = *auth_context != nullptr ? GRPC_ERROR_NONE : GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Could not create local auth context"); GRPC_CLOSURE_SCHED(on_peer_checked, error); } -static grpc_security_connector_vtable local_channel_vtable = { - local_channel_destroy, local_check_peer, local_channel_cmp}; - -static grpc_security_connector_vtable local_server_vtable = { - local_server_destroy, local_check_peer, local_server_cmp}; - -static bool local_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_local_channel_security_connector* local_sc = - reinterpret_cast(sc); - if (host == nullptr || local_sc == nullptr || - strcmp(host, local_sc->target_name) != 0) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "local call host does not match target name"); +class grpc_local_channel_security_connector final + : public grpc_channel_security_connector { + public: + grpc_local_channel_security_connector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name) + : grpc_channel_security_connector(GRPC_UDS_URL_SCHEME, + std::move(channel_creds), + std::move(request_metadata_creds)), + target_name_(gpr_strdup(target_name)) {} + + ~grpc_local_channel_security_connector() override { gpr_free(target_name_); } + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_manager) override { + tsi_handshaker* handshaker = nullptr; + GPR_ASSERT(local_tsi_handshaker_create(true /* is_client */, &handshaker) == + TSI_OK); + grpc_handshake_manager_add( + handshake_manager, grpc_security_handshaker_create(handshaker, this)); } - return true; -} -static void local_cancel_check_call_host(grpc_channel_security_connector* sc, - grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast( + other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) return c; + return strcmp(target_name_, other->target_name_); + } + + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + local_check_peer(this, peer, auth_context, on_peer_checked); + } + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + if (host == nullptr || strcmp(host, target_name_) != 0) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "local call host does not match target name"); + } + return true; + } -grpc_security_status grpc_local_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_channel_args* args, const char* target_name, - grpc_channel_security_connector** sc) { - if (channel_creds == nullptr || sc == nullptr || target_name == nullptr) { + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + const char* target_name() const { return target_name_; } + + private: + char* target_name_; +}; + +class grpc_local_server_security_connector final + : public grpc_server_security_connector { + public: + grpc_local_server_security_connector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(GRPC_UDS_URL_SCHEME, + std::move(server_creds)) {} + ~grpc_local_server_security_connector() override = default; + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_manager) override { + tsi_handshaker* handshaker = nullptr; + GPR_ASSERT(local_tsi_handshaker_create(false /* is_client */, + &handshaker) == TSI_OK); + grpc_handshake_manager_add( + handshake_manager, grpc_security_handshaker_create(handshaker, this)); + } + + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + local_check_peer(this, peer, auth_context, on_peer_checked); + } + + int cmp(const grpc_security_connector* other) const override { + return server_security_connector_cmp( + static_cast(other)); + } +}; +} // namespace + +grpc_core::RefCountedPtr +grpc_local_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const grpc_channel_args* args, const char* target_name) { + if (channel_creds == nullptr || target_name == nullptr) { gpr_log( GPR_ERROR, "Invalid arguments to grpc_local_channel_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } // Check if local_connect_type is UDS. Only UDS is supported for now. grpc_local_credentials* creds = - reinterpret_cast(channel_creds); - if (creds->connect_type != UDS) { + static_cast(channel_creds.get()); + if (creds->connect_type() != UDS) { gpr_log(GPR_ERROR, "Invalid local channel type to " "grpc_local_channel_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } // Check if target_name is a valid UDS address. const grpc_arg* server_uri_arg = @@ -196,51 +189,30 @@ grpc_security_status grpc_local_channel_security_connector_create( gpr_log(GPR_ERROR, "Invalid target_name to " "grpc_local_channel_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - auto c = static_cast( - gpr_zalloc(sizeof(grpc_local_channel_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &local_channel_vtable; - c->base.add_handshakers = local_channel_add_handshakers; - c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = local_check_call_host; - c->base.cancel_check_call_host = local_cancel_check_call_host; - c->base.base.url_scheme = - creds->connect_type == UDS ? GRPC_UDS_URL_SCHEME : nullptr; - c->target_name = gpr_strdup(target_name); - *sc = &c->base; - return GRPC_SECURITY_OK; + return grpc_core::MakeRefCounted( + channel_creds, request_metadata_creds, target_name); } -grpc_security_status grpc_local_server_security_connector_create( - grpc_server_credentials* server_creds, - grpc_server_security_connector** sc) { - if (server_creds == nullptr || sc == nullptr) { +grpc_core::RefCountedPtr +grpc_local_server_security_connector_create( + grpc_core::RefCountedPtr server_creds) { + if (server_creds == nullptr) { gpr_log( GPR_ERROR, "Invalid arguments to grpc_local_server_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } // Check if local_connect_type is UDS. Only UDS is supported for now. - grpc_local_server_credentials* creds = - reinterpret_cast(server_creds); - if (creds->connect_type != UDS) { + const grpc_local_server_credentials* creds = + static_cast(server_creds.get()); + if (creds->connect_type() != UDS) { gpr_log(GPR_ERROR, "Invalid local server type to " "grpc_local_server_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - auto c = static_cast( - gpr_zalloc(sizeof(grpc_local_server_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &local_server_vtable; - c->base.server_creds = grpc_server_credentials_ref(server_creds); - c->base.base.url_scheme = - creds->connect_type == UDS ? GRPC_UDS_URL_SCHEME : nullptr; - c->base.add_handshakers = local_server_add_handshakers; - *sc = &c->base; - return GRPC_SECURITY_OK; + return grpc_core::MakeRefCounted( + std::move(server_creds)); } diff --git a/src/core/lib/security/security_connector/local/local_security_connector.h b/src/core/lib/security/security_connector/local/local_security_connector.h index 5369a2127aa..6eee0ca9a6c 100644 --- a/src/core/lib/security/security_connector/local/local_security_connector.h +++ b/src/core/lib/security/security_connector/local/local_security_connector.h @@ -34,13 +34,13 @@ * - sc: address of local channel security connector instance to be returned * from the method. * - * It returns GRPC_SECURITY_OK on success, and an error stauts code on failure. + * It returns nullptr on failure. */ -grpc_security_status grpc_local_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_channel_args* args, const char* target_name, - grpc_channel_security_connector** sc); +grpc_core::RefCountedPtr +grpc_local_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const grpc_channel_args* args, const char* target_name); /** * This method creates a local server security connector. @@ -49,10 +49,11 @@ grpc_security_status grpc_local_channel_security_connector_create( * - sc: address of local server security connector instance to be returned from * the method. * - * It returns GRPC_SECURITY_OK on success, and an error status code on failure. + * It returns nullptr on failure. */ -grpc_security_status grpc_local_server_security_connector_create( - grpc_server_credentials* server_creds, grpc_server_security_connector** sc); +grpc_core::RefCountedPtr +grpc_local_server_security_connector_create( + grpc_core::RefCountedPtr server_creds); #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_LOCAL_SECURITY_CONNECTOR_H \ */ diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 02cecb0eb1e..96a19605466 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -35,150 +35,67 @@ #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/load_system_roots.h" +#include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/lib/security/transport/security_handshaker.h" grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount( false, "security_connector_refcount"); -void grpc_channel_security_connector_add_handshakers( - grpc_channel_security_connector* connector, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - if (connector != nullptr) { - connector->add_handshakers(connector, interested_parties, handshake_mgr); - } -} - -void grpc_server_security_connector_add_handshakers( - grpc_server_security_connector* connector, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - if (connector != nullptr) { - connector->add_handshakers(connector, interested_parties, handshake_mgr); - } -} - -void grpc_security_connector_check_peer(grpc_security_connector* sc, - tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - if (sc == nullptr) { - GRPC_CLOSURE_SCHED(on_peer_checked, - GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "cannot check peer -- no security connector")); - tsi_peer_destruct(&peer); - } else { - sc->vtable->check_peer(sc, peer, auth_context, on_peer_checked); - } -} - -int grpc_security_connector_cmp(grpc_security_connector* sc, - grpc_security_connector* other) { +grpc_server_security_connector::grpc_server_security_connector( + const char* url_scheme, + grpc_core::RefCountedPtr server_creds) + : grpc_security_connector(url_scheme), + server_creds_(std::move(server_creds)) {} + +grpc_channel_security_connector::grpc_channel_security_connector( + const char* url_scheme, + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds) + : grpc_security_connector(url_scheme), + channel_creds_(std::move(channel_creds)), + request_metadata_creds_(std::move(request_metadata_creds)) {} +grpc_channel_security_connector::~grpc_channel_security_connector() {} + +int grpc_security_connector_cmp(const grpc_security_connector* sc, + const grpc_security_connector* other) { if (sc == nullptr || other == nullptr) return GPR_ICMP(sc, other); - int c = GPR_ICMP(sc->vtable, other->vtable); - if (c != 0) return c; - return sc->vtable->cmp(sc, other); + return sc->cmp(other); } -int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1, - grpc_channel_security_connector* sc2) { - GPR_ASSERT(sc1->channel_creds != nullptr); - GPR_ASSERT(sc2->channel_creds != nullptr); - int c = GPR_ICMP(sc1->channel_creds, sc2->channel_creds); - if (c != 0) return c; - c = GPR_ICMP(sc1->request_metadata_creds, sc2->request_metadata_creds); - if (c != 0) return c; - c = GPR_ICMP((void*)sc1->check_call_host, (void*)sc2->check_call_host); - if (c != 0) return c; - c = GPR_ICMP((void*)sc1->cancel_check_call_host, - (void*)sc2->cancel_check_call_host); +int grpc_channel_security_connector::channel_security_connector_cmp( + const grpc_channel_security_connector* other) const { + const grpc_channel_security_connector* other_sc = + static_cast(other); + GPR_ASSERT(channel_creds() != nullptr); + GPR_ASSERT(other_sc->channel_creds() != nullptr); + int c = GPR_ICMP(channel_creds(), other_sc->channel_creds()); if (c != 0) return c; - return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers); + return GPR_ICMP(request_metadata_creds(), other_sc->request_metadata_creds()); } -int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1, - grpc_server_security_connector* sc2) { - GPR_ASSERT(sc1->server_creds != nullptr); - GPR_ASSERT(sc2->server_creds != nullptr); - int c = GPR_ICMP(sc1->server_creds, sc2->server_creds); - if (c != 0) return c; - return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers); -} - -bool grpc_channel_security_connector_check_call_host( - grpc_channel_security_connector* sc, const char* host, - grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, - grpc_error** error) { - if (sc == nullptr || sc->check_call_host == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "cannot check call host -- no security connector"); - return true; - } - return sc->check_call_host(sc, host, auth_context, on_call_host_checked, - error); -} - -void grpc_channel_security_connector_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - if (sc == nullptr || sc->cancel_check_call_host == nullptr) { - GRPC_ERROR_UNREF(error); - return; - } - sc->cancel_check_call_host(sc, on_call_host_checked, error); -} - -#ifndef NDEBUG -grpc_security_connector* grpc_security_connector_ref( - grpc_security_connector* sc, const char* file, int line, - const char* reason) { - if (sc == nullptr) return nullptr; - if (grpc_trace_security_connector_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SECURITY_CONNECTOR:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", sc, - val, val + 1, reason); - } -#else -grpc_security_connector* grpc_security_connector_ref( - grpc_security_connector* sc) { - if (sc == nullptr) return nullptr; -#endif - gpr_ref(&sc->refcount); - return sc; -} - -#ifndef NDEBUG -void grpc_security_connector_unref(grpc_security_connector* sc, - const char* file, int line, - const char* reason) { - if (sc == nullptr) return; - if (grpc_trace_security_connector_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SECURITY_CONNECTOR:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", sc, - val, val - 1, reason); - } -#else -void grpc_security_connector_unref(grpc_security_connector* sc) { - if (sc == nullptr) return; -#endif - if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc); +int grpc_server_security_connector::server_security_connector_cmp( + const grpc_server_security_connector* other) const { + const grpc_server_security_connector* other_sc = + static_cast(other); + GPR_ASSERT(server_creds() != nullptr); + GPR_ASSERT(other_sc->server_creds() != nullptr); + return GPR_ICMP(server_creds(), other_sc->server_creds()); } static void connector_arg_destroy(void* p) { - GRPC_SECURITY_CONNECTOR_UNREF((grpc_security_connector*)p, - "connector_arg_destroy"); + static_cast(p)->Unref(DEBUG_LOCATION, + "connector_arg_destroy"); } static void* connector_arg_copy(void* p) { - return GRPC_SECURITY_CONNECTOR_REF((grpc_security_connector*)p, - "connector_arg_copy"); + return static_cast(p) + ->Ref(DEBUG_LOCATION, "connector_arg_copy") + .release(); } static int connector_cmp(void* a, void* b) { - return grpc_security_connector_cmp(static_cast(a), - static_cast(b)); + return static_cast(a)->cmp( + static_cast(b)); } static const grpc_arg_pointer_vtable connector_arg_vtable = { diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index 4c921a87931..d90aa8c4dab 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -26,6 +26,7 @@ #include #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/tcp_server.h" @@ -34,8 +35,6 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount; -/* --- status enum. --- */ - typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status; /* --- security_connector object. --- @@ -43,54 +42,33 @@ typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status; A security connector object represents away to configure the underlying transport security mechanism and check the resulting trusted peer. */ -typedef struct grpc_security_connector grpc_security_connector; - #define GRPC_ARG_SECURITY_CONNECTOR "grpc.security_connector" -typedef struct { - void (*destroy)(grpc_security_connector* sc); - void (*check_peer)(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked); - int (*cmp)(grpc_security_connector* sc, grpc_security_connector* other); -} grpc_security_connector_vtable; - -struct grpc_security_connector { - const grpc_security_connector_vtable* vtable; - gpr_refcount refcount; - const char* url_scheme; -}; +class grpc_security_connector + : public grpc_core::RefCounted { + public: + explicit grpc_security_connector(const char* url_scheme) + : grpc_core::RefCounted( + &grpc_trace_security_connector_refcount), + url_scheme_(url_scheme) {} + virtual ~grpc_security_connector() = default; + + /* Check the peer. Callee takes ownership of the peer object. + When done, sets *auth_context and invokes on_peer_checked. */ + virtual void check_peer( + tsi_peer peer, grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) GRPC_ABSTRACT; + + /* Compares two security connectors. */ + virtual int cmp(const grpc_security_connector* other) const GRPC_ABSTRACT; + + const char* url_scheme() const { return url_scheme_; } -/* Refcounting. */ -#ifndef NDEBUG -#define GRPC_SECURITY_CONNECTOR_REF(p, r) \ - grpc_security_connector_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \ - grpc_security_connector_unref((p), __FILE__, __LINE__, (r)) -grpc_security_connector* grpc_security_connector_ref( - grpc_security_connector* policy, const char* file, int line, - const char* reason); -void grpc_security_connector_unref(grpc_security_connector* policy, - const char* file, int line, - const char* reason); -#else -#define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p)) -#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p)) -grpc_security_connector* grpc_security_connector_ref( - grpc_security_connector* policy); -void grpc_security_connector_unref(grpc_security_connector* policy); -#endif - -/* Check the peer. Callee takes ownership of the peer object. - When done, sets *auth_context and invokes on_peer_checked. */ -void grpc_security_connector_check_peer(grpc_security_connector* sc, - tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked); - -/* Compares two security connectors. */ -int grpc_security_connector_cmp(grpc_security_connector* sc, - grpc_security_connector* other); + GRPC_ABSTRACT_BASE_CLASS + + private: + const char* url_scheme_; +}; /* Util to encapsulate the connector in a channel arg. */ grpc_arg grpc_security_connector_to_arg(grpc_security_connector* sc); @@ -107,71 +85,89 @@ grpc_security_connector* grpc_security_connector_find_in_args( A channel security connector object represents a way to configure the underlying transport security mechanism on the client side. */ -typedef struct grpc_channel_security_connector grpc_channel_security_connector; - -struct grpc_channel_security_connector { - grpc_security_connector base; - grpc_channel_credentials* channel_creds; - grpc_call_credentials* request_metadata_creds; - bool (*check_call_host)(grpc_channel_security_connector* sc, const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error); - void (*cancel_check_call_host)(grpc_channel_security_connector* sc, - grpc_closure* on_call_host_checked, - grpc_error* error); - void (*add_handshakers)(grpc_channel_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); +class grpc_channel_security_connector : public grpc_security_connector { + public: + grpc_channel_security_connector( + const char* url_scheme, + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds); + ~grpc_channel_security_connector() override; + + /// Checks that the host that will be set for a call is acceptable. + /// Returns true if completed synchronously, in which case \a error will + /// be set to indicate the result. Otherwise, \a on_call_host_checked + /// will be invoked when complete. + virtual bool check_call_host(const char* host, + grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) GRPC_ABSTRACT; + /// Cancels a pending asychronous call to + /// grpc_channel_security_connector_check_call_host() with + /// \a on_call_host_checked as its callback. + virtual void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) GRPC_ABSTRACT; + /// Registers handshakers with \a handshake_mgr. + virtual void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) + GRPC_ABSTRACT; + + const grpc_channel_credentials* channel_creds() const { + return channel_creds_.get(); + } + grpc_channel_credentials* mutable_channel_creds() { + return channel_creds_.get(); + } + const grpc_call_credentials* request_metadata_creds() const { + return request_metadata_creds_.get(); + } + grpc_call_credentials* mutable_request_metadata_creds() { + return request_metadata_creds_.get(); + } + + GRPC_ABSTRACT_BASE_CLASS + + protected: + // Helper methods to be used in subclasses. + int channel_security_connector_cmp( + const grpc_channel_security_connector* other) const; + + private: + grpc_core::RefCountedPtr channel_creds_; + grpc_core::RefCountedPtr request_metadata_creds_; }; -/// A helper function for use in grpc_security_connector_cmp() implementations. -int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1, - grpc_channel_security_connector* sc2); - -/// Checks that the host that will be set for a call is acceptable. -/// Returns true if completed synchronously, in which case \a error will -/// be set to indicate the result. Otherwise, \a on_call_host_checked -/// will be invoked when complete. -bool grpc_channel_security_connector_check_call_host( - grpc_channel_security_connector* sc, const char* host, - grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, - grpc_error** error); - -/// Cancels a pending asychronous call to -/// grpc_channel_security_connector_check_call_host() with -/// \a on_call_host_checked as its callback. -void grpc_channel_security_connector_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error); - -/* Registers handshakers with \a handshake_mgr. */ -void grpc_channel_security_connector_add_handshakers( - grpc_channel_security_connector* connector, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); - /* --- server_security_connector object. --- A server security connector object represents a way to configure the underlying transport security mechanism on the server side. */ -typedef struct grpc_server_security_connector grpc_server_security_connector; - -struct grpc_server_security_connector { - grpc_security_connector base; - grpc_server_credentials* server_creds; - void (*add_handshakers)(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); +class grpc_server_security_connector : public grpc_security_connector { + public: + grpc_server_security_connector( + const char* url_scheme, + grpc_core::RefCountedPtr server_creds); + ~grpc_server_security_connector() override = default; + + virtual void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) + GRPC_ABSTRACT; + + const grpc_server_credentials* server_creds() const { + return server_creds_.get(); + } + grpc_server_credentials* mutable_server_creds() { + return server_creds_.get(); + } + + GRPC_ABSTRACT_BASE_CLASS + + protected: + // Helper methods to be used in subclasses. + int server_security_connector_cmp( + const grpc_server_security_connector* other) const; + + private: + grpc_core::RefCountedPtr server_creds_; }; -/// A helper function for use in grpc_security_connector_cmp() implementations. -int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1, - grpc_server_security_connector* sc2); - -void grpc_server_security_connector_add_handshakers( - grpc_server_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); - #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SECURITY_CONNECTOR_H */ diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index 20a9533dd13..14b2c4030f2 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/ssl/ssl_credentials.h" @@ -39,172 +40,10 @@ #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security.h" -typedef struct { - grpc_channel_security_connector base; - tsi_ssl_client_handshaker_factory* client_handshaker_factory; - char* target_name; - char* overridden_target_name; - const verify_peer_options* verify_options; -} grpc_ssl_channel_security_connector; - -typedef struct { - grpc_server_security_connector base; - tsi_ssl_server_handshaker_factory* server_handshaker_factory; -} grpc_ssl_server_security_connector; - -static bool server_connector_has_cert_config_fetcher( - grpc_ssl_server_security_connector* c) { - GPR_ASSERT(c != nullptr); - grpc_ssl_server_credentials* server_creds = - reinterpret_cast(c->base.server_creds); - GPR_ASSERT(server_creds != nullptr); - return server_creds->certificate_config_fetcher.cb != nullptr; -} - -static void ssl_channel_destroy(grpc_security_connector* sc) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast(sc); - grpc_channel_credentials_unref(c->base.channel_creds); - grpc_call_credentials_unref(c->base.request_metadata_creds); - tsi_ssl_client_handshaker_factory_unref(c->client_handshaker_factory); - c->client_handshaker_factory = nullptr; - if (c->target_name != nullptr) gpr_free(c->target_name); - if (c->overridden_target_name != nullptr) gpr_free(c->overridden_target_name); - gpr_free(sc); -} - -static void ssl_server_destroy(grpc_security_connector* sc) { - grpc_ssl_server_security_connector* c = - reinterpret_cast(sc); - grpc_server_credentials_unref(c->base.server_creds); - tsi_ssl_server_handshaker_factory_unref(c->server_handshaker_factory); - c->server_handshaker_factory = nullptr; - gpr_free(sc); -} - -static void ssl_channel_add_handshakers(grpc_channel_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast(sc); - // Instantiate TSI handshaker. - tsi_handshaker* tsi_hs = nullptr; - tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( - c->client_handshaker_factory, - c->overridden_target_name != nullptr ? c->overridden_target_name - : c->target_name, - &tsi_hs); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); - return; - } - // Create handshakers. - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); -} - -/* Attempts to replace the server_handshaker_factory with a new factory using - * the provided grpc_ssl_server_certificate_config. Should new factory creation - * fail, the existing factory will not be replaced. Returns true on success (new - * factory created). */ -static bool try_replace_server_handshaker_factory( - grpc_ssl_server_security_connector* sc, - const grpc_ssl_server_certificate_config* config) { - if (config == nullptr) { - gpr_log(GPR_ERROR, - "Server certificate config callback returned invalid (NULL) " - "config."); - return false; - } - gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config); - - size_t num_alpn_protocols = 0; - const char** alpn_protocol_strings = - grpc_fill_alpn_protocol_strings(&num_alpn_protocols); - tsi_ssl_pem_key_cert_pair* cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( - config->pem_key_cert_pairs, config->num_key_cert_pairs); - tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr; - grpc_ssl_server_credentials* server_creds = - reinterpret_cast(sc->base.server_creds); - tsi_result result = tsi_create_ssl_server_handshaker_factory_ex( - cert_pairs, config->num_key_cert_pairs, config->pem_root_certs, - grpc_get_tsi_client_certificate_request_type( - server_creds->config.client_certificate_request), - grpc_get_ssl_cipher_suites(), alpn_protocol_strings, - static_cast(num_alpn_protocols), &new_handshaker_factory); - gpr_free(cert_pairs); - gpr_free((void*)alpn_protocol_strings); - - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - return false; - } - tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory); - sc->server_handshaker_factory = new_handshaker_factory; - return true; -} - -/* Attempts to fetch the server certificate config if a callback is available. - * Current certificate config will continue to be used if the callback returns - * an error. Returns true if new credentials were sucessfully loaded. */ -static bool try_fetch_ssl_server_credentials( - grpc_ssl_server_security_connector* sc) { - grpc_ssl_server_certificate_config* certificate_config = nullptr; - bool status; - - GPR_ASSERT(sc != nullptr); - if (!server_connector_has_cert_config_fetcher(sc)) return false; - - grpc_ssl_server_credentials* server_creds = - reinterpret_cast(sc->base.server_creds); - grpc_ssl_certificate_config_reload_status cb_result = - server_creds->certificate_config_fetcher.cb( - server_creds->certificate_config_fetcher.user_data, - &certificate_config); - if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { - gpr_log(GPR_DEBUG, "No change in SSL server credentials."); - status = false; - } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) { - status = try_replace_server_handshaker_factory(sc, certificate_config); - } else { - // Log error, continue using previously-loaded credentials. - gpr_log(GPR_ERROR, - "Failed fetching new server credentials, continuing to " - "use previously-loaded credentials."); - status = false; - } - - if (certificate_config != nullptr) { - grpc_ssl_server_certificate_config_destroy(certificate_config); - } - return status; -} - -static void ssl_server_add_handshakers(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_ssl_server_security_connector* c = - reinterpret_cast(sc); - // Instantiate TSI handshaker. - try_fetch_ssl_server_credentials(c); - tsi_handshaker* tsi_hs = nullptr; - tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( - c->server_handshaker_factory, &tsi_hs); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); - return; - } - // Create handshakers. - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); -} - -static grpc_error* ssl_check_peer(grpc_security_connector* sc, - const char* peer_name, const tsi_peer* peer, - grpc_auth_context** auth_context) { +namespace { +grpc_error* ssl_check_peer( + const char* peer_name, const tsi_peer* peer, + grpc_core::RefCountedPtr* auth_context) { #if TSI_OPENSSL_ALPN_SUPPORT /* Check the ALPN if ALPN is supported. */ const tsi_peer_property* p = @@ -230,245 +69,384 @@ static grpc_error* ssl_check_peer(grpc_security_connector* sc, return GRPC_ERROR_NONE; } -static void ssl_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast(sc); - const char* target_name = c->overridden_target_name != nullptr - ? c->overridden_target_name - : c->target_name; - grpc_error* error = ssl_check_peer(sc, target_name, &peer, auth_context); - if (error == GRPC_ERROR_NONE && - c->verify_options->verify_peer_callback != nullptr) { - const tsi_peer_property* p = - tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); - if (p == nullptr) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: missing pem cert property."); - } else { - char* peer_pem = static_cast(gpr_malloc(p->value.length + 1)); - memcpy(peer_pem, p->value.data, p->value.length); - peer_pem[p->value.length] = '\0'; - int callback_status = c->verify_options->verify_peer_callback( - target_name, peer_pem, - c->verify_options->verify_peer_callback_userdata); - gpr_free(peer_pem); - if (callback_status) { - char* msg; - gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)", - callback_status); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); - } - } +class grpc_ssl_channel_security_connector final + : public grpc_channel_security_connector { + public: + grpc_ssl_channel_security_connector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const grpc_ssl_config* config, const char* target_name, + const char* overridden_target_name) + : grpc_channel_security_connector(GRPC_SSL_URL_SCHEME, + std::move(channel_creds), + std::move(request_metadata_creds)), + overridden_target_name_(overridden_target_name == nullptr + ? nullptr + : gpr_strdup(overridden_target_name)), + verify_options_(&config->verify_options) { + char* port; + gpr_split_host_port(target_name, &target_name_, &port); + gpr_free(port); } - GRPC_CLOSURE_SCHED(on_peer_checked, error); - tsi_peer_destruct(&peer); -} -static void ssl_server_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_error* error = ssl_check_peer(sc, nullptr, &peer, auth_context); - tsi_peer_destruct(&peer); - GRPC_CLOSURE_SCHED(on_peer_checked, error); -} + ~grpc_ssl_channel_security_connector() override { + tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); + if (target_name_ != nullptr) gpr_free(target_name_); + if (overridden_target_name_ != nullptr) gpr_free(overridden_target_name_); + } -static int ssl_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_ssl_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_ssl_channel_security_connector* c2 = - reinterpret_cast(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - c = strcmp(c1->target_name, c2->target_name); - if (c != 0) return c; - return (c1->overridden_target_name == nullptr || - c2->overridden_target_name == nullptr) - ? GPR_ICMP(c1->overridden_target_name, c2->overridden_target_name) - : strcmp(c1->overridden_target_name, c2->overridden_target_name); -} + grpc_security_status InitializeHandshakerFactory( + const grpc_ssl_config* config, const char* pem_root_certs, + const tsi_ssl_root_certs_store* root_store, + tsi_ssl_session_cache* ssl_session_cache) { + bool has_key_cert_pair = + config->pem_key_cert_pair != nullptr && + config->pem_key_cert_pair->private_key != nullptr && + config->pem_key_cert_pair->cert_chain != nullptr; + tsi_ssl_client_handshaker_options options; + memset(&options, 0, sizeof(options)); + GPR_DEBUG_ASSERT(pem_root_certs != nullptr); + options.pem_root_certs = pem_root_certs; + options.root_store = root_store; + options.alpn_protocols = + grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols); + if (has_key_cert_pair) { + options.pem_key_cert_pair = config->pem_key_cert_pair; + } + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.session_cache = ssl_session_cache; + const tsi_result result = + tsi_create_ssl_client_handshaker_factory_with_options( + &options, &client_handshaker_factory_); + gpr_free((void*)options.alpn_protocols); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + return GRPC_SECURITY_ERROR; + } + return GRPC_SECURITY_OK; + } -static int ssl_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - return grpc_server_security_connector_cmp( - reinterpret_cast(sc1), - reinterpret_cast(sc2)); -} + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) override { + // Instantiate TSI handshaker. + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( + client_handshaker_factory_, + overridden_target_name_ != nullptr ? overridden_target_name_ + : target_name_, + &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + // Create handshakers. + grpc_handshake_manager_add(handshake_mgr, + grpc_security_handshaker_create(tsi_hs, this)); + } -static bool ssl_channel_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast(sc); - grpc_security_status status = GRPC_SECURITY_ERROR; - tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); - if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; - /* If the target name was overridden, then the original target_name was - 'checked' transitively during the previous peer check at the end of the - handshake. */ - if (c->overridden_target_name != nullptr && - strcmp(host, c->target_name) == 0) { - status = GRPC_SECURITY_OK; + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + const char* target_name = overridden_target_name_ != nullptr + ? overridden_target_name_ + : target_name_; + grpc_error* error = ssl_check_peer(target_name, &peer, auth_context); + if (error == GRPC_ERROR_NONE && + verify_options_->verify_peer_callback != nullptr) { + const tsi_peer_property* p = + tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); + if (p == nullptr) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing pem cert property."); + } else { + char* peer_pem = static_cast(gpr_malloc(p->value.length + 1)); + memcpy(peer_pem, p->value.data, p->value.length); + peer_pem[p->value.length] = '\0'; + int callback_status = verify_options_->verify_peer_callback( + target_name, peer_pem, + verify_options_->verify_peer_callback_userdata); + gpr_free(peer_pem); + if (callback_status) { + char* msg; + gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)", + callback_status); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + } + } + } + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); } - if (status != GRPC_SECURITY_OK) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "call host does not match SSL server name"); + + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast(other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) return c; + c = strcmp(target_name_, other->target_name_); + if (c != 0) return c; + return (overridden_target_name_ == nullptr || + other->overridden_target_name_ == nullptr) + ? GPR_ICMP(overridden_target_name_, + other->overridden_target_name_) + : strcmp(overridden_target_name_, + other->overridden_target_name_); } - grpc_shallow_peer_destruct(&peer); - return true; -} -static void ssl_channel_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + grpc_security_status status = GRPC_SECURITY_ERROR; + tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); + if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; + /* If the target name was overridden, then the original target_name was + 'checked' transitively during the previous peer check at the end of the + handshake. */ + if (overridden_target_name_ != nullptr && strcmp(host, target_name_) == 0) { + status = GRPC_SECURITY_OK; + } + if (status != GRPC_SECURITY_OK) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "call host does not match SSL server name"); + } + grpc_shallow_peer_destruct(&peer); + return true; + } -static grpc_security_connector_vtable ssl_channel_vtable = { - ssl_channel_destroy, ssl_channel_check_peer, ssl_channel_cmp}; + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } -static grpc_security_connector_vtable ssl_server_vtable = { - ssl_server_destroy, ssl_server_check_peer, ssl_server_cmp}; + private: + tsi_ssl_client_handshaker_factory* client_handshaker_factory_; + char* target_name_; + char* overridden_target_name_; + const verify_peer_options* verify_options_; +}; + +class grpc_ssl_server_security_connector + : public grpc_server_security_connector { + public: + grpc_ssl_server_security_connector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(GRPC_SSL_URL_SCHEME, + std::move(server_creds)) {} + + ~grpc_ssl_server_security_connector() override { + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + } -grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_ssl_config* config, const char* target_name, - const char* overridden_target_name, - tsi_ssl_session_cache* ssl_session_cache, - grpc_channel_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_ssl_channel_security_connector* c; - char* port; - bool has_key_cert_pair; - tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); - options.alpn_protocols = - grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols); + bool has_cert_config_fetcher() const { + return static_cast(server_creds()) + ->has_cert_config_fetcher(); + } - if (config == nullptr || target_name == nullptr) { - gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); - goto error; + const tsi_ssl_server_handshaker_factory* server_handshaker_factory() const { + return server_handshaker_factory_; } - if (config->pem_root_certs == nullptr) { - // Use default root certificates. - options.pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); - options.root_store = grpc_core::DefaultSslRootStore::GetRootStore(); - if (options.pem_root_certs == nullptr) { - gpr_log(GPR_ERROR, "Could not get default pem root certs."); - goto error; + + grpc_security_status InitializeHandshakerFactory() { + if (has_cert_config_fetcher()) { + // Load initial credentials from certificate_config_fetcher: + if (!try_fetch_ssl_server_credentials()) { + gpr_log(GPR_ERROR, + "Failed loading SSL server credentials from fetcher."); + return GRPC_SECURITY_ERROR; + } + } else { + auto* server_credentials = + static_cast(server_creds()); + size_t num_alpn_protocols = 0; + const char** alpn_protocol_strings = + grpc_fill_alpn_protocol_strings(&num_alpn_protocols); + const tsi_result result = tsi_create_ssl_server_handshaker_factory_ex( + server_credentials->config().pem_key_cert_pairs, + server_credentials->config().num_key_cert_pairs, + server_credentials->config().pem_root_certs, + grpc_get_tsi_client_certificate_request_type( + server_credentials->config().client_certificate_request), + grpc_get_ssl_cipher_suites(), alpn_protocol_strings, + static_cast(num_alpn_protocols), + &server_handshaker_factory_); + gpr_free((void*)alpn_protocol_strings); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + return GRPC_SECURITY_ERROR; + } } - } else { - options.pem_root_certs = config->pem_root_certs; - } - c = static_cast( - gpr_zalloc(sizeof(grpc_ssl_channel_security_connector))); - - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &ssl_channel_vtable; - c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; - c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = ssl_channel_check_call_host; - c->base.cancel_check_call_host = ssl_channel_cancel_check_call_host; - c->base.add_handshakers = ssl_channel_add_handshakers; - gpr_split_host_port(target_name, &c->target_name, &port); - gpr_free(port); - if (overridden_target_name != nullptr) { - c->overridden_target_name = gpr_strdup(overridden_target_name); + return GRPC_SECURITY_OK; } - c->verify_options = &config->verify_options; - has_key_cert_pair = config->pem_key_cert_pair != nullptr && - config->pem_key_cert_pair->private_key != nullptr && - config->pem_key_cert_pair->cert_chain != nullptr; - if (has_key_cert_pair) { - options.pem_key_cert_pair = config->pem_key_cert_pair; + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) override { + // Instantiate TSI handshaker. + try_fetch_ssl_server_credentials(); + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( + server_handshaker_factory_, &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + // Create handshakers. + grpc_handshake_manager_add(handshake_mgr, + grpc_security_handshaker_create(tsi_hs, this)); } - options.cipher_suites = grpc_get_ssl_cipher_suites(); - options.session_cache = ssl_session_cache; - result = tsi_create_ssl_client_handshaker_factory_with_options( - &options, &c->client_handshaker_factory); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - ssl_channel_destroy(&c->base.base); - *sc = nullptr; - goto error; + + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + grpc_error* error = ssl_check_peer(nullptr, &peer, auth_context); + tsi_peer_destruct(&peer); + GRPC_CLOSURE_SCHED(on_peer_checked, error); } - *sc = &c->base; - gpr_free((void*)options.alpn_protocols); - return GRPC_SECURITY_OK; -error: - gpr_free((void*)options.alpn_protocols); - return GRPC_SECURITY_ERROR; -} + int cmp(const grpc_security_connector* other) const override { + return server_security_connector_cmp( + static_cast(other)); + } -static grpc_ssl_server_security_connector* -grpc_ssl_server_security_connector_initialize( - grpc_server_credentials* server_creds) { - grpc_ssl_server_security_connector* c = - static_cast( - gpr_zalloc(sizeof(grpc_ssl_server_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; - c->base.base.vtable = &ssl_server_vtable; - c->base.add_handshakers = ssl_server_add_handshakers; - c->base.server_creds = grpc_server_credentials_ref(server_creds); - return c; -} + private: + /* Attempts to fetch the server certificate config if a callback is available. + * Current certificate config will continue to be used if the callback returns + * an error. Returns true if new credentials were sucessfully loaded. */ + bool try_fetch_ssl_server_credentials() { + grpc_ssl_server_certificate_config* certificate_config = nullptr; + bool status; + + if (!has_cert_config_fetcher()) return false; + + grpc_ssl_server_credentials* server_creds = + static_cast(this->mutable_server_creds()); + grpc_ssl_certificate_config_reload_status cb_result = + server_creds->FetchCertConfig(&certificate_config); + if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { + gpr_log(GPR_DEBUG, "No change in SSL server credentials."); + status = false; + } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) { + status = try_replace_server_handshaker_factory(certificate_config); + } else { + // Log error, continue using previously-loaded credentials. + gpr_log(GPR_ERROR, + "Failed fetching new server credentials, continuing to " + "use previously-loaded credentials."); + status = false; + } -grpc_security_status grpc_ssl_server_security_connector_create( - grpc_server_credentials* gsc, grpc_server_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_ssl_server_credentials* server_credentials = - reinterpret_cast(gsc); - grpc_security_status retval = GRPC_SECURITY_OK; + if (certificate_config != nullptr) { + grpc_ssl_server_certificate_config_destroy(certificate_config); + } + return status; + } - GPR_ASSERT(server_credentials != nullptr); - GPR_ASSERT(sc != nullptr); - - grpc_ssl_server_security_connector* c = - grpc_ssl_server_security_connector_initialize(gsc); - if (server_connector_has_cert_config_fetcher(c)) { - // Load initial credentials from certificate_config_fetcher: - if (!try_fetch_ssl_server_credentials(c)) { - gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher."); - retval = GRPC_SECURITY_ERROR; + /* Attempts to replace the server_handshaker_factory with a new factory using + * the provided grpc_ssl_server_certificate_config. Should new factory + * creation fail, the existing factory will not be replaced. Returns true on + * success (new factory created). */ + bool try_replace_server_handshaker_factory( + const grpc_ssl_server_certificate_config* config) { + if (config == nullptr) { + gpr_log(GPR_ERROR, + "Server certificate config callback returned invalid (NULL) " + "config."); + return false; } - } else { + gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config); + size_t num_alpn_protocols = 0; const char** alpn_protocol_strings = grpc_fill_alpn_protocol_strings(&num_alpn_protocols); - result = tsi_create_ssl_server_handshaker_factory_ex( - server_credentials->config.pem_key_cert_pairs, - server_credentials->config.num_key_cert_pairs, - server_credentials->config.pem_root_certs, + tsi_ssl_pem_key_cert_pair* cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( + config->pem_key_cert_pairs, config->num_key_cert_pairs); + tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr; + const grpc_ssl_server_credentials* server_creds = + static_cast(this->server_creds()); + GPR_DEBUG_ASSERT(config->pem_root_certs != nullptr); + tsi_result result = tsi_create_ssl_server_handshaker_factory_ex( + cert_pairs, config->num_key_cert_pairs, config->pem_root_certs, grpc_get_tsi_client_certificate_request_type( - server_credentials->config.client_certificate_request), + server_creds->config().client_certificate_request), grpc_get_ssl_cipher_suites(), alpn_protocol_strings, - static_cast(num_alpn_protocols), - &c->server_handshaker_factory); + static_cast(num_alpn_protocols), &new_handshaker_factory); + gpr_free(cert_pairs); gpr_free((void*)alpn_protocol_strings); + if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", tsi_result_to_string(result)); - retval = GRPC_SECURITY_ERROR; + return false; } + set_server_handshaker_factory(new_handshaker_factory); + return true; + } + + void set_server_handshaker_factory( + tsi_ssl_server_handshaker_factory* new_factory) { + if (server_handshaker_factory_) { + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + } + server_handshaker_factory_ = new_factory; + } + + tsi_ssl_server_handshaker_factory* server_handshaker_factory_ = nullptr; +}; +} // namespace + +grpc_core::RefCountedPtr +grpc_ssl_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const grpc_ssl_config* config, const char* target_name, + const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache) { + if (config == nullptr || target_name == nullptr) { + gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); + return nullptr; } - if (retval == GRPC_SECURITY_OK) { - *sc = &c->base; + const char* pem_root_certs; + const tsi_ssl_root_certs_store* root_store; + if (config->pem_root_certs == nullptr) { + // Use default root certificates. + pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); + if (pem_root_certs == nullptr) { + gpr_log(GPR_ERROR, "Could not get default pem root certs."); + return nullptr; + } + root_store = grpc_core::DefaultSslRootStore::GetRootStore(); } else { - if (c != nullptr) ssl_server_destroy(&c->base.base); - if (sc != nullptr) *sc = nullptr; + pem_root_certs = config->pem_root_certs; + root_store = nullptr; + } + + grpc_core::RefCountedPtr c = + grpc_core::MakeRefCounted( + std::move(channel_creds), std::move(request_metadata_creds), config, + target_name, overridden_target_name); + const grpc_security_status result = c->InitializeHandshakerFactory( + config, pem_root_certs, root_store, ssl_session_cache); + if (result != GRPC_SECURITY_OK) { + return nullptr; } - return retval; + return c; +} + +grpc_core::RefCountedPtr +grpc_ssl_server_security_connector_create( + grpc_core::RefCountedPtr server_credentials) { + GPR_ASSERT(server_credentials != nullptr); + grpc_core::RefCountedPtr c = + grpc_core::MakeRefCounted( + std::move(server_credentials)); + const grpc_security_status retval = c->InitializeHandshakerFactory(); + if (retval != GRPC_SECURITY_OK) { + return nullptr; + } + return c; } diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.h b/src/core/lib/security/security_connector/ssl/ssl_security_connector.h index 9b805906061..70e26e338aa 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.h +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.h @@ -25,6 +25,7 @@ #include "src/core/lib/security/security_connector/security_connector.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security_interface.h" @@ -47,20 +48,21 @@ typedef struct { This function returns GRPC_SECURITY_OK in case of success or a specific error code otherwise. */ -grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, +grpc_core::RefCountedPtr +grpc_ssl_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, const grpc_ssl_config* config, const char* target_name, const char* overridden_target_name, - tsi_ssl_session_cache* ssl_session_cache, - grpc_channel_security_connector** sc); + tsi_ssl_session_cache* ssl_session_cache); /* Config for ssl servers. */ typedef struct { - tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs; - size_t num_key_cert_pairs; - char* pem_root_certs; - grpc_ssl_client_certificate_request_type client_certificate_request; + tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = nullptr; + size_t num_key_cert_pairs = 0; + char* pem_root_certs = nullptr; + grpc_ssl_client_certificate_request_type client_certificate_request = + GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE; } grpc_ssl_server_config; /* Creates an SSL server_security_connector. @@ -69,9 +71,9 @@ typedef struct { This function returns GRPC_SECURITY_OK in case of success or a specific error code otherwise. */ -grpc_security_status grpc_ssl_server_security_connector_create( - grpc_server_credentials* server_credentials, - grpc_server_security_connector** sc); +grpc_core::RefCountedPtr +grpc_ssl_server_security_connector_create( + grpc_core::RefCountedPtr server_credentials); #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_SSL_SECURITY_CONNECTOR_H \ */ diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index fbf41cfbc7c..29030f07ad6 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -30,6 +30,7 @@ #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/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/security_connector/load_system_roots.h" @@ -141,16 +142,17 @@ int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) { return r; } -grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) { +grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( + const tsi_peer* peer) { size_t i; - grpc_auth_context* ctx = nullptr; const char* peer_identity_property_name = nullptr; /* The caller has checked the certificate type property. */ GPR_ASSERT(peer->property_count >= 1); - ctx = grpc_auth_context_create(nullptr); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); grpc_auth_context_add_cstring_property( - ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_SSL_TRANSPORT_SECURITY_TYPE); for (i = 0; i < peer->property_count; i++) { const tsi_peer_property* prop = &peer->properties[i]; @@ -160,24 +162,26 @@ grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) { if (peer_identity_property_name == nullptr) { peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME; } - grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME, + grpc_auth_context_add_property(ctx.get(), GRPC_X509_CN_PROPERTY_NAME, prop->value.data, prop->value.length); } else if (strcmp(prop->name, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME; - grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME, + grpc_auth_context_add_property(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, prop->value.data, prop->value.length); } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) { - grpc_auth_context_add_property(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME, + grpc_auth_context_add_property(ctx.get(), + GRPC_X509_PEM_CERT_PROPERTY_NAME, prop->value.data, prop->value.length); } else if (strcmp(prop->name, TSI_SSL_SESSION_REUSED_PEER_PROPERTY) == 0) { - grpc_auth_context_add_property(ctx, GRPC_SSL_SESSION_REUSED_PROPERTY, + grpc_auth_context_add_property(ctx.get(), + GRPC_SSL_SESSION_REUSED_PROPERTY, prop->value.data, prop->value.length); } } if (peer_identity_property_name != nullptr) { GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( - ctx, peer_identity_property_name) == 1); + ctx.get(), peer_identity_property_name) == 1); } return ctx; } diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index 6f6d473311b..c9cd1a1d9c5 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -26,6 +26,7 @@ #include #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security_interface.h" @@ -47,7 +48,8 @@ grpc_get_tsi_client_certificate_request_type( const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols); /* Exposed for testing only. */ -grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer); +grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( + const tsi_peer* peer); tsi_peer grpc_shallow_peer_from_ssl_auth_context( const grpc_auth_context* auth_context); void grpc_shallow_peer_destruct(tsi_peer* peer); diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 6955e8698e2..66f86b8bc52 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -55,7 +55,7 @@ struct call_data { // that the memory is not initialized. void destroy() { grpc_credentials_mdelem_array_destroy(&md_array); - grpc_call_credentials_unref(creds); + creds.reset(); grpc_slice_unref_internal(host); grpc_slice_unref_internal(method); grpc_auth_metadata_context_reset(&auth_md_context); @@ -64,7 +64,7 @@ struct call_data { gpr_arena* arena; grpc_call_stack* owning_call; grpc_call_combiner* call_combiner; - grpc_call_credentials* creds = nullptr; + grpc_core::RefCountedPtr creds; grpc_slice host = grpc_empty_slice(); grpc_slice method = grpc_empty_slice(); /* pollset{_set} bound to this call; if we need to make external @@ -83,8 +83,18 @@ struct call_data { /* We can have a per-channel credentials. */ struct channel_data { - grpc_channel_security_connector* security_connector; - grpc_auth_context* auth_context; + channel_data(grpc_channel_security_connector* security_connector, + grpc_auth_context* auth_context) + : security_connector( + security_connector->Ref(DEBUG_LOCATION, "client_auth_filter")), + auth_context(auth_context->Ref(DEBUG_LOCATION, "client_auth_filter")) {} + ~channel_data() { + security_connector.reset(DEBUG_LOCATION, "client_auth_filter"); + auth_context.reset(DEBUG_LOCATION, "client_auth_filter"); + } + + grpc_core::RefCountedPtr security_connector; + grpc_core::RefCountedPtr auth_context; }; } // namespace @@ -98,10 +108,11 @@ void grpc_auth_metadata_context_reset( gpr_free(const_cast(auth_md_context->method_name)); auth_md_context->method_name = nullptr; } - GRPC_AUTH_CONTEXT_UNREF( - (grpc_auth_context*)auth_md_context->channel_auth_context, - "grpc_auth_metadata_context"); - auth_md_context->channel_auth_context = nullptr; + if (auth_md_context->channel_auth_context != nullptr) { + const_cast(auth_md_context->channel_auth_context) + ->Unref(DEBUG_LOCATION, "grpc_auth_metadata_context"); + auth_md_context->channel_auth_context = nullptr; + } } static void add_error(grpc_error** combined, grpc_error* error) { @@ -175,7 +186,10 @@ void grpc_auth_metadata_context_build( auth_md_context->service_url = service_url; auth_md_context->method_name = method_name; auth_md_context->channel_auth_context = - GRPC_AUTH_CONTEXT_REF(auth_context, "grpc_auth_metadata_context"); + auth_context == nullptr + ? nullptr + : auth_context->Ref(DEBUG_LOCATION, "grpc_auth_metadata_context") + .release(); gpr_free(service); gpr_free(host_and_port); } @@ -184,8 +198,8 @@ static void cancel_get_request_metadata(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); call_data* calld = static_cast(elem->call_data); if (error != GRPC_ERROR_NONE) { - grpc_call_credentials_cancel_get_request_metadata( - calld->creds, &calld->md_array, GRPC_ERROR_REF(error)); + calld->creds->cancel_get_request_metadata(&calld->md_array, + GRPC_ERROR_REF(error)); } } @@ -197,7 +211,7 @@ static void send_security_metadata(grpc_call_element* elem, static_cast( batch->payload->context[GRPC_CONTEXT_SECURITY].value); grpc_call_credentials* channel_call_creds = - chand->security_connector->request_metadata_creds; + chand->security_connector->mutable_request_metadata_creds(); int call_creds_has_md = (ctx != nullptr) && (ctx->creds != nullptr); if (channel_call_creds == nullptr && !call_creds_has_md) { @@ -207,8 +221,9 @@ static void send_security_metadata(grpc_call_element* elem, } if (channel_call_creds != nullptr && call_creds_has_md) { - calld->creds = grpc_composite_call_credentials_create(channel_call_creds, - ctx->creds, nullptr); + calld->creds = grpc_core::RefCountedPtr( + grpc_composite_call_credentials_create(channel_call_creds, + ctx->creds.get(), nullptr)); if (calld->creds == nullptr) { grpc_transport_stream_op_batch_finish_with_failure( batch, @@ -220,22 +235,22 @@ static void send_security_metadata(grpc_call_element* elem, return; } } else { - calld->creds = grpc_call_credentials_ref( - call_creds_has_md ? ctx->creds : channel_call_creds); + calld->creds = + call_creds_has_md ? ctx->creds->Ref() : channel_call_creds->Ref(); } grpc_auth_metadata_context_build( - chand->security_connector->base.url_scheme, calld->host, calld->method, - chand->auth_context, &calld->auth_md_context); + chand->security_connector->url_scheme(), calld->host, calld->method, + chand->auth_context.get(), &calld->auth_md_context); GPR_ASSERT(calld->pollent != nullptr); GRPC_CALL_STACK_REF(calld->owning_call, "get_request_metadata"); GRPC_CLOSURE_INIT(&calld->async_result_closure, on_credentials_metadata, batch, grpc_schedule_on_exec_ctx); grpc_error* error = GRPC_ERROR_NONE; - if (grpc_call_credentials_get_request_metadata( - calld->creds, calld->pollent, calld->auth_md_context, - &calld->md_array, &calld->async_result_closure, &error)) { + if (calld->creds->get_request_metadata( + calld->pollent, calld->auth_md_context, &calld->md_array, + &calld->async_result_closure, &error)) { // Synchronous return; invoke on_credentials_metadata() directly. on_credentials_metadata(batch, error); GRPC_ERROR_UNREF(error); @@ -279,9 +294,8 @@ static void cancel_check_call_host(void* arg, grpc_error* error) { call_data* calld = static_cast(elem->call_data); channel_data* chand = static_cast(elem->channel_data); if (error != GRPC_ERROR_NONE) { - grpc_channel_security_connector_cancel_check_call_host( - chand->security_connector, &calld->async_result_closure, - GRPC_ERROR_REF(error)); + chand->security_connector->cancel_check_call_host( + &calld->async_result_closure, GRPC_ERROR_REF(error)); } } @@ -299,16 +313,16 @@ static void auth_start_transport_stream_op_batch( GPR_ASSERT(batch->payload->context != nullptr); if (batch->payload->context[GRPC_CONTEXT_SECURITY].value == nullptr) { batch->payload->context[GRPC_CONTEXT_SECURITY].value = - grpc_client_security_context_create(calld->arena); + grpc_client_security_context_create(calld->arena, /*creds=*/nullptr); batch->payload->context[GRPC_CONTEXT_SECURITY].destroy = grpc_client_security_context_destroy; } grpc_client_security_context* sec_ctx = static_cast( batch->payload->context[GRPC_CONTEXT_SECURITY].value); - GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter"); + sec_ctx->auth_context.reset(DEBUG_LOCATION, "client_auth_filter"); sec_ctx->auth_context = - GRPC_AUTH_CONTEXT_REF(chand->auth_context, "client_auth_filter"); + chand->auth_context->Ref(DEBUG_LOCATION, "client_auth_filter"); } if (batch->send_initial_metadata) { @@ -327,8 +341,8 @@ static void auth_start_transport_stream_op_batch( grpc_schedule_on_exec_ctx); char* call_host = grpc_slice_to_c_string(calld->host); grpc_error* error = GRPC_ERROR_NONE; - if (grpc_channel_security_connector_check_call_host( - chand->security_connector, call_host, chand->auth_context, + if (chand->security_connector->check_call_host( + call_host, chand->auth_context.get(), &calld->async_result_closure, &error)) { // Synchronous return; invoke on_host_checked() directly. on_host_checked(batch, error); @@ -374,6 +388,10 @@ static void destroy_call_elem(grpc_call_element* elem, /* Constructor for channel_data */ static grpc_error* init_channel_elem(grpc_channel_element* elem, grpc_channel_element_args* args) { + /* The first and the last filters tend to be implemented differently to + handle the case that there's no 'next' filter to call on the up or down + path */ + GPR_ASSERT(!args->is_last); grpc_security_connector* sc = grpc_security_connector_find_in_args(args->channel_args); if (sc == nullptr) { @@ -386,33 +404,15 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Auth context missing from client auth filter args"); } - - /* grab pointers to our data from the channel element */ - channel_data* chand = static_cast(elem->channel_data); - - /* The first and the last filters tend to be implemented differently to - handle the case that there's no 'next' filter to call on the up or down - path */ - GPR_ASSERT(!args->is_last); - - /* initialize members */ - chand->security_connector = - reinterpret_cast( - GRPC_SECURITY_CONNECTOR_REF(sc, "client_auth_filter")); - chand->auth_context = - GRPC_AUTH_CONTEXT_REF(auth_context, "client_auth_filter"); + new (elem->channel_data) channel_data( + static_cast(sc), auth_context); return GRPC_ERROR_NONE; } /* Destructor for channel data */ static void destroy_channel_elem(grpc_channel_element* elem) { - /* grab pointers to our data from the channel element */ channel_data* chand = static_cast(elem->channel_data); - grpc_channel_security_connector* sc = chand->security_connector; - if (sc != nullptr) { - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "client_auth_filter"); - } - GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter"); + chand->~channel_data(); } const grpc_channel_filter grpc_client_auth_filter = { diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index 854a1c4af97..48d6901e883 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/handshaker_registry.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/transport/secure_endpoint.h" #include "src/core/lib/security/transport/tsi_error.h" @@ -38,34 +39,62 @@ #define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256 -typedef struct { +namespace { +struct security_handshaker { + security_handshaker(tsi_handshaker* handshaker, + grpc_security_connector* connector); + ~security_handshaker() { + gpr_mu_destroy(&mu); + tsi_handshaker_destroy(handshaker); + tsi_handshaker_result_destroy(handshaker_result); + if (endpoint_to_destroy != nullptr) { + grpc_endpoint_destroy(endpoint_to_destroy); + } + if (read_buffer_to_destroy != nullptr) { + grpc_slice_buffer_destroy_internal(read_buffer_to_destroy); + gpr_free(read_buffer_to_destroy); + } + gpr_free(handshake_buffer); + grpc_slice_buffer_destroy_internal(&outgoing); + auth_context.reset(DEBUG_LOCATION, "handshake"); + connector.reset(DEBUG_LOCATION, "handshake"); + } + + void Ref() { refs.Ref(); } + void Unref() { + if (refs.Unref()) { + grpc_core::Delete(this); + } + } + grpc_handshaker base; // State set at creation time. tsi_handshaker* handshaker; - grpc_security_connector* connector; + grpc_core::RefCountedPtr connector; gpr_mu mu; - gpr_refcount refs; + grpc_core::RefCount refs; - bool shutdown; + bool shutdown = false; // Endpoint and read buffer to destroy after a shutdown. - grpc_endpoint* endpoint_to_destroy; - grpc_slice_buffer* read_buffer_to_destroy; + grpc_endpoint* endpoint_to_destroy = nullptr; + grpc_slice_buffer* read_buffer_to_destroy = nullptr; // State saved while performing the handshake. - grpc_handshaker_args* args; - grpc_closure* on_handshake_done; + grpc_handshaker_args* args = nullptr; + grpc_closure* on_handshake_done = nullptr; - unsigned char* handshake_buffer; size_t handshake_buffer_size; + unsigned char* handshake_buffer; grpc_slice_buffer outgoing; grpc_closure on_handshake_data_sent_to_peer; grpc_closure on_handshake_data_received_from_peer; grpc_closure on_peer_checked; - grpc_auth_context* auth_context; - tsi_handshaker_result* handshaker_result; -} security_handshaker; + grpc_core::RefCountedPtr auth_context; + tsi_handshaker_result* handshaker_result = nullptr; +}; +} // namespace static size_t move_read_buffer_into_handshake_buffer(security_handshaker* h) { size_t bytes_in_read_buffer = h->args->read_buffer->length; @@ -85,26 +114,6 @@ static size_t move_read_buffer_into_handshake_buffer(security_handshaker* h) { return bytes_in_read_buffer; } -static void security_handshaker_unref(security_handshaker* h) { - if (gpr_unref(&h->refs)) { - gpr_mu_destroy(&h->mu); - tsi_handshaker_destroy(h->handshaker); - tsi_handshaker_result_destroy(h->handshaker_result); - if (h->endpoint_to_destroy != nullptr) { - grpc_endpoint_destroy(h->endpoint_to_destroy); - } - if (h->read_buffer_to_destroy != nullptr) { - grpc_slice_buffer_destroy_internal(h->read_buffer_to_destroy); - gpr_free(h->read_buffer_to_destroy); - } - gpr_free(h->handshake_buffer); - grpc_slice_buffer_destroy_internal(&h->outgoing); - GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake"); - GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake"); - gpr_free(h); - } -} - // Set args fields to NULL, saving the endpoint and read buffer for // later destruction. static void cleanup_args_for_failure_locked(security_handshaker* h) { @@ -194,7 +203,7 @@ static void on_peer_checked_inner(security_handshaker* h, grpc_error* error) { tsi_handshaker_result_destroy(h->handshaker_result); h->handshaker_result = nullptr; // Add auth context to channel args. - grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context); + grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context.get()); grpc_channel_args* tmp_args = h->args->args; h->args->args = grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1); @@ -211,7 +220,7 @@ static void on_peer_checked(void* arg, grpc_error* error) { gpr_mu_lock(&h->mu); on_peer_checked_inner(h, error); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); } static grpc_error* check_peer_locked(security_handshaker* h) { @@ -222,8 +231,7 @@ static grpc_error* check_peer_locked(security_handshaker* h) { return grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Peer extraction failed"), result); } - grpc_security_connector_check_peer(h->connector, peer, &h->auth_context, - &h->on_peer_checked); + h->connector->check_peer(peer, &h->auth_context, &h->on_peer_checked); return GRPC_ERROR_NONE; } @@ -281,7 +289,7 @@ static void on_handshake_next_done_grpc_wrapper( if (error != GRPC_ERROR_NONE) { security_handshake_failed_locked(h, error); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); } else { gpr_mu_unlock(&h->mu); } @@ -317,7 +325,7 @@ static void on_handshake_data_received_from_peer(void* arg, grpc_error* error) { h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Handshake read failed", &error, 1)); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); return; } // Copy all slices received. @@ -329,7 +337,7 @@ static void on_handshake_data_received_from_peer(void* arg, grpc_error* error) { if (error != GRPC_ERROR_NONE) { security_handshake_failed_locked(h, error); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); } else { gpr_mu_unlock(&h->mu); } @@ -343,7 +351,7 @@ static void on_handshake_data_sent_to_peer(void* arg, grpc_error* error) { h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Handshake write failed", &error, 1)); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); return; } // We may be done. @@ -355,7 +363,7 @@ static void on_handshake_data_sent_to_peer(void* arg, grpc_error* error) { if (error != GRPC_ERROR_NONE) { security_handshake_failed_locked(h, error); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); return; } } @@ -368,7 +376,7 @@ static void on_handshake_data_sent_to_peer(void* arg, grpc_error* error) { static void security_handshaker_destroy(grpc_handshaker* handshaker) { security_handshaker* h = reinterpret_cast(handshaker); - security_handshaker_unref(h); + h->Unref(); } static void security_handshaker_shutdown(grpc_handshaker* handshaker, @@ -393,14 +401,14 @@ static void security_handshaker_do_handshake(grpc_handshaker* handshaker, gpr_mu_lock(&h->mu); h->args = args; h->on_handshake_done = on_handshake_done; - gpr_ref(&h->refs); + h->Ref(); size_t bytes_received_size = move_read_buffer_into_handshake_buffer(h); grpc_error* error = do_handshaker_next_locked(h, h->handshake_buffer, bytes_received_size); if (error != GRPC_ERROR_NONE) { security_handshake_failed_locked(h, error); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); return; } gpr_mu_unlock(&h->mu); @@ -410,27 +418,32 @@ static const grpc_handshaker_vtable security_handshaker_vtable = { security_handshaker_destroy, security_handshaker_shutdown, security_handshaker_do_handshake, "security"}; -static grpc_handshaker* security_handshaker_create( - tsi_handshaker* handshaker, grpc_security_connector* connector) { - security_handshaker* h = static_cast( - gpr_zalloc(sizeof(security_handshaker))); - grpc_handshaker_init(&security_handshaker_vtable, &h->base); - h->handshaker = handshaker; - h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake"); - gpr_mu_init(&h->mu); - gpr_ref_init(&h->refs, 1); - h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE; - h->handshake_buffer = - static_cast(gpr_malloc(h->handshake_buffer_size)); - GRPC_CLOSURE_INIT(&h->on_handshake_data_sent_to_peer, - on_handshake_data_sent_to_peer, h, +namespace { +security_handshaker::security_handshaker(tsi_handshaker* handshaker, + grpc_security_connector* connector) + : handshaker(handshaker), + connector(connector->Ref(DEBUG_LOCATION, "handshake")), + handshake_buffer_size(GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE), + handshake_buffer( + static_cast(gpr_malloc(handshake_buffer_size))) { + grpc_handshaker_init(&security_handshaker_vtable, &base); + gpr_mu_init(&mu); + grpc_slice_buffer_init(&outgoing); + GRPC_CLOSURE_INIT(&on_handshake_data_sent_to_peer, + ::on_handshake_data_sent_to_peer, this, grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&h->on_handshake_data_received_from_peer, - on_handshake_data_received_from_peer, h, + GRPC_CLOSURE_INIT(&on_handshake_data_received_from_peer, + ::on_handshake_data_received_from_peer, this, grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&h->on_peer_checked, on_peer_checked, h, + GRPC_CLOSURE_INIT(&on_peer_checked, ::on_peer_checked, this, grpc_schedule_on_exec_ctx); - grpc_slice_buffer_init(&h->outgoing); +} +} // namespace + +static grpc_handshaker* security_handshaker_create( + tsi_handshaker* handshaker, grpc_security_connector* connector) { + security_handshaker* h = + grpc_core::New(handshaker, connector); return &h->base; } @@ -477,8 +490,9 @@ static void client_handshaker_factory_add_handshakers( grpc_channel_security_connector* security_connector = reinterpret_cast( grpc_security_connector_find_in_args(args)); - grpc_channel_security_connector_add_handshakers( - security_connector, interested_parties, handshake_mgr); + if (security_connector) { + security_connector->add_handshakers(interested_parties, handshake_mgr); + } } static void server_handshaker_factory_add_handshakers( @@ -488,8 +502,9 @@ static void server_handshaker_factory_add_handshakers( grpc_server_security_connector* security_connector = reinterpret_cast( grpc_security_connector_find_in_args(args)); - grpc_server_security_connector_add_handshakers( - security_connector, interested_parties, handshake_mgr); + if (security_connector) { + security_connector->add_handshakers(interested_parties, handshake_mgr); + } } static void handshaker_factory_destroy( diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc index 362f49a5843..f93eb4275e3 100644 --- a/src/core/lib/security/transport/server_auth_filter.cc +++ b/src/core/lib/security/transport/server_auth_filter.cc @@ -39,8 +39,12 @@ enum async_state { }; struct channel_data { - grpc_auth_context* auth_context; - grpc_server_credentials* creds; + channel_data(grpc_auth_context* auth_context, grpc_server_credentials* creds) + : auth_context(auth_context->Ref()), creds(creds->Ref()) {} + ~channel_data() { auth_context.reset(DEBUG_LOCATION, "server_auth_filter"); } + + grpc_core::RefCountedPtr auth_context; + grpc_core::RefCountedPtr creds; }; struct call_data { @@ -58,7 +62,7 @@ struct call_data { grpc_server_security_context_create(args.arena); channel_data* chand = static_cast(elem->channel_data); server_ctx->auth_context = - GRPC_AUTH_CONTEXT_REF(chand->auth_context, "server_auth_filter"); + chand->auth_context->Ref(DEBUG_LOCATION, "server_auth_filter"); if (args.context[GRPC_CONTEXT_SECURITY].value != nullptr) { args.context[GRPC_CONTEXT_SECURITY].destroy( args.context[GRPC_CONTEXT_SECURITY].value); @@ -208,7 +212,8 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { call_data* calld = static_cast(elem->call_data); grpc_transport_stream_op_batch* batch = calld->recv_initial_metadata_batch; if (error == GRPC_ERROR_NONE) { - if (chand->creds != nullptr && chand->creds->processor.process != nullptr) { + if (chand->creds != nullptr && + chand->creds->auth_metadata_processor().process != nullptr) { // We're calling out to the application, so we need to make sure // to drop the call combiner early if we get cancelled. GRPC_CLOSURE_INIT(&calld->cancel_closure, cancel_call, elem, @@ -218,9 +223,10 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { GRPC_CALL_STACK_REF(calld->owning_call, "server_auth_metadata"); calld->md = metadata_batch_to_md_array( batch->payload->recv_initial_metadata.recv_initial_metadata); - chand->creds->processor.process( - chand->creds->processor.state, chand->auth_context, - calld->md.metadata, calld->md.count, on_md_processing_done, elem); + chand->creds->auth_metadata_processor().process( + chand->creds->auth_metadata_processor().state, + chand->auth_context.get(), calld->md.metadata, calld->md.count, + on_md_processing_done, elem); return; } } @@ -290,23 +296,19 @@ static void destroy_call_elem(grpc_call_element* elem, static grpc_error* init_channel_elem(grpc_channel_element* elem, grpc_channel_element_args* args) { GPR_ASSERT(!args->is_last); - channel_data* chand = static_cast(elem->channel_data); grpc_auth_context* auth_context = grpc_find_auth_context_in_args(args->channel_args); GPR_ASSERT(auth_context != nullptr); - chand->auth_context = - GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter"); grpc_server_credentials* creds = grpc_find_server_credentials_in_args(args->channel_args); - chand->creds = grpc_server_credentials_ref(creds); + new (elem->channel_data) channel_data(auth_context, creds); return GRPC_ERROR_NONE; } /* Destructor for channel data */ static void destroy_channel_elem(grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); - GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter"); - grpc_server_credentials_unref(chand->creds); + chand->~channel_data(); } const grpc_channel_filter grpc_server_auth_filter = { diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index d0abe441a6a..4d0ed355aba 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -261,10 +261,10 @@ void MetadataCredentialsPluginWrapper::InvokePlugin( grpc_status_code* status_code, const char** error_details) { std::multimap metadata; - // const_cast is safe since the SecureAuthContext does not take owndership and - // the object is passed as a const ref to plugin_->GetMetadata. + // const_cast is safe since the SecureAuthContext only inc/dec the refcount + // and the object is passed as a const ref to plugin_->GetMetadata. SecureAuthContext cpp_channel_auth_context( - const_cast(context.channel_auth_context), false); + const_cast(context.channel_auth_context)); Status status = plugin_->GetMetadata(context.service_url, context.method_name, cpp_channel_auth_context, &metadata); diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 613f1d6dc2c..4918bd5a4d7 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -24,6 +24,7 @@ #include #include +#include "src/core/lib/security/credentials/credentials.h" #include "src/cpp/server/thread_pool_interface.h" namespace grpc { @@ -31,7 +32,9 @@ namespace grpc { class SecureChannelCredentials final : public ChannelCredentials { public: explicit SecureChannelCredentials(grpc_channel_credentials* c_creds); - ~SecureChannelCredentials() { grpc_channel_credentials_release(c_creds_); } + ~SecureChannelCredentials() { + if (c_creds_ != nullptr) c_creds_->Unref(); + } grpc_channel_credentials* GetRawCreds() { return c_creds_; } std::shared_ptr CreateChannel( @@ -51,7 +54,9 @@ class SecureChannelCredentials final : public ChannelCredentials { class SecureCallCredentials final : public CallCredentials { public: explicit SecureCallCredentials(grpc_call_credentials* c_creds); - ~SecureCallCredentials() { grpc_call_credentials_release(c_creds_); } + ~SecureCallCredentials() { + if (c_creds_ != nullptr) c_creds_->Unref(); + } grpc_call_credentials* GetRawCreds() { return c_creds_; } bool ApplyToCall(grpc_call* call) override; diff --git a/src/cpp/common/secure_auth_context.cc b/src/cpp/common/secure_auth_context.cc index 1d66dd3d1f1..7a2b5afed69 100644 --- a/src/cpp/common/secure_auth_context.cc +++ b/src/cpp/common/secure_auth_context.cc @@ -22,19 +22,12 @@ namespace grpc { -SecureAuthContext::SecureAuthContext(grpc_auth_context* ctx, - bool take_ownership) - : ctx_(ctx), take_ownership_(take_ownership) {} - -SecureAuthContext::~SecureAuthContext() { - if (take_ownership_) grpc_auth_context_release(ctx_); -} - std::vector SecureAuthContext::GetPeerIdentity() const { - if (!ctx_) { + if (ctx_ == nullptr) { return std::vector(); } - grpc_auth_property_iterator iter = grpc_auth_context_peer_identity(ctx_); + grpc_auth_property_iterator iter = + grpc_auth_context_peer_identity(ctx_.get()); std::vector identity; const grpc_auth_property* property = nullptr; while ((property = grpc_auth_property_iterator_next(&iter))) { @@ -45,20 +38,20 @@ std::vector SecureAuthContext::GetPeerIdentity() const { } grpc::string SecureAuthContext::GetPeerIdentityPropertyName() const { - if (!ctx_) { + if (ctx_ == nullptr) { return ""; } - const char* name = grpc_auth_context_peer_identity_property_name(ctx_); + const char* name = grpc_auth_context_peer_identity_property_name(ctx_.get()); return name == nullptr ? "" : name; } std::vector SecureAuthContext::FindPropertyValues( const grpc::string& name) const { - if (!ctx_) { + if (ctx_ == nullptr) { return std::vector(); } grpc_auth_property_iterator iter = - grpc_auth_context_find_properties_by_name(ctx_, name.c_str()); + grpc_auth_context_find_properties_by_name(ctx_.get(), name.c_str()); const grpc_auth_property* property = nullptr; std::vector values; while ((property = grpc_auth_property_iterator_next(&iter))) { @@ -68,9 +61,9 @@ std::vector SecureAuthContext::FindPropertyValues( } AuthPropertyIterator SecureAuthContext::begin() const { - if (ctx_) { + if (ctx_ != nullptr) { grpc_auth_property_iterator iter = - grpc_auth_context_property_iterator(ctx_); + grpc_auth_context_property_iterator(ctx_.get()); const grpc_auth_property* property = grpc_auth_property_iterator_next(&iter); return AuthPropertyIterator(property, &iter); @@ -85,19 +78,20 @@ AuthPropertyIterator SecureAuthContext::end() const { void SecureAuthContext::AddProperty(const grpc::string& key, const grpc::string_ref& value) { - if (!ctx_) return; - grpc_auth_context_add_property(ctx_, key.c_str(), value.data(), value.size()); + if (ctx_ == nullptr) return; + grpc_auth_context_add_property(ctx_.get(), key.c_str(), value.data(), + value.size()); } bool SecureAuthContext::SetPeerIdentityPropertyName(const grpc::string& name) { - if (!ctx_) return false; - return grpc_auth_context_set_peer_identity_property_name(ctx_, + if (ctx_ == nullptr) return false; + return grpc_auth_context_set_peer_identity_property_name(ctx_.get(), name.c_str()) != 0; } bool SecureAuthContext::IsPeerAuthenticated() const { - if (!ctx_) return false; - return grpc_auth_context_peer_is_authenticated(ctx_) != 0; + if (ctx_ == nullptr) return false; + return grpc_auth_context_peer_is_authenticated(ctx_.get()) != 0; } } // namespace grpc diff --git a/src/cpp/common/secure_auth_context.h b/src/cpp/common/secure_auth_context.h index 142617959cb..2e8f7937211 100644 --- a/src/cpp/common/secure_auth_context.h +++ b/src/cpp/common/secure_auth_context.h @@ -21,15 +21,17 @@ #include -struct grpc_auth_context; +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/security/context/security_context.h" namespace grpc { class SecureAuthContext final : public AuthContext { public: - SecureAuthContext(grpc_auth_context* ctx, bool take_ownership); + explicit SecureAuthContext(grpc_auth_context* ctx) + : ctx_(ctx != nullptr ? ctx->Ref() : nullptr) {} - ~SecureAuthContext() override; + ~SecureAuthContext() override = default; bool IsPeerAuthenticated() const override; @@ -50,8 +52,7 @@ class SecureAuthContext final : public AuthContext { virtual bool SetPeerIdentityPropertyName(const grpc::string& name) override; private: - grpc_auth_context* ctx_; - bool take_ownership_; + grpc_core::RefCountedPtr ctx_; }; } // namespace grpc diff --git a/src/cpp/common/secure_create_auth_context.cc b/src/cpp/common/secure_create_auth_context.cc index bc1387c8d75..908c46629e6 100644 --- a/src/cpp/common/secure_create_auth_context.cc +++ b/src/cpp/common/secure_create_auth_context.cc @@ -20,6 +20,7 @@ #include #include #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/cpp/common/secure_auth_context.h" namespace grpc { @@ -28,8 +29,8 @@ std::shared_ptr CreateAuthContext(grpc_call* call) { if (call == nullptr) { return std::shared_ptr(); } - return std::shared_ptr( - new SecureAuthContext(grpc_call_auth_context(call), true)); + grpc_core::RefCountedPtr ctx(grpc_call_auth_context(call)); + return std::make_shared(ctx.get()); } } // namespace grpc diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index ebb17def32b..453e76eb25d 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -61,7 +61,7 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor( metadata.insert(std::make_pair(StringRefFromSlice(&md[i].key), StringRefFromSlice(&md[i].value))); } - SecureAuthContext context(ctx, false); + SecureAuthContext context(ctx); AuthMetadataProcessor::OutputMetadata consumed_metadata; AuthMetadataProcessor::OutputMetadata response_metadata; diff --git a/test/core/security/alts_security_connector_test.cc b/test/core/security/alts_security_connector_test.cc index 9378236338d..bcba3408216 100644 --- a/test/core/security/alts_security_connector_test.cc +++ b/test/core/security/alts_security_connector_test.cc @@ -33,40 +33,34 @@ using grpc_core::internal::grpc_alts_auth_context_from_tsi_peer; /* This file contains unit tests of grpc_alts_auth_context_from_tsi_peer(). */ static void test_invalid_input_failure() { - tsi_peer peer; - grpc_auth_context* ctx; - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(nullptr, &ctx) == - GRPC_SECURITY_ERROR); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, nullptr) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(nullptr); + GPR_ASSERT(ctx == nullptr); } static void test_empty_certificate_type_failure() { tsi_peer peer; - grpc_auth_context* ctx = nullptr; GPR_ASSERT(tsi_construct_peer(0, &peer) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); GPR_ASSERT(ctx == nullptr); tsi_peer_destruct(&peer); } static void test_empty_peer_property_failure() { tsi_peer peer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, &peer.properties[0]) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); GPR_ASSERT(ctx == nullptr); tsi_peer_destruct(&peer); } static void test_missing_rpc_protocol_versions_property_failure() { tsi_peer peer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, @@ -74,23 +68,22 @@ static void test_missing_rpc_protocol_versions_property_failure() { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, "alice", &peer.properties[1]) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); GPR_ASSERT(ctx == nullptr); tsi_peer_destruct(&peer); } static void test_unknown_peer_property_failure() { tsi_peer peer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, &peer.properties[0]) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( "unknown", "alice", &peer.properties[1]) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); GPR_ASSERT(ctx == nullptr); tsi_peer_destruct(&peer); } @@ -119,7 +112,6 @@ static bool test_identity(const grpc_auth_context* ctx, static void test_alts_peer_to_auth_context_success() { tsi_peer peer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, @@ -144,11 +136,12 @@ static void test_alts_peer_to_auth_context_success() { GRPC_SLICE_START_PTR(serialized_peer_versions)), GRPC_SLICE_LENGTH(serialized_peer_versions), &peer.properties[2]) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_OK); - GPR_ASSERT( - test_identity(ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, "alice")); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); + GPR_ASSERT(ctx != nullptr); + GPR_ASSERT(test_identity(ctx.get(), TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, + "alice")); + ctx.reset(DEBUG_LOCATION, "test"); grpc_slice_unref(serialized_peer_versions); tsi_peer_destruct(&peer); } diff --git a/test/core/security/auth_context_test.cc b/test/core/security/auth_context_test.cc index 9a39afb8006..e7e0cb2ed94 100644 --- a/test/core/security/auth_context_test.cc +++ b/test/core/security/auth_context_test.cc @@ -19,114 +19,122 @@ #include #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "test/core/util/test_config.h" #include static void test_empty_context(void) { - grpc_auth_context* ctx = grpc_auth_context_create(nullptr); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); grpc_auth_property_iterator it; gpr_log(GPR_INFO, "test_empty_context"); GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == nullptr); - it = grpc_auth_context_peer_identity(ctx); + GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx.get()) == + nullptr); + it = grpc_auth_context_peer_identity(ctx.get()); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_property_iterator(ctx); + it = grpc_auth_context_property_iterator(ctx.get()); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_find_properties_by_name(ctx, "foo"); + it = grpc_auth_context_find_properties_by_name(ctx.get(), "foo"); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "bar") == - 0); - GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == nullptr); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + GPR_ASSERT( + grpc_auth_context_set_peer_identity_property_name(ctx.get(), "bar") == 0); + GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx.get()) == + nullptr); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_simple_context(void) { - grpc_auth_context* ctx = grpc_auth_context_create(nullptr); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); grpc_auth_property_iterator it; size_t i; gpr_log(GPR_INFO, "test_simple_context"); GPR_ASSERT(ctx != nullptr); - grpc_auth_context_add_cstring_property(ctx, "name", "chapi"); - grpc_auth_context_add_cstring_property(ctx, "name", "chapo"); - grpc_auth_context_add_cstring_property(ctx, "foo", "bar"); - GPR_ASSERT(ctx->properties.count == 3); - GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "name") == - 1); - - GPR_ASSERT( - strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0); - it = grpc_auth_context_property_iterator(ctx); - for (i = 0; i < ctx->properties.count; i++) { + grpc_auth_context_add_cstring_property(ctx.get(), "name", "chapi"); + grpc_auth_context_add_cstring_property(ctx.get(), "name", "chapo"); + grpc_auth_context_add_cstring_property(ctx.get(), "foo", "bar"); + GPR_ASSERT(ctx->properties().count == 3); + GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx.get(), + "name") == 1); + + GPR_ASSERT(strcmp(grpc_auth_context_peer_identity_property_name(ctx.get()), + "name") == 0); + it = grpc_auth_context_property_iterator(ctx.get()); + for (i = 0; i < ctx->properties().count; i++) { const grpc_auth_property* p = grpc_auth_property_iterator_next(&it); - GPR_ASSERT(p == &ctx->properties.array[i]); + GPR_ASSERT(p == &ctx->properties().array[i]); } GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_find_properties_by_name(ctx, "foo"); + it = grpc_auth_context_find_properties_by_name(ctx.get(), "foo"); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[2]); + &ctx->properties().array[2]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_peer_identity(ctx); + it = grpc_auth_context_peer_identity(ctx.get()); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[0]); + &ctx->properties().array[0]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[1]); + &ctx->properties().array[1]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_chained_context(void) { - grpc_auth_context* chained = grpc_auth_context_create(nullptr); - grpc_auth_context* ctx = grpc_auth_context_create(chained); + grpc_core::RefCountedPtr chained = + grpc_core::MakeRefCounted(nullptr); + grpc_auth_context* chained_ptr = chained.get(); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(std::move(chained)); + grpc_auth_property_iterator it; size_t i; gpr_log(GPR_INFO, "test_chained_context"); - GRPC_AUTH_CONTEXT_UNREF(chained, "chained"); - grpc_auth_context_add_cstring_property(chained, "name", "padapo"); - grpc_auth_context_add_cstring_property(chained, "foo", "baz"); - grpc_auth_context_add_cstring_property(ctx, "name", "chapi"); - grpc_auth_context_add_cstring_property(ctx, "name", "chap0"); - grpc_auth_context_add_cstring_property(ctx, "foo", "bar"); - GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "name") == - 1); - - GPR_ASSERT( - strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0); - it = grpc_auth_context_property_iterator(ctx); - for (i = 0; i < ctx->properties.count; i++) { + grpc_auth_context_add_cstring_property(chained_ptr, "name", "padapo"); + grpc_auth_context_add_cstring_property(chained_ptr, "foo", "baz"); + grpc_auth_context_add_cstring_property(ctx.get(), "name", "chapi"); + grpc_auth_context_add_cstring_property(ctx.get(), "name", "chap0"); + grpc_auth_context_add_cstring_property(ctx.get(), "foo", "bar"); + GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx.get(), + "name") == 1); + + GPR_ASSERT(strcmp(grpc_auth_context_peer_identity_property_name(ctx.get()), + "name") == 0); + it = grpc_auth_context_property_iterator(ctx.get()); + for (i = 0; i < ctx->properties().count; i++) { const grpc_auth_property* p = grpc_auth_property_iterator_next(&it); - GPR_ASSERT(p == &ctx->properties.array[i]); + GPR_ASSERT(p == &ctx->properties().array[i]); } - for (i = 0; i < chained->properties.count; i++) { + for (i = 0; i < chained_ptr->properties().count; i++) { const grpc_auth_property* p = grpc_auth_property_iterator_next(&it); - GPR_ASSERT(p == &chained->properties.array[i]); + GPR_ASSERT(p == &chained_ptr->properties().array[i]); } GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_find_properties_by_name(ctx, "foo"); + it = grpc_auth_context_find_properties_by_name(ctx.get(), "foo"); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[2]); + &ctx->properties().array[2]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &chained->properties.array[1]); + &chained_ptr->properties().array[1]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_peer_identity(ctx); + it = grpc_auth_context_peer_identity(ctx.get()); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[0]); + &ctx->properties().array[0]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[1]); + &ctx->properties().array[1]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &chained->properties.array[0]); + &chained_ptr->properties().array[0]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } int main(int argc, char** argv) { diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index a7a6050ec0a..b3a81617865 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -46,19 +46,6 @@ using grpc_core::internal::grpc_flush_cached_google_default_credentials; using grpc_core::internal::set_gce_tenancy_checker_for_testing; -/* -- Mock channel credentials. -- */ - -static grpc_channel_credentials* grpc_mock_channel_credentials_create( - const grpc_channel_credentials_vtable* vtable) { - grpc_channel_credentials* c = - static_cast(gpr_malloc(sizeof(*c))); - memset(c, 0, sizeof(*c)); - c->type = "mock"; - c->vtable = vtable; - gpr_ref_init(&c->refcount, 1); - return c; -} - /* -- Constants. -- */ static const char test_google_iam_authorization_token[] = "blahblahblhahb"; @@ -377,9 +364,9 @@ static void run_request_metadata_test(grpc_call_credentials* creds, grpc_auth_metadata_context auth_md_ctx, request_metadata_state* state) { grpc_error* error = GRPC_ERROR_NONE; - if (grpc_call_credentials_get_request_metadata( - creds, &state->pollent, auth_md_ctx, &state->md_array, - &state->on_request_metadata, &error)) { + if (creds->get_request_metadata(&state->pollent, auth_md_ctx, + &state->md_array, &state->on_request_metadata, + &error)) { // Synchronous result. Invoke the callback directly. check_request_metadata(state, error); GRPC_ERROR_UNREF(error); @@ -400,7 +387,7 @@ static void test_google_iam_creds(void) { grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, nullptr, nullptr}; run_request_metadata_test(creds, auth_md_ctx, state); - grpc_call_credentials_unref(creds); + creds->Unref(); } static void test_access_token_creds(void) { @@ -412,28 +399,36 @@ static void test_access_token_creds(void) { grpc_access_token_credentials_create("blah", nullptr); grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, nullptr, nullptr}; - GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); + GPR_ASSERT(strcmp(creds->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); run_request_metadata_test(creds, auth_md_ctx, state); - grpc_call_credentials_unref(creds); + creds->Unref(); } -static grpc_security_status check_channel_oauth2_create_security_connector( - grpc_channel_credentials* c, grpc_call_credentials* call_creds, - const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - GPR_ASSERT(strcmp(c->type, "mock") == 0); - GPR_ASSERT(call_creds != nullptr); - GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - return GRPC_SECURITY_OK; -} +namespace { +class check_channel_oauth2 final : public grpc_channel_credentials { + public: + check_channel_oauth2() : grpc_channel_credentials("mock") {} + ~check_channel_oauth2() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override { + GPR_ASSERT(strcmp(type(), "mock") == 0); + GPR_ASSERT(call_creds != nullptr); + GPR_ASSERT(strcmp(call_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == + 0); + return nullptr; + } +}; +} // namespace static void test_channel_oauth2_composite_creds(void) { grpc_core::ExecCtx exec_ctx; grpc_channel_args* new_args; - grpc_channel_credentials_vtable vtable = { - nullptr, check_channel_oauth2_create_security_connector, nullptr}; grpc_channel_credentials* channel_creds = - grpc_mock_channel_credentials_create(&vtable); + grpc_core::New(); grpc_call_credentials* oauth2_creds = grpc_access_token_credentials_create("blah", nullptr); grpc_channel_credentials* channel_oauth2_creds = @@ -441,9 +436,8 @@ static void test_channel_oauth2_composite_creds(void) { nullptr); grpc_channel_credentials_release(channel_creds); grpc_call_credentials_release(oauth2_creds); - GPR_ASSERT(grpc_channel_credentials_create_security_connector( - channel_oauth2_creds, nullptr, nullptr, nullptr, &new_args) == - GRPC_SECURITY_OK); + channel_oauth2_creds->create_security_connector(nullptr, nullptr, nullptr, + &new_args); grpc_channel_credentials_release(channel_oauth2_creds); } @@ -467,47 +461,54 @@ static void test_oauth2_google_iam_composite_creds(void) { grpc_call_credentials* composite_creds = grpc_composite_call_credentials_create(oauth2_creds, google_iam_creds, nullptr); - grpc_call_credentials_unref(oauth2_creds); - grpc_call_credentials_unref(google_iam_creds); - GPR_ASSERT( - strcmp(composite_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); - const grpc_call_credentials_array* creds_array = - grpc_composite_call_credentials_get_credentials(composite_creds); - GPR_ASSERT(creds_array->num_creds == 2); - GPR_ASSERT(strcmp(creds_array->creds_array[0]->type, + oauth2_creds->Unref(); + google_iam_creds->Unref(); + GPR_ASSERT(strcmp(composite_creds->type(), + GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); + const grpc_call_credentials_array& creds_array = + static_cast(composite_creds) + ->inner(); + GPR_ASSERT(creds_array.size() == 2); + GPR_ASSERT(strcmp(creds_array.get(0)->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - GPR_ASSERT(strcmp(creds_array->creds_array[1]->type, - GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); + GPR_ASSERT( + strcmp(creds_array.get(1)->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); run_request_metadata_test(composite_creds, auth_md_ctx, state); - grpc_call_credentials_unref(composite_creds); + composite_creds->Unref(); } -static grpc_security_status -check_channel_oauth2_google_iam_create_security_connector( - grpc_channel_credentials* c, grpc_call_credentials* call_creds, - const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - const grpc_call_credentials_array* creds_array; - GPR_ASSERT(strcmp(c->type, "mock") == 0); - GPR_ASSERT(call_creds != nullptr); - GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == - 0); - creds_array = grpc_composite_call_credentials_get_credentials(call_creds); - GPR_ASSERT(strcmp(creds_array->creds_array[0]->type, - GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - GPR_ASSERT(strcmp(creds_array->creds_array[1]->type, - GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); - return GRPC_SECURITY_OK; -} +namespace { +class check_channel_oauth2_google_iam final : public grpc_channel_credentials { + public: + check_channel_oauth2_google_iam() : grpc_channel_credentials("mock") {} + ~check_channel_oauth2_google_iam() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override { + GPR_ASSERT(strcmp(type(), "mock") == 0); + GPR_ASSERT(call_creds != nullptr); + GPR_ASSERT( + strcmp(call_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); + const grpc_call_credentials_array& creds_array = + static_cast(call_creds.get()) + ->inner(); + GPR_ASSERT(strcmp(creds_array.get(0)->type(), + GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); + GPR_ASSERT(strcmp(creds_array.get(1)->type(), + GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); + return nullptr; + } +}; +} // namespace static void test_channel_oauth2_google_iam_composite_creds(void) { grpc_core::ExecCtx exec_ctx; grpc_channel_args* new_args; - grpc_channel_credentials_vtable vtable = { - nullptr, check_channel_oauth2_google_iam_create_security_connector, - nullptr}; grpc_channel_credentials* channel_creds = - grpc_mock_channel_credentials_create(&vtable); + grpc_core::New(); grpc_call_credentials* oauth2_creds = grpc_access_token_credentials_create("blah", nullptr); grpc_channel_credentials* channel_oauth2_creds = @@ -524,9 +525,8 @@ static void test_channel_oauth2_google_iam_composite_creds(void) { grpc_channel_credentials_release(channel_oauth2_creds); grpc_call_credentials_release(google_iam_creds); - GPR_ASSERT(grpc_channel_credentials_create_security_connector( - channel_oauth2_iam_creds, nullptr, nullptr, nullptr, - &new_args) == GRPC_SECURITY_OK); + channel_oauth2_iam_creds->create_security_connector(nullptr, nullptr, nullptr, + &new_args); grpc_channel_credentials_release(channel_oauth2_iam_creds); } @@ -578,7 +578,7 @@ static int httpcli_get_should_not_be_called(const grpc_httpcli_request* request, return 1; } -static void test_compute_engine_creds_success(void) { +static void test_compute_engine_creds_success() { grpc_core::ExecCtx exec_ctx; expected_md emd[] = { {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}}; @@ -603,7 +603,7 @@ static void test_compute_engine_creds_success(void) { run_request_metadata_test(creds, auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } @@ -620,7 +620,7 @@ static void test_compute_engine_creds_failure(void) { grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override, httpcli_post_should_not_be_called); run_request_metadata_test(creds, auth_md_ctx, state); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } @@ -692,7 +692,7 @@ static void test_refresh_token_creds_success(void) { run_request_metadata_test(creds, auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } @@ -709,7 +709,7 @@ static void test_refresh_token_creds_failure(void) { grpc_httpcli_set_override(httpcli_get_should_not_be_called, refresh_token_httpcli_post_failure); run_request_metadata_test(creds, auth_md_ctx, state); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } @@ -762,7 +762,7 @@ static char* encode_and_sign_jwt_should_not_be_called( static grpc_service_account_jwt_access_credentials* creds_as_jwt( grpc_call_credentials* creds) { GPR_ASSERT(creds != nullptr); - GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_JWT) == 0); + GPR_ASSERT(strcmp(creds->type(), GRPC_CALL_CREDENTIALS_TYPE_JWT) == 0); return reinterpret_cast(creds); } @@ -773,7 +773,7 @@ static void test_jwt_creds_lifetime(void) { grpc_call_credentials* jwt_creds = grpc_service_account_jwt_access_credentials_create( json_key_string, grpc_max_auth_token_lifetime(), nullptr); - GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime, + GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(), grpc_max_auth_token_lifetime()) == 0); grpc_call_credentials_release(jwt_creds); @@ -782,8 +782,8 @@ static void test_jwt_creds_lifetime(void) { GPR_ASSERT(gpr_time_cmp(grpc_max_auth_token_lifetime(), token_lifetime) > 0); jwt_creds = grpc_service_account_jwt_access_credentials_create( json_key_string, token_lifetime, nullptr); - GPR_ASSERT( - gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime, token_lifetime) == 0); + GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(), + token_lifetime) == 0); grpc_call_credentials_release(jwt_creds); // Cropped lifetime. @@ -791,7 +791,7 @@ static void test_jwt_creds_lifetime(void) { token_lifetime = gpr_time_add(grpc_max_auth_token_lifetime(), add_to_max); jwt_creds = grpc_service_account_jwt_access_credentials_create( json_key_string, token_lifetime, nullptr); - GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime, + GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(), grpc_max_auth_token_lifetime()) == 0); grpc_call_credentials_release(jwt_creds); @@ -834,7 +834,7 @@ static void test_jwt_creds_success(void) { run_request_metadata_test(creds, auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); - grpc_call_credentials_unref(creds); + creds->Unref(); gpr_free(json_key_string); gpr_free(expected_md_value); grpc_jwt_encode_and_sign_set_override(nullptr); @@ -856,7 +856,7 @@ static void test_jwt_creds_signing_failure(void) { run_request_metadata_test(creds, auth_md_ctx, state); gpr_free(json_key_string); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_jwt_encode_and_sign_set_override(nullptr); } @@ -875,8 +875,6 @@ static void set_google_default_creds_env_var_with_file_contents( static void test_google_default_creds_auth_key(void) { grpc_core::ExecCtx exec_ctx; - grpc_service_account_jwt_access_credentials* jwt; - grpc_google_default_channel_credentials* default_creds; grpc_composite_channel_credentials* creds; char* json_key = test_json_key_str(); grpc_flush_cached_google_default_credentials(); @@ -885,37 +883,39 @@ static void test_google_default_creds_auth_key(void) { gpr_free(json_key); creds = reinterpret_cast( grpc_google_default_credentials_create()); - default_creds = reinterpret_cast( - creds->inner_creds); - GPR_ASSERT(default_creds->ssl_creds != nullptr); - jwt = reinterpret_cast( - creds->call_creds); + auto* default_creds = + reinterpret_cast( + creds->inner_creds()); + GPR_ASSERT(default_creds->ssl_creds() != nullptr); + auto* jwt = + reinterpret_cast( + creds->call_creds()); GPR_ASSERT( - strcmp(jwt->key.client_id, + strcmp(jwt->key().client_id, "777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") == 0); - grpc_channel_credentials_unref(&creds->base); + creds->Unref(); gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ } static void test_google_default_creds_refresh_token(void) { grpc_core::ExecCtx exec_ctx; - grpc_google_refresh_token_credentials* refresh; - grpc_google_default_channel_credentials* default_creds; grpc_composite_channel_credentials* creds; grpc_flush_cached_google_default_credentials(); set_google_default_creds_env_var_with_file_contents( "refresh_token_google_default_creds", test_refresh_token_str); creds = reinterpret_cast( grpc_google_default_credentials_create()); - default_creds = reinterpret_cast( - creds->inner_creds); - GPR_ASSERT(default_creds->ssl_creds != nullptr); - refresh = reinterpret_cast( - creds->call_creds); - GPR_ASSERT(strcmp(refresh->refresh_token.client_id, + auto* default_creds = + reinterpret_cast( + creds->inner_creds()); + GPR_ASSERT(default_creds->ssl_creds() != nullptr); + auto* refresh = + reinterpret_cast( + creds->call_creds()); + GPR_ASSERT(strcmp(refresh->refresh_token().client_id, "32555999999.apps.googleusercontent.com") == 0); - grpc_channel_credentials_unref(&creds->base); + creds->Unref(); gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ } @@ -965,16 +965,16 @@ static void test_google_default_creds_gce(void) { /* Verify that the default creds actually embeds a GCE creds. */ GPR_ASSERT(creds != nullptr); - GPR_ASSERT(creds->call_creds != nullptr); + GPR_ASSERT(creds->call_creds() != nullptr); grpc_httpcli_set_override(compute_engine_httpcli_get_success_override, httpcli_post_should_not_be_called); - run_request_metadata_test(creds->call_creds, auth_md_ctx, state); + run_request_metadata_test(creds->mutable_call_creds(), auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(g_test_gce_tenancy_checker_called == true); /* Cleanup. */ - grpc_channel_credentials_unref(&creds->base); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); grpc_override_well_known_credentials_path_getter(nullptr); } @@ -1003,14 +1003,14 @@ static void test_google_default_creds_non_gce(void) { grpc_google_default_credentials_create()); /* Verify that the default creds actually embeds a GCE creds. */ GPR_ASSERT(creds != nullptr); - GPR_ASSERT(creds->call_creds != nullptr); + GPR_ASSERT(creds->call_creds() != nullptr); grpc_httpcli_set_override(compute_engine_httpcli_get_success_override, httpcli_post_should_not_be_called); - run_request_metadata_test(creds->call_creds, auth_md_ctx, state); + run_request_metadata_test(creds->mutable_call_creds(), auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(g_test_gce_tenancy_checker_called == true); /* Cleanup. */ - grpc_channel_credentials_unref(&creds->base); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); grpc_override_well_known_credentials_path_getter(nullptr); } @@ -1121,7 +1121,7 @@ static void test_metadata_plugin_success(void) { GPR_ASSERT(state == PLUGIN_INITIAL_STATE); run_request_metadata_test(creds, auth_md_ctx, md_state); GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE); - grpc_call_credentials_unref(creds); + creds->Unref(); GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE); } @@ -1149,7 +1149,7 @@ static void test_metadata_plugin_failure(void) { GPR_ASSERT(state == PLUGIN_INITIAL_STATE); run_request_metadata_test(creds, auth_md_ctx, md_state); GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE); - grpc_call_credentials_unref(creds); + creds->Unref(); GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE); } @@ -1176,25 +1176,23 @@ static void test_channel_creds_duplicate_without_call_creds(void) { grpc_channel_credentials* channel_creds = grpc_fake_transport_security_credentials_create(); - grpc_channel_credentials* dup = - grpc_channel_credentials_duplicate_without_call_credentials( - channel_creds); + grpc_core::RefCountedPtr dup = + channel_creds->duplicate_without_call_credentials(); GPR_ASSERT(dup == channel_creds); - grpc_channel_credentials_unref(dup); + dup.reset(); grpc_call_credentials* call_creds = grpc_access_token_credentials_create("blah", nullptr); grpc_channel_credentials* composite_creds = grpc_composite_channel_credentials_create(channel_creds, call_creds, nullptr); - grpc_call_credentials_unref(call_creds); - dup = grpc_channel_credentials_duplicate_without_call_credentials( - composite_creds); + call_creds->Unref(); + dup = composite_creds->duplicate_without_call_credentials(); GPR_ASSERT(dup == channel_creds); - grpc_channel_credentials_unref(dup); + dup.reset(); - grpc_channel_credentials_unref(channel_creds); - grpc_channel_credentials_unref(composite_creds); + channel_creds->Unref(); + composite_creds->Unref(); } typedef struct { diff --git a/test/core/security/oauth2_utils.cc b/test/core/security/oauth2_utils.cc index 469129a6d03..c9e205ab743 100644 --- a/test/core/security/oauth2_utils.cc +++ b/test/core/security/oauth2_utils.cc @@ -86,9 +86,8 @@ char* grpc_test_fetch_oauth2_token_with_credentials( grpc_schedule_on_exec_ctx); grpc_error* error = GRPC_ERROR_NONE; - if (grpc_call_credentials_get_request_metadata(creds, &request.pops, null_ctx, - &request.md_array, - &request.closure, &error)) { + if (creds->get_request_metadata(&request.pops, null_ctx, &request.md_array, + &request.closure, &error)) { // Synchronous result; invoke callback directly. on_oauth2_response(&request, error); GRPC_ERROR_UNREF(error); diff --git a/test/core/security/print_google_default_creds_token.cc b/test/core/security/print_google_default_creds_token.cc index 4d251391ff2..398c58c6e17 100644 --- a/test/core/security/print_google_default_creds_token.cc +++ b/test/core/security/print_google_default_creds_token.cc @@ -96,11 +96,10 @@ int main(int argc, char** argv) { grpc_schedule_on_exec_ctx); error = GRPC_ERROR_NONE; - if (grpc_call_credentials_get_request_metadata( - (reinterpret_cast(creds)) - ->call_creds, - &sync.pops, context, &sync.md_array, &sync.on_request_metadata, - &error)) { + if (reinterpret_cast(creds) + ->mutable_call_creds() + ->get_request_metadata(&sync.pops, context, &sync.md_array, + &sync.on_request_metadata, &error)) { // Synchronous response. Invoke callback directly. on_metadata_response(&sync, error); GRPC_ERROR_UNREF(error); diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index e82a8627d40..2a31763c73c 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -27,6 +27,7 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/lib/security/security_connector/ssl_utils.h" @@ -83,22 +84,22 @@ static int check_ssl_peer_equivalence(const tsi_peer* original, static void test_unauthenticated_ssl_peer(void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, &peer.properties[0]) == TSI_OK); - ctx = grpc_ssl_peer_to_auth_context(&peer); + grpc_core::RefCountedPtr ctx = + grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx)); - GPR_ASSERT(check_transport_security_type(ctx)); + GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT(check_transport_security_type(ctx.get())); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static int check_identity(const grpc_auth_context* ctx, @@ -175,7 +176,6 @@ static int check_x509_pem_cert(const grpc_auth_context* ctx, static void test_cn_only_ssl_peer_to_auth_context(void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; const char* expected_cn = "cn1"; const char* expected_pem_cert = "pem_cert1"; GPR_ASSERT(tsi_construct_peer(3, &peer) == TSI_OK); @@ -188,26 +188,27 @@ static void test_cn_only_ssl_peer_to_auth_context(void) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, &peer.properties[2]) == TSI_OK); - ctx = grpc_ssl_peer_to_auth_context(&peer); + grpc_core::RefCountedPtr ctx = + grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); - GPR_ASSERT(check_identity(ctx, GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1)); - GPR_ASSERT(check_transport_security_type(ctx)); - GPR_ASSERT(check_x509_cn(ctx, expected_cn)); - GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT( + check_identity(ctx.get(), GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1)); + GPR_ASSERT(check_transport_security_type(ctx.get())); + GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); + GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_cn_and_one_san_ssl_peer_to_auth_context(void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; const char* expected_cn = "cn1"; const char* expected_san = "san1"; const char* expected_pem_cert = "pem_cert1"; @@ -224,27 +225,28 @@ static void test_cn_and_one_san_ssl_peer_to_auth_context(void) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, &peer.properties[3]) == TSI_OK); - ctx = grpc_ssl_peer_to_auth_context(&peer); + + grpc_core::RefCountedPtr ctx = + grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get())); GPR_ASSERT( - check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, &expected_san, 1)); - GPR_ASSERT(check_transport_security_type(ctx)); - GPR_ASSERT(check_x509_cn(ctx, expected_cn)); - GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); + check_identity(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, &expected_san, 1)); + GPR_ASSERT(check_transport_security_type(ctx.get())); + GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); + GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; const char* expected_cn = "cn1"; const char* expected_sans[] = {"san1", "san2", "san3"}; const char* expected_pem_cert = "pem_cert1"; @@ -265,28 +267,28 @@ static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) { TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, expected_sans[i], &peer.properties[3 + i]) == TSI_OK); } - ctx = grpc_ssl_peer_to_auth_context(&peer); + grpc_core::RefCountedPtr ctx = + grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); - GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans, - GPR_ARRAY_SIZE(expected_sans))); - GPR_ASSERT(check_transport_security_type(ctx)); - GPR_ASSERT(check_x509_cn(ctx, expected_cn)); - GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); - - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT(check_identity(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, + expected_sans, GPR_ARRAY_SIZE(expected_sans))); + GPR_ASSERT(check_transport_security_type(ctx.get())); + GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); + GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); + + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context( void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; const char* expected_cn = "cn1"; const char* expected_pem_cert = "pem_cert1"; const char* expected_sans[] = {"san1", "san2", "san3"}; @@ -311,21 +313,22 @@ static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context( TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, expected_sans[i], &peer.properties[5 + i]) == TSI_OK); } - ctx = grpc_ssl_peer_to_auth_context(&peer); + grpc_core::RefCountedPtr ctx = + grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); - GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans, - GPR_ARRAY_SIZE(expected_sans))); - GPR_ASSERT(check_transport_security_type(ctx)); - GPR_ASSERT(check_x509_cn(ctx, expected_cn)); - GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); - - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT(check_identity(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, + expected_sans, GPR_ARRAY_SIZE(expected_sans))); + GPR_ASSERT(check_transport_security_type(ctx.get())); + GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); + GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); + + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static const char* roots_for_override_api = "roots for override api"; diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc index d2bbb7c1c2e..c9380126dd0 100644 --- a/test/core/security/ssl_server_fuzzer.cc +++ b/test/core/security/ssl_server_fuzzer.cc @@ -82,16 +82,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ca_cert, &pem_key_cert_pair, 1, 0, nullptr); // Create security connector - grpc_server_security_connector* sc = nullptr; - grpc_security_status status = - grpc_server_credentials_create_security_connector(creds, &sc); - GPR_ASSERT(status == GRPC_SECURITY_OK); + grpc_core::RefCountedPtr sc = + creds->create_security_connector(); + GPR_ASSERT(sc != nullptr); grpc_millis deadline = GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(); struct handshake_state state; state.done_callback_called = false; grpc_handshake_manager* handshake_mgr = grpc_handshake_manager_create(); - grpc_server_security_connector_add_handshakers(sc, nullptr, handshake_mgr); + sc->add_handshakers(nullptr, handshake_mgr); grpc_handshake_manager_do_handshake( handshake_mgr, mock_endpoint, nullptr /* channel_args */, deadline, nullptr /* acceptor */, on_handshake_done, &state); @@ -110,7 +109,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { GPR_ASSERT(state.done_callback_called); grpc_handshake_manager_destroy(handshake_mgr); - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "test"); + sc.reset(DEBUG_LOCATION, "test"); grpc_server_credentials_release(creds); grpc_slice_unref(cert_slice); grpc_slice_unref(key_slice); diff --git a/test/core/surface/secure_channel_create_test.cc b/test/core/surface/secure_channel_create_test.cc index 5610d1ec4ab..e9bb815f6ee 100644 --- a/test/core/surface/secure_channel_create_test.cc +++ b/test/core/surface/secure_channel_create_test.cc @@ -39,7 +39,7 @@ void test_unknown_scheme_target(void) { GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client")); grpc_core::ExecCtx exec_ctx; GRPC_CHANNEL_INTERNAL_UNREF(chan, "test"); - grpc_channel_credentials_unref(creds); + creds->Unref(); } void test_security_connector_already_in_arg(void) { diff --git a/test/cpp/common/auth_property_iterator_test.cc b/test/cpp/common/auth_property_iterator_test.cc index 9634555e4b5..5a2844d518a 100644 --- a/test/cpp/common/auth_property_iterator_test.cc +++ b/test/cpp/common/auth_property_iterator_test.cc @@ -40,15 +40,14 @@ class TestAuthPropertyIterator : public AuthPropertyIterator { class AuthPropertyIteratorTest : public ::testing::Test { protected: void SetUp() override { - ctx_ = grpc_auth_context_create(nullptr); - grpc_auth_context_add_cstring_property(ctx_, "name", "chapi"); - grpc_auth_context_add_cstring_property(ctx_, "name", "chapo"); - grpc_auth_context_add_cstring_property(ctx_, "foo", "bar"); - EXPECT_EQ(1, - grpc_auth_context_set_peer_identity_property_name(ctx_, "name")); + ctx_ = grpc_core::MakeRefCounted(nullptr); + grpc_auth_context_add_cstring_property(ctx_.get(), "name", "chapi"); + grpc_auth_context_add_cstring_property(ctx_.get(), "name", "chapo"); + grpc_auth_context_add_cstring_property(ctx_.get(), "foo", "bar"); + EXPECT_EQ(1, grpc_auth_context_set_peer_identity_property_name(ctx_.get(), + "name")); } - void TearDown() override { grpc_auth_context_release(ctx_); } - grpc_auth_context* ctx_; + grpc_core::RefCountedPtr ctx_; }; TEST_F(AuthPropertyIteratorTest, DefaultCtor) { @@ -59,7 +58,7 @@ TEST_F(AuthPropertyIteratorTest, DefaultCtor) { TEST_F(AuthPropertyIteratorTest, GeneralTest) { grpc_auth_property_iterator c_iter = - grpc_auth_context_property_iterator(ctx_); + grpc_auth_context_property_iterator(ctx_.get()); const grpc_auth_property* property = grpc_auth_property_iterator_next(&c_iter); TestAuthPropertyIterator iter(property, &c_iter); diff --git a/test/cpp/common/secure_auth_context_test.cc b/test/cpp/common/secure_auth_context_test.cc index 6461f497433..03b3a9fdd8e 100644 --- a/test/cpp/common/secure_auth_context_test.cc +++ b/test/cpp/common/secure_auth_context_test.cc @@ -33,7 +33,7 @@ class SecureAuthContextTest : public ::testing::Test {}; // Created with nullptr TEST_F(SecureAuthContextTest, EmptyContext) { - SecureAuthContext context(nullptr, true); + SecureAuthContext context(nullptr); EXPECT_TRUE(context.GetPeerIdentity().empty()); EXPECT_TRUE(context.GetPeerIdentityPropertyName().empty()); EXPECT_TRUE(context.FindPropertyValues("").empty()); @@ -42,8 +42,10 @@ TEST_F(SecureAuthContextTest, EmptyContext) { } TEST_F(SecureAuthContextTest, Properties) { - grpc_auth_context* ctx = grpc_auth_context_create(nullptr); - SecureAuthContext context(ctx, true); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); + SecureAuthContext context(ctx.get()); + ctx.reset(); context.AddProperty("name", "chapi"); context.AddProperty("name", "chapo"); context.AddProperty("foo", "bar"); @@ -60,8 +62,10 @@ TEST_F(SecureAuthContextTest, Properties) { } TEST_F(SecureAuthContextTest, Iterators) { - grpc_auth_context* ctx = grpc_auth_context_create(nullptr); - SecureAuthContext context(ctx, true); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); + SecureAuthContext context(ctx.get()); + ctx.reset(); context.AddProperty("name", "chapi"); context.AddProperty("name", "chapo"); context.AddProperty("foo", "bar"); diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index bf990a07b5a..2eaacd429de 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -414,8 +414,8 @@ class GrpclbEnd2endTest : public ::testing::Test { std::shared_ptr creds( new SecureChannelCredentials(grpc_composite_channel_credentials_create( channel_creds, call_creds, nullptr))); - grpc_call_credentials_unref(call_creds); - grpc_channel_credentials_unref(channel_creds); + call_creds->Unref(); + channel_creds->Unref(); channel_ = CreateCustomChannel(uri.str(), creds, args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } From e6e10814993b5e6af93675bd468755786de1e20d Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Tue, 11 Dec 2018 10:29:08 -0800 Subject: [PATCH 293/534] Add support for Callback Client Streaming benchmarks --- test/cpp/qps/client.h | 28 ++--- test/cpp/qps/client_callback.cc | 176 ++++++++++++++++++++++++++++---- 2 files changed, 174 insertions(+), 30 deletions(-) diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 668d9419169..0b9837660be 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -236,6 +236,21 @@ class Client { return 0; } + bool IsClosedLoop() { return closed_loop_; } + + gpr_timespec NextIssueTime(int thread_idx) { + const gpr_timespec result = next_time_[thread_idx]; + next_time_[thread_idx] = + gpr_time_add(next_time_[thread_idx], + gpr_time_from_nanos(interarrival_timer_.next(thread_idx), + GPR_TIMESPAN)); + return result; + } + + bool ThreadCompleted() { + return static_cast(gpr_atm_acq_load(&thread_pool_done_)); + } + protected: bool closed_loop_; gpr_atm thread_pool_done_; @@ -289,14 +304,6 @@ class Client { } } - gpr_timespec NextIssueTime(int thread_idx) { - const gpr_timespec result = next_time_[thread_idx]; - next_time_[thread_idx] = - gpr_time_add(next_time_[thread_idx], - gpr_time_from_nanos(interarrival_timer_.next(thread_idx), - GPR_TIMESPAN)); - return result; - } std::function NextIssuer(int thread_idx) { return closed_loop_ ? std::function() : std::bind(&Client::NextIssueTime, this, thread_idx); @@ -380,10 +387,6 @@ class Client { double interval_start_time_; }; - bool ThreadCompleted() { - return static_cast(gpr_atm_acq_load(&thread_pool_done_)); - } - virtual void ThreadFunc(size_t thread_idx, Client::Thread* t) = 0; std::vector> threads_; @@ -442,6 +445,7 @@ class ClientImpl : public Client { config.payload_config()); } virtual ~ClientImpl() {} + const RequestType* request() { return &request_; } protected: const int cores_; diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index 87889e36dc5..00d5853a8e8 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -73,6 +73,20 @@ class CallbackClient virtual ~CallbackClient() {} + /** + * The main thread of the benchmark will be waiting on DestroyMultithreading. + * Increment the rpcs_done_ variable to signify that the Callback RPC + * after thread completion is done. When the last outstanding rpc increments + * the counter it should also signal the main thread's conditional variable. + */ + void NotifyMainThreadOfThreadCompletion() { + std::lock_guard l(shutdown_mu_); + rpcs_done_++; + if (rpcs_done_ == total_outstanding_rpcs_) { + shutdown_cv_.notify_one(); + } + } + protected: size_t num_threads_; size_t total_outstanding_rpcs_; @@ -93,23 +107,6 @@ class CallbackClient ThreadFuncImpl(t, thread_idx); } - virtual void ScheduleRpc(Thread* t, size_t thread_idx, - size_t ctx_vector_idx) = 0; - - /** - * The main thread of the benchmark will be waiting on DestroyMultithreading. - * Increment the rpcs_done_ variable to signify that the Callback RPC - * after thread completion is done. When the last outstanding rpc increments - * the counter it should also signal the main thread's conditional variable. - */ - void NotifyMainThreadOfThreadCompletion() { - std::lock_guard l(shutdown_mu_); - rpcs_done_++; - if (rpcs_done_ == total_outstanding_rpcs_) { - shutdown_cv_.notify_one(); - } - } - private: int NumThreads(const ClientConfig& config) { int num_threads = config.async_client_threads(); @@ -157,7 +154,7 @@ class CallbackUnaryClient final : public CallbackClient { void InitThreadFuncImpl(size_t thread_idx) override { return; } private: - void ScheduleRpc(Thread* t, size_t thread_idx, size_t vector_idx) override { + void ScheduleRpc(Thread* t, size_t thread_idx, size_t vector_idx) { if (!closed_loop_) { gpr_timespec next_issue_time = NextIssueTime(thread_idx); // Start an alarm callback to run the internal callback after @@ -199,11 +196,154 @@ class CallbackUnaryClient final : public CallbackClient { } }; +class CallbackStreamingClient : public CallbackClient { + public: + CallbackStreamingClient(const ClientConfig& config) + : CallbackClient(config), + messages_per_stream_(config.messages_per_stream()) { + for (int ch = 0; ch < config.client_channels(); ch++) { + for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) { + ctx_.emplace_back( + new CallbackClientRpcContext(channels_[ch].get_stub())); + } + } + StartThreads(num_threads_); + } + ~CallbackStreamingClient() {} + + void AddHistogramEntry(double start_, bool ok, void* thread_ptr) { + // Update Histogram with data from the callback run + HistogramEntry entry; + if (ok) { + entry.set_value((UsageTimer::Now() - start_) * 1e9); + } + ((Client::Thread*)thread_ptr)->UpdateHistogram(&entry); + } + + int messages_per_stream() { return messages_per_stream_; } + + protected: + const int messages_per_stream_; +}; + +class CallbackStreamingPingPongClient : public CallbackStreamingClient { + public: + CallbackStreamingPingPongClient(const ClientConfig& config) + : CallbackStreamingClient(config) {} + ~CallbackStreamingPingPongClient() {} +}; + +class CallbackStreamingPingPongReactor final + : public grpc::experimental::ClientBidiReactor { + public: + CallbackStreamingPingPongReactor( + CallbackStreamingPingPongClient* client, + std::unique_ptr ctx) + : client_(client), ctx_(std::move(ctx)), messages_issued_(0) {} + + void StartNewRpc() { + if (client_->ThreadCompleted()) return; + start_ = UsageTimer::Now(); + ctx_->stub_->experimental_async()->StreamingCall(&(ctx_->context_), this); + StartWrite(client_->request()); + StartCall(); + } + + void OnWriteDone(bool ok) override { + if (!ok || client_->ThreadCompleted()) { + if (!ok) gpr_log(GPR_ERROR, "Error writing RPC"); + StartWritesDone(); + return; + } + StartRead(&ctx_->response_); + } + + void OnReadDone(bool ok) override { + client_->AddHistogramEntry(start_, ok, thread_ptr_); + + if (client_->ThreadCompleted() || !ok || + (client_->messages_per_stream() != 0 && + ++messages_issued_ >= client_->messages_per_stream())) { + if (!ok) { + gpr_log(GPR_ERROR, "Error reading RPC"); + } + StartWritesDone(); + return; + } + StartWrite(client_->request()); + } + + void OnDone(const Status& s) override { + if (client_->ThreadCompleted() || !s.ok()) { + client_->NotifyMainThreadOfThreadCompletion(); + return; + } + ctx_.reset(new CallbackClientRpcContext(ctx_->stub_)); + ScheduleRpc(); + } + + void ScheduleRpc() { + if (client_->ThreadCompleted()) return; + + if (!client_->IsClosedLoop()) { + gpr_timespec next_issue_time = client_->NextIssueTime(thread_idx_); + // Start an alarm callback to run the internal callback after + // next_issue_time + ctx_->alarm_.experimental().Set(next_issue_time, + [this](bool ok) { StartNewRpc(); }); + } else { + StartNewRpc(); + } + } + + void set_thread_ptr(void* ptr) { thread_ptr_ = ptr; } + void set_thread_idx(int thread_idx) { thread_idx_ = thread_idx; } + + CallbackStreamingPingPongClient* client_; + std::unique_ptr ctx_; + int thread_idx_; // Needed to update histogram entries + void* thread_ptr_; // Needed to update histogram entries + double start_; // Track message start time + int messages_issued_; // Messages issued by this stream +}; + +class CallbackStreamingPingPongClientImpl final + : public CallbackStreamingPingPongClient { + public: + CallbackStreamingPingPongClientImpl(const ClientConfig& config) + : CallbackStreamingPingPongClient(config) { + for (size_t i = 0; i < total_outstanding_rpcs_; i++) + reactor_.emplace_back( + new CallbackStreamingPingPongReactor(this, std::move(ctx_[i]))); + } + ~CallbackStreamingPingPongClientImpl() {} + + bool ThreadFuncImpl(Client::Thread* t, size_t thread_idx) override { + for (size_t vector_idx = thread_idx; vector_idx < total_outstanding_rpcs_; + vector_idx += num_threads_) { + reactor_[vector_idx]->set_thread_ptr(t); + reactor_[vector_idx]->set_thread_idx(thread_idx); + reactor_[vector_idx]->ScheduleRpc(); + } + return true; + } + + void InitThreadFuncImpl(size_t thread_idx) override {} + + private: + std::vector> reactor_; +}; + +// TODO(mhaidry) : Implement Streaming from client, server and both ways + std::unique_ptr CreateCallbackClient(const ClientConfig& config) { switch (config.rpc_type()) { case UNARY: return std::unique_ptr(new CallbackUnaryClient(config)); case STREAMING: + return std::unique_ptr( + new CallbackStreamingPingPongClientImpl(config)); case STREAMING_FROM_CLIENT: case STREAMING_FROM_SERVER: case STREAMING_BOTH_WAYS: From 45b3230ef2b6a4a7e4c7a2348fa65b2c59fe579a Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Dec 2018 17:16:12 -0800 Subject: [PATCH 294/534] Add grpcio-status extension package * The new package has 2 API `from_call` and `to_status` * Utilize the experimental API `abort_with_status` * Add 5 unit test cases --- requirements.bazel.txt | 1 + src/python/grpcio_status/.gitignore | 3 + src/python/grpcio_status/MANIFEST.in | 3 + src/python/grpcio_status/README.rst | 9 + .../grpcio_status/grpc_status/BUILD.bazel | 14 ++ .../grpcio_status/grpc_status/__init__.py | 13 ++ .../grpcio_status/grpc_status/rpc_status.py | 88 +++++++++ src/python/grpcio_status/grpc_version.py | 17 ++ src/python/grpcio_status/setup.py | 86 +++++++++ src/python/grpcio_tests/setup.py | 1 + .../grpcio_tests/tests/status/BUILD.bazel | 19 ++ .../grpcio_tests/tests/status/__init__.py | 13 ++ .../tests/status/_grpc_status_test.py | 175 ++++++++++++++++++ src/python/grpcio_tests/tests/tests.json | 1 + .../grpcio_status/grpc_version.py.template | 19 ++ tools/distrib/pylint_code.sh | 1 + .../artifacts/build_artifact_python.sh | 5 + .../run_tests/helper_scripts/build_python.sh | 8 +- 18 files changed, 475 insertions(+), 1 deletion(-) create mode 100644 src/python/grpcio_status/.gitignore create mode 100644 src/python/grpcio_status/MANIFEST.in create mode 100644 src/python/grpcio_status/README.rst create mode 100644 src/python/grpcio_status/grpc_status/BUILD.bazel create mode 100644 src/python/grpcio_status/grpc_status/__init__.py create mode 100644 src/python/grpcio_status/grpc_status/rpc_status.py create mode 100644 src/python/grpcio_status/grpc_version.py create mode 100644 src/python/grpcio_status/setup.py create mode 100644 src/python/grpcio_tests/tests/status/BUILD.bazel create mode 100644 src/python/grpcio_tests/tests/status/__init__.py create mode 100644 src/python/grpcio_tests/tests/status/_grpc_status_test.py create mode 100644 templates/src/python/grpcio_status/grpc_version.py.template diff --git a/requirements.bazel.txt b/requirements.bazel.txt index 7794aec752e..e97843794e4 100644 --- a/requirements.bazel.txt +++ b/requirements.bazel.txt @@ -13,3 +13,4 @@ urllib3>=1.23 chardet==3.0.4 certifi==2017.4.17 idna==2.7 +googleapis-common-protos==1.5.5 diff --git a/src/python/grpcio_status/.gitignore b/src/python/grpcio_status/.gitignore new file mode 100644 index 00000000000..19d1523efde --- /dev/null +++ b/src/python/grpcio_status/.gitignore @@ -0,0 +1,3 @@ +build/ +grpcio_status.egg-info/ +dist/ diff --git a/src/python/grpcio_status/MANIFEST.in b/src/python/grpcio_status/MANIFEST.in new file mode 100644 index 00000000000..eca719a9c20 --- /dev/null +++ b/src/python/grpcio_status/MANIFEST.in @@ -0,0 +1,3 @@ +include grpc_version.py +recursive-include grpc_status *.py +global-exclude *.pyc diff --git a/src/python/grpcio_status/README.rst b/src/python/grpcio_status/README.rst new file mode 100644 index 00000000000..dc2f7b1dab1 --- /dev/null +++ b/src/python/grpcio_status/README.rst @@ -0,0 +1,9 @@ +gRPC Python Status Proto +=========================== + +Reference package for GRPC Python status proto mapping. + +Dependencies +------------ + +Depends on the `grpcio` package, available from PyPI via `pip install grpcio`. diff --git a/src/python/grpcio_status/grpc_status/BUILD.bazel b/src/python/grpcio_status/grpc_status/BUILD.bazel new file mode 100644 index 00000000000..223a077c3f2 --- /dev/null +++ b/src/python/grpcio_status/grpc_status/BUILD.bazel @@ -0,0 +1,14 @@ +load("@grpc_python_dependencies//:requirements.bzl", "requirement") + +package(default_visibility = ["//visibility:public"]) + +py_library( + name = "grpc_status", + srcs = ["rpc_status.py",], + deps = [ + "//src/python/grpcio/grpc:grpcio", + requirement('protobuf'), + requirement('googleapis-common-protos'), + ], + imports=["../",], +) diff --git a/src/python/grpcio_status/grpc_status/__init__.py b/src/python/grpcio_status/grpc_status/__init__.py new file mode 100644 index 00000000000..38fdfc9c5cf --- /dev/null +++ b/src/python/grpcio_status/grpc_status/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2018 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. diff --git a/src/python/grpcio_status/grpc_status/rpc_status.py b/src/python/grpcio_status/grpc_status/rpc_status.py new file mode 100644 index 00000000000..36c8eba37d5 --- /dev/null +++ b/src/python/grpcio_status/grpc_status/rpc_status.py @@ -0,0 +1,88 @@ +# Copyright 2018 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. +"""Reference implementation for status mapping in gRPC Python.""" + +import collections + +import grpc + +# TODO(https://github.com/bazelbuild/bazel/issues/6844) +# Due to Bazel issue, the namespace packages won't resolve correctly. +# Adding this unused-import as a workaround to avoid module-not-found error +# under Bazel builds. +import google.protobuf # pylint: disable=unused-import +from google.rpc import status_pb2 + +_CODE_TO_GRPC_CODE_MAPPING = dict([(x.value[0], x) for x in grpc.StatusCode]) + +_GRPC_DETAILS_METADATA_KEY = 'grpc-status-details-bin' + + +class _Status( + collections.namedtuple( + '_Status', ('code', 'details', 'trailing_metadata')), grpc.Status): + pass + + +def _code_to_grpc_status_code(code): + try: + return _CODE_TO_GRPC_CODE_MAPPING[code] + except KeyError: + raise ValueError('Invalid status code %s' % code) + + +def from_call(call): + """Returns a google.rpc.status.Status message corresponding to a given grpc.Call. + + Args: + call: A grpc.Call instance. + + Returns: + A google.rpc.status.Status message representing the status of the RPC. + + Raises: + ValueError: If the status code, status message is inconsistent with the rich status + inside of the google.rpc.status.Status. + """ + for key, value in call.trailing_metadata(): + if key == _GRPC_DETAILS_METADATA_KEY: + rich_status = status_pb2.Status.FromString(value) + if call.code().value[0] != rich_status.code: + raise ValueError( + 'Code in Status proto (%s) doesn\'t match status code (%s)' + % (_code_to_grpc_status_code(rich_status.code), + call.code())) + if call.details() != rich_status.message: + raise ValueError( + 'Message in Status proto (%s) doesn\'t match status details (%s)' + % (rich_status.message, call.details())) + return rich_status + return None + + +def to_status(status): + """Convert a google.rpc.status.Status message to grpc.Status. + + Args: + status: a google.rpc.status.Status message representing the non-OK status + to terminate the RPC with and communicate it to the client. + + Returns: + A grpc.Status instance. + """ + return _Status( + code=_code_to_grpc_status_code(status.code), + details=status.message, + trailing_metadata=((_GRPC_DETAILS_METADATA_KEY, + status.SerializeToString()),)) diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py new file mode 100644 index 00000000000..e009843b94f --- /dev/null +++ b/src/python/grpcio_status/grpc_version.py @@ -0,0 +1,17 @@ +# Copyright 2018 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. + +# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! + +VERSION = '1.18.0.dev0' diff --git a/src/python/grpcio_status/setup.py b/src/python/grpcio_status/setup.py new file mode 100644 index 00000000000..0601498bc51 --- /dev/null +++ b/src/python/grpcio_status/setup.py @@ -0,0 +1,86 @@ +# Copyright 2018 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. +"""Setup module for the GRPC Python package's status mapping.""" + +import os + +import setuptools + +# Ensure we're in the proper directory whether or not we're being used by pip. +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +# Break import-style to ensure we can actually find our local modules. +import grpc_version + + +class _NoOpCommand(setuptools.Command): + """No-op command.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + pass + + +CLASSIFIERS = [ + 'Development Status :: 5 - Production/Stable', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'License :: OSI Approved :: Apache Software License', +] + +PACKAGE_DIRECTORIES = { + '': '.', +} + +INSTALL_REQUIRES = ( + 'protobuf>=3.6.0', + 'grpcio>={version}'.format(version=grpc_version.VERSION), + 'googleapis-common-protos>=1.5.5', +) + +SETUP_REQUIRES = () +COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, + 'build_package_protos': _NoOpCommand, +} + +setuptools.setup( + name='grpcio-status', + version=grpc_version.VERSION, + description='Status proto mapping for gRPC', + author='The gRPC Authors', + author_email='grpc-io@googlegroups.com', + url='https://grpc.io', + license='Apache License 2.0', + classifiers=CLASSIFIERS, + package_dir=PACKAGE_DIRECTORIES, + packages=setuptools.find_packages('.'), + install_requires=INSTALL_REQUIRES, + setup_requires=SETUP_REQUIRES, + cmdclass=COMMAND_CLASS) diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index f56425ac6d3..f9cb9d0cec9 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -40,6 +40,7 @@ INSTALL_REQUIRES = ( 'coverage>=4.0', 'enum34>=1.0.4', 'grpcio>={version}'.format(version=grpc_version.VERSION), 'grpcio-channelz>={version}'.format(version=grpc_version.VERSION), + 'grpcio-status>={version}'.format(version=grpc_version.VERSION), 'grpcio-tools>={version}'.format(version=grpc_version.VERSION), 'grpcio-health-checking>={version}'.format(version=grpc_version.VERSION), 'oauth2client>=1.4.7', 'protobuf>=3.6.0', 'six>=1.10', 'google-auth>=1.0.0', diff --git a/src/python/grpcio_tests/tests/status/BUILD.bazel b/src/python/grpcio_tests/tests/status/BUILD.bazel new file mode 100644 index 00000000000..937e50498e0 --- /dev/null +++ b/src/python/grpcio_tests/tests/status/BUILD.bazel @@ -0,0 +1,19 @@ +load("@grpc_python_dependencies//:requirements.bzl", "requirement") + +package(default_visibility = ["//visibility:public"]) + +py_test( + name = "grpc_status_test", + srcs = ["_grpc_status_test.py"], + main = "_grpc_status_test.py", + size = "small", + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_status/grpc_status:grpc_status", + "//src/python/grpcio_tests/tests/unit:test_common", + "//src/python/grpcio_tests/tests/unit/framework/common:common", + requirement('protobuf'), + requirement('googleapis-common-protos'), + ], + imports = ["../../",], +) diff --git a/src/python/grpcio_tests/tests/status/__init__.py b/src/python/grpcio_tests/tests/status/__init__.py new file mode 100644 index 00000000000..38fdfc9c5cf --- /dev/null +++ b/src/python/grpcio_tests/tests/status/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2018 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. diff --git a/src/python/grpcio_tests/tests/status/_grpc_status_test.py b/src/python/grpcio_tests/tests/status/_grpc_status_test.py new file mode 100644 index 00000000000..5969338736f --- /dev/null +++ b/src/python/grpcio_tests/tests/status/_grpc_status_test.py @@ -0,0 +1,175 @@ +# Copyright 2018 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. +"""Tests of grpc_status.""" + +import unittest + +import logging +import traceback + +import grpc +from grpc_status import rpc_status + +from tests.unit import test_common + +from google.protobuf import any_pb2 +from google.rpc import code_pb2, status_pb2, error_details_pb2 + +_STATUS_OK = '/test/StatusOK' +_STATUS_NOT_OK = '/test/StatusNotOk' +_ERROR_DETAILS = '/test/ErrorDetails' +_INCONSISTENT = '/test/Inconsistent' +_INVALID_CODE = '/test/InvalidCode' + +_REQUEST = b'\x00\x00\x00' +_RESPONSE = b'\x01\x01\x01' + +_GRPC_DETAILS_METADATA_KEY = 'grpc-status-details-bin' + +_STATUS_DETAILS = 'This is an error detail' +_STATUS_DETAILS_ANOTHER = 'This is another error detail' + + +def _ok_unary_unary(request, servicer_context): + return _RESPONSE + + +def _not_ok_unary_unary(request, servicer_context): + servicer_context.abort(grpc.StatusCode.INTERNAL, _STATUS_DETAILS) + + +def _error_details_unary_unary(request, servicer_context): + details = any_pb2.Any() + details.Pack( + error_details_pb2.DebugInfo( + stack_entries=traceback.format_stack(), + detail='Intensionally invoked')) + rich_status = status_pb2.Status( + code=code_pb2.INTERNAL, + message=_STATUS_DETAILS, + details=[details], + ) + servicer_context.abort_with_status(rpc_status.to_status(rich_status)) + + +def _inconsistent_unary_unary(request, servicer_context): + rich_status = status_pb2.Status( + code=code_pb2.INTERNAL, + message=_STATUS_DETAILS, + ) + servicer_context.set_code(grpc.StatusCode.NOT_FOUND) + servicer_context.set_details(_STATUS_DETAILS_ANOTHER) + # User put inconsistent status information in trailing metadata + servicer_context.set_trailing_metadata(((_GRPC_DETAILS_METADATA_KEY, + rich_status.SerializeToString()),)) + + +def _invalid_code_unary_unary(request, servicer_context): + rich_status = status_pb2.Status( + code=42, + message='Invalid code', + ) + servicer_context.abort_with_status(rpc_status.to_status(rich_status)) + + +class _GenericHandler(grpc.GenericRpcHandler): + + def service(self, handler_call_details): + if handler_call_details.method == _STATUS_OK: + return grpc.unary_unary_rpc_method_handler(_ok_unary_unary) + elif handler_call_details.method == _STATUS_NOT_OK: + return grpc.unary_unary_rpc_method_handler(_not_ok_unary_unary) + elif handler_call_details.method == _ERROR_DETAILS: + return grpc.unary_unary_rpc_method_handler( + _error_details_unary_unary) + elif handler_call_details.method == _INCONSISTENT: + return grpc.unary_unary_rpc_method_handler( + _inconsistent_unary_unary) + elif handler_call_details.method == _INVALID_CODE: + return grpc.unary_unary_rpc_method_handler( + _invalid_code_unary_unary) + else: + return None + + +class StatusTest(unittest.TestCase): + + def setUp(self): + self._server = test_common.test_server() + self._server.add_generic_rpc_handlers((_GenericHandler(),)) + port = self._server.add_insecure_port('[::]:0') + self._server.start() + + self._channel = grpc.insecure_channel('localhost:%d' % port) + + def tearDown(self): + self._server.stop(None) + self._channel.close() + + def test_status_ok(self): + try: + _, call = self._channel.unary_unary(_STATUS_OK).with_call(_REQUEST) + except grpc.RpcError as rpc_error: + self.fail(rpc_error) + # Succeed RPC doesn't have status + status = rpc_status.from_call(call) + self.assertIs(status, None) + + def test_status_not_ok(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_STATUS_NOT_OK).with_call(_REQUEST) + rpc_error = exception_context.exception + + self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) + # Failed RPC doesn't automatically generate status + status = rpc_status.from_call(rpc_error) + self.assertIs(status, None) + + def test_error_details(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_ERROR_DETAILS).with_call(_REQUEST) + rpc_error = exception_context.exception + + status = rpc_status.from_call(rpc_error) + self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) + self.assertEqual(status.code, code_pb2.Code.Value('INTERNAL')) + + # Check if the underlying proto message is intact + self.assertEqual(status.details[0].Is( + error_details_pb2.DebugInfo.DESCRIPTOR), True) + info = error_details_pb2.DebugInfo() + status.details[0].Unpack(info) + self.assertIn('_error_details_unary_unary', info.stack_entries[-1]) + + def test_code_message_validation(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_INCONSISTENT).with_call(_REQUEST) + rpc_error = exception_context.exception + self.assertEqual(rpc_error.code(), grpc.StatusCode.NOT_FOUND) + + # Code/Message validation failed + self.assertRaises(ValueError, rpc_status.from_call, rpc_error) + + def test_invalid_code(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_INVALID_CODE).with_call(_REQUEST) + rpc_error = exception_context.exception + self.assertEqual(rpc_error.code(), grpc.StatusCode.UNKNOWN) + # Invalid status code exception raised during coversion + self.assertIn('Invalid status code', rpc_error.details()) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index 44700e979e9..b27e6f26938 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -15,6 +15,7 @@ "protoc_plugin._split_definitions_test.SplitProtoSingleProtocExecutionProtocStyleTest", "protoc_plugin.beta_python_plugin_test.PythonPluginTest", "reflection._reflection_servicer_test.ReflectionServicerTest", + "status._grpc_status_test.StatusTest", "testing._client_test.ClientTest", "testing._server_test.FirstServiceServicerTest", "testing._time_test.StrictFakeTimeTest", diff --git a/templates/src/python/grpcio_status/grpc_version.py.template b/templates/src/python/grpcio_status/grpc_version.py.template new file mode 100644 index 00000000000..727e01edb93 --- /dev/null +++ b/templates/src/python/grpcio_status/grpc_version.py.template @@ -0,0 +1,19 @@ +%YAML 1.2 +--- | + # Copyright 2018 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. + + # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! + + VERSION = '${settings.python_version.pep440()}' diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh index d17eb9fdb82..8a5f7af6c6c 100755 --- a/tools/distrib/pylint_code.sh +++ b/tools/distrib/pylint_code.sh @@ -24,6 +24,7 @@ DIRS=( 'src/python/grpcio_health_checking/grpc_health' 'src/python/grpcio_reflection/grpc_reflection' 'src/python/grpcio_testing/grpc_testing' + 'src/python/grpcio_status/grpc_status' ) TEST_DIRS=( diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index 605470325ab..18eb70c8574 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -123,6 +123,11 @@ then ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_reflection/setup.py \ preprocess build_package_protos sdist cp -r src/python/grpcio_reflection/dist/* "$ARTIFACT_DIR" + + # Build grpcio_status source distribution + ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_status/setup.py \ + preprocess build_package_protos sdist + cp -r src/python/grpcio_status/dist/* "$ARTIFACT_DIR" fi cp -r dist/* "$ARTIFACT_DIR" diff --git a/tools/run_tests/helper_scripts/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh index e43f1fb429c..7cd1ef9d517 100755 --- a/tools/run_tests/helper_scripts/build_python.sh +++ b/tools/run_tests/helper_scripts/build_python.sh @@ -204,12 +204,18 @@ $VENV_PYTHON "$ROOT/src/python/grpcio_reflection/setup.py" preprocess $VENV_PYTHON "$ROOT/src/python/grpcio_reflection/setup.py" build_package_protos pip_install_dir "$ROOT/src/python/grpcio_reflection" +# Build/install status proto mapping +$VENV_PYTHON "$ROOT/src/python/grpcio_status/setup.py" preprocess +$VENV_PYTHON "$ROOT/src/python/grpcio_status/setup.py" build_package_protos +pip_install_dir "$ROOT/src/python/grpcio_status" + # Install testing pip_install_dir "$ROOT/src/python/grpcio_testing" # Build/install tests $VENV_PYTHON -m pip install coverage==4.4 oauth2client==4.1.0 \ - google-auth==1.0.0 requests==2.14.2 + google-auth==1.0.0 requests==2.14.2 \ + googleapis-common-protos==1.5.5 $VENV_PYTHON "$ROOT/src/python/grpcio_tests/setup.py" preprocess $VENV_PYTHON "$ROOT/src/python/grpcio_tests/setup.py" build_package_protos pip_install_dir "$ROOT/src/python/grpcio_tests" From 4ec4c0b6b44976fedada0f50fe3c823314491f2a Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Thu, 13 Dec 2018 10:56:32 -0800 Subject: [PATCH 295/534] Set SSL_CTX_set_verify even if pem_client_root_certs is null --- src/core/tsi/ssl_transport_security.cc | 47 +++++++++++++------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index d6a72ada0d8..efaf733503e 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -1850,31 +1850,30 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options( break; } SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names); - switch (options->client_certificate_request) { - case TSI_DONT_REQUEST_CLIENT_CERTIFICATE: - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_NONE, nullptr); - break; - case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, - NullVerifyCallback); - break; - case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, nullptr); - break; - case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: - SSL_CTX_set_verify( - impl->ssl_contexts[i], - SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, - NullVerifyCallback); - break; - case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: - SSL_CTX_set_verify( - impl->ssl_contexts[i], - SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); - break; - } - /* TODO(jboeuf): Add revocation verification. */ } + switch (options->client_certificate_request) { + case TSI_DONT_REQUEST_CLIENT_CERTIFICATE: + SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_NONE, nullptr); + break; + case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, + NullVerifyCallback); + break; + case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, nullptr); + break; + case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + NullVerifyCallback); + break; + case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + nullptr); + break; + } + /* TODO(jboeuf): Add revocation verification. */ result = extract_x509_subject_names_from_pem_cert( options->pem_key_cert_pairs[i].cert_chain, From 5ea2ed602b9d7dfec109c520446e6e0570840d45 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 12 Dec 2018 18:52:26 -0800 Subject: [PATCH 296/534] Move most c-ares logs under a tracer --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 42 ++++++++++------- .../dns/c_ares/grpc_ares_ev_driver.cc | 47 ++++++++++++------- .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 43 +++++++++-------- 3 files changed, 74 insertions(+), 58 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index fc83fc44889..abacd0c960d 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -170,7 +170,7 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args) } AresDnsResolver::~AresDnsResolver() { - gpr_log(GPR_DEBUG, "destroying AresDnsResolver"); + GRPC_CARES_TRACE_LOG("resolver:%p destroying AresDnsResolver", this); if (resolved_result_ != nullptr) { grpc_channel_args_destroy(resolved_result_); } @@ -182,7 +182,8 @@ AresDnsResolver::~AresDnsResolver() { void AresDnsResolver::NextLocked(grpc_channel_args** target_result, grpc_closure* on_complete) { - gpr_log(GPR_DEBUG, "AresDnsResolver::NextLocked() is called."); + GRPC_CARES_TRACE_LOG("resolver:%p AresDnsResolver::NextLocked() is called.", + this); GPR_ASSERT(next_completion_ == nullptr); next_completion_ = on_complete; target_result_ = target_result; @@ -225,12 +226,14 @@ void AresDnsResolver::ShutdownLocked() { void AresDnsResolver::OnNextResolutionLocked(void* arg, grpc_error* error) { AresDnsResolver* r = static_cast(arg); GRPC_CARES_TRACE_LOG( - "%p re-resolution timer fired. error: %s. shutdown_initiated_: %d", r, - grpc_error_string(error), r->shutdown_initiated_); + "resolver:%p re-resolution timer fired. error: %s. shutdown_initiated_: " + "%d", + r, grpc_error_string(error), r->shutdown_initiated_); r->have_next_resolution_timer_ = false; if (error == GRPC_ERROR_NONE && !r->shutdown_initiated_) { if (!r->resolving_) { - GRPC_CARES_TRACE_LOG("%p start resolving due to re-resolution timer", r); + GRPC_CARES_TRACE_LOG( + "resolver:%p start resolving due to re-resolution timer", r); r->StartResolvingLocked(); } } @@ -327,8 +330,8 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { service_config_string = ChooseServiceConfig(r->service_config_json_); gpr_free(r->service_config_json_); if (service_config_string != nullptr) { - gpr_log(GPR_INFO, "selected service config choice: %s", - service_config_string); + GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s", + r, service_config_string); args_to_remove[num_args_to_remove++] = GRPC_ARG_SERVICE_CONFIG; args_to_add[num_args_to_add++] = grpc_channel_arg_string_create( (char*)GRPC_ARG_SERVICE_CONFIG, service_config_string); @@ -344,11 +347,11 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { r->backoff_.Reset(); } else if (!r->shutdown_initiated_) { const char* msg = grpc_error_string(error); - gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg); + GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed: %s", r, msg); grpc_millis next_try = r->backoff_.NextAttemptTime(); grpc_millis timeout = next_try - ExecCtx::Get()->Now(); - gpr_log(GPR_INFO, "dns resolution failed (will retry): %s", - grpc_error_string(error)); + GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed (will retry): %s", + r, grpc_error_string(error)); GPR_ASSERT(!r->have_next_resolution_timer_); r->have_next_resolution_timer_ = true; // TODO(roth): We currently deal with this ref manually. Once the @@ -357,9 +360,10 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { RefCountedPtr self = r->Ref(DEBUG_LOCATION, "retry-timer"); self.release(); if (timeout > 0) { - gpr_log(GPR_DEBUG, "retrying in %" PRId64 " milliseconds", timeout); + GRPC_CARES_TRACE_LOG("resolver:%p retrying in %" PRId64 " milliseconds", + r, timeout); } else { - gpr_log(GPR_DEBUG, "retrying immediately"); + GRPC_CARES_TRACE_LOG("resolver:%p retrying immediately", r); } grpc_timer_init(&r->next_resolution_timer_, next_try, &r->on_next_resolution_); @@ -385,10 +389,10 @@ void AresDnsResolver::MaybeStartResolvingLocked() { if (ms_until_next_resolution > 0) { const grpc_millis last_resolution_ago = grpc_core::ExecCtx::Get()->Now() - last_resolution_timestamp_; - gpr_log(GPR_DEBUG, - "In cooldown from last resolution (from %" PRId64 - " ms ago). Will resolve again in %" PRId64 " ms", - last_resolution_ago, ms_until_next_resolution); + GRPC_CARES_TRACE_LOG( + "resolver:%p In cooldown from last resolution (from %" PRId64 + " ms ago). Will resolve again in %" PRId64 " ms", + this, last_resolution_ago, ms_until_next_resolution); have_next_resolution_timer_ = true; // TODO(roth): We currently deal with this ref manually. Once the // new closure API is done, find a way to track this ref with the timer @@ -405,7 +409,6 @@ void AresDnsResolver::MaybeStartResolvingLocked() { } void AresDnsResolver::StartResolvingLocked() { - gpr_log(GPR_DEBUG, "Start resolving."); // TODO(roth): We currently deal with this ref manually. Once the // new closure API is done, find a way to track this ref with the timer // callback as part of the type system. @@ -420,6 +423,8 @@ void AresDnsResolver::StartResolvingLocked() { request_service_config_ ? &service_config_json_ : nullptr, query_timeout_ms_, combiner()); last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); + GRPC_CARES_TRACE_LOG("resolver:%p Started resolving. pending_request_:%p", + this, pending_request_); } void AresDnsResolver::MaybeFinishNextLocked() { @@ -427,7 +432,8 @@ void AresDnsResolver::MaybeFinishNextLocked() { *target_result_ = resolved_result_ == nullptr ? nullptr : grpc_channel_args_copy(resolved_result_); - gpr_log(GPR_DEBUG, "AresDnsResolver::MaybeFinishNextLocked()"); + GRPC_CARES_TRACE_LOG("resolver:%p AresDnsResolver::MaybeFinishNextLocked()", + this); GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE); next_completion_ = nullptr; published_version_ = resolved_version_; diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc index 8abc34c6edb..d99c2e30047 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -90,15 +90,18 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver); static grpc_ares_ev_driver* grpc_ares_ev_driver_ref( grpc_ares_ev_driver* ev_driver) { - gpr_log(GPR_DEBUG, "Ref ev_driver %" PRIuPTR, (uintptr_t)ev_driver); + GRPC_CARES_TRACE_LOG("request:%p Ref ev_driver %p", ev_driver->request, + ev_driver); gpr_ref(&ev_driver->refs); return ev_driver; } static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) { - gpr_log(GPR_DEBUG, "Unref ev_driver %" PRIuPTR, (uintptr_t)ev_driver); + GRPC_CARES_TRACE_LOG("request:%p Unref ev_driver %p", ev_driver->request, + ev_driver); if (gpr_unref(&ev_driver->refs)) { - gpr_log(GPR_DEBUG, "destroy ev_driver %" PRIuPTR, (uintptr_t)ev_driver); + GRPC_CARES_TRACE_LOG("request:%p destroy ev_driver %p", ev_driver->request, + ev_driver); GPR_ASSERT(ev_driver->fds == nullptr); GRPC_COMBINER_UNREF(ev_driver->combiner, "free ares event driver"); ares_destroy(ev_driver->channel); @@ -108,7 +111,8 @@ static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) { } static void fd_node_destroy_locked(fd_node* fdn) { - gpr_log(GPR_DEBUG, "delete fd: %s", fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p delete fd: %s", fdn->ev_driver->request, + fdn->grpc_polled_fd->GetName()); GPR_ASSERT(!fdn->readable_registered); GPR_ASSERT(!fdn->writable_registered); GPR_ASSERT(fdn->already_shutdown); @@ -136,7 +140,7 @@ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, memset(&opts, 0, sizeof(opts)); opts.flags |= ARES_FLAG_STAYOPEN; int status = ares_init_options(&(*ev_driver)->channel, &opts, ARES_OPT_FLAGS); - gpr_log(GPR_DEBUG, "grpc_ares_ev_driver_create_locked"); + GRPC_CARES_TRACE_LOG("request:%p grpc_ares_ev_driver_create_locked", request); if (status != ARES_SUCCESS) { char* err_msg; gpr_asprintf(&err_msg, "Failed to init ares channel. C-ares error: %s", @@ -203,8 +207,9 @@ static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as) { static void on_timeout_locked(void* arg, grpc_error* error) { grpc_ares_ev_driver* driver = static_cast(arg); GRPC_CARES_TRACE_LOG( - "ev_driver=%p on_timeout_locked. driver->shutting_down=%d. err=%s", - driver, driver->shutting_down, grpc_error_string(error)); + "request:%p ev_driver=%p on_timeout_locked. driver->shutting_down=%d. " + "err=%s", + driver->request, driver, driver->shutting_down, grpc_error_string(error)); if (!driver->shutting_down && error == GRPC_ERROR_NONE) { grpc_ares_ev_driver_shutdown_locked(driver); } @@ -216,7 +221,8 @@ static void on_readable_locked(void* arg, grpc_error* error) { grpc_ares_ev_driver* ev_driver = fdn->ev_driver; const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked(); fdn->readable_registered = false; - gpr_log(GPR_DEBUG, "readable on %s", fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p readable on %s", fdn->ev_driver->request, + fdn->grpc_polled_fd->GetName()); if (error == GRPC_ERROR_NONE) { do { ares_process_fd(ev_driver->channel, as, ARES_SOCKET_BAD); @@ -239,7 +245,8 @@ static void on_writable_locked(void* arg, grpc_error* error) { grpc_ares_ev_driver* ev_driver = fdn->ev_driver; const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked(); fdn->writable_registered = false; - gpr_log(GPR_DEBUG, "writable on %s", fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p writable on %s", ev_driver->request, + fdn->grpc_polled_fd->GetName()); if (error == GRPC_ERROR_NONE) { ares_process_fd(ev_driver->channel, ARES_SOCKET_BAD, as); } else { @@ -278,7 +285,8 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) { fdn->grpc_polled_fd = ev_driver->polled_fd_factory->NewGrpcPolledFdLocked( socks[i], ev_driver->pollset_set, ev_driver->combiner); - gpr_log(GPR_DEBUG, "new fd: %s", fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p new fd: %s", ev_driver->request, + fdn->grpc_polled_fd->GetName()); fdn->ev_driver = ev_driver; fdn->readable_registered = false; fdn->writable_registered = false; @@ -295,8 +303,9 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) { if (ARES_GETSOCK_READABLE(socks_bitmask, i) && !fdn->readable_registered) { grpc_ares_ev_driver_ref(ev_driver); - gpr_log(GPR_DEBUG, "notify read on: %s", - fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p notify read on: %s", + ev_driver->request, + fdn->grpc_polled_fd->GetName()); fdn->grpc_polled_fd->RegisterForOnReadableLocked(&fdn->read_closure); fdn->readable_registered = true; } @@ -304,8 +313,9 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) { // has not been registered with this socket. if (ARES_GETSOCK_WRITABLE(socks_bitmask, i) && !fdn->writable_registered) { - gpr_log(GPR_DEBUG, "notify write on: %s", - fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p notify write on: %s", + ev_driver->request, + fdn->grpc_polled_fd->GetName()); grpc_ares_ev_driver_ref(ev_driver); fdn->grpc_polled_fd->RegisterForOnWriteableLocked( &fdn->write_closure); @@ -332,7 +342,8 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) { // If the ev driver has no working fd, all the tasks are done. if (new_list == nullptr) { ev_driver->working = false; - gpr_log(GPR_DEBUG, "ev driver stop working"); + GRPC_CARES_TRACE_LOG("request:%p ev driver stop working", + ev_driver->request); } } @@ -345,9 +356,9 @@ void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) { ? GRPC_MILLIS_INF_FUTURE : ev_driver->query_timeout_ms + grpc_core::ExecCtx::Get()->Now(); GRPC_CARES_TRACE_LOG( - "ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in %" PRId64 - " ms", - ev_driver, timeout); + "request:%p ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in " + "%" PRId64 " ms", + ev_driver->request, ev_driver, timeout); grpc_ares_ev_driver_ref(ev_driver); grpc_timer_init(&ev_driver->query_timeout, timeout, &ev_driver->on_timeout_locked); diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index 68977567694..1a7e5d06268 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -96,11 +96,11 @@ static void log_address_sorting_list(const ServerAddressList& addresses, for (size_t i = 0; i < addresses.size(); i++) { char* addr_str; if (grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true)) { - gpr_log(GPR_DEBUG, "c-ares address sorting: %s[%" PRIuPTR "]=%s", + gpr_log(GPR_INFO, "c-ares address sorting: %s[%" PRIuPTR "]=%s", input_output_str, i, addr_str); gpr_free(addr_str); } else { - gpr_log(GPR_DEBUG, + gpr_log(GPR_INFO, "c-ares address sorting: %s[%" PRIuPTR "]=", input_output_str, i); } @@ -209,10 +209,10 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, addresses.emplace_back(&addr, addr_len, args); char output[INET6_ADDRSTRLEN]; ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN); - gpr_log(GPR_DEBUG, - "c-ares resolver gets a AF_INET6 result: \n" - " addr: %s\n port: %d\n sin6_scope_id: %d\n", - output, ntohs(hr->port), addr.sin6_scope_id); + GRPC_CARES_TRACE_LOG( + "request:%p c-ares resolver gets a AF_INET6 result: \n" + " addr: %s\n port: %d\n sin6_scope_id: %d\n", + r, output, ntohs(hr->port), addr.sin6_scope_id); break; } case AF_INET: { @@ -226,10 +226,10 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, addresses.emplace_back(&addr, addr_len, args); char output[INET_ADDRSTRLEN]; ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN); - gpr_log(GPR_DEBUG, - "c-ares resolver gets a AF_INET result: \n" - " addr: %s\n port: %d\n", - output, ntohs(hr->port)); + GRPC_CARES_TRACE_LOG( + "request:%p c-ares resolver gets a AF_INET result: \n" + " addr: %s\n port: %d\n", + r, output, ntohs(hr->port)); break; } } @@ -252,9 +252,9 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, static void on_srv_query_done_locked(void* arg, int status, int timeouts, unsigned char* abuf, int alen) { grpc_ares_request* r = static_cast(arg); - gpr_log(GPR_DEBUG, "on_query_srv_done_locked"); + GRPC_CARES_TRACE_LOG("request:%p on_query_srv_done_locked", r); if (status == ARES_SUCCESS) { - gpr_log(GPR_DEBUG, "on_query_srv_done_locked ARES_SUCCESS"); + GRPC_CARES_TRACE_LOG("request:%p on_query_srv_done_locked ARES_SUCCESS", r); struct ares_srv_reply* reply; const int parse_status = ares_parse_srv_reply(abuf, alen, &reply); if (parse_status == ARES_SUCCESS) { @@ -297,9 +297,9 @@ static const char g_service_config_attribute_prefix[] = "grpc_config="; static void on_txt_done_locked(void* arg, int status, int timeouts, unsigned char* buf, int len) { - gpr_log(GPR_DEBUG, "on_txt_done_locked"); char* error_msg; grpc_ares_request* r = static_cast(arg); + GRPC_CARES_TRACE_LOG("request:%p on_txt_done_locked", r); const size_t prefix_len = sizeof(g_service_config_attribute_prefix) - 1; struct ares_txt_ext* result = nullptr; struct ares_txt_ext* reply = nullptr; @@ -332,7 +332,8 @@ static void on_txt_done_locked(void* arg, int status, int timeouts, service_config_len += result->length; } (*r->service_config_json_out)[service_config_len] = '\0'; - gpr_log(GPR_INFO, "found service config: %s", *r->service_config_json_out); + GRPC_CARES_TRACE_LOG("request:%p found service config: %s", r, + *r->service_config_json_out); } // Clean up. ares_free_data(reply); @@ -358,12 +359,6 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( grpc_error* error = GRPC_ERROR_NONE; grpc_ares_hostbyname_request* hr = nullptr; ares_channel* channel = nullptr; - /* TODO(zyc): Enable tracing after #9603 is checked in */ - /* if (grpc_dns_trace) { - gpr_log(GPR_DEBUG, "resolve_address (blocking): name=%s, default_port=%s", - name, default_port); - } */ - /* parse name, splitting it into host and port parts */ char* host; char* port; @@ -388,7 +383,7 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver); // If dns_server is specified, use it. if (dns_server != nullptr) { - gpr_log(GPR_INFO, "Using DNS server %s", dns_server); + GRPC_CARES_TRACE_LOG("request:%p Using DNS server %s", r, dns_server); grpc_resolved_address addr; if (grpc_parse_ipv4_hostport(dns_server, &addr, false /* log_errors */)) { r->dns_server_addr.family = AF_INET; @@ -513,7 +508,7 @@ static bool resolve_as_ip_literal_locked( static bool target_matches_localhost_inner(const char* name, char** host, char** port) { if (!gpr_split_host_port(name, host, port)) { - gpr_log(GPR_INFO, "Unable to split host and port for name: %s", name); + gpr_log(GPR_ERROR, "Unable to split host and port for name: %s", name); return false; } if (gpr_stricmp(*host, "localhost") == 0) { @@ -547,6 +542,10 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( r->success = false; r->error = GRPC_ERROR_NONE; r->pending_queries = 0; + GRPC_CARES_TRACE_LOG( + "request:%p c-ares grpc_dns_lookup_ares_locked_impl name=%s, " + "default_port=%s", + r, name, default_port); // Early out if the target is an ipv4 or ipv6 literal. if (resolve_as_ip_literal_locked(name, default_port, addrs)) { GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); From 48ac4ee48a56582c86f2ada6d3281e37590c57c4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 13 Dec 2018 11:21:45 -0800 Subject: [PATCH 297/534] Test assert failure --- src/objective-c/tests/InteropTests.m | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 3665e9705d8..656af188884 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -197,7 +197,8 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testEmptyUnaryRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnaryWithV2API"]; + __weak XCTestExpectation *expectReceive = [self expectationWithDescription:@"EmptyUnaryWithV2API received message"]; + __weak XCTestExpectation *expectComplete = [self expectationWithDescription:@"EmptyUnaryWithV2API completed"]; GPBEmpty *request = [GPBEmpty message]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; @@ -212,11 +213,12 @@ BOOL isRemoteInteropTest(NSString *host) { if (message) { id expectedResponse = [GPBEmpty message]; XCTAssertEqualObjects(message, expectedResponse); - [expectation fulfill]; + [expectReceive fulfill]; } } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { XCTAssertNil(error, @"Unexpected error: %@", error); + [expectComplete fulfill]; }] callOptions:options]; [call start]; @@ -249,9 +251,9 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testLargeUnaryRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectRecvMessage = + __weak XCTestExpectation *expectReceive = [self expectationWithDescription:@"LargeUnaryWithV2API received message"]; - __weak XCTestExpectation *expectRecvComplete = + __weak XCTestExpectation *expectComplete = [self expectationWithDescription:@"LargeUnaryWithV2API received complete"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -277,12 +279,12 @@ BOOL isRemoteInteropTest(NSString *host) { [NSMutableData dataWithLength:314159]; XCTAssertEqualObjects(message, expectedResponse); - [expectRecvMessage fulfill]; + [expectReceive fulfill]; } } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { XCTAssertNil(error, @"Unexpected error: %@", error); - [expectRecvComplete fulfill]; + [expectComplete fulfill]; }] callOptions:options]; [call start]; From dc502a80988763abefb70938d020123ef0422e18 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 13 Dec 2018 11:27:26 -0800 Subject: [PATCH 298/534] clang-format --- src/objective-c/tests/InteropTests.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 656af188884..717dfd81f7d 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -197,8 +197,10 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testEmptyUnaryRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectReceive = [self expectationWithDescription:@"EmptyUnaryWithV2API received message"]; - __weak XCTestExpectation *expectComplete = [self expectationWithDescription:@"EmptyUnaryWithV2API completed"]; + __weak XCTestExpectation *expectReceive = + [self expectationWithDescription:@"EmptyUnaryWithV2API received message"]; + __weak XCTestExpectation *expectComplete = + [self expectationWithDescription:@"EmptyUnaryWithV2API completed"]; GPBEmpty *request = [GPBEmpty message]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; From 0f0822d53f37ea9da8bf838e5b3c62b05afe2f10 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 13 Dec 2018 16:33:02 -0800 Subject: [PATCH 299/534] WIP: Utilize the GitHub Check Feature --- tools/profiling/bloat/bloat_diff.py | 4 +- tools/profiling/ios_bin/binary_size.py | 4 +- .../microbenchmarks/bm_diff/bm_main.py | 4 +- tools/profiling/qps/qps_diff.py | 4 +- tools/run_tests/python_utils/check_on_pr.py | 98 +++++++++++++++++++ 5 files changed, 106 insertions(+), 8 deletions(-) create mode 100644 tools/run_tests/python_utils/check_on_pr.py diff --git a/tools/profiling/bloat/bloat_diff.py b/tools/profiling/bloat/bloat_diff.py index 91611c2ca4a..36189151e9e 100755 --- a/tools/profiling/bloat/bloat_diff.py +++ b/tools/profiling/bloat/bloat_diff.py @@ -25,7 +25,7 @@ import sys sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils')) -import comment_on_pr +import check_on_pr argp = argparse.ArgumentParser(description='Perform diff on microbenchmarks') @@ -90,4 +90,4 @@ for lib in LIBS: text += '\n\n' print text -comment_on_pr.comment_on_pr('```\n%s\n```' % text) +check_on_pr.check_on_pr('Bloat Difference', '```\n%s\n```' % text) diff --git a/tools/profiling/ios_bin/binary_size.py b/tools/profiling/ios_bin/binary_size.py index d4d134fef37..f0c8dd01a01 100755 --- a/tools/profiling/ios_bin/binary_size.py +++ b/tools/profiling/ios_bin/binary_size.py @@ -26,7 +26,7 @@ from parse_link_map import parse_link_map sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils')) -import comment_on_pr +import check_on_pr # Only show diff 1KB or greater diff_threshold = 1000 @@ -147,4 +147,4 @@ for frameworks in [False, True]: print text -comment_on_pr.comment_on_pr('```\n%s\n```' % text) +check_on_pr.check_on_pr('Binary Size', '```\n%s\n```' % text) diff --git a/tools/profiling/microbenchmarks/bm_diff/bm_main.py b/tools/profiling/microbenchmarks/bm_diff/bm_main.py index 96c63ba060e..e5061b24f57 100755 --- a/tools/profiling/microbenchmarks/bm_diff/bm_main.py +++ b/tools/profiling/microbenchmarks/bm_diff/bm_main.py @@ -30,7 +30,7 @@ import subprocess sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils')) -import comment_on_pr +import check_on_pr sys.path.append( os.path.join( @@ -152,7 +152,7 @@ def main(args): if note: text = note + '\n\n' + text print('%s' % text) - comment_on_pr.comment_on_pr('```\n%s\n```' % text) + check_on_pr.check_on_pr('Benchmark', '```\n%s\n```' % text) if __name__ == '__main__': diff --git a/tools/profiling/qps/qps_diff.py b/tools/profiling/qps/qps_diff.py index 393f862b4db..2c73b236e25 100755 --- a/tools/profiling/qps/qps_diff.py +++ b/tools/profiling/qps/qps_diff.py @@ -33,7 +33,7 @@ import bm_speedup sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils')) -import comment_on_pr +import check_on_pr def _args(): @@ -164,7 +164,7 @@ def main(args): else: text = '[qps] No significant performance differences' print('%s' % text) - comment_on_pr.comment_on_pr('```\n%s\n```' % text) + check_on_pr.check_on_pr('QPS', '```\n%s\n```' % text) if __name__ == '__main__': diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py new file mode 100644 index 00000000000..96418bf2d3a --- /dev/null +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -0,0 +1,98 @@ +# Copyright 2018 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. + +from __future__ import print_function +import os +import json +import time +import datetime + +import requests +import jwt + +_GITHUB_API_PREFIX = 'https://api.github.com' +_GITHUB_REPO = 'lidizheng/grpc' +_GITHUB_APP_ID = 22288 +_INSTALLATION_ID = 516307 +_GITHUB_APP_KEY = open(os.environ['HOME'] + '/.ssh/google-grpc-checker.2018-12-13.private-key.pem', 'r').read() + +_ACCESS_TOKEN_CACHE = None + +def _jwt_token(): + return jwt.encode({ + 'iat': int(time.time()), + 'exp': int(time.time() + 60 * 10), # expire in 10 minutes + 'iss': _GITHUB_APP_ID, + }, _GITHUB_APP_KEY, algorithm='RS256') + +def _access_token(): + global _ACCESS_TOKEN_CACHE + if _ACCESS_TOKEN_CACHE == None or _ACCESS_TOKEN_CACHE['exp'] < time.time(): + resp = requests.post( + url='https://api.github.com/app/installations/%s/access_tokens' % _INSTALLATION_ID, + headers={ + 'Authorization': 'Bearer %s' % _jwt_token().decode('ASCII'), + 'Accept': 'application/vnd.github.machine-man-preview+json', + } + ) + _ACCESS_TOKEN_CACHE = {'token': resp.json()['token'], 'exp': time.time()+60} + return _ACCESS_TOKEN_CACHE['token'] + +def _call(url, method='GET', json=None): + if not url.startswith('https://'): + url = _GITHUB_API_PREFIX + url + headers={ + 'Authorization': 'Bearer %s' % _access_token(), + 'Accept': 'application/vnd.github.antiope-preview+json', + } + return requests.request( + method=method, + url=url, + headers=headers, + json=json) + +def _latest_commit(): + resp = _call('/repos/%s/pulls/%s/commits' % (_GITHUB_REPO, os.environ['ghprbPullId'])) + return resp.json()[-1] + +def check_on_pr(name, summary, success=True): + """Create/Update a check on current pull request. + + The check runs are aggregated by their name, so newer check will update the + older check with the same name. + + Requires environment variable 'ghprbPullId' to indicate which pull request + should be updated. + + Args: + name: The name of the check. + summary: A str in Markdown to be used as the detail information of the check. + success: A bool indicates whether the check is succeed or not. + """ + if 'ghprbPullId' not in os.environ: + print('Missing ghprbPullId env var: not commenting') + return + commit = _latest_commit() + resp = _call('/repos/%s/check-runs' % _GITHUB_REPO, method='POST', json={ + 'name': name, + 'head_sha': commit['sha'], + 'status': 'completed', + 'completed_at': '%sZ' % datetime.datetime.utcnow().replace(microsecond=0).isoformat(), + 'conclusion': 'success' if success else 'failure', + 'output': { + 'title': name, + 'summary': summary, + } + }) + print('Result of Creating/Updating Check on PR:', json.dumps(resp.json(), indent=2)) From b4ccbdb124e11dd740cd042cfab88aa38e34398d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 13 Dec 2018 16:48:28 -0800 Subject: [PATCH 300/534] Remove some annotations in GRPCRequestHeader --- src/objective-c/GRPCClient/GRPCCall.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 4ef8cee36de..f36b814cec3 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -370,11 +370,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (nullable id)objectForKeyedSubscript:(nonnull id)key; -- (void)setObject:(nullable id)obj forKeyedSubscript:(nonnull id)key; +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)obj forKeyedSubscript:(id)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(nonnull id)key; +- (void)removeObjectForKey:(id)key; @end #pragma clang diagnostic push From 63e73e428fdfaf940074bb59753cd26ad24d3b49 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 13 Dec 2018 16:51:58 -0800 Subject: [PATCH 301/534] Metadata tutorial --- examples/cpp/metadata/Makefile | 96 +++ examples/cpp/metadata/README.md | 69 +++ examples/cpp/metadata/greeter_client | Bin 0 -> 267800 bytes examples/cpp/metadata/greeter_client.cc | 95 +++ examples/cpp/metadata/greeter_client.o | Bin 0 -> 101304 bytes examples/cpp/metadata/greeter_server | Bin 0 -> 278392 bytes examples/cpp/metadata/greeter_server.cc | 82 +++ examples/cpp/metadata/greeter_server.o | Bin 0 -> 112144 bytes examples/cpp/metadata/helloworld.grpc.pb.cc | 70 +++ examples/cpp/metadata/helloworld.grpc.pb.h | 197 ++++++ examples/cpp/metadata/helloworld.grpc.pb.o | Bin 0 -> 398496 bytes examples/cpp/metadata/helloworld.pb.cc | 638 ++++++++++++++++++++ examples/cpp/metadata/helloworld.pb.h | 419 +++++++++++++ examples/cpp/metadata/helloworld.pb.o | Bin 0 -> 111592 bytes 14 files changed, 1666 insertions(+) create mode 100644 examples/cpp/metadata/Makefile create mode 100644 examples/cpp/metadata/README.md create mode 100755 examples/cpp/metadata/greeter_client create mode 100644 examples/cpp/metadata/greeter_client.cc create mode 100644 examples/cpp/metadata/greeter_client.o create mode 100755 examples/cpp/metadata/greeter_server create mode 100644 examples/cpp/metadata/greeter_server.cc create mode 100644 examples/cpp/metadata/greeter_server.o create mode 100644 examples/cpp/metadata/helloworld.grpc.pb.cc create mode 100644 examples/cpp/metadata/helloworld.grpc.pb.h create mode 100644 examples/cpp/metadata/helloworld.grpc.pb.o create mode 100644 examples/cpp/metadata/helloworld.pb.cc create mode 100644 examples/cpp/metadata/helloworld.pb.h create mode 100644 examples/cpp/metadata/helloworld.pb.o diff --git a/examples/cpp/metadata/Makefile b/examples/cpp/metadata/Makefile new file mode 100644 index 00000000000..46be8bfaa3c --- /dev/null +++ b/examples/cpp/metadata/Makefile @@ -0,0 +1,96 @@ +# +# 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. +# + HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) +CXX = g++ +CPPFLAGS += `pkg-config --cflags protobuf grpc` +CXXFLAGS += -std=c++11 +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -lgrpc++_reflection\ + -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ + -ldl +endif +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + PROTOS_PATH = ../../protos + vpath %.proto $(PROTOS_PATH) + all: system-check greeter_client greeter_server + greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + .PRECIOUS: %.grpc.pb.cc +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + .PRECIOUS: %.pb.cc +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + # The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/examples/cpp/metadata/README.md b/examples/cpp/metadata/README.md new file mode 100644 index 00000000000..7b33074ba1e --- /dev/null +++ b/examples/cpp/metadata/README.md @@ -0,0 +1,69 @@ +# Metadata Example + +## Overview + +This example shows you how to add custom headers on the client and server and +how to access them. + +Custom metadata must follow the "Custom-Metadata" format listed in +https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md, with the +exception of binary headers, which don't have to be base64 encoded. + +### Get the tutorial source code + The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: + ```sh +$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc +``` + Change your current directory to examples/cpp/metadata + ```sh +$ cd examples/cpp/metadata +``` + +### Generating gRPC code + To generate the client and server side interfaces: + ```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + ```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` +### Try it! +Build client and server: + +```sh +$ make +``` + +Run the server, which will listen on port 50051: + +```sh +$ ./greeter_server +``` + +Run the client (in a different terminal): + +```sh +$ ./greeter_client +``` + +If things go smoothly, you will see in the client terminal: + +"Client received initial metadata from server: initial metadata value" +"Client received trailing metadata from server: trailing metadata value" +"Client received message: Hello World" + + +And in the server terminal: + +"Header key: custom-bin , value: " +"Header key: custom-header , value: Custom Value" +"Header key: user-agent , value: grpc-c++/1.16.0-dev grpc-c/6.0.0-dev (linux; chttp2; gao)" + +Note that the value for custom-bin doesn't print nicely because it's a binary +value. You can indicate a binary value through appending "-bin" to the header key. + +We did not add the user-agent metadata as a custom header. This shows how +the gRPC framework adds some headers under the hood that may show up in the +metadata map. diff --git a/examples/cpp/metadata/greeter_client b/examples/cpp/metadata/greeter_client new file mode 100755 index 0000000000000000000000000000000000000000..929a51c3a5b426131d0573b2e5cd91da16f1ecf4 GIT binary patch literal 267800 zcmdqK3tXJV)jz(upcswd1;sn@igzF(5;c_=S2vnO3_+~vs+ZZB=Wu*{os zzdHSJf{|9w&b=k+Te7cunsUTux$;9)x$;94zIhfZu+KbA``9*q=jwd#^DN}?W1ht2 zr|A8rD*oR0yQ;D&1asb+yy8{KDYOit`XVk7F zU;V}7_vRe>(1lgcU%d6Q3gk85OFHB5O&!(olfvmOEk698zUsV|jMTAXeOr(B&Fh%w z+a;?r_0rC9W7DPu_8#XOGcJAfxUr)HXQnUooi$@+QOjPVd@VlT4QKW2>&rURzsu;9 zhbvZ$&KcX{E7)f=s>y1bcHCLrS!enVoN->x;TbKyu{Y=V&Pw%_kLzCH+daeQD;<4S zj_?9De2w@v<9ju}OYr>`zTd{zeDtu91-=j9`w+el4`E=vQW_+JE06e$g8`0@!@cb>l&*S@ohV|;_OZxe;e!hz5 zYxw>S-{0f=I==k8sUE(!@O&HJeth4>_mB9#kM9TgI{1Ew?^b+2!gtzp_jad#5LmJN zgi8;)@VCzt)~(s{)M4LP{b~0hi>DoW>4C@o@R!vO9sBvRD}S7p``EyBbANWpaZ9h+ z^W~>dv|Jp!Gk#HvG_iTb{Zvbynoy@`BS|c=OY@t2eAX^v!*8A3M|k z>ek_BH*Sb5?^rW&w?}G!pa+V}o@PVD~0iiI5) zXJ@rs^oO!odD@-IDT@|VXx{>#7%Cm!

LvYO3=Q>NReJDEDZ5Vo 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%0D5LaD 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 d`es|tB;We)N~N#mwEyrq8R +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class CustomHeaderClient { + public: + CustomHeaderClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + + // Setting custom metadata to be sent to the server + context.AddMetadata("custom-header", "Custom Value"); + + // Setting custom binary metadata + char bytes[8] = {'\0', '\1', '\2', '\3', + '\4', '\5', '\6', '\7'}; + context.AddMetadata("custom-bin", grpc::string(bytes, 8)); + + // The actual RPC. + Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. + if (status.ok()) { + std::cout << "Client received initial metadata from server: " << context.GetServerInitialMetadata().find("custom-server-metadata")->second << std::endl; + std::cout << "Client received trailing metadata from server: " << context.GetServerTrailingMetadata().find("custom-trailing-metadata")->second << std::endl; + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureChannelCredentials()). + CustomHeaderClient greeter(grpc::CreateChannel( + "localhost:50051", grpc::InsecureChannelCredentials())); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Client received message: " << reply << std::endl; + return 0; +} diff --git a/examples/cpp/metadata/greeter_client.o b/examples/cpp/metadata/greeter_client.o new file mode 100644 index 0000000000000000000000000000000000000000..483cb0741cf7ac3f32e14729cb8280d97346ecfc GIT binary patch literal 101304 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 z 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 bdM5cie7Cal3nk;9Y{^RhooGPxcIE#7vdv

+#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + std::string prefix("Hello "); + + // Get the client's initial metadata + std::cout << "Client metadata: " << std::endl; + const std::multimap metadata = context->client_metadata(); + for (auto iter = metadata.begin(); iter != metadata.end(); ++iter) { + std::cout << "Header key: " << iter->first << " , value: " << iter->second << std::endl; + } + + context->AddInitialMetadata("custom-server-metadata", "initial metadata value"); + context->AddTrailingMetadata("custom-trailing-metadata", "trailing metadata value"); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} diff --git a/examples/cpp/metadata/greeter_server.o b/examples/cpp/metadata/greeter_server.o new file mode 100644 index 0000000000000000000000000000000000000000..dc197b2d14cb36605b595aec47dfbde9cb1df81b GIT binary patch literal 112144 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%0Ab0J=P1b&%@)Zc;B z$&rkoc`;#_z^_o0`p;;Aqg?hoXA1mEL7x)%RRUikaLk9>V4c9P7W9t^oP9h@{-eO> z2>N{jPYC?@{`v;XJ6GW63cO0-QGuhL6DX}(;MIbDxxkYG-yraL0^cU^`2v4i;57p8 zJ3!x{{_JBQa1_c=_(ia0tO+h6F5J6V)AN%^Sd6zHwnA}0lHokIPc-X zq&)&}Vqypf(!_@4`l7&x3A|b04qm$j0v{&u zn+0Aj@MQw86Zmq0uNL?Ufo~G{Edqa0;I|5VkHA+7eBeR)2K8?j_%MOrCh&5BuM&8Z zz*h@=jlequzFFX368NhEzg^%T34D#fk01vU_5ZTKM+y8Z0-r7LI|SY)@H+**PT*?= zzD3|)75EN;e@)<>0$(TaoP+fZ>W||OkBRvL|GJ<*UEoN+n$ji-{2PLPs=$$+>#j!N z{4N05Rto%XkU=h1@@>c3gwg#v#_;1vS@k-(b-{$qi!5%|Lb-z@N-2z3kCkDz$*m)Gl4e={O1B+Bk;!rzFFXp3w*o4pAh)#0!KUK zy66=6lY)NmVfqHkwN>CH0)I;2vjzUNz}p1=jKJ3ke4D_x2>cfU-y!g41>Py}=LA0Z zaD9XNKQHhSfxjT|*#iHiz^@nhuLQnA;8>sADQ$zmUljD)1paG*?-KY+0?$1{-=O|4 z3w)@+Stcfz3;Y#9UnlV23VgM|QN~yB4_uo9xV!!^qGfS?Dlyj?0Y~=fu!duBBtT*W z9!}|uz>l^#Bj&cWI0_gMzg(ZiJfgW#Cn;Kt!XdtOfVy<}?G5)wdES>B0v~URXGZUS z1PSO}?LZk65=GG;#igo5z7GHDd13of1 zoY(`=@U;l7Kb#Zi5boWI5) zZ{KNu)|`nsIHHFp^Q=F}RvaIXzkH9^)WSK4;ZYNeZNJWi+iwL;hrk8uuzMd#4VM*v zKh58=HO@QyD|?z{u<_!R>g)VPE$T3H_>PeNCN$4W_^Ab>AU$7&ou(*qLYcJ)_4Nw; zRG0eDN1)jIKS_4y81|qNMcp`Tizf}Jt=>MtoJCEupCjHI2XF^#sWaU3GKamQ~g7_YoJP6Bs z%nQ#V)^zgWtjO9XiK~i%)48 zCg-lcnh9CbS2GQHu`-4{)v;4ueAp9Q2+r3x8265|vR|ifhMHtQ&(jR%*Bdr1%*MAY zp=Vb(*@;^dXR6*%06&pM$6valdSBA#U`qPiU+#IB{>JR3%Iv~%;nAT7J$v?Le3gk) z=l%^vzU&~k{XVV9U-dYJ;?b6^Nj#~Ns)IjF3W>oFq2d!sGAcr31I7|0z zO1~P&n7tl!Or<}oZcNhIomlCXws$(F_y8|diaW@7YyRFK)H@1zU*WaM57?xuV-NNw z~lHX z(_a>0c)fqxreAdSr+KQAWwl2Mr!omc*sl{j16uW(ciQd4JY_*Wmq>lu*j*Ut`g~uk zIH))40XzOGm?Dg#=SHJ$ol=7>8?@pPDYnemhE_<7|Sz}MBgBIxvPef6ZrE?tf+ zj*SdfNe_N9JG=8AO|9J%=gFuYIB=efn}07gKv(Obz0u&jq?66j-sz50bnB?sY}9wC zV$k+_qndE+NqfFxZZ_?E@3dQhWdGMAuTqoCqGD^#nzizIS@G{a8F-1)&Gta|gb7$0PYp$m>OkzQdBd z!}5X>dt>|xxLQV!&wb1Lc^qlS7A4-!DHq8tytiW3)hjyhV7t$w7GY;h_s_WdTolCP zGxzgQI&PU>d*NHDj|%Q$34opc-WhGYrEz?6HW*y!;U{5<5{44%=Mcdj8q7t8KcFg&5iUns~TaCBX_4#7*8 zX}5+Hbsk&GeiodB{|{JM^XwUhriQ@zkm?{We^vGDknb6u zI!3QIMM=Z!>O?)i4!tx7n8sr^jx-}N`%Ll?ya#4OdBk3@3cBcUhAr>j33b7IdT$tk zx-*@x7gQi!LFni@KU>dQe83Dr@!%nQTDtgI=?M6dN1_gPT+h73^t+e9Xl)`fY%?{I z;jwyQ@p#Ogi5y7P4`ER=^8tA}uUa_tE}m#^PArz0Pr4LR=Z%QR=eM=Ro082fjSY#q z+SKCs!a`?6Rbzd9vH^aB+t8Rwj<{&rtl=%GMAZV~Pu9feH7Dwm@H5Hg#?~hNW8eMw z`@%W!y>473aq}j)ULv>q|I?HvX7_AHN^Ud>q>ND-8Vjol)lF(8iCy<;IIX zo1ygoBiu6|hc^Cd#qBt<{CI8|^Koe7uQTxfDGT{21OFRY@bfopr2cr$8SBlVP5*qC+W7gK0J8peX2FlPj+f+r3+`Dihc@}U6t|!M(JadUk%1r2e`C2E z+T=SxitlwHu?DmemrlE`8c%k4<&wCemuX8 z`8c%kk23J%xk=2&p^d-Pz>nuBF&~FE{&EBVpP@aOk3$>(Y~q*w7rz6_d>q>NYYg)L zl7)OeuT0ke+gb20HOPM_3;xvx{=a6yk8>?vQvZJf#`VUbt^PI``2Pm^F&~FE{>=t{ z98;K&LmNMy<%pNm|6RCeJ`QdCXzO@M{`cUX`8c%kziQw|otTe98~;uN|L!d0?;(CU z{%p-cKAug5m*mHDBw23`ZTjycep!EeAV22g(8ixj-=UHGzs*Aa5e9y26PC-NO@2P{ z%kty-i_FKNjen>?KAum=d>q>NM;Z8E%Ywhuz>nwKv0M&q^6|_Iykz~q5BJQ+p^bmG zfq!=v^6}gJc**)ln`F5h+T`Q6>x2Awt{U@kXyeCkqvIvZkLRf|ABQ&nr3U$bhy0k2 zLmU4}gZxjkkbkE^KA!u-ayhigzuO=mzpKuC9NPFd8sy_gc$tqw8$W-)ShhcYPoDWW zwDE5t`Lg}`WWm49z~46ue*Vs~l>b2%?f*xTFUybT%yGFnw3YvD13!+b%*UaPe-H6X z{SU~3ztg~fU>5v+BiQ@={SUvr&3bca(?8F^kLPYMABQ&n;|=_IS?~`v@E@85KYw3a zw*O&S@Skgte|Q%Bd_Jjcf1Fdf-Z-??-%OG(^~dwSn2$pn|CI**qqE?zHk5yG7W_>H z`DbRq&)++j^*1aF{^bV!@f(27~^1 z&LQ)0Xye~((EqqB`1$+s(*8coqWoJ8`k$DE{1*-U=u>jJIkc6ZzjH6^{~uZC|F)t2 z{+R{;9)tb`S?J$skdJFRTy73+q^COv$LmU4P z13#WK$$T8z_zMmE_)Nik9NPHLHSptE6wJq=ji1j=mi33{EHNL4HvXAJAo)jT!9T~q zKRgTmI^vi8e?%7iDFc6T7W~&6^#4~D_P^4=kLOYn?1r}bztg~9k_G>I;+OUJaTfY- zH1Oj&mYM3m*`Pn3bC)UqV+Q$nE@r0u+YIvYnL1Pc?FRYdv*6!hkUt>{{Tfw93Q<>PswneyimzqH?27W{(^{4=xQ&o}6g=VxZB zKcC|w%a7-2X3Ae;kdNnXX39UwP<}jbGgJO@13#Y2nJGV?OC!sFMHc*X4CTjjH8Yi8 zXVCxZEcp5S9BF@e9%rWVuQ%vFCky_S2L41A{C67o=Vrmb-cWyd4riw2-)N9uody5H z27WxhGgJ9n4g7eXXQuow8u;;i&rJDu5Wlpank@Kt8sy`7p_$6xW8lYgMKk5^H1Ok^ zY^MBu`-jJWJQp-m{ygHB^@ryYX39Unv1 zW~%=h13#X3nJNF>#D9eDhHC%Qf3nbjvq3(d=b5Se$B19{-Wc*B4}(<9)5ag958f96FJk=zorHv$a2AA_=U%85Uy z|57?{i|dQ&gZCFff~o%VakCs;T+dkl--dhUXZ$k2P{m;RSCahGAx&O^;;1vrO#BaJ z$d709nD~EB{HIFc5D(Tfo++ftA4n)Ml>dI94VEAGl$qr7gBNV?^j!fl&H!LG@t;eM z`*0t3SpPFD{MQiw8EN=&pO8uZox~s9n;O)=$-;j>@gJW?{?{!0PZPg9BMP$$%Kr-R zo7%6!(0+KnR|6Kq~`C z+af6c+ay0&e^(AtZ0`Bh`Yzmlzp?0FNBlTH$}6bg$DVLLq@^!<9i}g`JW~EyQFZ4 z2j&0PB0om*=MX>I&yx@j%E$LCCixH2M1Laja}bn20QgPyztK?srwsBZTI9b-^4nQ3 zg+ck}TjXyg`D=&|%m0i){^J(;m(awMZvN>H&&j6xt0Bg8^UqQX|8n9_=f7PC{HFS^ z*r^L%D9VrL>IK{XC5!y8lKgb-|AIySQj#zG{|g5B{lQN+)!)M;AN@ml1=~Ld_)X|P{?Gz#~!T(r<*^=0>7#J z+YRzxGssVo{9w6CNd6wJhWj^QPR=Te{zItX>GZ$FqW>;~{`g1@@OZ$7rAb+1l z{tl9V1`DPzDF5FU`Rho&Y=7*M!SbI2>l9EmA^*G2v05NK#*lPP>)t@*ehYt|g+Hi& z0X%1$qxNtcUbs4iT}(r{9gioQ~Na; z^#6xJ|G!w|521ncgf#Nsu*hF&kdOP{g7z~CI*6(M#*_TH0r^NPud{&PRQ~lOe-06& z{eBGbp#0Sq`5Q=ny7BW?i+t5tKweD9?=;AN)gpf%$xqjRUbe`OVP}O)_MiX4eX#t4 z;W^n<|3}e-*MTY*?@zG)8!Y_!#2TLI0O5@{gi{2h7`dVOiyMEELdG{vjFiFS76#6aS4; z7{r71*9`oo^6#bcw-GCi!{qYeqT#A7+sM9gF-v^x&UP{yi4?Lk;qeFvuSS>kOv$ z8%FY}8r)h4_P+yx-&FomgZ!fm@~^hYpG@-8&A*pf_@2B`)$rp|6<@bwckpE{wEmpzu6-Hmn1)(|FFa& zf4xEeNe20QEb{y0>-q|gUszZ2s)r70s=p)hHB~zPe^~fWBmQ*j5AOrNss6W6`Q`j^ zilO{%@SJVZe~v}}p#A*S!rx5%!*n&ce^Hja-U5D;{<{qNpJvd10d#Pa{`cf-DbuAe zhzIqb2mB`aga57><@`6)Ape^d`G3#X{OQJ@Pb~boCuhcw&zUCu=aBwj9_m8>+D8C5&T*x-0|DTCJ zUHv~`;onF6d%55g2Ib!e{HF5ff1nw*5+9bo2>u1hT0vytRPl09(&fiEYuP*|> zN&ZffFWY~lLH>sp`A40irKEfRv&SO8(;$DeLH^m`AehR3F3BGx3k&gJ{oiWgFDL#D zY4~pjepCJBQNv67EiveS3d~a`{r8gmboO_fh5x`ITJd!JD}djm{}$3;w*NT>{ok_4 zA7YV@WtG<-E%LV;#RALU04^7|B+%l}J~KPHX*Pb~7EC;5d!{zV4)t1a>!8u-%rFSi1} zsr;P=`DF(Ahr&1kaA^D=M)HIGA8F+^5co~Cy)|8s!fRQ~mb_OCR^-)512;1_hor<;F=fSxA(k0t(e_OsT)KaBWmF>`SR z?Pm?}o65h1%8zq4UO4_-3jc!sR}ADJNpSu3t3wr=lTQD~Ec_dZKVAR*De#;0--|C> z;FA6Ka)bV*AjhQt(;4dj6AS;V8S1|o=uGDqsvMSh7v{#=9nMHcym8Om=4epC4?4DzcD^53(_ zpG@+D{Ri7xUdNtkuD>gZKVAE;v+!R-{4|WZB7^ep0De>XYYgQ_Un-Y!;(mD`I0%?$ zaQs+9@<+ImbtEXiAMl&xFEz-&#vuQCi~J`@emeVGWRbtlAivHa|5J{=nZ_1lzv~8W_tIZ2xniU*I)I{q_C? zpy|ylN;#j5R`um@SEhXB>7Oi>O%Xu z(IEdT7WvnZ{Ci!=IuexMVUfRu!{@9V`@(+Y@6|XTmaQ_D77X!bk{2TwR zS!DT_8RWlUkw1at2j^eN!gmcEW!Arf_|x_O0l;t4e+TI=`~NKl{Sy}X*JLRFN{jrx z2Kg%u@_%lTzntXLFyPi%u>Kyg$j|N6EVBH!8RVZf+Fbt+lKkNNqoDkgf!|dB`6OT3 z&uWAGjTZTTBl+p%zg&Sq`;P#>N&gDcpZT%>-EPqT9*g|*!7soo zo&FzK_{%foA34@s{>zDff>y)*8!Z0_;5U_jouT}9n96UFe>cgW>Pps;p!}~}dz=)nCOEdQy{!64g^ z{jMkeOI=PK3G(Lyze)eW|JC$!h#&12e~TW}zuqGM-y|QBeHZE~uNsT|Hj*#<|J?@p zf49gl1iuom@j7t-2Fw4hMgB&E{Cf=YPd(dQ|IH*no&Dwmzp4IrkbF6QtT)L24#|%M z3bvKx4|PkfBiw!r-(!)V|G%1I4iRGe#r|cfogI-w#eUXkdNor1mzc;quW1N|0N`!>xnCX`T70?;5W7Z zPLdxZLahId2Kh0PAN>7T1<5~>1yPt6xNiV{oMR#ZyoUIL`tm)8wXA=Df9O69aQRXH z?;G^Lk@OGNUsD?SEbdyCA86Q8gZv*Drl8c@o&Y=o^Wl4^2sa6|Nj6)z7byl literal 0 HcmV?d00001 diff --git a/examples/cpp/metadata/helloworld.grpc.pb.cc b/examples/cpp/metadata/helloworld.grpc.pb.cc new file mode 100644 index 00000000000..4255687148b --- /dev/null +++ b/examples/cpp/metadata/helloworld.grpc.pb.cc @@ -0,0 +1,70 @@ +// Generated by the gRPC C++ plugin. +// If you make any local change, they will be lost. +// source: helloworld.proto + +#include "helloworld.pb.h" +#include "helloworld.grpc.pb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +namespace helloworld { + +static const char* Greeter_method_names[] = { + "/helloworld.Greeter/SayHello", +}; + +std::unique_ptr< Greeter::Stub> Greeter::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) { + (void)options; + std::unique_ptr< Greeter::Stub> stub(new Greeter::Stub(channel)); + return stub; +} + +Greeter::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) + : channel_(channel), rpcmethod_SayHello_(Greeter_method_names[0], ::grpc::internal::RpcMethod::NORMAL_RPC, channel) + {} + +::grpc::Status Greeter::Stub::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) { + return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_SayHello_, context, request, response); +} + +void Greeter::Stub::experimental_async::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response, std::function f) { + return ::grpc::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_SayHello_, context, request, response, std::move(f)); +} + +::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::AsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return ::grpc::internal::ClientAsyncResponseReaderFactory< ::helloworld::HelloReply>::Create(channel_.get(), cq, rpcmethod_SayHello_, context, request, true); +} + +::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::PrepareAsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return ::grpc::internal::ClientAsyncResponseReaderFactory< ::helloworld::HelloReply>::Create(channel_.get(), cq, rpcmethod_SayHello_, context, request, false); +} + +Greeter::Service::Service() { + AddMethod(new ::grpc::internal::RpcServiceMethod( + Greeter_method_names[0], + ::grpc::internal::RpcMethod::NORMAL_RPC, + new ::grpc::internal::RpcMethodHandler< Greeter::Service, ::helloworld::HelloRequest, ::helloworld::HelloReply>( + std::mem_fn(&Greeter::Service::SayHello), this))); +} + +Greeter::Service::~Service() { +} + +::grpc::Status Greeter::Service::SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) { + (void) context; + (void) request; + (void) response; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + + +} // namespace helloworld + diff --git a/examples/cpp/metadata/helloworld.grpc.pb.h b/examples/cpp/metadata/helloworld.grpc.pb.h new file mode 100644 index 00000000000..73cc75e0a62 --- /dev/null +++ b/examples/cpp/metadata/helloworld.grpc.pb.h @@ -0,0 +1,197 @@ +// Generated by the gRPC C++ plugin. +// If you make any local change, they will be lost. +// source: helloworld.proto +// Original file comments: +// Copyright 2015 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_helloworld_2eproto__INCLUDED +#define GRPC_helloworld_2eproto__INCLUDED + +#include "helloworld.pb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { +class CompletionQueue; +class Channel; +class ServerCompletionQueue; +class ServerContext; +} // namespace grpc + +namespace helloworld { + +// The greeting service definition. +class Greeter final { + public: + static constexpr char const* service_full_name() { + return "helloworld.Greeter"; + } + class StubInterface { + public: + virtual ~StubInterface() {} + // Sends a greeting + virtual ::grpc::Status SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) = 0; + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>> AsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>>(AsyncSayHelloRaw(context, request, cq)); + } + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>> PrepareAsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>>(PrepareAsyncSayHelloRaw(context, request, cq)); + } + class experimental_async_interface { + public: + virtual ~experimental_async_interface() {} + // Sends a greeting + virtual void SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response, std::function) = 0; + }; + virtual class experimental_async_interface* experimental_async() { return nullptr; } + private: + virtual ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>* AsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>* PrepareAsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) = 0; + }; + class Stub final : public StubInterface { + public: + Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); + ::grpc::Status SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) override; + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>> AsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>>(AsyncSayHelloRaw(context, request, cq)); + } + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>> PrepareAsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>>(PrepareAsyncSayHelloRaw(context, request, cq)); + } + class experimental_async final : + public StubInterface::experimental_async_interface { + public: + void SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response, std::function) override; + private: + friend class Stub; + explicit experimental_async(Stub* stub): stub_(stub) { } + Stub* stub() { return stub_; } + Stub* stub_; + }; + class experimental_async_interface* experimental_async() override { return &async_stub_; } + + private: + std::shared_ptr< ::grpc::ChannelInterface> channel_; + class experimental_async async_stub_{this}; + ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* AsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* PrepareAsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) override; + const ::grpc::internal::RpcMethod rpcmethod_SayHello_; + }; + static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); + + class Service : public ::grpc::Service { + public: + Service(); + virtual ~Service(); + // Sends a greeting + virtual ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response); + }; + template + class WithAsyncMethod_SayHello : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithAsyncMethod_SayHello() { + ::grpc::Service::MarkMethodAsync(0); + } + ~WithAsyncMethod_SayHello() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestSayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); + } + }; + typedef WithAsyncMethod_SayHello AsyncService; + template + class WithGenericMethod_SayHello : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithGenericMethod_SayHello() { + ::grpc::Service::MarkMethodGeneric(0); + } + ~WithGenericMethod_SayHello() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template + class WithRawMethod_SayHello : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithRawMethod_SayHello() { + ::grpc::Service::MarkMethodRaw(0); + } + ~WithRawMethod_SayHello() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestSayHello(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); + } + }; + template + class WithStreamedUnaryMethod_SayHello : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithStreamedUnaryMethod_SayHello() { + ::grpc::Service::MarkMethodStreamed(0, + new ::grpc::internal::StreamedUnaryHandler< ::helloworld::HelloRequest, ::helloworld::HelloReply>(std::bind(&WithStreamedUnaryMethod_SayHello::StreamedSayHello, this, std::placeholders::_1, std::placeholders::_2))); + } + ~WithStreamedUnaryMethod_SayHello() override { + BaseClassMustBeDerivedFromService(this); + } + // disable regular version of this method + ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + // replace default version of method with streamed unary + virtual ::grpc::Status StreamedSayHello(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::helloworld::HelloRequest,::helloworld::HelloReply>* server_unary_streamer) = 0; + }; + typedef WithStreamedUnaryMethod_SayHello StreamedUnaryService; + typedef Service SplitStreamedService; + typedef WithStreamedUnaryMethod_SayHello StreamedService; +}; + +} // namespace helloworld + + +#endif // GRPC_helloworld_2eproto__INCLUDED diff --git a/examples/cpp/metadata/helloworld.grpc.pb.o b/examples/cpp/metadata/helloworld.grpc.pb.o new file mode 100644 index 0000000000000000000000000000000000000000..234283660c2185112bf5a40874899672b328aa80 GIT binary patch literal 398496 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 w=02@|e2cV41O4aeXEX08#pYMFzIkvk#=-yP + +#include +#include +#include +#include +#include +#include +#include +#include +// This is a temporary google only hack +#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS +#include "third_party/protobuf/version.h" +#endif +// @@protoc_insertion_point(includes) + +namespace helloworld { +class HelloRequestDefaultTypeInternal { + public: + ::google::protobuf::internal::ExplicitlyConstructed + _instance; +} _HelloRequest_default_instance_; +class HelloReplyDefaultTypeInternal { + public: + ::google::protobuf::internal::ExplicitlyConstructed + _instance; +} _HelloReply_default_instance_; +} // namespace helloworld +namespace protobuf_helloworld_2eproto { +static void InitDefaultsHelloRequest() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + + { + void* ptr = &::helloworld::_HelloRequest_default_instance_; + new (ptr) ::helloworld::HelloRequest(); + ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); + } + ::helloworld::HelloRequest::InitAsDefaultInstance(); +} + +::google::protobuf::internal::SCCInfo<0> scc_info_HelloRequest = + {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsHelloRequest}, {}}; + +static void InitDefaultsHelloReply() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + + { + void* ptr = &::helloworld::_HelloReply_default_instance_; + new (ptr) ::helloworld::HelloReply(); + ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); + } + ::helloworld::HelloReply::InitAsDefaultInstance(); +} + +::google::protobuf::internal::SCCInfo<0> scc_info_HelloReply = + {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsHelloReply}, {}}; + +void InitDefaults() { + ::google::protobuf::internal::InitSCC(&scc_info_HelloRequest.base); + ::google::protobuf::internal::InitSCC(&scc_info_HelloReply.base); +} + +::google::protobuf::Metadata file_level_metadata[2]; + +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloRequest, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloRequest, name_), + ~0u, // no _has_bits_ + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloReply, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloReply, message_), +}; +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, sizeof(::helloworld::HelloRequest)}, + { 6, -1, sizeof(::helloworld::HelloReply)}, +}; + +static ::google::protobuf::Message const * const file_default_instances[] = { + reinterpret_cast(&::helloworld::_HelloRequest_default_instance_), + reinterpret_cast(&::helloworld::_HelloReply_default_instance_), +}; + +void protobuf_AssignDescriptors() { + AddDescriptors(); + AssignDescriptors( + "helloworld.proto", schemas, file_default_instances, TableStruct::offsets, + file_level_metadata, NULL, NULL); +} + +void protobuf_AssignDescriptorsOnce() { + static ::google::protobuf::internal::once_flag once; + ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); +} + +void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD; +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 2); +} + +void AddDescriptorsImpl() { + InitDefaults(); + static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + "\n\020helloworld.proto\022\nhelloworld\"\034\n\014HelloR" + "equest\022\014\n\004name\030\001 \001(\t\"\035\n\nHelloReply\022\017\n\007me" + "ssage\030\001 \001(\t2I\n\007Greeter\022>\n\010SayHello\022\030.hel" + "loworld.HelloRequest\032\026.helloworld.HelloR" + "eply\"\000B6\n\033io.grpc.examples.helloworldB\017H" + "elloWorldProtoP\001\242\002\003HLWb\006proto3" + }; + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + descriptor, 230); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "helloworld.proto", &protobuf_RegisterTypes); +} + +void AddDescriptors() { + static ::google::protobuf::internal::once_flag once; + ::google::protobuf::internal::call_once(once, AddDescriptorsImpl); +} +// Force AddDescriptors() to be called at dynamic initialization time. +struct StaticDescriptorInitializer { + StaticDescriptorInitializer() { + AddDescriptors(); + } +} static_descriptor_initializer; +} // namespace protobuf_helloworld_2eproto +namespace helloworld { + +// =================================================================== + +void HelloRequest::InitAsDefaultInstance() { +} +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int HelloRequest::kNameFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +HelloRequest::HelloRequest() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + ::google::protobuf::internal::InitSCC( + &protobuf_helloworld_2eproto::scc_info_HelloRequest.base); + SharedCtor(); + // @@protoc_insertion_point(constructor:helloworld.HelloRequest) +} +HelloRequest::HelloRequest(const HelloRequest& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + _internal_metadata_.MergeFrom(from._internal_metadata_); + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (from.name().size() > 0) { + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + // @@protoc_insertion_point(copy_constructor:helloworld.HelloRequest) +} + +void HelloRequest::SharedCtor() { + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +HelloRequest::~HelloRequest() { + // @@protoc_insertion_point(destructor:helloworld.HelloRequest) + SharedDtor(); +} + +void HelloRequest::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +void HelloRequest::SetCachedSize(int size) const { + _cached_size_.Set(size); +} +const ::google::protobuf::Descriptor* HelloRequest::descriptor() { + ::protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); + return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; +} + +const HelloRequest& HelloRequest::default_instance() { + ::google::protobuf::internal::InitSCC(&protobuf_helloworld_2eproto::scc_info_HelloRequest.base); + return *internal_default_instance(); +} + + +void HelloRequest::Clear() { +// @@protoc_insertion_point(message_clear_start:helloworld.HelloRequest) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + _internal_metadata_.Clear(); +} + +bool HelloRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:helloworld.HelloRequest) + for (;;) { + ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // string name = 1; + case 1: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->name().data(), static_cast(this->name().length()), + ::google::protobuf::internal::WireFormatLite::PARSE, + "helloworld.HelloRequest.name")); + } else { + goto handle_unusual; + } + break; + } + + default: { + handle_unusual: + if (tag == 0) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:helloworld.HelloRequest) + return true; +failure: + // @@protoc_insertion_point(parse_failure:helloworld.HelloRequest) + return false; +#undef DO_ +} + +void HelloRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:helloworld.HelloRequest) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->name().data(), static_cast(this->name().length()), + ::google::protobuf::internal::WireFormatLite::SERIALIZE, + "helloworld.HelloRequest.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } + // @@protoc_insertion_point(serialize_end:helloworld.HelloRequest) +} + +::google::protobuf::uint8* HelloRequest::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + (void)deterministic; // Unused + // @@protoc_insertion_point(serialize_to_array_start:helloworld.HelloRequest) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->name().data(), static_cast(this->name().length()), + ::google::protobuf::internal::WireFormatLite::SERIALIZE, + "helloworld.HelloRequest.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } + // @@protoc_insertion_point(serialize_to_array_end:helloworld.HelloRequest) + return target; +} + +size_t HelloRequest::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:helloworld.HelloRequest) + size_t total_size = 0; + + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } + // string name = 1; + if (this->name().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); + SetCachedSize(cached_size); + return total_size; +} + +void HelloRequest::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:helloworld.HelloRequest) + GOOGLE_DCHECK_NE(&from, this); + const HelloRequest* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:helloworld.HelloRequest) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:helloworld.HelloRequest) + MergeFrom(*source); + } +} + +void HelloRequest::MergeFrom(const HelloRequest& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:helloworld.HelloRequest) + GOOGLE_DCHECK_NE(&from, this); + _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from.name().size() > 0) { + + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } +} + +void HelloRequest::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:helloworld.HelloRequest) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void HelloRequest::CopyFrom(const HelloRequest& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:helloworld.HelloRequest) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool HelloRequest::IsInitialized() const { + return true; +} + +void HelloRequest::Swap(HelloRequest* other) { + if (other == this) return; + InternalSwap(other); +} +void HelloRequest::InternalSwap(HelloRequest* other) { + using std::swap; + name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); + _internal_metadata_.Swap(&other->_internal_metadata_); +} + +::google::protobuf::Metadata HelloRequest::GetMetadata() const { + protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); + return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages]; +} + + +// =================================================================== + +void HelloReply::InitAsDefaultInstance() { +} +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int HelloReply::kMessageFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +HelloReply::HelloReply() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + ::google::protobuf::internal::InitSCC( + &protobuf_helloworld_2eproto::scc_info_HelloReply.base); + SharedCtor(); + // @@protoc_insertion_point(constructor:helloworld.HelloReply) +} +HelloReply::HelloReply(const HelloReply& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + _internal_metadata_.MergeFrom(from._internal_metadata_); + message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (from.message().size() > 0) { + message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_); + } + // @@protoc_insertion_point(copy_constructor:helloworld.HelloReply) +} + +void HelloReply::SharedCtor() { + message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +HelloReply::~HelloReply() { + // @@protoc_insertion_point(destructor:helloworld.HelloReply) + SharedDtor(); +} + +void HelloReply::SharedDtor() { + message_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +void HelloReply::SetCachedSize(int size) const { + _cached_size_.Set(size); +} +const ::google::protobuf::Descriptor* HelloReply::descriptor() { + ::protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); + return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; +} + +const HelloReply& HelloReply::default_instance() { + ::google::protobuf::internal::InitSCC(&protobuf_helloworld_2eproto::scc_info_HelloReply.base); + return *internal_default_instance(); +} + + +void HelloReply::Clear() { +// @@protoc_insertion_point(message_clear_start:helloworld.HelloReply) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + _internal_metadata_.Clear(); +} + +bool HelloReply::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:helloworld.HelloReply) + for (;;) { + ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // string message = 1; + case 1: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_message())); + DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->message().data(), static_cast(this->message().length()), + ::google::protobuf::internal::WireFormatLite::PARSE, + "helloworld.HelloReply.message")); + } else { + goto handle_unusual; + } + break; + } + + default: { + handle_unusual: + if (tag == 0) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:helloworld.HelloReply) + return true; +failure: + // @@protoc_insertion_point(parse_failure:helloworld.HelloReply) + return false; +#undef DO_ +} + +void HelloReply::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:helloworld.HelloReply) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // string message = 1; + if (this->message().size() > 0) { + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->message().data(), static_cast(this->message().length()), + ::google::protobuf::internal::WireFormatLite::SERIALIZE, + "helloworld.HelloReply.message"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->message(), output); + } + + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } + // @@protoc_insertion_point(serialize_end:helloworld.HelloReply) +} + +::google::protobuf::uint8* HelloReply::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + (void)deterministic; // Unused + // @@protoc_insertion_point(serialize_to_array_start:helloworld.HelloReply) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // string message = 1; + if (this->message().size() > 0) { + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->message().data(), static_cast(this->message().length()), + ::google::protobuf::internal::WireFormatLite::SERIALIZE, + "helloworld.HelloReply.message"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->message(), target); + } + + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } + // @@protoc_insertion_point(serialize_to_array_end:helloworld.HelloReply) + return target; +} + +size_t HelloReply::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:helloworld.HelloReply) + size_t total_size = 0; + + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } + // string message = 1; + if (this->message().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->message()); + } + + int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); + SetCachedSize(cached_size); + return total_size; +} + +void HelloReply::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:helloworld.HelloReply) + GOOGLE_DCHECK_NE(&from, this); + const HelloReply* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:helloworld.HelloReply) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:helloworld.HelloReply) + MergeFrom(*source); + } +} + +void HelloReply::MergeFrom(const HelloReply& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:helloworld.HelloReply) + GOOGLE_DCHECK_NE(&from, this); + _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from.message().size() > 0) { + + message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_); + } +} + +void HelloReply::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:helloworld.HelloReply) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void HelloReply::CopyFrom(const HelloReply& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:helloworld.HelloReply) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool HelloReply::IsInitialized() const { + return true; +} + +void HelloReply::Swap(HelloReply* other) { + if (other == this) return; + InternalSwap(other); +} +void HelloReply::InternalSwap(HelloReply* other) { + using std::swap; + message_.Swap(&other->message_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); + _internal_metadata_.Swap(&other->_internal_metadata_); +} + +::google::protobuf::Metadata HelloReply::GetMetadata() const { + protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); + return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages]; +} + + +// @@protoc_insertion_point(namespace_scope) +} // namespace helloworld +namespace google { +namespace protobuf { +template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::helloworld::HelloRequest* Arena::CreateMaybeMessage< ::helloworld::HelloRequest >(Arena* arena) { + return Arena::CreateInternal< ::helloworld::HelloRequest >(arena); +} +template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::helloworld::HelloReply* Arena::CreateMaybeMessage< ::helloworld::HelloReply >(Arena* arena) { + return Arena::CreateInternal< ::helloworld::HelloReply >(arena); +} +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/examples/cpp/metadata/helloworld.pb.h b/examples/cpp/metadata/helloworld.pb.h new file mode 100644 index 00000000000..57f6817e310 --- /dev/null +++ b/examples/cpp/metadata/helloworld.pb.h @@ -0,0 +1,419 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto + +#ifndef PROTOBUF_INCLUDED_helloworld_2eproto +#define PROTOBUF_INCLUDED_helloworld_2eproto + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3006001 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: export +#include // IWYU pragma: export +#include +// @@protoc_insertion_point(includes) +#define PROTOBUF_INTERNAL_EXPORT_protobuf_helloworld_2eproto + +namespace protobuf_helloworld_2eproto { +// Internal implementation detail -- do not use these members. +struct TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[2]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; + static const ::google::protobuf::uint32 offsets[]; +}; +void AddDescriptors(); +} // namespace protobuf_helloworld_2eproto +namespace helloworld { +class HelloReply; +class HelloReplyDefaultTypeInternal; +extern HelloReplyDefaultTypeInternal _HelloReply_default_instance_; +class HelloRequest; +class HelloRequestDefaultTypeInternal; +extern HelloRequestDefaultTypeInternal _HelloRequest_default_instance_; +} // namespace helloworld +namespace google { +namespace protobuf { +template<> ::helloworld::HelloReply* Arena::CreateMaybeMessage<::helloworld::HelloReply>(Arena*); +template<> ::helloworld::HelloRequest* Arena::CreateMaybeMessage<::helloworld::HelloRequest>(Arena*); +} // namespace protobuf +} // namespace google +namespace helloworld { + +// =================================================================== + +class HelloRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:helloworld.HelloRequest) */ { + public: + HelloRequest(); + virtual ~HelloRequest(); + + HelloRequest(const HelloRequest& from); + + inline HelloRequest& operator=(const HelloRequest& from) { + CopyFrom(from); + return *this; + } + #if LANG_CXX11 + HelloRequest(HelloRequest&& from) noexcept + : HelloRequest() { + *this = ::std::move(from); + } + + inline HelloRequest& operator=(HelloRequest&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif + static const ::google::protobuf::Descriptor* descriptor(); + static const HelloRequest& default_instance(); + + static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY + static inline const HelloRequest* internal_default_instance() { + return reinterpret_cast( + &_HelloRequest_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + void Swap(HelloRequest* other); + friend void swap(HelloRequest& a, HelloRequest& b) { + a.Swap(&b); + } + + // implements Message ---------------------------------------------- + + inline HelloRequest* New() const final { + return CreateMaybeMessage(NULL); + } + + HelloRequest* New(::google::protobuf::Arena* arena) const final { + return CreateMaybeMessage(arena); + } + void CopyFrom(const ::google::protobuf::Message& from) final; + void MergeFrom(const ::google::protobuf::Message& from) final; + void CopyFrom(const HelloRequest& from); + void MergeFrom(const HelloRequest& from); + void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) final; + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const final; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(HelloRequest* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return NULL; + } + inline void* MaybeArenaPtr() const { + return NULL; + } + public: + + ::google::protobuf::Metadata GetMetadata() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + #if LANG_CXX11 + void set_name(::std::string&& value); + #endif + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::internal::ArenaStringPtr name_; + mutable ::google::protobuf::internal::CachedSize _cached_size_; + friend struct ::protobuf_helloworld_2eproto::TableStruct; +}; +// ------------------------------------------------------------------- + +class HelloReply : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:helloworld.HelloReply) */ { + public: + HelloReply(); + virtual ~HelloReply(); + + HelloReply(const HelloReply& from); + + inline HelloReply& operator=(const HelloReply& from) { + CopyFrom(from); + return *this; + } + #if LANG_CXX11 + HelloReply(HelloReply&& from) noexcept + : HelloReply() { + *this = ::std::move(from); + } + + inline HelloReply& operator=(HelloReply&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif + static const ::google::protobuf::Descriptor* descriptor(); + static const HelloReply& default_instance(); + + static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY + static inline const HelloReply* internal_default_instance() { + return reinterpret_cast( + &_HelloReply_default_instance_); + } + static constexpr int kIndexInFileMessages = + 1; + + void Swap(HelloReply* other); + friend void swap(HelloReply& a, HelloReply& b) { + a.Swap(&b); + } + + // implements Message ---------------------------------------------- + + inline HelloReply* New() const final { + return CreateMaybeMessage(NULL); + } + + HelloReply* New(::google::protobuf::Arena* arena) const final { + return CreateMaybeMessage(arena); + } + void CopyFrom(const ::google::protobuf::Message& from) final; + void MergeFrom(const ::google::protobuf::Message& from) final; + void CopyFrom(const HelloReply& from); + void MergeFrom(const HelloReply& from); + void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) final; + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const final; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(HelloReply* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return NULL; + } + inline void* MaybeArenaPtr() const { + return NULL; + } + public: + + ::google::protobuf::Metadata GetMetadata() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // string message = 1; + void clear_message(); + static const int kMessageFieldNumber = 1; + const ::std::string& message() const; + void set_message(const ::std::string& value); + #if LANG_CXX11 + void set_message(::std::string&& value); + #endif + void set_message(const char* value); + void set_message(const char* value, size_t size); + ::std::string* mutable_message(); + ::std::string* release_message(); + void set_allocated_message(::std::string* message); + + // @@protoc_insertion_point(class_scope:helloworld.HelloReply) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::internal::ArenaStringPtr message_; + mutable ::google::protobuf::internal::CachedSize _cached_size_; + friend struct ::protobuf_helloworld_2eproto::TableStruct; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// HelloRequest + +// string name = 1; +inline void HelloRequest::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& HelloRequest::name() const { + // @@protoc_insertion_point(field_get:helloworld.HelloRequest.name) + return name_.GetNoArena(); +} +inline void HelloRequest::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:helloworld.HelloRequest.name) +} +#if LANG_CXX11 +inline void HelloRequest::set_name(::std::string&& value) { + + name_.SetNoArena( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:helloworld.HelloRequest.name) +} +#endif +inline void HelloRequest::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:helloworld.HelloRequest.name) +} +inline void HelloRequest::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:helloworld.HelloRequest.name) +} +inline ::std::string* HelloRequest::mutable_name() { + + // @@protoc_insertion_point(field_mutable:helloworld.HelloRequest.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* HelloRequest::release_name() { + // @@protoc_insertion_point(field_release:helloworld.HelloRequest.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void HelloRequest::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:helloworld.HelloRequest.name) +} + +// ------------------------------------------------------------------- + +// HelloReply + +// string message = 1; +inline void HelloReply::clear_message() { + message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& HelloReply::message() const { + // @@protoc_insertion_point(field_get:helloworld.HelloReply.message) + return message_.GetNoArena(); +} +inline void HelloReply::set_message(const ::std::string& value) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:helloworld.HelloReply.message) +} +#if LANG_CXX11 +inline void HelloReply::set_message(::std::string&& value) { + + message_.SetNoArena( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:helloworld.HelloReply.message) +} +#endif +inline void HelloReply::set_message(const char* value) { + GOOGLE_DCHECK(value != NULL); + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:helloworld.HelloReply.message) +} +inline void HelloReply::set_message(const char* value, size_t size) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:helloworld.HelloReply.message) +} +inline ::std::string* HelloReply::mutable_message() { + + // @@protoc_insertion_point(field_mutable:helloworld.HelloReply.message) + return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* HelloReply::release_message() { + // @@protoc_insertion_point(field_release:helloworld.HelloReply.message) + + return message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void HelloReply::set_allocated_message(::std::string* message) { + if (message != NULL) { + + } else { + + } + message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message); + // @@protoc_insertion_point(field_set_allocated:helloworld.HelloReply.message) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace helloworld + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_INCLUDED_helloworld_2eproto diff --git a/examples/cpp/metadata/helloworld.pb.o b/examples/cpp/metadata/helloworld.pb.o new file mode 100644 index 0000000000000000000000000000000000000000..85671e8aaa3b10080aba2cde1b103fe994eaa612 GIT binary patch literal 111592 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 Date: Thu, 13 Dec 2018 17:05:39 -0800 Subject: [PATCH 302/534] Fix typo && remove unecessary except --- src/python/grpcio_tests/tests/status/_grpc_status_test.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/python/grpcio_tests/tests/status/_grpc_status_test.py b/src/python/grpcio_tests/tests/status/_grpc_status_test.py index 5969338736f..519c372a960 100644 --- a/src/python/grpcio_tests/tests/status/_grpc_status_test.py +++ b/src/python/grpcio_tests/tests/status/_grpc_status_test.py @@ -54,7 +54,7 @@ def _error_details_unary_unary(request, servicer_context): details.Pack( error_details_pb2.DebugInfo( stack_entries=traceback.format_stack(), - detail='Intensionally invoked')) + detail='Intentionally invoked')) rich_status = status_pb2.Status( code=code_pb2.INTERNAL, message=_STATUS_DETAILS, @@ -118,10 +118,8 @@ class StatusTest(unittest.TestCase): self._channel.close() def test_status_ok(self): - try: - _, call = self._channel.unary_unary(_STATUS_OK).with_call(_REQUEST) - except grpc.RpcError as rpc_error: - self.fail(rpc_error) + _, call = self._channel.unary_unary(_STATUS_OK).with_call(_REQUEST) + # Succeed RPC doesn't have status status = rpc_status.from_call(call) self.assertIs(status, None) From b9cb2459ea4b2956547abf5fb516b553d85f1ae2 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 13 Dec 2018 17:18:38 -0800 Subject: [PATCH 303/534] Include LICENSE in artifact --- src/python/grpcio_status/MANIFEST.in | 1 + src/python/grpcio_status/setup.py | 19 +++++---- src/python/grpcio_status/status_commands.py | 39 +++++++++++++++++++ .../artifacts/build_artifact_python.sh | 2 +- 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 src/python/grpcio_status/status_commands.py diff --git a/src/python/grpcio_status/MANIFEST.in b/src/python/grpcio_status/MANIFEST.in index eca719a9c20..09b8ea721e8 100644 --- a/src/python/grpcio_status/MANIFEST.in +++ b/src/python/grpcio_status/MANIFEST.in @@ -1,3 +1,4 @@ include grpc_version.py recursive-include grpc_status *.py global-exclude *.pyc +include LICENSE diff --git a/src/python/grpcio_status/setup.py b/src/python/grpcio_status/setup.py index 0601498bc51..a59cdd0f0f5 100644 --- a/src/python/grpcio_status/setup.py +++ b/src/python/grpcio_status/setup.py @@ -63,12 +63,18 @@ INSTALL_REQUIRES = ( 'googleapis-common-protos>=1.5.5', ) -SETUP_REQUIRES = () -COMMAND_CLASS = { - # wire up commands to no-op not to break the external dependencies - 'preprocess': _NoOpCommand, - 'build_package_protos': _NoOpCommand, -} +try: + import status_commands as _status_commands + # we are in the build environment, otherwise the above import fails + COMMAND_CLASS = { + # Run preprocess from the repository *before* doing any packaging! + 'preprocess': _status_commands.Preprocess, + } +except ImportError: + COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, + } setuptools.setup( name='grpcio-status', @@ -82,5 +88,4 @@ setuptools.setup( package_dir=PACKAGE_DIRECTORIES, packages=setuptools.find_packages('.'), install_requires=INSTALL_REQUIRES, - setup_requires=SETUP_REQUIRES, cmdclass=COMMAND_CLASS) diff --git a/src/python/grpcio_status/status_commands.py b/src/python/grpcio_status/status_commands.py new file mode 100644 index 00000000000..78cd497f622 --- /dev/null +++ b/src/python/grpcio_status/status_commands.py @@ -0,0 +1,39 @@ +# Copyright 2018 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. +"""Provides distutils command classes for the GRPC Python setup process.""" + +import os +import shutil + +import setuptools + +ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) +LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') + + +class Preprocess(setuptools.Command): + """Command to copy LICENSE from root directory.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + if os.path.isfile(LICENSE): + shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index 18eb70c8574..e451ced338f 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -126,7 +126,7 @@ then # Build grpcio_status source distribution ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_status/setup.py \ - preprocess build_package_protos sdist + preprocess sdist cp -r src/python/grpcio_status/dist/* "$ARTIFACT_DIR" fi From 5a38d1956fb7007108a310e0280df58c9c824cec Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 14 Dec 2018 10:08:22 -0800 Subject: [PATCH 304/534] Make yapf happy --- tools/run_tests/python_utils/check_on_pr.py | 78 +++++++++++++-------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index 96418bf2d3a..935d59713ef 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -25,47 +25,57 @@ _GITHUB_API_PREFIX = 'https://api.github.com' _GITHUB_REPO = 'lidizheng/grpc' _GITHUB_APP_ID = 22288 _INSTALLATION_ID = 516307 -_GITHUB_APP_KEY = open(os.environ['HOME'] + '/.ssh/google-grpc-checker.2018-12-13.private-key.pem', 'r').read() +_GITHUB_APP_KEY = open( + os.environ['HOME'] + '/.ssh/google-grpc-checker.2018-12-13.private-key.pem', + 'r').read() _ACCESS_TOKEN_CACHE = None + def _jwt_token(): - return jwt.encode({ - 'iat': int(time.time()), - 'exp': int(time.time() + 60 * 10), # expire in 10 minutes - 'iss': _GITHUB_APP_ID, - }, _GITHUB_APP_KEY, algorithm='RS256') + return jwt.encode( + { + 'iat': int(time.time()), + 'exp': int(time.time() + 60 * 10), # expire in 10 minutes + 'iss': _GITHUB_APP_ID, + }, + _GITHUB_APP_KEY, + algorithm='RS256') + def _access_token(): global _ACCESS_TOKEN_CACHE if _ACCESS_TOKEN_CACHE == None or _ACCESS_TOKEN_CACHE['exp'] < time.time(): resp = requests.post( - url='https://api.github.com/app/installations/%s/access_tokens' % _INSTALLATION_ID, + url='https://api.github.com/app/installations/%s/access_tokens' % + _INSTALLATION_ID, headers={ 'Authorization': 'Bearer %s' % _jwt_token().decode('ASCII'), 'Accept': 'application/vnd.github.machine-man-preview+json', - } - ) - _ACCESS_TOKEN_CACHE = {'token': resp.json()['token'], 'exp': time.time()+60} + }) + _ACCESS_TOKEN_CACHE = { + 'token': resp.json()['token'], + 'exp': time.time() + 60 + } return _ACCESS_TOKEN_CACHE['token'] + def _call(url, method='GET', json=None): if not url.startswith('https://'): url = _GITHUB_API_PREFIX + url - headers={ + headers = { 'Authorization': 'Bearer %s' % _access_token(), 'Accept': 'application/vnd.github.antiope-preview+json', } - return requests.request( - method=method, - url=url, - headers=headers, - json=json) + return requests.request(method=method, url=url, headers=headers, json=json) + def _latest_commit(): - resp = _call('/repos/%s/pulls/%s/commits' % (_GITHUB_REPO, os.environ['ghprbPullId'])) + resp = _call('/repos/%s/pulls/%s/commits' % (_GITHUB_REPO, + os.environ['ghprbPullId'])) return resp.json()[-1] + def check_on_pr(name, summary, success=True): """Create/Update a check on current pull request. @@ -84,15 +94,25 @@ def check_on_pr(name, summary, success=True): print('Missing ghprbPullId env var: not commenting') return commit = _latest_commit() - resp = _call('/repos/%s/check-runs' % _GITHUB_REPO, method='POST', json={ - 'name': name, - 'head_sha': commit['sha'], - 'status': 'completed', - 'completed_at': '%sZ' % datetime.datetime.utcnow().replace(microsecond=0).isoformat(), - 'conclusion': 'success' if success else 'failure', - 'output': { - 'title': name, - 'summary': summary, - } - }) - print('Result of Creating/Updating Check on PR:', json.dumps(resp.json(), indent=2)) + resp = _call( + '/repos/%s/check-runs' % _GITHUB_REPO, + method='POST', + json={ + 'name': + name, + 'head_sha': + commit['sha'], + 'status': + 'completed', + 'completed_at': + '%sZ' % + datetime.datetime.utcnow().replace(microsecond=0).isoformat(), + 'conclusion': + 'success' if success else 'failure', + 'output': { + 'title': name, + 'summary': summary, + } + }) + print('Result of Creating/Updating Check on PR:', + json.dumps(resp.json(), indent=2)) From 40b8ca97a1d89153711e0d965cd25de1099862f1 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 14 Dec 2018 10:10:57 -0800 Subject: [PATCH 305/534] Update docstring to make it more clear * Mark API as experimental * Rephrase the raise condition * Add more detail to the returned object --- src/python/grpcio_status/grpc_status/rpc_status.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/python/grpcio_status/grpc_status/rpc_status.py b/src/python/grpcio_status/grpc_status/rpc_status.py index 36c8eba37d5..e23a20968ec 100644 --- a/src/python/grpcio_status/grpc_status/rpc_status.py +++ b/src/python/grpcio_status/grpc_status/rpc_status.py @@ -45,6 +45,8 @@ def _code_to_grpc_status_code(code): def from_call(call): """Returns a google.rpc.status.Status message corresponding to a given grpc.Call. + This is an EXPERIMENTAL API. + Args: call: A grpc.Call instance. @@ -52,8 +54,8 @@ def from_call(call): A google.rpc.status.Status message representing the status of the RPC. Raises: - ValueError: If the status code, status message is inconsistent with the rich status - inside of the google.rpc.status.Status. + ValueError: If the gRPC call's code or details are inconsistent with the + status code and message inside of the google.rpc.status.Status. """ for key, value in call.trailing_metadata(): if key == _GRPC_DETAILS_METADATA_KEY: @@ -74,12 +76,14 @@ def from_call(call): def to_status(status): """Convert a google.rpc.status.Status message to grpc.Status. + This is an EXPERIMENTAL API. + Args: status: a google.rpc.status.Status message representing the non-OK status to terminate the RPC with and communicate it to the client. Returns: - A grpc.Status instance. + A grpc.Status instance representing the input google.rpc.status.Status message. """ return _Status( code=_code_to_grpc_status_code(status.code), From 5ec78a286d7be61aec929b133c031a7a1af262df Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Fri, 14 Dec 2018 10:36:51 -0800 Subject: [PATCH 306/534] Added support for fixed load benchmarks, all the rpcs access one requestor to the get the next issue time for the RPC --- test/cpp/qps/client_callback.cc | 35 ++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index 00d5853a8e8..1880f46d43d 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -66,7 +66,10 @@ class CallbackClient config, BenchmarkStubCreator) { num_threads_ = NumThreads(config); rpcs_done_ = 0; - SetupLoadTest(config, num_threads_); + + // Don't divide the fixed load among threads as the user threads + // only bootstrap the RPCs + SetupLoadTest(config, 1); total_outstanding_rpcs_ = config.client_channels() * config.outstanding_rpcs_per_channel(); } @@ -87,6 +90,11 @@ class CallbackClient } } + gpr_timespec NextIssueTime() { + std::lock_guard l(next_issue_time_mu_); + return Client::NextIssueTime(0); + } + protected: size_t num_threads_; size_t total_outstanding_rpcs_; @@ -108,6 +116,8 @@ class CallbackClient } private: + std::mutex next_issue_time_mu_; // Used by next issue time + int NumThreads(const ClientConfig& config) { int num_threads = config.async_client_threads(); if (num_threads <= 0) { // Use dynamic sizing @@ -146,7 +156,7 @@ class CallbackUnaryClient final : public CallbackClient { bool ThreadFuncImpl(Thread* t, size_t thread_idx) override { for (size_t vector_idx = thread_idx; vector_idx < total_outstanding_rpcs_; vector_idx += num_threads_) { - ScheduleRpc(t, thread_idx, vector_idx); + ScheduleRpc(t, vector_idx); } return true; } @@ -154,26 +164,26 @@ class CallbackUnaryClient final : public CallbackClient { void InitThreadFuncImpl(size_t thread_idx) override { return; } private: - void ScheduleRpc(Thread* t, size_t thread_idx, size_t vector_idx) { + void ScheduleRpc(Thread* t, size_t vector_idx) { if (!closed_loop_) { - gpr_timespec next_issue_time = NextIssueTime(thread_idx); + gpr_timespec next_issue_time = NextIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time ctx_[vector_idx]->alarm_.experimental().Set( - next_issue_time, [this, t, thread_idx, vector_idx](bool ok) { - IssueUnaryCallbackRpc(t, thread_idx, vector_idx); + next_issue_time, [this, t, vector_idx](bool ok) { + IssueUnaryCallbackRpc(t, vector_idx); }); } else { - IssueUnaryCallbackRpc(t, thread_idx, vector_idx); + IssueUnaryCallbackRpc(t, vector_idx); } } - void IssueUnaryCallbackRpc(Thread* t, size_t thread_idx, size_t vector_idx) { + void IssueUnaryCallbackRpc(Thread* t, size_t vector_idx) { GPR_TIMER_SCOPE("CallbackUnaryClient::ThreadFunc", 0); double start = UsageTimer::Now(); ctx_[vector_idx]->stub_->experimental_async()->UnaryCall( (&ctx_[vector_idx]->context_), &request_, &ctx_[vector_idx]->response_, - [this, t, thread_idx, start, vector_idx](grpc::Status s) { + [this, t, start, vector_idx](grpc::Status s) { // Update Histogram with data from the callback run HistogramEntry entry; if (s.ok()) { @@ -190,7 +200,7 @@ class CallbackUnaryClient final : public CallbackClient { ctx_[vector_idx].reset( new CallbackClientRpcContext(ctx_[vector_idx]->stub_)); // Schedule a new RPC - ScheduleRpc(t, thread_idx, vector_idx); + ScheduleRpc(t, vector_idx); } }); } @@ -287,7 +297,7 @@ class CallbackStreamingPingPongReactor final if (client_->ThreadCompleted()) return; if (!client_->IsClosedLoop()) { - gpr_timespec next_issue_time = client_->NextIssueTime(thread_idx_); + gpr_timespec next_issue_time = client_->NextIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time ctx_->alarm_.experimental().Set(next_issue_time, @@ -298,11 +308,9 @@ class CallbackStreamingPingPongReactor final } void set_thread_ptr(void* ptr) { thread_ptr_ = ptr; } - void set_thread_idx(int thread_idx) { thread_idx_ = thread_idx; } CallbackStreamingPingPongClient* client_; std::unique_ptr ctx_; - int thread_idx_; // Needed to update histogram entries void* thread_ptr_; // Needed to update histogram entries double start_; // Track message start time int messages_issued_; // Messages issued by this stream @@ -323,7 +331,6 @@ class CallbackStreamingPingPongClientImpl final for (size_t vector_idx = thread_idx; vector_idx < total_outstanding_rpcs_; vector_idx += num_threads_) { reactor_[vector_idx]->set_thread_ptr(t); - reactor_[vector_idx]->set_thread_idx(thread_idx); reactor_[vector_idx]->ScheduleRpc(); } return true; From 8621bd47adb7dec1f16bbd616890fd3b0df3336e Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 14 Dec 2018 11:23:18 -0800 Subject: [PATCH 307/534] Assign noop to build_package_protos for backward compatibility --- src/python/grpcio_status/setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/python/grpcio_status/setup.py b/src/python/grpcio_status/setup.py index a59cdd0f0f5..983d3ea430b 100644 --- a/src/python/grpcio_status/setup.py +++ b/src/python/grpcio_status/setup.py @@ -69,11 +69,13 @@ try: COMMAND_CLASS = { # Run preprocess from the repository *before* doing any packaging! 'preprocess': _status_commands.Preprocess, + 'build_package_protos': _NoOpCommand, } except ImportError: COMMAND_CLASS = { # wire up commands to no-op not to break the external dependencies 'preprocess': _NoOpCommand, + 'build_package_protos': _NoOpCommand, } setuptools.setup( From ca4e55e6caae393e33784d51f1e9d2352608c4dc Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 14 Dec 2018 13:03:22 -0800 Subject: [PATCH 308/534] Benchmark to show that byte buffer copy is size-independent --- CMakeLists.txt | 49 ++++++++++++++ Makefile | 49 ++++++++++++++ build.yaml | 22 +++++++ test/cpp/microbenchmarks/BUILD | 7 ++ test/cpp/microbenchmarks/bm_byte_buffer.cc | 65 +++++++++++++++++++ .../generated/sources_and_headers.json | 22 +++++++ tools/run_tests/generated/tests.json | 22 +++++++ 7 files changed, 236 insertions(+) create mode 100644 test/cpp/microbenchmarks/bm_byte_buffer.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index fb233cc3601..e296eaee734 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -526,6 +526,9 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_arena) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_byte_buffer) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_call_create) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -11191,6 +11194,52 @@ target_link_libraries(bm_arena ) +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_byte_buffer + test/cpp/microbenchmarks/bm_byte_buffer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_byte_buffer + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(bm_byte_buffer + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_test_util_unsecure + grpc_test_util_unsecure + grpc++_unsecure + grpc_unsecure + gpr_test_util + gpr + grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index c4d8a0b95cb..9cc4aeecc4d 100644 --- a/Makefile +++ b/Makefile @@ -1135,6 +1135,7 @@ auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test backoff_test: $(BINDIR)/$(CONFIG)/backoff_test bdp_estimator_test: $(BINDIR)/$(CONFIG)/bdp_estimator_test bm_arena: $(BINDIR)/$(CONFIG)/bm_arena +bm_byte_buffer: $(BINDIR)/$(CONFIG)/bm_byte_buffer bm_call_create: $(BINDIR)/$(CONFIG)/bm_call_create bm_channel: $(BINDIR)/$(CONFIG)/bm_channel bm_chttp2_hpack: $(BINDIR)/$(CONFIG)/bm_chttp2_hpack @@ -1641,6 +1642,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/backoff_test \ $(BINDIR)/$(CONFIG)/bdp_estimator_test \ $(BINDIR)/$(CONFIG)/bm_arena \ + $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ $(BINDIR)/$(CONFIG)/bm_channel \ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \ @@ -1825,6 +1827,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/backoff_test \ $(BINDIR)/$(CONFIG)/bdp_estimator_test \ $(BINDIR)/$(CONFIG)/bm_arena \ + $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ $(BINDIR)/$(CONFIG)/bm_channel \ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \ @@ -2259,6 +2262,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/bdp_estimator_test || ( echo test bdp_estimator_test failed ; exit 1 ) $(E) "[RUN] Testing bm_arena" $(Q) $(BINDIR)/$(CONFIG)/bm_arena || ( echo test bm_arena failed ; exit 1 ) + $(E) "[RUN] Testing bm_byte_buffer" + $(Q) $(BINDIR)/$(CONFIG)/bm_byte_buffer || ( echo test bm_byte_buffer failed ; exit 1 ) $(E) "[RUN] Testing bm_call_create" $(Q) $(BINDIR)/$(CONFIG)/bm_call_create || ( echo test bm_call_create failed ; exit 1 ) $(E) "[RUN] Testing bm_channel" @@ -16084,6 +16089,50 @@ endif endif +BM_BYTE_BUFFER_SRC = \ + test/cpp/microbenchmarks/bm_byte_buffer.cc \ + +BM_BYTE_BUFFER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_BYTE_BUFFER_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_byte_buffer: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/bm_byte_buffer: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_byte_buffer: $(PROTOBUF_DEP) $(BM_BYTE_BUFFER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_BYTE_BUFFER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_byte_buffer + +endif + +endif + +$(BM_BYTE_BUFFER_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_byte_buffer.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + +deps_bm_byte_buffer: $(BM_BYTE_BUFFER_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_BYTE_BUFFER_OBJS:.o=.dep) +endif +endif + + BM_CALL_CREATE_SRC = \ test/cpp/microbenchmarks/bm_call_create.cc \ diff --git a/build.yaml b/build.yaml index 6e2ed16398e..5f4d554a467 100644 --- a/build.yaml +++ b/build.yaml @@ -4015,6 +4015,28 @@ targets: - linux - posix uses_polling: false +- name: bm_byte_buffer + build: test + language: c++ + src: + - test/cpp/microbenchmarks/bm_byte_buffer.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure + - grpc_test_util_unsecure + - grpc++_unsecure + - grpc_unsecure + - gpr_test_util + - gpr + - grpc++_test_config + benchmark: true + defaults: benchmark + platforms: + - mac + - linux + - posix + uses_polling: false - name: bm_call_create build: test language: c++ diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 097e92f5836..93ed962a00d 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -61,6 +61,13 @@ grpc_cc_binary( deps = [":helpers"], ) +grpc_cc_binary( + name = "bm_byte_buffer", + testonly = 1, + srcs = ["bm_byte_buffer.cc"], + deps = [":helpers"], +) + grpc_cc_binary( name = "bm_channel", testonly = 1, diff --git a/test/cpp/microbenchmarks/bm_byte_buffer.cc b/test/cpp/microbenchmarks/bm_byte_buffer.cc new file mode 100644 index 00000000000..a359e6f6212 --- /dev/null +++ b/test/cpp/microbenchmarks/bm_byte_buffer.cc @@ -0,0 +1,65 @@ +/* + * + * Copyright 2015 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 benchmark exists to show that byte-buffer copy is size-independent */ + +#include + +#include +#include +#include +#include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" + +namespace grpc { +namespace testing { + +auto& force_library_initialization = Library::get(); + +static void BM_ByteBuffer_Copy(benchmark::State& state) { + int num_slices = state.range(0); + size_t slice_size = state.range(1); + std::vector slices; + while (num_slices > 0) { + num_slices--; + std::unique_ptr buf(new char[slice_size]); + memset(buf.get(), 0, slice_size); + slices.emplace_back(buf.get(), slice_size); + } + grpc::ByteBuffer bb(slices.data(), num_slices); + while (state.KeepRunning()) { + grpc::ByteBuffer cc(bb); + } +} +BENCHMARK(BM_ByteBuffer_Copy)->Ranges({{1, 64}, {1, 1024 * 1024}}); + +} // namespace testing +} // namespace grpc + +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index c87d7209e7d..38cdd49fc7f 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -2789,6 +2789,28 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "benchmark", + "gpr", + "gpr_test_util", + "grpc++_test_config", + "grpc++_test_util_unsecure", + "grpc++_unsecure", + "grpc_benchmark", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "bm_byte_buffer", + "src": [ + "test/cpp/microbenchmarks/bm_byte_buffer.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "benchmark", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index cc28e52ae21..bca2ef53878 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3363,6 +3363,28 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_byte_buffer", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": false + }, { "args": [], "benchmark": true, From 653160d8067e648c94c7ab095dc7fe4bbe1f3271 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Dec 2018 13:47:33 -0800 Subject: [PATCH 309/534] Make NSMutableDictionary annotation right --- src/objective-c/GRPCClient/GRPCCall.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index f36b814cec3..d4d16024fa0 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -370,11 +370,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (id)objectForKeyedSubscript:(id)key; -- (void)setObject:(id)obj forKeyedSubscript:(id)key; +- (nullable id)objectForKeyedSubscript:(nonnull id)key; +- (void)setObject:(nonnull id)obj forKeyedSubscript:(nonnull id)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(id)key; +- (void)removeObjectForKey:(nonnull id)key; @end #pragma clang diagnostic push From 4f91630d6b2ba9fbf0b75e2dbaa1932a739f2b17 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Dec 2018 13:46:53 -0800 Subject: [PATCH 310/534] CFStream use serial dispatch queue --- src/core/lib/iomgr/cfstream_handle.cc | 98 ++++++++++++--------------- src/core/lib/iomgr/cfstream_handle.h | 2 + 2 files changed, 46 insertions(+), 54 deletions(-) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index 827fd24831e..bb402f96cf5 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -52,62 +52,53 @@ CFStreamHandle* CFStreamHandle::CreateStreamHandle( void CFStreamHandle::ReadCallback(CFReadStreamRef stream, CFStreamEventType type, void* client_callback_info) { + grpc_core::ExecCtx exec_ctx; CFStreamHandle* handle = static_cast(client_callback_info); - CFSTREAM_HANDLE_REF(handle, "read callback"); - dispatch_async( - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - grpc_core::ExecCtx exec_ctx; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_DEBUG, "CFStream ReadCallback (%p, %p, %lu, %p)", handle, - stream, type, client_callback_info); - } - switch (type) { - case kCFStreamEventOpenCompleted: - handle->open_event_.SetReady(); - break; - case kCFStreamEventHasBytesAvailable: - case kCFStreamEventEndEncountered: - handle->read_event_.SetReady(); - break; - case kCFStreamEventErrorOccurred: - handle->open_event_.SetReady(); - handle->read_event_.SetReady(); - break; - default: - GPR_UNREACHABLE_CODE(return ); - } - CFSTREAM_HANDLE_UNREF(handle, "read callback"); - }); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_DEBUG, "CFStream ReadCallback (%p, %p, %lu, %p)", handle, + stream, type, client_callback_info); + } + switch (type) { + case kCFStreamEventOpenCompleted: + handle->open_event_.SetReady(); + break; + case kCFStreamEventHasBytesAvailable: + case kCFStreamEventEndEncountered: + handle->read_event_.SetReady(); + break; + case kCFStreamEventErrorOccurred: + handle->open_event_.SetReady(); + handle->read_event_.SetReady(); + break; + default: + GPR_UNREACHABLE_CODE(return ); + } } void CFStreamHandle::WriteCallback(CFWriteStreamRef stream, CFStreamEventType type, void* clientCallBackInfo) { + grpc_core::ExecCtx exec_ctx; CFStreamHandle* handle = static_cast(clientCallBackInfo); - CFSTREAM_HANDLE_REF(handle, "write callback"); - dispatch_async( - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - grpc_core::ExecCtx exec_ctx; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle, - stream, type, clientCallBackInfo); - } - switch (type) { - case kCFStreamEventOpenCompleted: - handle->open_event_.SetReady(); - break; - case kCFStreamEventCanAcceptBytes: - case kCFStreamEventEndEncountered: - handle->write_event_.SetReady(); - break; - case kCFStreamEventErrorOccurred: - handle->open_event_.SetReady(); - handle->write_event_.SetReady(); - break; - default: - GPR_UNREACHABLE_CODE(return ); - } - CFSTREAM_HANDLE_UNREF(handle, "write callback"); - }); + printf("** CFStreamHandle::WriteCallback\n"); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle, + stream, type, clientCallBackInfo); + } + switch (type) { + case kCFStreamEventOpenCompleted: + handle->open_event_.SetReady(); + break; + case kCFStreamEventCanAcceptBytes: + case kCFStreamEventEndEncountered: + handle->write_event_.SetReady(); + break; + case kCFStreamEventErrorOccurred: + handle->open_event_.SetReady(); + handle->write_event_.SetReady(); + break; + default: + GPR_UNREACHABLE_CODE(return ); + } } CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream, @@ -116,6 +107,7 @@ CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream, open_event_.InitEvent(); read_event_.InitEvent(); write_event_.InitEvent(); + dispatch_queue_ = dispatch_queue_create(nullptr, DISPATCH_QUEUE_SERIAL); CFStreamClientContext ctx = {0, static_cast(this), CFStreamHandle::Retain, CFStreamHandle::Release, nil}; @@ -129,10 +121,8 @@ CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream, kCFStreamEventOpenCompleted | kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, CFStreamHandle::WriteCallback, &ctx); - CFReadStreamScheduleWithRunLoop(read_stream, CFRunLoopGetMain(), - kCFRunLoopCommonModes); - CFWriteStreamScheduleWithRunLoop(write_stream, CFRunLoopGetMain(), - kCFRunLoopCommonModes); + CFReadStreamSetDispatchQueue(read_stream, dispatch_queue_); + CFWriteStreamSetDispatchQueue(write_stream, dispatch_queue_); } CFStreamHandle::~CFStreamHandle() { diff --git a/src/core/lib/iomgr/cfstream_handle.h b/src/core/lib/iomgr/cfstream_handle.h index 4258e72431c..93ec5f044bb 100644 --- a/src/core/lib/iomgr/cfstream_handle.h +++ b/src/core/lib/iomgr/cfstream_handle.h @@ -62,6 +62,8 @@ class CFStreamHandle final { grpc_core::LockfreeEvent read_event_; grpc_core::LockfreeEvent write_event_; + dispatch_queue_t dispatch_queue_; + gpr_refcount refcount_; }; From b0b4c0d9c36d9b3185c5b792ca6e8954ff065e54 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 14 Dec 2018 13:52:25 -0800 Subject: [PATCH 311/534] Add API comments indicating that byte buffer copy is size-independent --- include/grpcpp/impl/codegen/byte_buffer.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h index 53ecb53371b..a77e36dfc50 100644 --- a/include/grpcpp/impl/codegen/byte_buffer.h +++ b/include/grpcpp/impl/codegen/byte_buffer.h @@ -93,7 +93,9 @@ class ByteBuffer final { } /// Constuct a byte buffer by referencing elements of existing buffer - /// \a buf. Wrapper of core function grpc_byte_buffer_copy + /// \a buf. Wrapper of core function grpc_byte_buffer_copy . This is not + /// a deep copy; it is just a referencing. As a result, its performance is + /// size-independent. ByteBuffer(const ByteBuffer& buf); ~ByteBuffer() { @@ -102,6 +104,9 @@ class ByteBuffer final { } } + /// Wrapper of core function grpc_byte_buffer_copy . This is not + /// a deep copy; it is just a referencing. As a result, its performance is + /// size-independent. ByteBuffer& operator=(const ByteBuffer&); /// Dump (read) the buffer contents into \a slices. @@ -117,7 +122,9 @@ class ByteBuffer final { /// Make a duplicate copy of the internals of this byte /// buffer so that we have our own owned version of it. - /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable + /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable. + /// This is not a deep copy; it is a referencing and its performance + /// is size-independent. void Duplicate() { buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buffer_); } From a744221a2c5b93d8bd90c266ffea68de34c44acd Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Fri, 14 Dec 2018 14:14:46 -0800 Subject: [PATCH 312/534] Editing appid and installation id Created these from the grpc-bot account. --- tools/run_tests/python_utils/check_on_pr.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index 935d59713ef..f756e4bdaa4 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -22,9 +22,9 @@ import requests import jwt _GITHUB_API_PREFIX = 'https://api.github.com' -_GITHUB_REPO = 'lidizheng/grpc' -_GITHUB_APP_ID = 22288 -_INSTALLATION_ID = 516307 +_GITHUB_REPO = 'grpc/grpc' +_GITHUB_APP_ID = 22338 +_INSTALLATION_ID = 519109 _GITHUB_APP_KEY = open( os.environ['HOME'] + '/.ssh/google-grpc-checker.2018-12-13.private-key.pem', 'r').read() From 580d43d03f20b0b92f4b7ae950225a1dcd3387a0 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 13 Dec 2018 16:55:08 -0800 Subject: [PATCH 313/534] Address reviewer comments and remove binary files --- examples/BUILD | 15 + examples/cpp/metadata/README.md | 5 +- examples/cpp/metadata/greeter_client | Bin 267800 -> 0 bytes examples/cpp/metadata/greeter_client.o | Bin 101304 -> 0 bytes examples/cpp/metadata/greeter_server | Bin 278392 -> 0 bytes examples/cpp/metadata/greeter_server.cc | 14 +- examples/cpp/metadata/greeter_server.o | Bin 112144 -> 0 bytes examples/cpp/metadata/helloworld.grpc.pb.cc | 70 --- examples/cpp/metadata/helloworld.grpc.pb.h | 197 ------ examples/cpp/metadata/helloworld.grpc.pb.o | Bin 398496 -> 0 bytes examples/cpp/metadata/helloworld.pb.cc | 638 -------------------- examples/cpp/metadata/helloworld.pb.h | 419 ------------- examples/cpp/metadata/helloworld.pb.o | Bin 111592 -> 0 bytes 13 files changed, 29 insertions(+), 1329 deletions(-) delete mode 100755 examples/cpp/metadata/greeter_client delete mode 100644 examples/cpp/metadata/greeter_client.o delete mode 100755 examples/cpp/metadata/greeter_server delete mode 100644 examples/cpp/metadata/greeter_server.o delete mode 100644 examples/cpp/metadata/helloworld.grpc.pb.cc delete mode 100644 examples/cpp/metadata/helloworld.grpc.pb.h delete mode 100644 examples/cpp/metadata/helloworld.grpc.pb.o delete mode 100644 examples/cpp/metadata/helloworld.pb.cc delete mode 100644 examples/cpp/metadata/helloworld.pb.h delete mode 100644 examples/cpp/metadata/helloworld.pb.o diff --git a/examples/BUILD b/examples/BUILD index 0f18cfa9ba7..22f2f0a4f1a 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -51,3 +51,18 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) + +cc_binary( + name = "metadata_client", + srcs = ["cpp/metadata/greeter_client.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) + +cc_binary( + name = "metadata_server", + srcs = ["cpp/metadata/greeter_server.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) + diff --git a/examples/cpp/metadata/README.md b/examples/cpp/metadata/README.md index 7b33074ba1e..96ad3d19bdb 100644 --- a/examples/cpp/metadata/README.md +++ b/examples/cpp/metadata/README.md @@ -57,13 +57,10 @@ If things go smoothly, you will see in the client terminal: And in the server terminal: -"Header key: custom-bin , value: " +"Header key: custom-bin , value: 01234567" "Header key: custom-header , value: Custom Value" "Header key: user-agent , value: grpc-c++/1.16.0-dev grpc-c/6.0.0-dev (linux; chttp2; gao)" -Note that the value for custom-bin doesn't print nicely because it's a binary -value. You can indicate a binary value through appending "-bin" to the header key. - We did not add the user-agent metadata as a custom header. This shows how the gRPC framework adds some headers under the hood that may show up in the metadata map. diff --git a/examples/cpp/metadata/greeter_client b/examples/cpp/metadata/greeter_client deleted file mode 100755 index 929a51c3a5b426131d0573b2e5cd91da16f1ecf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 267800 zcmdqK3tXJV)jz(upcswd1;sn@igzF(5;c_=S2vnO3_+~vs+ZZB=Wu*{os zzdHSJf{|9w&b=k+Te7cunsUTux$;9)x$;94zIhfZu+KbA``9*q=jwd#^DN}?W1ht2 zr|A8rD*oR0yQ;D&1asb+yy8{KDYOit`XVk7F zU;V}7_vRe>(1lgcU%d6Q3gk85OFHB5O&!(olfvmOEk698zUsV|jMTAXeOr(B&Fh%w z+a;?r_0rC9W7DPu_8#XOGcJAfxUr)HXQnUooi$@+QOjPVd@VlT4QKW2>&rURzsu;9 zhbvZ$&KcX{E7)f=s>y1bcHCLrS!enVoN->x;TbKyu{Y=V&Pw%_kLzCH+daeQD;<4S zj_?9De2w@v<9ju}OYr>`zTd{zeDtu91-=j9`w+el4`E=vQW_+JE06e$g8`0@!@cb>l&*S@ohV|;_OZxe;e!hz5 zYxw>S-{0f=I==k8sUE(!@O&HJeth4>_mB9#kM9TgI{1Ew?^b+2!gtzp_jad#5LmJN zgi8;)@VCzt)~(s{)M4LP{b~0hi>DoW>4C@o@R!vO9sBvRD}S7p``EyBbANWpaZ9h+ z^W~>dv|Jp!Gk#HvG_iTb{Zvbynoy@`BS|c=OY@t2eAX^v!*8A3M|k z>ek_BH*Sb5?^rW&w?}G!pa+V}o@PVD~0iiI5) zXJ@rs^oO!odD@-IDT@|VXx{>#7%Cm!

LvYO3=Q>NReJDEDZ5Vo zc%SE<+UM!TQeTI>GtOqd?)9zTkkyR z*6!Ue`t3jVedN*)?g`)W;DWn)+xMGs&TDU8KY76|M_-dYexL55XZJrlIBxYji$@3F z`D@z^l~eYA`hu%F_I~8>_s@Iro4?uAeAu~{y_>ai_U#ovxUK)>yS6;_!(V0p^jFXP z^GDZQaYW-eZ+-aqD`%BWKK+14F1=*;+{f~7p1PtveB%jMec9Ogz|))F{MJ8~uYdc( z@BeLb_=d_$#x(A~{@s@Kvmd@7^qvySN&=+ezKfm+2 zr_kj|KQ(*#eA;Bk;aqoYV)z3vKqxZe^9+noB0Bdcq5lXBQX>4xV-v$qPr^^m$%*lo z?wJ^V7wmANdItea1V8!E#PE-HPYmDl#KiE56B5I(J3cYIDTy4;pXl=)K0^9F-&0BG zPXd0Tb_J5a4^0ApAPJu*?30-O)+BPyL(q|kpN?eoll05r9*OCcCDFqhlIY2oN${Ua zf`4=p`ApAA%+InU@Gp|+^KO7A8eg9$q4RzceQQdhw;8)7=5smd?3X~VK8La;>aUu- z#PCOw^l#II#Q6K>CWfDuM9z0-C&nL#pePZa%}Mm+)Fk>=m4u(EN#y?<1XYRZy*>&2 zl_dRMdt72VCnv$bKFN3=m!#ewCef2KlE6!n$YDzoIV=J^k^W3eBIo(z6Sw!!Bzkpl z5_^7o5{nP=7aw%e7&EiAk0MaOi5xVMh;9yexdZpV}nyd^|}%{`P40_-{q$X4I%x(R)vq^^0^ob zI+TO6x8kQj!>6Euq<>ej!tc}Y4`62qzxJ03fbdK{FN%E9eVvU8pZdqo?pkgOHT^GKx0mlAU&|4?Uld!u{#_J)|2_&H(DVxqQ}_!tKFp?kIuI|h-q(gz z`aunE1!IKIepdlF9{4#|w>R*yO24Y>eKCn%T?zdp|D9S7jXqD*^7+AE6depJ`P6Cp z4}7T7S84d2SXU!IUj2Dc>%Uij>M^dUPb~~C>A#`- z@#N78z7qXH{sUV6Mz5X$KZN&aJ;_q&zHy*Ky-nBsYxMS2>G%D7nR@-t$l*A26Y)DW zKQIgO`7P`%`8n_%mA*;C+eMz~zO3&k{Hccd@D}I~;q{(zy=;F)r~ig{ezu6eNb^q|CNe9)K5NNX!{WG@VQyru~H3(xscEP=wFVb za;+zZ+b@vIdT-R@(a^tC%c0jp|0CUB-=3=|e4y!1M7v1GJB}_g{jT}HUE|*?^r4>` zj&N5#*J8ku&e9DkZS-nbx2wg&&()&;2aVAG^Dy42Z~a=%rd@Amss8Qq(3ygcV7(jf zRrMPE{~7w7@Z*B2y~|X#??UiNJt@@or&Ggc!7dU1^|cD{vKI6OdR#2g`i9{npH|I( z`cV*+_1P;+(K%_XB4F0V58qwEo8DK*=vMh0qV0os99_1L;&Y+LF8%#L1z+PC*Kh5r z=s)|gqT8$K9}9-rF7No7q2Z@$JJzJ}i}iSE(c{Immu{VOyn243*5?9`-MAL?h(Gq{ zitvWf>Y0TOB|K|Dr`5wZW&+yYa*)B;xZE9fwR@uLv9de}Z~xA3BaydYG!~odtrV)2HdzYx#de z`@2EUIJ#@R!uRUWh1zapzpDrvKL38a!q2%vwRa!&@D)QpS?|0O1weK3c`QryZ@2D8 zB<1rf$bs_g-Cyw^(C|NNKjQQFk#i;}I)xf;{874=zgHiYAvmXeR%`hn+>*~$bOiOS z+v67+QxtxowzpXt|0|3~wrin|uZ$e_)%LdEBhNb^H?}L=GcG0y|NHr}wEZ#k57qI; z?ft4k6OUDEJvsCf1vhhz-|Kq2J@xvqZ&lw=*HkyJc|Lcma!>JZfpuR%$+s8rmi+Pw_;um^2!!0s;ez)Y^rEz zDl1c{i4iZJJ$XT0-GZ86fnlJax)$VWD{68lO=}3&RunfiRM##jYHG-xG+o%3Q46}@ zz+W`GIHxRMko-mG%`R>_rL3%S$&%dM+`M@ejn$Q?pG9X>7B}VQRxYe)C~In{sBUVU zQRy$Pz(0P!uk7O4=Xn{(&7Bo&Y^+!ioLSuz%*#0^*fgu+nt4H~r>IW2^DkyeZ^0Pn zr%Y>XtX@!iRZaG#UvqwQQ;bd`wsI%whMZkd ziQc&;Z^{gMY3EfIoxOPHx=@tNt1717@^a3qZmg_msIptx zm{`3=h$465^qOEr!`T%zHS;PeuS{Gjp>R)`6P(`=Y+RVQh^xm_MCWHLs;|k-pH@>- zR|$bktASz%tNe>7*AZh!jmF$l&aaiCx)AghA}ns2(sWIIu&laveqG|yMk=|v7<6-i zJG)|0@XUM}(_h1CZZ353?CRR;#)as&V*eZ&Hw zjyrl+ZeBy2&^&7PN1C@d?kDELgUT=uQj4coz%^GDS6>@!oLe`op`qd$f6>B(Ml#k_ z#q|}H!IH*c)y%ru1xjSaBNR0zkpH-PB^v(;C6rqLS3I|_siNl0YnpH~ABe z{Sm`CcXCy5enoRl6C8mKY&7%iHzyCX?q;UlsT9INDpr-QiJezd_-=WkBKo0c7A!ncjBQws`YgjfoR*QsEjk$~{HG*{_X5W1X7In4x(3bOu|L zHG=+JCJ`&qb$pGb{LdJMv+};id*n`3aRvTuq_3&2MxgvP(v3|bY8n}ZY#ZI9k9iYi z=&Kk;&B~M&@K^6#aK6(WmN!Y}s}sxW5u#xt6$?EQ8;dwglsnl3GmLW?xFmCzuCgZ* zlgZ4>oxU(wc_jnpX|+|hvP(Q=PiMESN3nQ6ufP-UgD}E9&NphC>-~!`8!B47ZDQW( zJGhLSzR!k}L?8tn_z#$m^J|M2HaAsa-Z-Zja}RKP-eSM97YX8ecNqSM!XYbwOVp2U z^|_PH^b^u&cXEWtMBBuZiG3^`$w-TnH`y92j8NzoOlY!`!$krbZwwWu+j%)f6%CC+ zT3fM!9tWFXqMt}4Y|)4%fxJm3a%c!vHjBwAt6}6(_BEPlO#@A6=WRp63Ul-6|K?UK zaHrT;Bw{w!f1D~cHPl@bTa`&Nll(Wh{waxllik6I{6At+toAKvsINT!cvk;9}ge))Lq-(K2BQsl99mT+$63aIYCp<6Dz+oO6ii5RP#Z47W&5dg5 zhcYLFg{zcoX_yECdi541Qhh~r!wg2a_#f%qoU-B|*8y@Hn`U5jhbT2zP?{mx6$0|-=9kUl zOe~0%`ruW~6*V)kDntw-`AOvzQ)?M!U05rsYmk!X&y_$rUh)5n`XF}_mIJv67n~Dp z#B>u2-;0Z6v~FvFO-!i$W<0~>#+foR+90LLWySSnm37TnrK&2!_Cs*S%-K`04^rDK zdlGqNGwUj^EUT}psjj@npXc|Zb7rC65Kut{WCEOI$SQ4D9X@$M*@Bwt`v3CrsizJ9 zwVE-x@~X0?3Oy}1{=#c2?IE0-C{qtXZO7(q9grzcS@;QvNXlCUwk6A|4ktg8xC)K=AC$(5#8 zRN0lTJtEy^DeKOC7zwo{(m~`ng^s_vQf48O@)%~71(#sSy?PM>gNhnh4CA27uA+x7 zlQ5^Qfoo|-hdgzhU!TZ>c>5$*T!@O|xN<%pD~$=-qQ>gTnsm&^(8U|`xdP$-6XP2$ zPY0JYnMGf(dEGWA9wG?k#2Ef(oZY1P)wNarIXYC-j3x@B5^9F+l;Z-iyh#htkqtro zBY`ITsU`6d!nNt>Xln!xgyw37gl^C!Vah9AGp3XD)Cj_MWMP}4I}hy@|^lg`bBIdtAWFq!JVm9!NWBLXF%eJB@l8<#uE_*T^~$K zU8N2^W}G{R%Xx6Vi*2uo4gFef8P~)@k0OvLE&%3P^(q1x5j!Oqz}u99cKIXd7|AkH zOE3nEVKZhSaqno$m}nxP9mqtrEHZszMQts1(syoRj_D72sS#%!5Pe856_-JU6irl6 zg<*=VibjbfN3=AVvMCOYVrWw_LIJmB{JqHkMe$+G7@`JPWhHDx(JAt?uD(bP4J2)x7%siE!G(>6g%PYh&gE(c>VQ|r z%$!s9ih0$Ga}laQ=__yu$340vN+9P4b*NO_ls6@|M50zwFn55_nO9N6gNpNtz?!>u zgNUXoC@Tb5Bb`$$)@8>PokyI`($GzSJkKk zIXg}VU3k9qpzt*h2M=q@aKf&Vdo0i?NDn7)>#i=V3Dz!XT38n3F*3Dbigi51q&11g z0wy=fhQVa0npB0dZbduMesskw%ye*ggXf=SfF*d&xeUt5_58Yqt8t#u4cNKTq8gNM z8Z-~5ip^?17^$g|8Q)ImA?Fct)>R1Xcn_c_V}pn%f&m~Yh!8_UNuSJu#kxveNBmIJ z1$IJ;N{bd5B}SEykHj97h&n~RGuoLuv8))qQ;$R2ms))SAp|Vuw3f!>5g-gU&-^b(#1Pt_VVQ*rYf!+fcAMi z&dKz=f0JCGM#_lnjINlu{!R?N$;v8;Flw)6WNw?R#%u6Oz#?U`5bBB5X~3!)%$XWq zu+grr@0?~r&u5i22Ai~b6qSf`v(>eg4MDE5@#JwL_p3O;8of5Nbqf$WSXOo?wA3|7 zML5?|R&`Bn#UjwGtZ3w>ql7PD#S^_Gve=b#5w_%)DQmwosygXkF^f|;)DS>5;mFk@ znRM;Ag3IIorK*H*?ipzYV2&DKd-UvJ;NKB@a{N4vD=(1R^lxYJtr)w zy&9{7W!x=V6lC;Ssiu+ebG4O=>d~Qy1G!B$zoNRv2PlSs)@_Jt2{x7&1s5qq1{#=+ z%kC3UNK3yAvk2#SePuy*4>INy=>x1Ilgmd&Ny>=S>8!`C*`Z( zrKNyRIw?2TH@&oU+L<%Ta!;BVpEJo$+P_cA%axaa^s8L*dyL#Nr``?XjdNq=_P||y zqj4J@{~M#T%#&rAw=4b~4csyKmmj?DrhhS4!AM(`BbLH6rC45-AQk>HX>)&}qM>fV z+f{Ig#}9KzSEW;h@-8~fdPeQQe~J?C;!FHr@|<}5ZQ*SzFP_TCRI;*!d-DL0R(y_k z=kZ#rFALwIqp!i6qp7|&yl=`6YuFdRO@8x%)p%2S7hi{)pW^!gUfN_nKNUkigt&M0 z-LA{L{NR-kdy4OuI$b6CV|{CNy6M=P@e1J>-*0sKD#;)1dl6}V%zcvPJ;VO%6ueX4 zGil(X?o#kI9{5R{6}-y>?=7V~aCe^v-l^$#d*S+hz8(*}Tf_T2@S)7Zg?_&WK6*D* zuj7Hw)bK$Me9dHqKjeXb_Y?*9?WO85a=1>vpPKH0uRcKGWqRO)n}khYmIr=dw}NMT z;Ds7q;DNVj`h{M2zTz|Bfp5_8A`ko~{k~(l2kz7Fvo7?&`!$_<4}6@K+Y%3a;S;J| zZ60`+=D))O-z8P?zuE&Y((q0X{Hw>uHf|^xVdj;i3e`pk8kn7&AlmY9=N%Oqr(F?@6)gLz|DOjogTP(55CI-H}?&! z^T5qL4c#8NxnHN(3)kbc&jUC2k@S1u<~{F058T|hG30@p`#gO5eP*MF<~`|D58T{; zlkS0=dnqzKaPuB{wg+zR@5%AN&HK{@9=LhGKPMyJJ`d^l_zOJn*KSdEpwI(9_*Mlk z^1#2;_XL!B;QKzL@XI}LbKlQG58T}6QSX62sq0@Z)Y*aK{6$*XZ>I7%haG${TziJxVf*W$OG@t_idDW;GG&??}3|pR@yvpUyI_u z!vi<+?DW9vHU1h8-1xzD9(aew@Aklr-u8On-5S5o12_8bc;LR}ivJ-G+{iywj~kS=2`%VHLc(2AU^}zd0zj)x?n*SCL-0hu~9+}sPb&I9k%_mlN_;HH23JaE&$ zjt6e~cgO=b_g$sx{xtG8`kCp08~x1oz>R(udf;7J4n-cgxj(7g12^}jE%dh zo~7l}=7F1g-Bx?xh5DYPH6FORCv2SuZthj;@xc2vojwoT-1Fpk;N~8|ArIW#|CFlz zgOPuWz85Op0}tqQmIrR`8_V&)&Hamo9=N#&vB(4O*Y}n=hsVz^OnS%zpT0~vvP{o? zm(OT;jt73^588bwA}6z71bv;UDi}`+O}Hz76lQ@DH=_yDWSg z-f!WTTKMZMd>h_p!H)rcx-R1+fg68Ix!L%c+WvUq*-79FlfaD~_0lQOB-Cg5Qw@-kAj6l?2|M1m2qj-k$_Mm;`S8fVW-74|w6m4|w6m-gx0dR==NX=|j3T z9&LEPj)zIdhPUXr%L_N_%3gR^5`43M>BaY1`eWBykOW?o1YT;%*`{OSdT+f&mKc#Q>jEchY|K4`(~EclQG zzsiDVTlWHAZo$p{w%lXYSD{L7zg`z5{6-7k+}};O9aorpr3u$dgi^}fk4g9k0#W~% zdx{Ca&w`tKy$Nr(;4PYe!u67qoA`J3%-j1;#p|HS-1HFEVzkHnO9`Nv2p8uN-g*}7wYqsTkt(B_(BVg zt6SYqy#?RXh2n3yS@1Lq-eSScm}YjH1>eiU@37#wg4g}5w&3Q@S7vrvaQp9&tg+y@ za@hTJS#Vq>>weZ*aB~MRGrKJ~u26M9Jr?{>7wYr%TJS6j-eR12PM!P71Hu@*ejf*)tWvn;r|Q_nKiz__w%}7Oc&7#bh6P_^!OyVZT^791g0HjS(=2$m1wYe* z_gL`h7QEMj`z?5%1wY$@_gnCDEVyIA0~UPHg3qwvLl*oz3+~hNV%pA`7ChC0&$8g@ z7JRk^&$Qs@TktFkUSz?uE%*f%Jja61vET(3yx4*lTJX6RJYc~~EO?OxztDo0TJVc3 zc)11trUhSU!7sMp^%ne63%|I%A-G@;0vtmZW=w@8)$tx z^(o(Q{*wR=AN4f;O*^a*znB)zqW#189JPUIh8)peN&kxJ(M)$s`WH+ybd7dN`ln1Y zl(>UjcB`nM^ZOi1thRRHhjs zM0+Kj$27y~Xt$(~W11m)v`f;5GtJN;+9~M+nP$ik?U3}|Ofyu7wn%y$(+m-!^^zXV zG(-Dnxun0i2Wf`%(IQEI$}~fVXrZJ(WSUD#(Hu#?%QQoXXqKd3XPTiyG+oj!G0l)6 z>XY=dOmhh+I`~hv|4F8^nC_SK2BsM@M0+LuE2inxqurAJ1=9=>qFs{yDboxMqMefd z5z`C_q8*aHnQ4Xs(H2SH$n-Hx*Gu|(rn8wYm-MwvAIo%+q#KxK2oNol^c74W&vcHY z=P`W((^-35l?>yBng`gNx1vZLveeu-(i>ZniB&oWIH9Uc6K z^gq*uO!rHA1JiWL(OyaaifOvyXt$()!8BcPv`f-IW%?|pJ0<-irs;~K9g@D8X}aKO zi==O4nyxomFX`)<4lrFV>1&yu!E}+N8<;+q=|V|g!8BcNG)L0&n5L_ZW=Z;Drs-m% z>5`tqG+k@dC+TyUrb~?uej)wOG+k-5U(%;CO&1#Nm2@7{be+*|Ngu~FU1qdP(uXrm zR~hY;^npy%MMgU$y*JZzjnNiKk7JrHFvW^I6(qkUBsUK(HhbPB{S2z?7jt=>4VxVETUn z9Gd>|mksyNKPm076+-{Ar)c$KX_SBGE+B^UU&o^)aO_toAK3iWm_TSSu-Q2yFltNS z#jlz&LGUU~a1RnpMz3Y+U%`g2`Q$+B)Q>yytAzaQ5on)!9OygaA#o>wf3~DN2fR^a zr-h9Dc33ftH1y=r{DK!v!+c_M55!Ljujx^X9 zXEy)_4ww=84T=z<83ksB9Ol0S9^ivBFPV1fw96F#HWxMVT#Qv*JjcHAa2xWF z^goA$hE!95;W2PL#m#z<*^kTtC?)}daRx8~A(4I)<<)-Kkm_F4Fb#c;*7W`it$7gU zTDQiijPok;H=?(|&D8G@>C?Xr4|k~I&in9`8$VE)=YmzI`N zshl7w6{_kwsG`7-r&6}iQU~fH>M$Pa0(qQ%E94=dba}LPr*5R+*xq^U5azXZXEJ?y zj&K{rU~p!^0~%5fpl=3_qg)g+R5RlI1uo7Y{4bP3%W0+(c;+P*U!@pBYcPg7fsbdz zxr+GVjLutxH-O078n6-LZHua(K;f-ZRktP(E<)Vt?<8^{RN_E+`;qRa661-!^7rD2 zudlU#RO`^Fv|Bk~FVi?Zc=iCN8&CAPe;uCq#&FZtcEb>;QNEW#jyOF09|%1;km~%B zA`3l<4Ad+`|1ra8xHR4QU&I}O&=!u&;Nkd5M$z6~*%x?jf(p3Q=O7o&L8(sCua_d5BJH1nW65#$5!Klh|%Q z8NEff>~^zs%aH08JR%O=E9x9lQja))V+V@)i#X3i0MKjELYIop`zf_n|GpWGSLz?H ztK^J-B}&WfkI6U-HGd|g!bO?w{?91n-#POT*O|JVN*SUl2SR z0h^Xi7Ch3)Bg+u}6#zlw%8fRExJu$KZshhY=?W(IkaifUe*eWqX&PzBY`3 z79h1i@%khFHQV!WZKQ$S{GN$!T3`-a83BXTj@G5nO@O- z-DMH~D;R?1-FHNeQo|mZjbB9LWfK7`jEH)K4#`Yhp;kDTgB2gcL_9)<5r^(Azq+EbUI+x~3%& zfA28D#SxgB`*#g-ps~CvJF2&}yCvlBBv6@F2zx4~9?O@$@fAq0Wt|CHb|+efFAAz5 z+YMD1nA~1MgVC=*?|(8p9P+QhuxfQifkfI5yW9M0Q4U{>Qib#i%AxD-Yxmz5@^4LB z>+fnE9JQi5ZRO9<>~{ZFaC0YICyma^TNUW^acL{tlu*$75$7PNhO!?mn&?uL&>c-n zmA3Lv7W(tY5W_YjQQDz2 zZ#Oa|+K0ii#I{=jjFxp6EnTq@ie$vuh>^_aVsw{lNGnmJXwU>Zl@kSqkSDK!H zEzMF&6XABKWKEm@5syf(6sHhzju^B=x_@}qFp2bcG@nC*y#7p# zFoYa0yoV{$7-oTTHF$gsaAf#95fo4PK*5)j_t2Ao{z-SsCTRPLKVbGJwjJ@6(!35* zxmX4>gWIK!ubC6J)nEWw(xHF-2%-K&0NG98PJob@Z{W}wp{H${SAyouP(Ml5lYHyb z<(OgVNP;a~zO_Rbe_|nnozSCPWmL^>Fu*q}dN@K6}tvU@=V-Bx}DRQoB^7B4kyy46PC{?+K0*C=t|>K{9m5 z6C8(N4QUaRC>(?2ZnAKL2%JIk4H%Q;SnQ-o_6J#vbab$#SVM_HhRArX836M}`ObHn zfq?8=Sa%GBU_MltxZv112)#8y^_DG)4UmrRuub^c5m^2-J4iasJE;eYL(s;-rU~*3 zyu1NV3$++jX<llxJ6>gGncSP}rvVBj?WP^|PFBTK&;R~m~6;`_AzB&6nDTu7l> zn);JzoFz5$6Rp`3Jpll8%|7U>n-pf%X6S|>DTwnwB7;>T){SL>ie#lq*2*Ou9PO*rgF&&>{8)4wnrsXz zpYdkV(#{p#%}1gs{lMwLvj@*^Jn@Z9^Ah-yDqUtBp6gJi3(qb**Wih7tgLNrsr^8X zIBjAoRX`+wumT_-%u34+z@m9lZFKII5u9?V%!xBD!$Vuqq%-{EVS!;guWyy<8fr21PX5(F+UNc|BD&^GvXgi_y_-{dD zJv00HL(voy5! zJt%y5eAyr3X83(*icRo8GQWxiDKgH;0nZiGcv~pjMn~wg1l(d)b5lq@)c=p(I^mlJ-ltiY$^87M&yA9?m zLHKZ`)1or$sar2<>V-ljjYI5M!kyut4(Exf+ZnJ`n7S3vWW{FqyZ7(t4F6?u3K3@- zO1i$uo#8*Kb06mT;1bh1itpOTrtYBJ#v!~fm6YTvvX7~;13EQ*K`KHRS+Y|3| zjJjBg=T#Gl2QpN9GF5x_VtdeYyR#wI4F6RLwj<8;w*WVhi95spwa)z?Fy)=$55n&L z>ofdGqd_^G@zE>RZ1+3RAA5#>(QAtLJE>PtqSy@oO^i%?HvXp4ybiYXX&KDPX88M{ zz1ug#4}qqhFy2J+|N0Dnx@z;^U$)wO3tHlt;g`Rvn!SeRN1APB_#c3I&kX;MVx#^~ zXZUxCz!@ap#n=fP$7cACK!HZi@JshmE!^@4OZnnv__ysr4497uGyGkUmuQCH2kGbz zdlNsC&Z#gV83c>}znsGyHqRR9Z9qUn+oNR-DKw<2fxzvfku8B_lZH zMwzc?wBupcN%diofXt%Bk)rLbOZ$Ayhit+m+~+K&$l#r^C!8iWvM&mg3I7E=YN%vm-M;gc{~jTw=YH>Vo5HYQk2)yd710jp&gKpoUn6fFLzp;Gj(C{$MN9ALgCl}LvXLptfXY8>IjSA-T@ zRq5G2HV{+?MZXR(2(%KCM`iI=sWJwNv4bP*nOnYIy3bj<+*0eu{7IJ1OZ=@DMC%z2NrB4&J zZcRXg+a!a{EQ(^Y6k%2LQVut%$5;@T1A(GIjO%UC=0dZkE9Q$kFa!H(%95vgCh(H5 zs!n(qDYTol7I#I+c-wZx`96wsicqMR(+Sd}gdbm>D4iXHw1VPN-w#EM)u&*}*RNw%lBZTH};M=|f zZE6DochK5a*5TilyZNtna+mPzPe{j*tIElIyV*$Ft5zAiS-@#|f`xqC*ihN+3R$V> z3*eJ(?+7A@qaJ6 z7JfXS*b`CeHrft;jVAm7LqWTPevXRePg6y0e<=q~i=gW0spihdkc+9^(oUajxpuAR z#Td}gzihEI^l#`cGa-Yo&)+jbWy1cEj5|)qa2`^0b0#qLgiJJNCNNZ&za*W^6$B`Z z9Dy5ro{izUK<2$*y;HQ>EEokV*jbYWTPZ!zyb~$L2gGTj3{V)a?Bu1Pg z+4UH`Ay}F)HY?=XDf_>K+uPj_rzLy>3g@}m8RM--Y&ac` zYqke)?%C7>UjnZhYKGiP`r$ix=IJ#w;1)Cn?iHobGjPOkSs)LMLEedoM~q;lym)pH zfPp84FXbc`5Pw98glPB0DGh3c8~9(l{+KjSqW(FSh&YJT;0WXV0r*G8C!g!CMr%g7 z(o!A~^-zEOLlOUHlsKIJMut5ob~1`dGyFsCCM1HFqxSWMnqNUdXc_YSuV8s3;vZDS z2Tk$8zp?mMbuwZol%Dp$U`zl)L{k{VgqgfUjHc`(QkJ|8wqx<-OGH3E97fe~1ot0M zb;LOu>Jy`B31v&5JtcaTvUi)GjUgGYjd6{SiD*1JIhI+mzK)TF%Hg0tYZrZ8sA`Wt z@i|g+#$yubWzvli7^8?mISLcb7?u)GsJT~*2!5G$Qm610?VyGv-;5Oo|FJ90mzt^x z02hK203y9&n||jMLffpi{(I_e_14>_09L(kU^tDaS1Z(xw3Um+(zG;GG2nL1{!(GY znevs}_s$el=^f{~@JY0V;f%7Xm?iV}e>h`WEZ0=ZH(#t)q`Ni>x(QXL)feXOfC`Qr znKWT3-B32$mIXq+8Z(@-e-q7DoPKc<<#YCiihAfNje>4OoX-$pdUDB!-e2b1Njf)X zWyNTOQ?_8r7avio`W_!i(W>u`k-1iV9gxw8`r_IoQflpn^de5@X9hbK71Ka*&$;>U zG-KjY+kpnJI3oU4^$Mj6w?XOn7^P_*N|1>)Bjcnej#sA%P6}P_wX)>>W<(T;v|%Ir zj0h>8x@FnAY#LIyaSrlc=Ff#78A566c8Vl7!(qcfzpf9BoIxNZ()x6^b*_2@tDx)`aVhNbH7gNc=ZvIfMuRoWK>xVf>dugGw^--Y%w=t$ffhpR|NdXLf$pt^M+w9Yl3X0zKequ6;V(>M&Q&^u;kq4%yV zTzfNOZ-tEWFBDaKVXBxS6puKUa}5yhRC$&Xn|L+{yhNN5EnPFoJDIIR^jy7#;s8#B z`Xl@7JkBbbM?V(lL)_W9$CurOqXLQLvj#{1R8DN9sm_2R__br zW6mw;VW7G)oN|){{OBYd4S;=zF7pt1NeLGA(F$1DaQ^d`E7v?3P1FbPT_z2!Bj2VN zwn6IxMeBM^>qER66i-V#drM@Zer7zgA|*w&ULm%V3McO$AYc*h(e@_*OIyq2P+QSh zqi!zsZPIJ}H`4R+b=3CorP-v5Y3=_?TeFd;=kz)>W}s+h8|2=CXA7p1OHfImT|W}X z8&rN2i8$?otCe3M6{6cv0u^MsV+u3tWvM0X*^?rihl*%G{Slp-}5 znh*LN$i&y*359%LD^V`8T9)4Fnt;9%V~Z#DBdxeoW2HPge}WGO0R{6hbct4a6%Al=YOjTcQ?S))0A^C* zS`vh-VTP;`=f~1t2tHFT66$DE*#8gaJj6~9F~@Ims4wjq-#}7#Kof?yo(MFJF9Q07^@NM7q;jxuBgFgT-JG;l4gCSrj|m{yve&q5RyyqCNCO@@J7$c2GcgDhx7_H z)x*jeytn~;Vw`Mo9ylBvo~lAf zu+yE%I`_Ipmy=UH5$E^hK`M_p{z)tdON4a?j3ymYyZjf}QVN7-_0Ckrx*zd4c!2rR zG)ulgIuRk;-rR#lrC#vXHzV}Pj8IP?^rFPCc;y``PD~{%`_y15Y64<&H>~wK)YOHV z)&Oq}%WOKG)VciDtF6Ifgz!u=LM_dU`mOo-%~Zutn87u+?b<;U%fA*sIHL2Ga|M|Z zsu8CgqJV{m>DGYrW3su9s$rdmF@^Tio&Aa$EMbs>)WzVXzjU1(m1&wtjK6I{d;p3Yj|sB=yT^nVNxyQ zub7PfI!%wpsUR>j^hdf?_ciuPA_zb?@o6E{$JXADm<|%pk@ezfm%DQkF)t89#swmV zA@Rv-(s2Vy8yn&^&h}jYR~wAEqLwTa8RHE;==B=tbtm+CH6(>~ z8gaTPjj(K3tlNmQ9|A040IpxqKVv-+6pf#uy12LZ4@ahvgVeGd7lytERPX?F)1n9b6=U~XeR z0b^tkl@6K^dc>R>9wCI4Qh9@FNQGM;#pptSLnuC!wzlv{Pd}L%keVP7DG(`CaUp+m z$1qfsPI#m+6LO@ zsXb$%n<&sc6q*9yC*b}@*JiAB<)!>k5t_F~?M*CSx`xCT^Np~s_1{D>DB>#*S=$pA zp(pL_iI0&WMmvS}lJ|s^@$<+KQhkpIDT1@n=w1!p4Di6AF(;l%ZfCMu<)}YlLt@^- z^bj|q^>keInpvS!{KJ$hC>>-&Uw)Vk(bAB*X#!nY$HgJ`I2fa1MvjOHiIHOY<#l$zPC#2C`KerH8>J^HCUVI{H}|2NduO&E zwc!$J_`~u*!^?%`Oc3p*KK&6IjDuGuc_bBD)C;!_MI{!A48M%rK1jvf85GlM@~xNO z;&cr90jDOWV*C`vK%QZspXN%YgU~=?L1wN-CtR%rG7R6bf%c4#E|$i8AP+Q#+nGX( z^50FA68oLne%8bc)nZ?Fr zKO3V49E8I`->*ysQXF)#*uYQ{*jC#YPYdu7E?#9o195EsfYO5>l7&SvjLo6M2 zDXNlIj*_n_X_h#+7$XbPGE`xorD82h@9eK%8tZ63K$pbnK4@hxN9I|y* zw$6G8StIbsxw&!EWt_F^f303f2efg)gTV z(#)#>Ch`B}GFaIE0a0_wzo0~%Mi$dsLHn~73FlE76GtoS!@o0Y3y6P!O2N6BNkyDj z*-%Y4gx}G-SW(39pfRd7Vx#>|T5Etgvd9;JvEag5Z(tNnO<;5XX!RHq7}Z0CRfE$H z>3j`pARR9;emzZP)$g!m48L9b*Pz1o9XVIUZ{~RKKXqVk5%P}jD zr|FcJ4zOC+1xbE=Q(*D4wqHK=Iom6r?6kG?dS5T{9jU%B+X!ge{n*-#*-y!z0__|W zP_0j)YtFUUbuz*^3BLzs;`pUADtga9MNq)R{WKh^IPA+gsOWYI3#nmxs*G6X;M#_W zGXRj$|Kjw^d`KTDRt>1TYqNz{d$v654mAZN7Xw2aJY;omWmOdo#eeVEt~(RbPM%m5-zAc zNV8+EvEi2$`AlrSaZ z6-hb;updN*mS9m;)}Okxo?Xq8grb3{1WPJM4Hbbw4e3_JQQY%M6fBGWdJZf zyb1$kd3GCQkHn27iS4&(Lvt=-_P@>+1N3Kk&;S+DPRXomM!E_6NfEv8-hmPq|3j!} z{{=!NhdRouf@d;O9&j;MV_P0%k{!|UnHilcZ`esuijgHbUF`%^s|1rss;Kh{)agzg zM5u1r7ocY&+h;r;%8o@F-8RKWgpsieai#8Qvn%xrAb}m$8h8tiDy$*$jG+89DiiDH z*eGUi8O|&}r$?}n*E@H+-ImQRc@gQ@46hu$hB4QSkqDd4aVNH2?9^$0mXa8-Sb#9` z`0pGa3F;BL@6Rk0HMRq20jSCP#+^gRmd-*QMNm3e4zU<($jSeFqSPRpif4u*^wX~;%}EP0S>spcV@&zO=pmXg?3&*+5KZzB$|2!A|R zEW#V|@K}VRq!vNzzh})NrjdiHcLxLE4v9TzE$kiIoDnucO+c=cw!58!UQ7*qt&Qav z5rKdPM0OOts^}W(lx|8gj`Z4AjO!si4H^$>W<4f;ya`;bEh`+g-jBg2@h7z}FtTZw zfrru!hv5#jWF|_Ks-RrMC8y&{ByvreEf0h&nJ{`{p)YgbDZ8xxFd73bDb4|vZfH;s zVzC0G3wdnHJ;RmABC9p0)jiwK}ddU zw`|6UAD1v2_eFrU=sn~m?B7J8w*16w!?@IhI@Hs!lEd{&l?WHX!JAq=c!dQ6IKb@I z&!x`rq|wRIEwZiMxzM~#f$-9f*c`RtAgZO%Yp>4=gu_`BS{SF8!Yd0!j1gzfpV$e8 zA*k0Xl_TA7j4U|2xcAY>YcV`~ySt?%QaJ7oi%ur6B($u8uwvBl<{B=>x6%W<;>!2c zKcp;qulcNQaT_lI9K z;rfE%`kdi<3_`u$ZSg>!jz`S3Tv54JQ!z1DSZUad%-En-!qR(Ju98KZU;h}^>G zg%!c!L%dHa(F}GrVy4b+E#5;cpvKUs#a5V&_Z4vb%EO<3WL6#^~gDmk_BebL5G;aK>YKE{DQsY$iern$C9f-U&DMHQa|YmU~KS?3)u| z>$YO2m%$svfwzY2wxS+)4mt!g4fEhGFY$6QBUN2{Xs`|M2!}K7$&F)v3uaL**d=Sa z9E&PvPDdV2qMaCMpStIn#7o !5#mb9)^`LbvddzX1=<=`(g?!SbwEa-r4*GN6ozk<#tA z9SgyF4_NO856_(;vf3gKSbntv>eCGp9;mOhdQ*R*aDSw6Te}ODMeGT*H^4Z~8l1^4 zXfNqje?o)&a~f0P;BccHPHgkPjrMc{40Tj1huW-$OWqEsqh-j&_MR+8G*QD(P?a9# zR*IT@>+={chBMCizG(OoJgDIyJH_8E#s2yYY1g0S;cDbWRV-B%tCC`dIkRVHtT_(* zZ2-E@ws6b~XMA&_^lqH(Q#ofO$T4+`YLeo43?6+xC~SHY6!gtINPhc| zdQGHxI)=l=Q>AN)0u7$BmrwcpEhh>A8WLB}>(%}6d z2>0Yf7VHWJMe`uXyv^6%;7g5Yy-P5}aVW;3kVll#Zla0PfE+jJRPqTc6C4lUJ=X`nI@r|v@Es? z>iDx1g{g*u8-n|B+$7+J;8y%C?XsnX$xo^@x3wG6VyuUmPYjDkYuK7XC5puq#q(1{ z6cKs2qPRqf;+gM?C=P@~#JaL@Tzy{gmpD?RV*+PPAS*Y!_nj1_ipY$eHP%Z-+k=RW ziiAP6W3XF4$A)|3yNO8jn)bFCInDpsQa0`riBVHNl!x261*&md+of?qv~jqX7qe8- zfk1tW+%pdPT!KEV&(Y(0E5vBc5C?8gVUMCS3qWFu|Gi}hpt+Pr)J!~h=e zy?&Y!T%!`)y?9V7#`wqOx*uI2ou>rNc(brzM2QK}Y^5nNE*~=A67ipH1KCLgN zl)@PY+{j0M5Dyt|QdHEkPb`>d0)i(9l1sg8XWEJzMBF^D-i+_r*@5;8a{{4hfk5a2 zjHj~;kS;{J6zOu7(_K!A0b^;IC>2vmvPCqdr(r+lh93xR^o+*kyWvQn7ehs*1K&c* z3DGk4wG|Z&)bIxngP^fsG3{*pBkyD7SLaJV%##QDAxmtgZv&=3P_Cu@nSr$FSUHsS z<5`_bU1EE#Xh|_z;_pJm>#**JmdHx7%N2bE6GdYE`Y`ga6;T2$qxEyKX#JQdwX9$7 zBw_3sdANGMNcBd0oAk!Pc&OemQZV&-B*qcO8hgb0p(+IE#`^WqtUx2nRE4Fw!jvMB z1ain)eI}p7_2t9$rNi|_u==jC7n>1#tIF5`$2Co{zJzkpZdtwgXmEbhx z5AtwZ`z_Vl|M`xz_Ch?^+KfjP@&g(483hg<`P4DG67nr-Oy!LiE+cvI>xLpFE(ovA#m>(pOHx zzLE;t3%M|vwu+;}(c78S2+C_UO**-vt5KaAJJUfs6TglW&X{sE)s(hryVhE+4;i}z zSHbzp4wgSNuDm^W(Db55CFe(ZbFdn5a76=M(v^p~*wP3IOmKSH>+|3+^}3j`?W7eR zUm3y`!P7)b^B1h7mQKA559i0x1BZo$$k=JQbZl$wkq@^;=F}AFiO5B>kcVx@_>$T9goi6p2M?LI0K6x zpqoB$k~&=D68iD)v=gK&0O8{)H0ARyz7apwvGjQT01pWyrH^|bDGi{4aasUo#n*Pq z8nu6DBNzl9I4^)Fy10?QfAA;HAWTWE}YTQ%18csJjC>Zq==txRA%@4 ztJ3N5rRS;AXR6Y7#!Bl>+YOsJO8jjQjfi_~3PJKR;@|m`>?2FZEm+%U5&cJiKE%{r z5W+o29#D%^S1r(z8L4LS#m%cFap%**8M6*|M~m5O zGqJDCtk}y~sa4iM9y}z#F%>)d8bNiQzI8Ft_1CHF__1Tgt&C3T_vO&UL{vZl+t4Ft zhl+x|V?_n@^7d$}2$5OYnr)0vsqjb0LWS{sNkj3M51&h(H}CowqhK&huPyHWsqc6GU81c z=`4}YFQqDxd=kqICoZlNfAJ9AuKas1$#Zt~w(}Z+@&_2>E@8V0bj{QPem8EdrKwcu~G@7SZ`&C!_jPBhb&k~=m@{k&l5}&zAbr5G*l3=C(8*Was=i~ z$R^apHLA*lc|$f`96d7vhKM3g)X>N8Ws1lMZADhB*Vz-9t`B9i)IlyhF+GJvJ{=YG zlk}@@y~vY#A#ADi8C5BZq#_ziRT98ED>Vd62c3{i*~OTVJbl$yjM(+BxT+i7eSVhnu>?c zg#<rd z8kt5hFMVftctaauA+>;xt#n>6N|3YPzJx!Owl=I7a{pr5aC6^qbMJ6-&oB>%OECN= z;^H+oDz)`z;?LTTudzFn(Jz-l4&k69Z-Bca5(TK^gL0(eSuoxY#$g7i<22Futt`ZG zpcH39QR)-ERpA!V=(2w*M&&jo#z9cg$6TZ`(AL$*4ew-mUT+g)Rb&iSrFl0z&E~14 zviosCJJy&=P5M5hm5T$aXxbV=STdaPhGZ6@mnFFn?c~fa&K*r7ai!%|Fc!2E+2(a} zHX@vH)Bz*n!jT?Qv-%s#C7ki>UQz@srK`Hd>_YzHW^N)MEFiPqqU<<+_TlQQ;^&p6 z_?c)H;?7bHAAJ~sy&#Ea#Ccnq>E3YmBw0emoJt7>4*SEZN1SH_4_cwi$B1|iH;H_Ef*|Y6|afml3$<1eEo4PaNjp$H4sYd zowGWUOkho^uKGQ!`9O)EH?aUC-Hm7?8X0lQa2mk<1M#yYTLwD10o1W0AbY#2)E;iB zW9?G7otq=XH4ml~Mu_qFsYaotZj5KB6)x}u6*G*q`oo!I$Bjo0KYXE*v6kPf)WPy2 zS)i{l<7KpL1ZKL$2}Vf#?SP%~6R8O`0ShJOp%XQUTz_^cB*%J^cYBQ#`a zeW4gh6a%IRdDE3&Lli0n@xLTv0IbH{N&maJI+AJDFfAn*(>flz&taYG+vR+8#wU%q z!@+3$pIAy3n*G3wI6ooNyj3R*hlz_Hv_*bUfoVO~VG#Cf@E;VIR;d@IsPJn@Wt_Bw z$1nQuzSD1@RAj9;5Z+@no~Q_~u!$4;_$v(h*h@>o!V<#doi)@B&nRNdk#b@IP}A?3 z(WxrOVvyfqw@TsDP?#s+gwIl1Cm}Llh|qpGxXwkdS(F(9y6o^jSuqs_ZIl2UPe?;J z9b~5DAcAP0lTMe+U;-z;j)ggXHn8~%XxVEDHZIn}yY`W`1CfjB>6!$3Tl*7RJaR=9 zno*PHj_+KP5(^dBecQK!eQY&%DvR^R(m8EkIskm(w^_RIR+ zzb-)A&ROXoL=ZP`G10czu(;7ULyZ9}d~(A;919p0`N-dip#f6+W%N0yR6Fl&5`l9^?3Usr4nvHbQ~ z+^0rLI-GI!Zf;bg8w=KPUk_F%bvl*lCF<1(sqH-{CV4b9t~c+XymkM5yJ3XK!2Rjz z@%4fB1Gq6Wp&dq^^q;18!bo~L=ekWvDCjlD%M;~?GyZqicwTs%3U#hEZP1#AMPRp0 zC*gN8UhTHGpqG_abMltWGu@#lhGalJDpnx0%8^vK9}i6A`s5MrC9r*^!i+e7Uq3t? zkv|Oq3ckq7v8bL_H?lGnzwiSug0D?Tg2Et*F^J1U7#Ru>Zd=1PYt9%0D5LaD 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 z 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 bdM5cie7Cal3nk;9Y{^RhooGPxcIE#7vdv

metadata = context->client_metadata(); for (auto iter = metadata.begin(); iter != metadata.end(); ++iter) { - std::cout << "Header key: " << iter->first << " , value: " << iter->second << std::endl; + std::cout << "Header key: " << iter->first << ", value: "; + // Check for binary value + size_t isbin = iter->first.find("-bin"); + if ((isbin != std::string::npos) && (isbin + 4 == iter->first.size())) { + std::cout << std::hex; + for (auto c : iter->second) { + std::cout << static_cast(c); + } + std::cout << std::dec; + } else { + std::cout << iter->second; + } + std::cout << std::endl; } context->AddInitialMetadata("custom-server-metadata", "initial metadata value"); diff --git a/examples/cpp/metadata/greeter_server.o b/examples/cpp/metadata/greeter_server.o deleted file mode 100644 index dc197b2d14cb36605b595aec47dfbde9cb1df81b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 112144 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%0Ab0J=P1b&%@)Zc;B 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 diff --git a/examples/cpp/metadata/helloworld.grpc.pb.cc b/examples/cpp/metadata/helloworld.grpc.pb.cc deleted file mode 100644 index 4255687148b..00000000000 --- a/examples/cpp/metadata/helloworld.grpc.pb.cc +++ /dev/null @@ -1,70 +0,0 @@ -// Generated by the gRPC C++ plugin. -// If you make any local change, they will be lost. -// source: helloworld.proto - -#include "helloworld.pb.h" -#include "helloworld.grpc.pb.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -namespace helloworld { - -static const char* Greeter_method_names[] = { - "/helloworld.Greeter/SayHello", -}; - -std::unique_ptr< Greeter::Stub> Greeter::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) { - (void)options; - std::unique_ptr< Greeter::Stub> stub(new Greeter::Stub(channel)); - return stub; -} - -Greeter::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) - : channel_(channel), rpcmethod_SayHello_(Greeter_method_names[0], ::grpc::internal::RpcMethod::NORMAL_RPC, channel) - {} - -::grpc::Status Greeter::Stub::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) { - return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_SayHello_, context, request, response); -} - -void Greeter::Stub::experimental_async::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response, std::function f) { - return ::grpc::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_SayHello_, context, request, response, std::move(f)); -} - -::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::AsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { - return ::grpc::internal::ClientAsyncResponseReaderFactory< ::helloworld::HelloReply>::Create(channel_.get(), cq, rpcmethod_SayHello_, context, request, true); -} - -::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::PrepareAsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { - return ::grpc::internal::ClientAsyncResponseReaderFactory< ::helloworld::HelloReply>::Create(channel_.get(), cq, rpcmethod_SayHello_, context, request, false); -} - -Greeter::Service::Service() { - AddMethod(new ::grpc::internal::RpcServiceMethod( - Greeter_method_names[0], - ::grpc::internal::RpcMethod::NORMAL_RPC, - new ::grpc::internal::RpcMethodHandler< Greeter::Service, ::helloworld::HelloRequest, ::helloworld::HelloReply>( - std::mem_fn(&Greeter::Service::SayHello), this))); -} - -Greeter::Service::~Service() { -} - -::grpc::Status Greeter::Service::SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) { - (void) context; - (void) request; - (void) response; - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); -} - - -} // namespace helloworld - diff --git a/examples/cpp/metadata/helloworld.grpc.pb.h b/examples/cpp/metadata/helloworld.grpc.pb.h deleted file mode 100644 index 73cc75e0a62..00000000000 --- a/examples/cpp/metadata/helloworld.grpc.pb.h +++ /dev/null @@ -1,197 +0,0 @@ -// Generated by the gRPC C++ plugin. -// If you make any local change, they will be lost. -// source: helloworld.proto -// Original file comments: -// Copyright 2015 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_helloworld_2eproto__INCLUDED -#define GRPC_helloworld_2eproto__INCLUDED - -#include "helloworld.pb.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace grpc { -class CompletionQueue; -class Channel; -class ServerCompletionQueue; -class ServerContext; -} // namespace grpc - -namespace helloworld { - -// The greeting service definition. -class Greeter final { - public: - static constexpr char const* service_full_name() { - return "helloworld.Greeter"; - } - class StubInterface { - public: - virtual ~StubInterface() {} - // Sends a greeting - virtual ::grpc::Status SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) = 0; - std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>> AsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>>(AsyncSayHelloRaw(context, request, cq)); - } - std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>> PrepareAsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>>(PrepareAsyncSayHelloRaw(context, request, cq)); - } - class experimental_async_interface { - public: - virtual ~experimental_async_interface() {} - // Sends a greeting - virtual void SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response, std::function) = 0; - }; - virtual class experimental_async_interface* experimental_async() { return nullptr; } - private: - virtual ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>* AsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) = 0; - virtual ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>* PrepareAsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) = 0; - }; - class Stub final : public StubInterface { - public: - Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); - ::grpc::Status SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) override; - std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>> AsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>>(AsyncSayHelloRaw(context, request, cq)); - } - std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>> PrepareAsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>>(PrepareAsyncSayHelloRaw(context, request, cq)); - } - class experimental_async final : - public StubInterface::experimental_async_interface { - public: - void SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response, std::function) override; - private: - friend class Stub; - explicit experimental_async(Stub* stub): stub_(stub) { } - Stub* stub() { return stub_; } - Stub* stub_; - }; - class experimental_async_interface* experimental_async() override { return &async_stub_; } - - private: - std::shared_ptr< ::grpc::ChannelInterface> channel_; - class experimental_async async_stub_{this}; - ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* AsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) override; - ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* PrepareAsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) override; - const ::grpc::internal::RpcMethod rpcmethod_SayHello_; - }; - static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); - - class Service : public ::grpc::Service { - public: - Service(); - virtual ~Service(); - // Sends a greeting - virtual ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response); - }; - template - class WithAsyncMethod_SayHello : public BaseClass { - private: - void BaseClassMustBeDerivedFromService(const Service *service) {} - public: - WithAsyncMethod_SayHello() { - ::grpc::Service::MarkMethodAsync(0); - } - ~WithAsyncMethod_SayHello() override { - BaseClassMustBeDerivedFromService(this); - } - // disable synchronous version of this method - ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { - abort(); - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); - } - void RequestSayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); - } - }; - typedef WithAsyncMethod_SayHello AsyncService; - template - class WithGenericMethod_SayHello : public BaseClass { - private: - void BaseClassMustBeDerivedFromService(const Service *service) {} - public: - WithGenericMethod_SayHello() { - ::grpc::Service::MarkMethodGeneric(0); - } - ~WithGenericMethod_SayHello() override { - BaseClassMustBeDerivedFromService(this); - } - // disable synchronous version of this method - ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { - abort(); - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); - } - }; - template - class WithRawMethod_SayHello : public BaseClass { - private: - void BaseClassMustBeDerivedFromService(const Service *service) {} - public: - WithRawMethod_SayHello() { - ::grpc::Service::MarkMethodRaw(0); - } - ~WithRawMethod_SayHello() override { - BaseClassMustBeDerivedFromService(this); - } - // disable synchronous version of this method - ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { - abort(); - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); - } - void RequestSayHello(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); - } - }; - template - class WithStreamedUnaryMethod_SayHello : public BaseClass { - private: - void BaseClassMustBeDerivedFromService(const Service *service) {} - public: - WithStreamedUnaryMethod_SayHello() { - ::grpc::Service::MarkMethodStreamed(0, - new ::grpc::internal::StreamedUnaryHandler< ::helloworld::HelloRequest, ::helloworld::HelloReply>(std::bind(&WithStreamedUnaryMethod_SayHello::StreamedSayHello, this, std::placeholders::_1, std::placeholders::_2))); - } - ~WithStreamedUnaryMethod_SayHello() override { - BaseClassMustBeDerivedFromService(this); - } - // disable regular version of this method - ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { - abort(); - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); - } - // replace default version of method with streamed unary - virtual ::grpc::Status StreamedSayHello(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::helloworld::HelloRequest,::helloworld::HelloReply>* server_unary_streamer) = 0; - }; - typedef WithStreamedUnaryMethod_SayHello StreamedUnaryService; - typedef Service SplitStreamedService; - typedef WithStreamedUnaryMethod_SayHello StreamedService; -}; - -} // namespace helloworld - - -#endif // GRPC_helloworld_2eproto__INCLUDED diff --git a/examples/cpp/metadata/helloworld.grpc.pb.o b/examples/cpp/metadata/helloworld.grpc.pb.o deleted file mode 100644 index 234283660c2185112bf5a40874899672b328aa80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 398496 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 w=02@|e2cV41O4aeXEX08#pYMFzIkvk#=-yP - -#include -#include -#include -#include -#include -#include -#include -#include -// This is a temporary google only hack -#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS -#include "third_party/protobuf/version.h" -#endif -// @@protoc_insertion_point(includes) - -namespace helloworld { -class HelloRequestDefaultTypeInternal { - public: - ::google::protobuf::internal::ExplicitlyConstructed - _instance; -} _HelloRequest_default_instance_; -class HelloReplyDefaultTypeInternal { - public: - ::google::protobuf::internal::ExplicitlyConstructed - _instance; -} _HelloReply_default_instance_; -} // namespace helloworld -namespace protobuf_helloworld_2eproto { -static void InitDefaultsHelloRequest() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::helloworld::_HelloRequest_default_instance_; - new (ptr) ::helloworld::HelloRequest(); - ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); - } - ::helloworld::HelloRequest::InitAsDefaultInstance(); -} - -::google::protobuf::internal::SCCInfo<0> scc_info_HelloRequest = - {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsHelloRequest}, {}}; - -static void InitDefaultsHelloReply() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::helloworld::_HelloReply_default_instance_; - new (ptr) ::helloworld::HelloReply(); - ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); - } - ::helloworld::HelloReply::InitAsDefaultInstance(); -} - -::google::protobuf::internal::SCCInfo<0> scc_info_HelloReply = - {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsHelloReply}, {}}; - -void InitDefaults() { - ::google::protobuf::internal::InitSCC(&scc_info_HelloRequest.base); - ::google::protobuf::internal::InitSCC(&scc_info_HelloReply.base); -} - -::google::protobuf::Metadata file_level_metadata[2]; - -const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { - ~0u, // no _has_bits_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloRequest, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloRequest, name_), - ~0u, // no _has_bits_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloReply, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloReply, message_), -}; -static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { - { 0, -1, sizeof(::helloworld::HelloRequest)}, - { 6, -1, sizeof(::helloworld::HelloReply)}, -}; - -static ::google::protobuf::Message const * const file_default_instances[] = { - reinterpret_cast(&::helloworld::_HelloRequest_default_instance_), - reinterpret_cast(&::helloworld::_HelloReply_default_instance_), -}; - -void protobuf_AssignDescriptors() { - AddDescriptors(); - AssignDescriptors( - "helloworld.proto", schemas, file_default_instances, TableStruct::offsets, - file_level_metadata, NULL, NULL); -} - -void protobuf_AssignDescriptorsOnce() { - static ::google::protobuf::internal::once_flag once; - ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); -} - -void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD; -void protobuf_RegisterTypes(const ::std::string&) { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 2); -} - -void AddDescriptorsImpl() { - InitDefaults(); - static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { - "\n\020helloworld.proto\022\nhelloworld\"\034\n\014HelloR" - "equest\022\014\n\004name\030\001 \001(\t\"\035\n\nHelloReply\022\017\n\007me" - "ssage\030\001 \001(\t2I\n\007Greeter\022>\n\010SayHello\022\030.hel" - "loworld.HelloRequest\032\026.helloworld.HelloR" - "eply\"\000B6\n\033io.grpc.examples.helloworldB\017H" - "elloWorldProtoP\001\242\002\003HLWb\006proto3" - }; - ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - descriptor, 230); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( - "helloworld.proto", &protobuf_RegisterTypes); -} - -void AddDescriptors() { - static ::google::protobuf::internal::once_flag once; - ::google::protobuf::internal::call_once(once, AddDescriptorsImpl); -} -// Force AddDescriptors() to be called at dynamic initialization time. -struct StaticDescriptorInitializer { - StaticDescriptorInitializer() { - AddDescriptors(); - } -} static_descriptor_initializer; -} // namespace protobuf_helloworld_2eproto -namespace helloworld { - -// =================================================================== - -void HelloRequest::InitAsDefaultInstance() { -} -#if !defined(_MSC_VER) || _MSC_VER >= 1900 -const int HelloRequest::kNameFieldNumber; -#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 - -HelloRequest::HelloRequest() - : ::google::protobuf::Message(), _internal_metadata_(NULL) { - ::google::protobuf::internal::InitSCC( - &protobuf_helloworld_2eproto::scc_info_HelloRequest.base); - SharedCtor(); - // @@protoc_insertion_point(constructor:helloworld.HelloRequest) -} -HelloRequest::HelloRequest(const HelloRequest& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (from.name().size() > 0) { - name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); - } - // @@protoc_insertion_point(copy_constructor:helloworld.HelloRequest) -} - -void HelloRequest::SharedCtor() { - name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - -HelloRequest::~HelloRequest() { - // @@protoc_insertion_point(destructor:helloworld.HelloRequest) - SharedDtor(); -} - -void HelloRequest::SharedDtor() { - name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - -void HelloRequest::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const ::google::protobuf::Descriptor* HelloRequest::descriptor() { - ::protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); - return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; -} - -const HelloRequest& HelloRequest::default_instance() { - ::google::protobuf::internal::InitSCC(&protobuf_helloworld_2eproto::scc_info_HelloRequest.base); - return *internal_default_instance(); -} - - -void HelloRequest::Clear() { -// @@protoc_insertion_point(message_clear_start:helloworld.HelloRequest) - ::google::protobuf::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - _internal_metadata_.Clear(); -} - -bool HelloRequest::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:helloworld.HelloRequest) - for (;;) { - ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // string name = 1; - case 1: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - this->name().data(), static_cast(this->name().length()), - ::google::protobuf::internal::WireFormatLite::PARSE, - "helloworld.HelloRequest.name")); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, _internal_metadata_.mutable_unknown_fields())); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:helloworld.HelloRequest) - return true; -failure: - // @@protoc_insertion_point(parse_failure:helloworld.HelloRequest) - return false; -#undef DO_ -} - -void HelloRequest::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:helloworld.HelloRequest) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // string name = 1; - if (this->name().size() > 0) { - ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - this->name().data(), static_cast(this->name().length()), - ::google::protobuf::internal::WireFormatLite::SERIALIZE, - "helloworld.HelloRequest.name"); - ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( - 1, this->name(), output); - } - - if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); - } - // @@protoc_insertion_point(serialize_end:helloworld.HelloRequest) -} - -::google::protobuf::uint8* HelloRequest::InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused - // @@protoc_insertion_point(serialize_to_array_start:helloworld.HelloRequest) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // string name = 1; - if (this->name().size() > 0) { - ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - this->name().data(), static_cast(this->name().length()), - ::google::protobuf::internal::WireFormatLite::SERIALIZE, - "helloworld.HelloRequest.name"); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); - } - // @@protoc_insertion_point(serialize_to_array_end:helloworld.HelloRequest) - return target; -} - -size_t HelloRequest::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:helloworld.HelloRequest) - size_t total_size = 0; - - if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); - } - // string name = 1; - if (this->name().size() > 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } - - int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void HelloRequest::MergeFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_merge_from_start:helloworld.HelloRequest) - GOOGLE_DCHECK_NE(&from, this); - const HelloRequest* source = - ::google::protobuf::internal::DynamicCastToGenerated( - &from); - if (source == NULL) { - // @@protoc_insertion_point(generalized_merge_from_cast_fail:helloworld.HelloRequest) - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - // @@protoc_insertion_point(generalized_merge_from_cast_success:helloworld.HelloRequest) - MergeFrom(*source); - } -} - -void HelloRequest::MergeFrom(const HelloRequest& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:helloworld.HelloRequest) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - if (from.name().size() > 0) { - - name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); - } -} - -void HelloRequest::CopyFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_copy_from_start:helloworld.HelloRequest) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void HelloRequest::CopyFrom(const HelloRequest& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:helloworld.HelloRequest) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool HelloRequest::IsInitialized() const { - return true; -} - -void HelloRequest::Swap(HelloRequest* other) { - if (other == this) return; - InternalSwap(other); -} -void HelloRequest::InternalSwap(HelloRequest* other) { - using std::swap; - name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - _internal_metadata_.Swap(&other->_internal_metadata_); -} - -::google::protobuf::Metadata HelloRequest::GetMetadata() const { - protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); - return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages]; -} - - -// =================================================================== - -void HelloReply::InitAsDefaultInstance() { -} -#if !defined(_MSC_VER) || _MSC_VER >= 1900 -const int HelloReply::kMessageFieldNumber; -#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 - -HelloReply::HelloReply() - : ::google::protobuf::Message(), _internal_metadata_(NULL) { - ::google::protobuf::internal::InitSCC( - &protobuf_helloworld_2eproto::scc_info_HelloReply.base); - SharedCtor(); - // @@protoc_insertion_point(constructor:helloworld.HelloReply) -} -HelloReply::HelloReply(const HelloReply& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (from.message().size() > 0) { - message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_); - } - // @@protoc_insertion_point(copy_constructor:helloworld.HelloReply) -} - -void HelloReply::SharedCtor() { - message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - -HelloReply::~HelloReply() { - // @@protoc_insertion_point(destructor:helloworld.HelloReply) - SharedDtor(); -} - -void HelloReply::SharedDtor() { - message_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - -void HelloReply::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const ::google::protobuf::Descriptor* HelloReply::descriptor() { - ::protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); - return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; -} - -const HelloReply& HelloReply::default_instance() { - ::google::protobuf::internal::InitSCC(&protobuf_helloworld_2eproto::scc_info_HelloReply.base); - return *internal_default_instance(); -} - - -void HelloReply::Clear() { -// @@protoc_insertion_point(message_clear_start:helloworld.HelloReply) - ::google::protobuf::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - _internal_metadata_.Clear(); -} - -bool HelloReply::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:helloworld.HelloReply) - for (;;) { - ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // string message = 1; - case 1: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_message())); - DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - this->message().data(), static_cast(this->message().length()), - ::google::protobuf::internal::WireFormatLite::PARSE, - "helloworld.HelloReply.message")); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, _internal_metadata_.mutable_unknown_fields())); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:helloworld.HelloReply) - return true; -failure: - // @@protoc_insertion_point(parse_failure:helloworld.HelloReply) - return false; -#undef DO_ -} - -void HelloReply::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:helloworld.HelloReply) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // string message = 1; - if (this->message().size() > 0) { - ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - this->message().data(), static_cast(this->message().length()), - ::google::protobuf::internal::WireFormatLite::SERIALIZE, - "helloworld.HelloReply.message"); - ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( - 1, this->message(), output); - } - - if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); - } - // @@protoc_insertion_point(serialize_end:helloworld.HelloReply) -} - -::google::protobuf::uint8* HelloReply::InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused - // @@protoc_insertion_point(serialize_to_array_start:helloworld.HelloReply) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // string message = 1; - if (this->message().size() > 0) { - ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - this->message().data(), static_cast(this->message().length()), - ::google::protobuf::internal::WireFormatLite::SERIALIZE, - "helloworld.HelloReply.message"); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->message(), target); - } - - if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); - } - // @@protoc_insertion_point(serialize_to_array_end:helloworld.HelloReply) - return target; -} - -size_t HelloReply::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:helloworld.HelloReply) - size_t total_size = 0; - - if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); - } - // string message = 1; - if (this->message().size() > 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->message()); - } - - int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void HelloReply::MergeFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_merge_from_start:helloworld.HelloReply) - GOOGLE_DCHECK_NE(&from, this); - const HelloReply* source = - ::google::protobuf::internal::DynamicCastToGenerated( - &from); - if (source == NULL) { - // @@protoc_insertion_point(generalized_merge_from_cast_fail:helloworld.HelloReply) - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - // @@protoc_insertion_point(generalized_merge_from_cast_success:helloworld.HelloReply) - MergeFrom(*source); - } -} - -void HelloReply::MergeFrom(const HelloReply& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:helloworld.HelloReply) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - if (from.message().size() > 0) { - - message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_); - } -} - -void HelloReply::CopyFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_copy_from_start:helloworld.HelloReply) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void HelloReply::CopyFrom(const HelloReply& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:helloworld.HelloReply) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool HelloReply::IsInitialized() const { - return true; -} - -void HelloReply::Swap(HelloReply* other) { - if (other == this) return; - InternalSwap(other); -} -void HelloReply::InternalSwap(HelloReply* other) { - using std::swap; - message_.Swap(&other->message_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - _internal_metadata_.Swap(&other->_internal_metadata_); -} - -::google::protobuf::Metadata HelloReply::GetMetadata() const { - protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); - return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages]; -} - - -// @@protoc_insertion_point(namespace_scope) -} // namespace helloworld -namespace google { -namespace protobuf { -template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::helloworld::HelloRequest* Arena::CreateMaybeMessage< ::helloworld::HelloRequest >(Arena* arena) { - return Arena::CreateInternal< ::helloworld::HelloRequest >(arena); -} -template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::helloworld::HelloReply* Arena::CreateMaybeMessage< ::helloworld::HelloReply >(Arena* arena) { - return Arena::CreateInternal< ::helloworld::HelloReply >(arena); -} -} // namespace protobuf -} // namespace google - -// @@protoc_insertion_point(global_scope) diff --git a/examples/cpp/metadata/helloworld.pb.h b/examples/cpp/metadata/helloworld.pb.h deleted file mode 100644 index 57f6817e310..00000000000 --- a/examples/cpp/metadata/helloworld.pb.h +++ /dev/null @@ -1,419 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto - -#ifndef PROTOBUF_INCLUDED_helloworld_2eproto -#define PROTOBUF_INCLUDED_helloworld_2eproto - -#include - -#include - -#if GOOGLE_PROTOBUF_VERSION < 3006001 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include // IWYU pragma: export -#include // IWYU pragma: export -#include -// @@protoc_insertion_point(includes) -#define PROTOBUF_INTERNAL_EXPORT_protobuf_helloworld_2eproto - -namespace protobuf_helloworld_2eproto { -// Internal implementation detail -- do not use these members. -struct TableStruct { - static const ::google::protobuf::internal::ParseTableField entries[]; - static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; - static const ::google::protobuf::internal::ParseTable schema[2]; - static const ::google::protobuf::internal::FieldMetadata field_metadata[]; - static const ::google::protobuf::internal::SerializationTable serialization_table[]; - static const ::google::protobuf::uint32 offsets[]; -}; -void AddDescriptors(); -} // namespace protobuf_helloworld_2eproto -namespace helloworld { -class HelloReply; -class HelloReplyDefaultTypeInternal; -extern HelloReplyDefaultTypeInternal _HelloReply_default_instance_; -class HelloRequest; -class HelloRequestDefaultTypeInternal; -extern HelloRequestDefaultTypeInternal _HelloRequest_default_instance_; -} // namespace helloworld -namespace google { -namespace protobuf { -template<> ::helloworld::HelloReply* Arena::CreateMaybeMessage<::helloworld::HelloReply>(Arena*); -template<> ::helloworld::HelloRequest* Arena::CreateMaybeMessage<::helloworld::HelloRequest>(Arena*); -} // namespace protobuf -} // namespace google -namespace helloworld { - -// =================================================================== - -class HelloRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:helloworld.HelloRequest) */ { - public: - HelloRequest(); - virtual ~HelloRequest(); - - HelloRequest(const HelloRequest& from); - - inline HelloRequest& operator=(const HelloRequest& from) { - CopyFrom(from); - return *this; - } - #if LANG_CXX11 - HelloRequest(HelloRequest&& from) noexcept - : HelloRequest() { - *this = ::std::move(from); - } - - inline HelloRequest& operator=(HelloRequest&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - #endif - static const ::google::protobuf::Descriptor* descriptor(); - static const HelloRequest& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const HelloRequest* internal_default_instance() { - return reinterpret_cast( - &_HelloRequest_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - void Swap(HelloRequest* other); - friend void swap(HelloRequest& a, HelloRequest& b) { - a.Swap(&b); - } - - // implements Message ---------------------------------------------- - - inline HelloRequest* New() const final { - return CreateMaybeMessage(NULL); - } - - HelloRequest* New(::google::protobuf::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CopyFrom(const ::google::protobuf::Message& from) final; - void MergeFrom(const ::google::protobuf::Message& from) final; - void CopyFrom(const HelloRequest& from); - void MergeFrom(const HelloRequest& from); - void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) final; - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const final; - ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const final; - void InternalSwap(HelloRequest* other); - private: - inline ::google::protobuf::Arena* GetArenaNoVirtual() const { - return NULL; - } - inline void* MaybeArenaPtr() const { - return NULL; - } - public: - - ::google::protobuf::Metadata GetMetadata() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // string name = 1; - void clear_name(); - static const int kNameFieldNumber = 1; - const ::std::string& name() const; - void set_name(const ::std::string& value); - #if LANG_CXX11 - void set_name(::std::string&& value); - #endif - void set_name(const char* value); - void set_name(const char* value, size_t size); - ::std::string* mutable_name(); - ::std::string* release_name(); - void set_allocated_name(::std::string* name); - - // @@protoc_insertion_point(class_scope:helloworld.HelloRequest) - private: - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - ::google::protobuf::internal::ArenaStringPtr name_; - mutable ::google::protobuf::internal::CachedSize _cached_size_; - friend struct ::protobuf_helloworld_2eproto::TableStruct; -}; -// ------------------------------------------------------------------- - -class HelloReply : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:helloworld.HelloReply) */ { - public: - HelloReply(); - virtual ~HelloReply(); - - HelloReply(const HelloReply& from); - - inline HelloReply& operator=(const HelloReply& from) { - CopyFrom(from); - return *this; - } - #if LANG_CXX11 - HelloReply(HelloReply&& from) noexcept - : HelloReply() { - *this = ::std::move(from); - } - - inline HelloReply& operator=(HelloReply&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - #endif - static const ::google::protobuf::Descriptor* descriptor(); - static const HelloReply& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const HelloReply* internal_default_instance() { - return reinterpret_cast( - &_HelloReply_default_instance_); - } - static constexpr int kIndexInFileMessages = - 1; - - void Swap(HelloReply* other); - friend void swap(HelloReply& a, HelloReply& b) { - a.Swap(&b); - } - - // implements Message ---------------------------------------------- - - inline HelloReply* New() const final { - return CreateMaybeMessage(NULL); - } - - HelloReply* New(::google::protobuf::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CopyFrom(const ::google::protobuf::Message& from) final; - void MergeFrom(const ::google::protobuf::Message& from) final; - void CopyFrom(const HelloReply& from); - void MergeFrom(const HelloReply& from); - void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) final; - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const final; - ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const final; - void InternalSwap(HelloReply* other); - private: - inline ::google::protobuf::Arena* GetArenaNoVirtual() const { - return NULL; - } - inline void* MaybeArenaPtr() const { - return NULL; - } - public: - - ::google::protobuf::Metadata GetMetadata() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // string message = 1; - void clear_message(); - static const int kMessageFieldNumber = 1; - const ::std::string& message() const; - void set_message(const ::std::string& value); - #if LANG_CXX11 - void set_message(::std::string&& value); - #endif - void set_message(const char* value); - void set_message(const char* value, size_t size); - ::std::string* mutable_message(); - ::std::string* release_message(); - void set_allocated_message(::std::string* message); - - // @@protoc_insertion_point(class_scope:helloworld.HelloReply) - private: - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - ::google::protobuf::internal::ArenaStringPtr message_; - mutable ::google::protobuf::internal::CachedSize _cached_size_; - friend struct ::protobuf_helloworld_2eproto::TableStruct; -}; -// =================================================================== - - -// =================================================================== - -#ifdef __GNUC__ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif // __GNUC__ -// HelloRequest - -// string name = 1; -inline void HelloRequest::clear_name() { - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline const ::std::string& HelloRequest::name() const { - // @@protoc_insertion_point(field_get:helloworld.HelloRequest.name) - return name_.GetNoArena(); -} -inline void HelloRequest::set_name(const ::std::string& value) { - - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:helloworld.HelloRequest.name) -} -#if LANG_CXX11 -inline void HelloRequest::set_name(::std::string&& value) { - - name_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:helloworld.HelloRequest.name) -} -#endif -inline void HelloRequest::set_name(const char* value) { - GOOGLE_DCHECK(value != NULL); - - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:helloworld.HelloRequest.name) -} -inline void HelloRequest::set_name(const char* value, size_t size) { - - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:helloworld.HelloRequest.name) -} -inline ::std::string* HelloRequest::mutable_name() { - - // @@protoc_insertion_point(field_mutable:helloworld.HelloRequest.name) - return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline ::std::string* HelloRequest::release_name() { - // @@protoc_insertion_point(field_release:helloworld.HelloRequest.name) - - return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void HelloRequest::set_allocated_name(::std::string* name) { - if (name != NULL) { - - } else { - - } - name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); - // @@protoc_insertion_point(field_set_allocated:helloworld.HelloRequest.name) -} - -// ------------------------------------------------------------------- - -// HelloReply - -// string message = 1; -inline void HelloReply::clear_message() { - message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline const ::std::string& HelloReply::message() const { - // @@protoc_insertion_point(field_get:helloworld.HelloReply.message) - return message_.GetNoArena(); -} -inline void HelloReply::set_message(const ::std::string& value) { - - message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:helloworld.HelloReply.message) -} -#if LANG_CXX11 -inline void HelloReply::set_message(::std::string&& value) { - - message_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:helloworld.HelloReply.message) -} -#endif -inline void HelloReply::set_message(const char* value) { - GOOGLE_DCHECK(value != NULL); - - message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:helloworld.HelloReply.message) -} -inline void HelloReply::set_message(const char* value, size_t size) { - - message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:helloworld.HelloReply.message) -} -inline ::std::string* HelloReply::mutable_message() { - - // @@protoc_insertion_point(field_mutable:helloworld.HelloReply.message) - return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline ::std::string* HelloReply::release_message() { - // @@protoc_insertion_point(field_release:helloworld.HelloReply.message) - - return message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void HelloReply::set_allocated_message(::std::string* message) { - if (message != NULL) { - - } else { - - } - message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message); - // @@protoc_insertion_point(field_set_allocated:helloworld.HelloReply.message) -} - -#ifdef __GNUC__ - #pragma GCC diagnostic pop -#endif // __GNUC__ -// ------------------------------------------------------------------- - - -// @@protoc_insertion_point(namespace_scope) - -} // namespace helloworld - -// @@protoc_insertion_point(global_scope) - -#endif // PROTOBUF_INCLUDED_helloworld_2eproto diff --git a/examples/cpp/metadata/helloworld.pb.o b/examples/cpp/metadata/helloworld.pb.o deleted file mode 100644 index 85671e8aaa3b10080aba2cde1b103fe994eaa612..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111592 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 Date: Fri, 14 Dec 2018 16:06:15 -0800 Subject: [PATCH 314/534] more nullability annotation --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index d4d16024fa0..404d4b76568 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -282,7 +282,7 @@ NS_ASSUME_NONNULL_END */ @interface GRPCCall : GRXWriter -- (nullable instancetype)init NS_UNAVAILABLE; +- (instancetype)init NS_UNAVAILABLE; /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index b7f08480dc0..b866f268ee1 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -18,6 +18,8 @@ #import +NS_ASSUME_NONNULL_BEGIN + /** * Safety remark of a gRPC method as defined in RFC 2616 Section 9.1 */ @@ -66,7 +68,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)provideTokenToHandler:(void (^_Nullable)(NSString *_Nullable token))handler; +- (void)provideTokenToHandler:(void (^)(NSString *_Nullable token))handler; /** * This method is deprecated. Please use \a provideTokenToHandler. @@ -74,7 +76,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)getTokenWithHandler:(void (^_Nullable)(NSString *_Nullable token))handler; +- (void)getTokenWithHandler:(void (^)(NSString *_Nullable token))handler; @end @@ -210,7 +212,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Return if the channel options are equal to another object. */ -- (BOOL)hasChannelOptionsEqualTo:(nonnull GRPCCallOptions *)callOptions; +- (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; /** * Hash for channel options. @@ -352,3 +354,5 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { @property(readwrite) NSUInteger channelID; @end + +NS_ASSUME_NONNULL_END From b90652ab0329e67697e71282b785187a4d1cb223 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Dec 2018 16:07:20 -0800 Subject: [PATCH 315/534] remove debug information --- src/core/lib/iomgr/cfstream_handle.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index bb402f96cf5..6cb9ca1a0d4 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -79,7 +79,6 @@ void CFStreamHandle::WriteCallback(CFWriteStreamRef stream, void* clientCallBackInfo) { grpc_core::ExecCtx exec_ctx; CFStreamHandle* handle = static_cast(clientCallBackInfo); - printf("** CFStreamHandle::WriteCallback\n"); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle, stream, type, clientCallBackInfo); From c097e21259db28d8b80ed661c0c0e3d808466ed1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Dec 2018 17:55:11 -0800 Subject: [PATCH 316/534] Nullability annotation fix --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 404d4b76568..15b1c904498 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -282,7 +282,7 @@ NS_ASSUME_NONNULL_END */ @interface GRPCCall : GRXWriter -- (instancetype)init NS_UNAVAILABLE; +- (nonnull instancetype)init NS_UNAVAILABLE; /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of From 0531d3d3adfd12e1d9aeaa49fb19096b4c1fb5d9 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Sun, 16 Dec 2018 14:50:26 -0800 Subject: [PATCH 317/534] extend local credentials to support tcp loopback --- CMakeLists.txt | 98 +- Makefile | 92 +- build.yaml | 2 + gRPC-Core.podspec | 2 + grpc.gyp | 2 + include/grpc/grpc_security_constants.h | 6 +- .../lib/http/httpcli_security_connector.cc | 2 +- .../alts/alts_security_connector.cc | 10 +- .../fake/fake_security_connector.cc | 7 +- .../local/local_security_connector.cc | 103 +- .../security_connector/security_connector.h | 3 +- .../ssl/ssl_security_connector.cc | 4 +- .../security/transport/security_handshaker.cc | 3 +- test/core/end2end/BUILD | 13 + test/core/end2end/fixtures/h2_local_ipv4.cc | 72 + test/core/end2end/fixtures/h2_local_ipv6.cc | 72 + test/core/end2end/fixtures/h2_local_uds.cc | 71 + .../fixtures/{h2_local.cc => local_util.cc} | 84 +- test/core/end2end/fixtures/local_util.h | 41 + test/core/end2end/gen_build_yaml.py | 4 +- test/core/end2end/generate_tests.bzl | 6 +- .../generated/sources_and_headers.json | 43 +- tools/run_tests/generated/tests.json | 3600 ++++++++++++++++- 23 files changed, 4131 insertions(+), 209 deletions(-) create mode 100644 test/core/end2end/fixtures/h2_local_ipv4.cc create mode 100644 test/core/end2end/fixtures/h2_local_ipv6.cc create mode 100644 test/core/end2end/fixtures/h2_local_uds.cc rename test/core/end2end/fixtures/{h2_local.cc => local_util.cc} (61%) create mode 100644 test/core/end2end/fixtures/local_util.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e296eaee734..b6ceb50a5f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -456,7 +456,13 @@ add_dependencies(buildtests_c h2_full+trace_test) add_dependencies(buildtests_c h2_full+workarounds_test) add_dependencies(buildtests_c h2_http_proxy_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_dependencies(buildtests_c h2_local_test) +add_dependencies(buildtests_c h2_local_ipv4_test) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c h2_local_ipv6_test) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c h2_local_uds_test) endif() add_dependencies(buildtests_c h2_oauth2_test) add_dependencies(buildtests_c h2_proxy_test) @@ -1784,6 +1790,7 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc test/core/end2end/cq_verifier.cc test/core/end2end/fixtures/http_proxy_fixture.cc + test/core/end2end/fixtures/local_util.cc test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc @@ -2104,6 +2111,7 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc test/core/end2end/cq_verifier.cc test/core/end2end/fixtures/http_proxy_fixture.cc + test/core/end2end/fixtures/local_util.cc test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc @@ -17028,12 +17036,88 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_executable(h2_local_test - test/core/end2end/fixtures/h2_local.cc +add_executable(h2_local_ipv4_test + test/core/end2end/fixtures/h2_local_ipv4.cc +) + + +target_include_directories(h2_local_ipv4_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(h2_local_ipv4_test + ${_gRPC_ALLTARGETS_LIBRARIES} + end2end_tests + grpc_test_util + grpc + gpr_test_util + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_local_ipv4_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_local_ipv4_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(h2_local_ipv6_test + test/core/end2end/fixtures/h2_local_ipv6.cc +) + + +target_include_directories(h2_local_ipv6_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(h2_local_ipv6_test + ${_gRPC_ALLTARGETS_LIBRARIES} + end2end_tests + grpc_test_util + grpc + gpr_test_util + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_local_ipv6_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_local_ipv6_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(h2_local_uds_test + test/core/end2end/fixtures/h2_local_uds.cc ) -target_include_directories(h2_local_test +target_include_directories(h2_local_uds_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${_gRPC_SSL_INCLUDE_DIR} @@ -17046,7 +17130,7 @@ target_include_directories(h2_local_test PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) -target_link_libraries(h2_local_test +target_link_libraries(h2_local_uds_test ${_gRPC_ALLTARGETS_LIBRARIES} end2end_tests grpc_test_util @@ -17057,8 +17141,8 @@ target_link_libraries(h2_local_test # avoid dependency on libstdc++ if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(h2_local_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(h2_local_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + set_target_properties(h2_local_uds_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_local_uds_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) endif() endif() diff --git a/Makefile b/Makefile index 9cc4aeecc4d..7b4a1fb0d5e 100644 --- a/Makefile +++ b/Makefile @@ -1324,7 +1324,9 @@ h2_full+pipe_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_test h2_full+trace_test: $(BINDIR)/$(CONFIG)/h2_full+trace_test h2_full+workarounds_test: $(BINDIR)/$(CONFIG)/h2_full+workarounds_test h2_http_proxy_test: $(BINDIR)/$(CONFIG)/h2_http_proxy_test -h2_local_test: $(BINDIR)/$(CONFIG)/h2_local_test +h2_local_ipv4_test: $(BINDIR)/$(CONFIG)/h2_local_ipv4_test +h2_local_ipv6_test: $(BINDIR)/$(CONFIG)/h2_local_ipv6_test +h2_local_uds_test: $(BINDIR)/$(CONFIG)/h2_local_uds_test h2_oauth2_test: $(BINDIR)/$(CONFIG)/h2_oauth2_test h2_proxy_test: $(BINDIR)/$(CONFIG)/h2_proxy_test h2_sockpair_test: $(BINDIR)/$(CONFIG)/h2_sockpair_test @@ -1582,7 +1584,9 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/h2_full+trace_test \ $(BINDIR)/$(CONFIG)/h2_full+workarounds_test \ $(BINDIR)/$(CONFIG)/h2_http_proxy_test \ - $(BINDIR)/$(CONFIG)/h2_local_test \ + $(BINDIR)/$(CONFIG)/h2_local_ipv4_test \ + $(BINDIR)/$(CONFIG)/h2_local_ipv6_test \ + $(BINDIR)/$(CONFIG)/h2_local_uds_test \ $(BINDIR)/$(CONFIG)/h2_oauth2_test \ $(BINDIR)/$(CONFIG)/h2_proxy_test \ $(BINDIR)/$(CONFIG)/h2_sockpair_test \ @@ -4268,6 +4272,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ test/core/end2end/cq_verifier.cc \ test/core/end2end/fixtures/http_proxy_fixture.cc \ + test/core/end2end/fixtures/local_util.cc \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ @@ -4574,6 +4579,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ test/core/end2end/cq_verifier.cc \ test/core/end2end/fixtures/http_proxy_fixture.cc \ + test/core/end2end/fixtures/local_util.cc \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ @@ -23711,34 +23717,98 @@ endif endif -H2_LOCAL_TEST_SRC = \ - test/core/end2end/fixtures/h2_local.cc \ +H2_LOCAL_IPV4_TEST_SRC = \ + test/core/end2end/fixtures/h2_local_ipv4.cc \ -H2_LOCAL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_TEST_SRC)))) +H2_LOCAL_IPV4_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_IPV4_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/h2_local_test: openssl_dep_error +$(BINDIR)/$(CONFIG)/h2_local_ipv4_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/h2_local_test: $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_local_ipv4_test: $(H2_LOCAL_IPV4_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_test + $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_IPV4_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_ipv4_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local_ipv4.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_h2_local_test: $(H2_LOCAL_TEST_OBJS:.o=.dep) +deps_h2_local_ipv4_test: $(H2_LOCAL_IPV4_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(H2_LOCAL_TEST_OBJS:.o=.dep) +-include $(H2_LOCAL_IPV4_TEST_OBJS:.o=.dep) +endif +endif + + +H2_LOCAL_IPV6_TEST_SRC = \ + test/core/end2end/fixtures/h2_local_ipv6.cc \ + +H2_LOCAL_IPV6_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_IPV6_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/h2_local_ipv6_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/h2_local_ipv6_test: $(H2_LOCAL_IPV6_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_IPV6_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_ipv6_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local_ipv6.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_h2_local_ipv6_test: $(H2_LOCAL_IPV6_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(H2_LOCAL_IPV6_TEST_OBJS:.o=.dep) +endif +endif + + +H2_LOCAL_UDS_TEST_SRC = \ + test/core/end2end/fixtures/h2_local_uds.cc \ + +H2_LOCAL_UDS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_UDS_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/h2_local_uds_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/h2_local_uds_test: $(H2_LOCAL_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_uds_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_h2_local_uds_test: $(H2_LOCAL_UDS_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(H2_LOCAL_UDS_TEST_OBJS:.o=.dep) endif endif diff --git a/build.yaml b/build.yaml index 5f4d554a467..7f1f11a3c03 100644 --- a/build.yaml +++ b/build.yaml @@ -900,6 +900,7 @@ filegroups: - src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h - test/core/end2end/cq_verifier.h - test/core/end2end/fixtures/http_proxy_fixture.h + - test/core/end2end/fixtures/local_util.h - test/core/end2end/fixtures/proxy.h - test/core/iomgr/endpoint_tests.h - test/core/util/debugger_macros.h @@ -920,6 +921,7 @@ filegroups: - src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc - test/core/end2end/cq_verifier.cc - test/core/end2end/fixtures/http_proxy_fixture.cc + - test/core/end2end/fixtures/local_util.cc - test/core/end2end/fixtures/proxy.cc - test/core/iomgr/endpoint_tests.cc - test/core/util/debugger_macros.cc diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 5ab7a49cd27..4826044a3d7 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1207,6 +1207,7 @@ Pod::Spec.new do |s| 'test/core/security/oauth2_utils.cc', 'test/core/end2end/cq_verifier.cc', 'test/core/end2end/fixtures/http_proxy_fixture.cc', + 'test/core/end2end/fixtures/local_util.cc', 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', @@ -1233,6 +1234,7 @@ Pod::Spec.new do |s| 'test/core/security/oauth2_utils.h', 'test/core/end2end/cq_verifier.h', 'test/core/end2end/fixtures/http_proxy_fixture.h', + 'test/core/end2end/fixtures/local_util.h', 'test/core/end2end/fixtures/proxy.h', 'test/core/iomgr/endpoint_tests.h', 'test/core/util/debugger_macros.h', diff --git a/grpc.gyp b/grpc.gyp index 00f06a1e54e..32d4bd409e6 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -617,6 +617,7 @@ 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', 'test/core/end2end/cq_verifier.cc', 'test/core/end2end/fixtures/http_proxy_fixture.cc', + 'test/core/end2end/fixtures/local_util.cc', 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', @@ -857,6 +858,7 @@ 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', 'test/core/end2end/cq_verifier.cc', 'test/core/end2end/fixtures/http_proxy_fixture.cc', + 'test/core/end2end/fixtures/local_util.cc', 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h index f935557f2d4..a082f670107 100644 --- a/include/grpc/grpc_security_constants.h +++ b/include/grpc/grpc_security_constants.h @@ -106,10 +106,10 @@ typedef enum { } grpc_ssl_client_certificate_request_type; /** - * Type of local connection for which local channel/server credentials will be - * applied. It only supports UDS for now. + * Type of local connections for which local channel/server credentials will be + * applied. It supports UDS and local TCP connections. */ -typedef enum { UDS = 0 } grpc_local_connect_type; +typedef enum { UDS = 0, LOCAL_TCP } grpc_local_connect_type; #ifdef __cplusplus } diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 6802851392c..fdea7511cca 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -85,7 +85,7 @@ class grpc_httpcli_ssl_channel_security_connector final return handshaker_factory_; } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* /*auth_context*/, grpc_closure* on_peer_checked) override { grpc_error* error = GRPC_ERROR_NONE; diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.cc b/src/core/lib/security/security_connector/alts/alts_security_connector.cc index 6db70ef1720..3ad0cc353cb 100644 --- a/src/core/lib/security/security_connector/alts/alts_security_connector.cc +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.cc @@ -48,7 +48,7 @@ void alts_set_rpc_protocol_versions( GRPC_PROTOCOL_VERSION_MIN_MINOR); } -void atls_check_peer(tsi_peer peer, +void alts_check_peer(tsi_peer peer, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) { *auth_context = @@ -93,10 +93,10 @@ class grpc_alts_channel_security_connector final handshake_manager, grpc_security_handshaker_create(handshaker, this)); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { - atls_check_peer(peer, auth_context, on_peer_checked); + alts_check_peer(peer, auth_context, on_peer_checked); } int cmp(const grpc_security_connector* other_sc) const override { @@ -151,10 +151,10 @@ class grpc_alts_server_security_connector final handshake_manager, grpc_security_handshaker_create(handshaker, this)); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { - atls_check_peer(peer, auth_context, on_peer_checked); + alts_check_peer(peer, auth_context, on_peer_checked); } int cmp(const grpc_security_connector* other) const override { diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.cc b/src/core/lib/security/security_connector/fake/fake_security_connector.cc index d2cdaaac77c..e3b8affb360 100644 --- a/src/core/lib/security/security_connector/fake/fake_security_connector.cc +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.cc @@ -71,7 +71,7 @@ class grpc_fake_channel_security_connector final if (target_name_override_ != nullptr) gpr_free(target_name_override_); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override; @@ -250,7 +250,8 @@ end: } void grpc_fake_channel_security_connector::check_peer( - tsi_peer peer, grpc_core::RefCountedPtr* auth_context, + tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) { fake_check_peer(this, peer, auth_context, on_peer_checked); fake_secure_name_check(); @@ -265,7 +266,7 @@ class grpc_fake_server_security_connector std::move(server_creds)) {} ~grpc_fake_server_security_connector() override = default; - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { fake_check_peer(this, peer, auth_context, on_peer_checked); diff --git a/src/core/lib/security/security_connector/local/local_security_connector.cc b/src/core/lib/security/security_connector/local/local_security_connector.cc index 7a59e54e9a7..7cc482c16c5 100644 --- a/src/core/lib/security/security_connector/local/local_security_connector.cc +++ b/src/core/lib/security/security_connector/local/local_security_connector.cc @@ -32,12 +32,16 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/socket_utils.h" +#include "src/core/lib/iomgr/unix_sockets_posix.h" #include "src/core/lib/security/credentials/local/local_credentials.h" #include "src/core/lib/security/transport/security_handshaker.h" #include "src/core/tsi/local_transport_security.h" #define GRPC_UDS_URI_PATTERN "unix:" -#define GRPC_UDS_URL_SCHEME "unix" #define GRPC_LOCAL_TRANSPORT_SECURITY_TYPE "local" namespace { @@ -55,18 +59,59 @@ grpc_core::RefCountedPtr local_auth_context_create() { } void local_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, - grpc_closure* on_peer_checked) { + grpc_closure* on_peer_checked, + grpc_local_connect_type type) { + int fd = grpc_endpoint_get_fd(ep); + grpc_resolved_address resolved_addr; + memset(&resolved_addr, 0, sizeof(resolved_addr)); + resolved_addr.len = GRPC_MAX_SOCKADDR_SIZE; + bool is_endpoint_local = false; + if (getsockname(fd, reinterpret_cast(resolved_addr.addr), + &resolved_addr.len) == 0) { + grpc_resolved_address addr_normalized; + grpc_resolved_address* addr = + grpc_sockaddr_is_v4mapped(&resolved_addr, &addr_normalized) + ? &addr_normalized + : &resolved_addr; + grpc_sockaddr* sock_addr = reinterpret_cast(&addr->addr); + // UDS + if (type == UDS && grpc_is_unix_socket(addr)) { + is_endpoint_local = true; + // IPV4 + } else if (type == LOCAL_TCP && sock_addr->sa_family == GRPC_AF_INET) { + const grpc_sockaddr_in* addr4 = + reinterpret_cast(sock_addr); + if (grpc_htonl(addr4->sin_addr.s_addr) == INADDR_LOOPBACK) { + is_endpoint_local = true; + } + // IPv6 + } else if (type == LOCAL_TCP && sock_addr->sa_family == GRPC_AF_INET6) { + const grpc_sockaddr_in6* addr6 = + reinterpret_cast(addr); + if (memcmp(&addr6->sin6_addr, &in6addr_loopback, + sizeof(in6addr_loopback)) == 0) { + is_endpoint_local = true; + } + } + } + grpc_error* error = GRPC_ERROR_NONE; + if (!is_endpoint_local) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Endpoint is neither UDS or TCP loopback address."); + GRPC_CLOSURE_SCHED(on_peer_checked, error); + return; + } /* Create an auth context which is necessary to pass the santiy check in - * {client, server}_auth_filter that verifies if the pepp's auth context is + * {client, server}_auth_filter that verifies if the peer's auth context is * obtained during handshakes. The auth context is only checked for its * existence and not actually used. */ *auth_context = local_auth_context_create(); - grpc_error* error = *auth_context != nullptr - ? GRPC_ERROR_NONE - : GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Could not create local auth context"); + error = *auth_context != nullptr ? GRPC_ERROR_NONE + : GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Could not create local auth context"); GRPC_CLOSURE_SCHED(on_peer_checked, error); } @@ -77,8 +122,7 @@ class grpc_local_channel_security_connector final grpc_core::RefCountedPtr channel_creds, grpc_core::RefCountedPtr request_metadata_creds, const char* target_name) - : grpc_channel_security_connector(GRPC_UDS_URL_SCHEME, - std::move(channel_creds), + : grpc_channel_security_connector(nullptr, std::move(channel_creds), std::move(request_metadata_creds)), target_name_(gpr_strdup(target_name)) {} @@ -102,10 +146,13 @@ class grpc_local_channel_security_connector final return strcmp(target_name_, other->target_name_); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { - local_check_peer(this, peer, auth_context, on_peer_checked); + grpc_local_credentials* creds = + reinterpret_cast(mutable_channel_creds()); + local_check_peer(this, peer, ep, auth_context, on_peer_checked, + creds->connect_type()); } bool check_call_host(const char* host, grpc_auth_context* auth_context, @@ -134,8 +181,7 @@ class grpc_local_server_security_connector final public: grpc_local_server_security_connector( grpc_core::RefCountedPtr server_creds) - : grpc_server_security_connector(GRPC_UDS_URL_SCHEME, - std::move(server_creds)) {} + : grpc_server_security_connector(nullptr, std::move(server_creds)) {} ~grpc_local_server_security_connector() override = default; void add_handshakers(grpc_pollset_set* interested_parties, @@ -147,10 +193,13 @@ class grpc_local_server_security_connector final handshake_manager, grpc_security_handshaker_create(handshaker, this)); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { - local_check_peer(this, peer, auth_context, on_peer_checked); + grpc_local_server_credentials* creds = + static_cast(mutable_server_creds()); + local_check_peer(this, peer, ep, auth_context, on_peer_checked, + creds->connect_type()); } int cmp(const grpc_security_connector* other) const override { @@ -171,23 +220,18 @@ grpc_local_channel_security_connector_create( "Invalid arguments to grpc_local_channel_security_connector_create()"); return nullptr; } - // Check if local_connect_type is UDS. Only UDS is supported for now. + // Perform sanity check on UDS address. For TCP local connection, the check + // will be done during check_peer procedure. grpc_local_credentials* creds = static_cast(channel_creds.get()); - if (creds->connect_type() != UDS) { - gpr_log(GPR_ERROR, - "Invalid local channel type to " - "grpc_local_channel_security_connector_create()"); - return nullptr; - } - // Check if target_name is a valid UDS address. const grpc_arg* server_uri_arg = grpc_channel_args_find(args, GRPC_ARG_SERVER_URI); const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg); - if (strncmp(GRPC_UDS_URI_PATTERN, server_uri_str, + if (creds->connect_type() == UDS && + strncmp(GRPC_UDS_URI_PATTERN, server_uri_str, strlen(GRPC_UDS_URI_PATTERN)) != 0) { gpr_log(GPR_ERROR, - "Invalid target_name to " + "Invalid UDS target name to " "grpc_local_channel_security_connector_create()"); return nullptr; } @@ -204,15 +248,6 @@ grpc_local_server_security_connector_create( "Invalid arguments to grpc_local_server_security_connector_create()"); return nullptr; } - // Check if local_connect_type is UDS. Only UDS is supported for now. - const grpc_local_server_credentials* creds = - static_cast(server_creds.get()); - if (creds->connect_type() != UDS) { - gpr_log(GPR_ERROR, - "Invalid local server type to " - "grpc_local_server_security_connector_create()"); - return nullptr; - } return grpc_core::MakeRefCounted( std::move(server_creds)); } diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index d90aa8c4dab..74b0ef21a62 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -56,7 +56,8 @@ class grpc_security_connector /* Check the peer. Callee takes ownership of the peer object. When done, sets *auth_context and invokes on_peer_checked. */ virtual void check_peer( - tsi_peer peer, grpc_core::RefCountedPtr* auth_context, + tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) GRPC_ABSTRACT; /* Compares two security connectors. */ diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index 14b2c4030f2..7414ab1a37f 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -146,7 +146,7 @@ class grpc_ssl_channel_security_connector final grpc_security_handshaker_create(tsi_hs, this)); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { const char* target_name = overridden_target_name_ != nullptr @@ -299,7 +299,7 @@ class grpc_ssl_server_security_connector grpc_security_handshaker_create(tsi_hs, this)); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { grpc_error* error = ssl_check_peer(nullptr, &peer, auth_context); diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index 48d6901e883..01831dab10f 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -231,7 +231,8 @@ static grpc_error* check_peer_locked(security_handshaker* h) { return grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Peer extraction failed"), result); } - h->connector->check_peer(peer, &h->auth_context, &h->on_peer_checked); + h->connector->check_peer(peer, h->args->endpoint, &h->auth_context, + &h->on_peer_checked); return GRPC_ERROR_NONE; } diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index 398e8a2d9ad..9d7f96683e0 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -70,6 +70,19 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "local_util", + srcs = ["fixtures/local_util.cc"], + hdrs = ["fixtures/local_util.h", + "end2end_tests.h"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "bad_server_response_test", srcs = ["bad_server_response_test.cc"], diff --git a/test/core/end2end/fixtures/h2_local_ipv4.cc b/test/core/end2end/fixtures/h2_local_ipv4.cc new file mode 100644 index 00000000000..f6996bf6be3 --- /dev/null +++ b/test/core/end2end/fixtures/h2_local_ipv4.cc @@ -0,0 +1,72 @@ +/* + * + * 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 + +#include + +#include "src/core/lib/gpr/host_port.h" +#include "test/core/end2end/end2end_tests.h" +#include "test/core/end2end/fixtures/local_util.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv4( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f = + grpc_end2end_local_chttp2_create_fixture_fullstack(); + int port = grpc_pick_unused_port_or_die(); + gpr_join_host_port( + &static_cast(f.fixture_data) + ->localaddr, + "127.0.0.1", port); + return f; +} + +static void chttp2_init_client_fullstack_ipv4(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, LOCAL_TCP); +} + +static void chttp2_init_server_fullstack_ipv4(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, LOCAL_TCP); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"chttp2/fullstack_local_ipv4", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + nullptr, chttp2_create_fixture_fullstack_ipv4, + chttp2_init_client_fullstack_ipv4, chttp2_init_server_fullstack_ipv4, + grpc_end2end_local_chttp2_tear_down_fullstack}}; + +int main(int argc, char** argv) { + size_t i; + grpc::testing::TestEnvironment env(argc, argv); + grpc_end2end_tests_pre_init(); + grpc_init(); + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + grpc_shutdown(); + return 0; +} diff --git a/test/core/end2end/fixtures/h2_local_ipv6.cc b/test/core/end2end/fixtures/h2_local_ipv6.cc new file mode 100644 index 00000000000..e360727ca82 --- /dev/null +++ b/test/core/end2end/fixtures/h2_local_ipv6.cc @@ -0,0 +1,72 @@ +/* + * + * 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 + +#include + +#include "src/core/lib/gpr/host_port.h" +#include "test/core/end2end/end2end_tests.h" +#include "test/core/end2end/fixtures/local_util.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv6( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f = + grpc_end2end_local_chttp2_create_fixture_fullstack(); + int port = grpc_pick_unused_port_or_die(); + gpr_join_host_port( + &static_cast(f.fixture_data) + ->localaddr, + "[::1]", port); + return f; +} + +static void chttp2_init_client_fullstack_ipv6(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, LOCAL_TCP); +} + +static void chttp2_init_server_fullstack_ipv6(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, LOCAL_TCP); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"chttp2/fullstack_local_ipv6", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + nullptr, chttp2_create_fixture_fullstack_ipv6, + chttp2_init_client_fullstack_ipv6, chttp2_init_server_fullstack_ipv6, + grpc_end2end_local_chttp2_tear_down_fullstack}}; + +int main(int argc, char** argv) { + size_t i; + grpc::testing::TestEnvironment env(argc, argv); + grpc_end2end_tests_pre_init(); + grpc_init(); + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + grpc_shutdown(); + return 0; +} diff --git a/test/core/end2end/fixtures/h2_local_uds.cc b/test/core/end2end/fixtures/h2_local_uds.cc new file mode 100644 index 00000000000..f1bce213dc2 --- /dev/null +++ b/test/core/end2end/fixtures/h2_local_uds.cc @@ -0,0 +1,71 @@ +/* + * + * Copyright 2015 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 + +#include + +#include "test/core/end2end/end2end_tests.h" +#include "test/core/end2end/fixtures/local_util.h" +#include "test/core/util/test_config.h" + +static int unique = 1; + +static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_uds( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f = + grpc_end2end_local_chttp2_create_fixture_fullstack(); + gpr_asprintf( + &static_cast(f.fixture_data) + ->localaddr, + "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++); + return f; +} + +static void chttp2_init_client_fullstack_uds(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, UDS); +} + +static void chttp2_init_server_fullstack_uds(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, UDS); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"chttp2/fullstack_local_uds", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + nullptr, chttp2_create_fixture_fullstack_uds, + chttp2_init_client_fullstack_uds, chttp2_init_server_fullstack_uds, + grpc_end2end_local_chttp2_tear_down_fullstack}}; + +int main(int argc, char** argv) { + size_t i; + grpc::testing::TestEnvironment env(argc, argv); + grpc_end2end_tests_pre_init(); + grpc_init(); + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + grpc_shutdown(); + return 0; +} diff --git a/test/core/end2end/fixtures/h2_local.cc b/test/core/end2end/fixtures/local_util.cc similarity index 61% rename from test/core/end2end/fixtures/h2_local.cc rename to test/core/end2end/fixtures/local_util.cc index 18d690ff222..5f0b0300ac0 100644 --- a/test/core/end2end/fixtures/h2_local.cc +++ b/test/core/end2end/fixtures/local_util.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015 gRPC authors. + * 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. @@ -16,11 +16,7 @@ * */ -#include "test/core/end2end/end2end_tests.h" - -#include -#include -#include +#include "test/core/end2end/fixtures/local_util.h" #include #include @@ -34,39 +30,28 @@ #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; - -static int unique = 1; - -static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( - grpc_channel_args* client_args, grpc_channel_args* server_args) { +grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack() { grpc_end2end_test_fixture f; - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + grpc_end2end_local_fullstack_fixture_data* ffd = + static_cast( + gpr_malloc(sizeof(grpc_end2end_local_fullstack_fixture_data))); memset(&f, 0, sizeof(f)); - - gpr_asprintf(&ffd->localaddr, "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), - unique++); - f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); - return f; } -void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, - grpc_channel_args* client_args) { - grpc_channel_credentials* creds = grpc_local_credentials_create(UDS); - fullstack_fixture_data* ffd = - static_cast(f->fixture_data); +void grpc_end2end_local_chttp2_init_client_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* client_args, + grpc_local_connect_type type) { + grpc_channel_credentials* creds = grpc_local_credentials_create(type); + grpc_end2end_local_fullstack_fixture_data* ffd = + static_cast(f->fixture_data); f->client = grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client != nullptr); @@ -98,11 +83,12 @@ static void process_auth_failure(void* state, grpc_auth_context* ctx, cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr); } -void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, - grpc_channel_args* server_args) { - grpc_server_credentials* creds = grpc_local_server_credentials_create(UDS); - fullstack_fixture_data* ffd = - static_cast(f->fixture_data); +void grpc_end2end_local_chttp2_init_server_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* server_args, + grpc_local_connect_type type) { + grpc_server_credentials* creds = grpc_local_server_credentials_create(type); + grpc_end2end_local_fullstack_fixture_data* ffd = + static_cast(f->fixture_data); if (f->server) { grpc_server_destroy(f->server); } @@ -119,36 +105,10 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, grpc_server_start(f->server); } -void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { - fullstack_fixture_data* ffd = - static_cast(f->fixture_data); +void grpc_end2end_local_chttp2_tear_down_fullstack( + grpc_end2end_test_fixture* f) { + grpc_end2end_local_fullstack_fixture_data* ffd = + static_cast(f->fixture_data); gpr_free(ffd->localaddr); gpr_free(ffd); } - -/* All test configurations */ -static grpc_end2end_test_config configs[] = { - {"chttp2/fullstack_local", - FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | - FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | - FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | - FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, - nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, - chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, -}; - -int main(int argc, char** argv) { - size_t i; - - grpc::testing::TestEnvironment env(argc, argv); - grpc_end2end_tests_pre_init(); - grpc_init(); - - for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { - grpc_end2end_tests(argc, argv, configs[i]); - } - - grpc_shutdown(); - - return 0; -} diff --git a/test/core/end2end/fixtures/local_util.h b/test/core/end2end/fixtures/local_util.h new file mode 100644 index 00000000000..f133b4d977e --- /dev/null +++ b/test/core/end2end/fixtures/local_util.h @@ -0,0 +1,41 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include + +#include "src/core/lib/surface/channel.h" + +typedef struct grpc_end2end_local_fullstack_fixture_data { + char* localaddr; +} grpc_end2end_local_fullstack_fixture_data; + +/* Utility functions shared by h2_local tests. */ +grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack(); + +void grpc_end2end_local_chttp2_init_client_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* client_args, + grpc_local_connect_type type); + +void grpc_end2end_local_chttp2_init_server_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* server_args, + grpc_local_connect_type type); + +void grpc_end2end_local_chttp2_tear_down_fullstack( + grpc_end2end_test_fixture* f); diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 601d3bac387..c9518d9b815 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -74,7 +74,9 @@ END2END_FIXTURES = { 'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace( ci_mac=False, tracing=True, large_writes=False, exclude_iomgrs=['uv']), 'h2_ssl': default_secure_fixture_options, - 'h2_local': local_fixture_options, + 'h2_local_uds': local_fixture_options, + 'h2_local_ipv4': local_fixture_options, + 'h2_local_ipv6': local_fixture_options, 'h2_ssl_proxy': default_secure_fixture_options._replace( includes_proxy=True, ci_mac=False, exclude_iomgrs=['uv']), 'h2_uds': uds_fixture_options, diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 81956db841f..8f194b28252 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -85,7 +85,9 @@ END2END_FIXTURES = { client_channel = False, ), "h2_ssl": _fixture_options(secure = True), - "h2_local": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), + "h2_local_uds": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), + "h2_local_ipv4": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), + "h2_local_ipv6": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), "h2_ssl_proxy": _fixture_options(includes_proxy = True, secure = True), "h2_uds": _fixture_options( dns_resolver = False, @@ -376,6 +378,7 @@ def grpc_end2end_tests(): ":ssl_test_data", ":http_proxy", ":proxy", + ":local_util", ], ) @@ -426,6 +429,7 @@ def grpc_end2end_nosec_tests(): ":ssl_test_data", ":http_proxy", ":proxy", + ":local_util", ], ) diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 38cdd49fc7f..40c49895fd7 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -6241,9 +6241,45 @@ "headers": [], "is_filegroup": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "src": [ - "test/core/end2end/fixtures/h2_local.cc" + "test/core/end2end/fixtures/h2_local_ipv4.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "end2end_tests", + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "h2_local_ipv6_test", + "src": [ + "test/core/end2end/fixtures/h2_local_ipv6.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "end2end_tests", + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "h2_local_uds_test", + "src": [ + "test/core/end2end/fixtures/h2_local_uds.cc" ], "third_party": false, "type": "target" @@ -10683,6 +10719,7 @@ "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h", "test/core/end2end/cq_verifier.h", "test/core/end2end/fixtures/http_proxy_fixture.h", + "test/core/end2end/fixtures/local_util.h", "test/core/end2end/fixtures/proxy.h", "test/core/iomgr/endpoint_tests.h", "test/core/util/debugger_macros.h", @@ -10710,6 +10747,8 @@ "test/core/end2end/cq_verifier.h", "test/core/end2end/fixtures/http_proxy_fixture.cc", "test/core/end2end/fixtures/http_proxy_fixture.h", + "test/core/end2end/fixtures/local_util.cc", + "test/core/end2end/fixtures/local_util.h", "test/core/end2end/fixtures/proxy.cc", "test/core/end2end/fixtures/proxy.h", "test/core/iomgr/endpoint_tests.cc", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index bca2ef53878..3a348e4a92f 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -22376,7 +22376,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22399,7 +22399,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22422,7 +22422,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22445,7 +22445,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22468,7 +22468,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22491,7 +22491,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22514,7 +22514,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22537,7 +22537,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22560,7 +22560,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22583,7 +22583,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22606,7 +22606,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22629,7 +22629,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22652,7 +22652,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22675,7 +22675,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22698,7 +22698,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22721,7 +22721,7 @@ ], "flaky": true, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22744,7 +22744,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22767,7 +22767,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22790,7 +22790,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22813,7 +22813,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22836,7 +22836,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22859,7 +22859,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22882,7 +22882,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22905,7 +22905,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22928,7 +22928,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22951,7 +22951,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22974,7 +22974,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22997,7 +22997,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23020,7 +23020,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23043,7 +23043,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23066,7 +23066,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23089,7 +23089,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23112,7 +23112,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23135,7 +23135,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23158,7 +23158,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23181,7 +23181,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23204,7 +23204,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23227,7 +23227,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23250,7 +23250,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23273,7 +23273,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23296,7 +23296,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23319,7 +23319,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23342,7 +23342,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23365,7 +23365,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23388,7 +23388,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23411,7 +23411,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23434,7 +23434,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23457,7 +23457,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23480,7 +23480,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23503,7 +23503,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23526,7 +23526,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23549,7 +23549,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23572,7 +23572,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23595,7 +23595,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23618,7 +23618,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23641,7 +23641,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23664,7 +23664,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23687,7 +23687,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23710,7 +23710,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23733,7 +23733,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23756,7 +23756,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23779,7 +23779,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23802,7 +23802,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23825,7 +23825,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23848,7 +23848,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23871,7 +23871,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23894,7 +23894,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23917,7 +23917,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23940,7 +23940,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23963,7 +23963,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23986,7 +23986,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -24009,7 +24009,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -24032,7 +24032,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -24055,7 +24055,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -24078,7 +24078,3457 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "authority_not_supported" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_hostname" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_ping" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "binary_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "call_creds" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_accept" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_client_done" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_invoke" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_round_trip" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_before_invoke" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_in_a_vacuum" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_with_status" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "channelz" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "compressed_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "connectivity" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "disappearing_server" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": true, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "empty_batch" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_latency" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_status_code" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "graceful_server_shutdown" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "high_initial_seqno" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "hpack_size" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "idempotent_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "invoke_large_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "large_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_concurrent_streams" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_age" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_idle" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_message_length" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "negative_deadline" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "network_status_change" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_error_on_hotpath" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_logging" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_op" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping_pong_streaming" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "registered_call" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_flags" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "resource_quota_server" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_cancellation" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_disabled" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_initial_batch" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_subsequent_batch" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_non_retriable_status" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_non_retriable_status_before_recv_trailing_metadata_started" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_initial_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_message" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_delay" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_disabled" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_after_commit" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_succeeds_before_replay_finished" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_throttled" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_too_many_attempts" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "server_finishes_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_calls" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_tags" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_cacheable_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_delayed_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_compressed_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_ping_pong_streaming" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "streaming_error_response" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "trailing_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "workaround_cronet_compression" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering_at_end" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "authority_not_supported" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_hostname" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_ping" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "binary_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "call_creds" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_accept" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_client_done" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_invoke" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_round_trip" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_before_invoke" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_in_a_vacuum" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_with_status" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "channelz" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "compressed_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "connectivity" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "disappearing_server" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": true, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "empty_batch" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_latency" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_status_code" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "graceful_server_shutdown" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "high_initial_seqno" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "hpack_size" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "idempotent_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "invoke_large_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "large_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_concurrent_streams" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_age" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_idle" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_message_length" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "negative_deadline" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "network_status_change" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_error_on_hotpath" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_logging" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_op" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping_pong_streaming" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "registered_call" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_flags" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "resource_quota_server" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_cancellation" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_disabled" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_initial_batch" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_subsequent_batch" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_non_retriable_status" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_non_retriable_status_before_recv_trailing_metadata_started" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_initial_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_message" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_delay" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_disabled" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_after_commit" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_succeeds_before_replay_finished" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_throttled" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_too_many_attempts" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "server_finishes_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_calls" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_tags" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_cacheable_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_delayed_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_compressed_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_ping_pong_streaming" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "streaming_error_response" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "trailing_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "workaround_cronet_compression" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering_at_end" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", "platforms": [ "linux", "mac", From f2324e1c056249dd7862799443809e4964c4866a Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Sun, 16 Dec 2018 16:01:14 -0800 Subject: [PATCH 318/534] Reset the SendMessage pointer before post-interception --- include/grpcpp/impl/codegen/call_op_set.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index b4c34a01c9a..b2100c68b7f 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -325,7 +325,11 @@ class CallOpSendMessage { } void SetFinishInterceptionHookPoint( - InterceptorBatchMethodsImpl* interceptor_methods) {} + InterceptorBatchMethodsImpl* interceptor_methods) { + // The contents of the SendMessage value that was previously set + // has had its references stolen by core's operations + interceptor_methods->SetSendMessage(nullptr); + } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { hijacked_ = true; From 76f0cd4d4d0e5051806a04063d0f86508eda9c12 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 17 Dec 2018 16:19:46 +0100 Subject: [PATCH 319/534] prevent setting wrong time on macos high sierra kokoro workers --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index bafe0d98c1a..d80bcbd1838 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -19,14 +19,6 @@ launchctl limit maxfiles ulimit -a -# synchronize the clock -date -sudo systemsetup -setusingnetworktime off -sudo systemsetup -setnetworktimeserver "$( ipconfig getoption en0 server_identifier )" -sudo systemsetup -settimezone America/Los_Angeles -sudo systemsetup -setusingnetworktime on -date - # Add GCP credentials for BQ access pip install google-api-python-client oauth2client --user python export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json From 240eb480864a0be9f9af5c452b290de3385f1211 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 17 Dec 2018 16:19:46 +0100 Subject: [PATCH 320/534] prevent setting wrong time on macos high sierra kokoro workers --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 0ef9735c1cd..067a60da822 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -19,14 +19,6 @@ launchctl limit maxfiles ulimit -a -# synchronize the clock -date -sudo systemsetup -setusingnetworktime off -sudo systemsetup -setnetworktimeserver "$( ipconfig getoption en0 server_identifier )" -sudo systemsetup -settimezone America/Los_Angeles -sudo systemsetup -setusingnetworktime on -date - # Add GCP credentials for BQ access # pin google-api-python-client to avoid https://github.com/grpc/grpc/issues/15600 pip install google-api-python-client==1.6.7 --user python From 191e8f1c9cbf0080910e5c43a0997f90a5f5bd0f Mon Sep 17 00:00:00 2001 From: kkm Date: Fri, 7 Dec 2018 00:29:32 -0800 Subject: [PATCH 321/534] Use x64 tools on 64-bit Windows in Grpc.Tools The Windows Nano Server Docker image does not support 32-bit executables. See: https://docs.microsoft.com/windows-server/get-started/getting-started-with-nano-server#important-differences-in-nano-server See: https://github.com/grpc/grpc/pull/13207#issuecomment-444846082 Close: #13098 (wontfix) --- src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets | 3 +-- .../Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets b/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets index 5f76c03ce57..3fe1ccc9181 100644 --- a/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets @@ -22,9 +22,8 @@ - $(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_x86\$(gRPC_PluginFileName).exe + >$(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)\$(gRPC_PluginFileName).exe $(Protobuf_PackagedToolsPath)/$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)/$(gRPC_PluginFileName) diff --git a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets index 1d233d23a80..26f9efb5a84 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -74,9 +74,8 @@ $(_Protobuf_ToolsOs) $(_Protobuf_ToolsCpu) - $(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_x86\protoc.exe + >$(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)\protoc.exe $(Protobuf_PackagedToolsPath)/$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)/protoc From 082b63e09592502b0900a5dff214dc70efb9de56 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 7 Dec 2018 09:23:54 -0800 Subject: [PATCH 322/534] Refactor server deallocation --- .../_cython/_cygrpc/completion_queue.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/server.pyx.pxi | 10 +- src/python/grpcio/grpc/_server.py | 106 +++++++++++------- .../tests/channelz/_channelz_servicer_test.py | 2 - 4 files changed, 73 insertions(+), 47 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi index 141116df5dd..3c33b46dbb8 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -49,7 +49,7 @@ cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline): cdef _interpret_event(grpc_event c_event): cdef _Tag tag if c_event.type == GRPC_QUEUE_TIMEOUT: - # NOTE(nathaniel): For now we coopt ConnectivityEvent here. + # TODO(ericgribkoff) Do not coopt ConnectivityEvent here. return None, ConnectivityEvent(GRPC_QUEUE_TIMEOUT, False, None) elif c_event.type == GRPC_QUEUE_SHUTDOWN: # NOTE(nathaniel): For now we coopt ConnectivityEvent here. diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index ce701724fd3..1b8d6790fb3 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -128,7 +128,9 @@ cdef class Server: with nogil: grpc_server_cancel_all_calls(self.c_server) - def __dealloc__(self): + # TODO(ericgribkoff) Determine what, if any, portion of this is safe to call + # from __dealloc__, and potentially remove backup_shutdown_queue. + def destroy(self): if self.c_server != NULL: if not self.is_started: pass @@ -146,4 +148,8 @@ cdef class Server: while not self.is_shutdown: time.sleep(0) grpc_server_destroy(self.c_server) - grpc_shutdown() + self.c_server = NULL + + def __dealloc(self): + if self.c_server == NULL: + grpc_shutdown() diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 3bbfa47da53..eb750ef1a82 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -48,7 +48,7 @@ _CANCELLED = 'cancelled' _EMPTY_FLAGS = 0 -_UNEXPECTED_EXIT_SERVER_GRACE = 1.0 +_DEALLOCATED_SERVER_CHECK_PERIOD_S = 1.0 def _serialized_request(request_event): @@ -676,6 +676,9 @@ class _ServerState(object): self.rpc_states = set() self.due = set() + # A "volatile" flag to interrupt the daemon serving thread + self.server_deallocated = False + def _add_generic_handlers(state, generic_handlers): with state.lock: @@ -702,6 +705,7 @@ def _request_call(state): # TODO(https://github.com/grpc/grpc/issues/6597): delete this function. def _stop_serving(state): if not state.rpc_states and not state.due: + state.server.destroy() for shutdown_event in state.shutdown_events: shutdown_event.set() state.stage = _ServerStage.STOPPED @@ -715,49 +719,69 @@ def _on_call_completed(state): state.active_rpc_count -= 1 -def _serve(state): - while True: - event = state.completion_queue.poll() - if event.tag is _SHUTDOWN_TAG: +def _process_event_and_continue(state, event): + should_continue = True + if event.tag is _SHUTDOWN_TAG: + with state.lock: + state.due.remove(_SHUTDOWN_TAG) + if _stop_serving(state): + should_continue = False + elif event.tag is _REQUEST_CALL_TAG: + with state.lock: + state.due.remove(_REQUEST_CALL_TAG) + concurrency_exceeded = ( + state.maximum_concurrent_rpcs is not None and + state.active_rpc_count >= state.maximum_concurrent_rpcs) + rpc_state, rpc_future = _handle_call( + event, state.generic_handlers, state.interceptor_pipeline, + state.thread_pool, concurrency_exceeded) + if rpc_state is not None: + state.rpc_states.add(rpc_state) + if rpc_future is not None: + state.active_rpc_count += 1 + rpc_future.add_done_callback( + lambda unused_future: _on_call_completed(state)) + if state.stage is _ServerStage.STARTED: + _request_call(state) + elif _stop_serving(state): + should_continue = False + else: + rpc_state, callbacks = event.tag(event) + for callback in callbacks: + callable_util.call_logging_exceptions(callback, + 'Exception calling callback!') + if rpc_state is not None: with state.lock: - state.due.remove(_SHUTDOWN_TAG) + state.rpc_states.remove(rpc_state) if _stop_serving(state): - return - elif event.tag is _REQUEST_CALL_TAG: - with state.lock: - state.due.remove(_REQUEST_CALL_TAG) - concurrency_exceeded = ( - state.maximum_concurrent_rpcs is not None and - state.active_rpc_count >= state.maximum_concurrent_rpcs) - rpc_state, rpc_future = _handle_call( - event, state.generic_handlers, state.interceptor_pipeline, - state.thread_pool, concurrency_exceeded) - if rpc_state is not None: - state.rpc_states.add(rpc_state) - if rpc_future is not None: - state.active_rpc_count += 1 - rpc_future.add_done_callback( - lambda unused_future: _on_call_completed(state)) - if state.stage is _ServerStage.STARTED: - _request_call(state) - elif _stop_serving(state): - return - else: - rpc_state, callbacks = event.tag(event) - for callback in callbacks: - callable_util.call_logging_exceptions( - callback, 'Exception calling callback!') - if rpc_state is not None: - with state.lock: - state.rpc_states.remove(rpc_state) - if _stop_serving(state): - return + should_continue = False + return should_continue + + +def _serve(state): + while True: + timeout = time.time() + _DEALLOCATED_SERVER_CHECK_PERIOD_S + event = state.completion_queue.poll(timeout) + if state.server_deallocated: + _begin_shutdown_once(state) + if event.completion_type != cygrpc.CompletionType.queue_timeout: + if not _process_event_and_continue(state, event): + return # We want to force the deletion of the previous event # ~before~ we poll again; if the event has a reference # to a shutdown Call object, this can induce spinlock. event = None +def _begin_shutdown_once(state): + with state.lock: + if state.stage is _ServerStage.STARTED: + state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG) + state.stage = _ServerStage.GRACE + state.shutdown_events = [] + state.due.add(_SHUTDOWN_TAG) + + def _stop(state, grace): with state.lock: if state.stage is _ServerStage.STOPPED: @@ -765,11 +789,7 @@ def _stop(state, grace): shutdown_event.set() return shutdown_event else: - if state.stage is _ServerStage.STARTED: - state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG) - state.stage = _ServerStage.GRACE - state.shutdown_events = [] - state.due.add(_SHUTDOWN_TAG) + _begin_shutdown_once(state) shutdown_event = threading.Event() state.shutdown_events.append(shutdown_event) if grace is None: @@ -840,7 +860,9 @@ class _Server(grpc.Server): return _stop(self._state, grace) def __del__(self): - _stop(self._state, None) + # We can not grab a lock in __del__(), so set a flag to signal the + # serving daemon thread (if it exists) to initiate shutdown. + self._state.server_deallocated = True def create_server(thread_pool, generic_rpc_handlers, interceptors, options, diff --git a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py index 8ca51895224..5265911a0be 100644 --- a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -88,8 +88,6 @@ def _generate_channel_server_pairs(n): def _close_channel_server_pairs(pairs): for pair in pairs: pair.server.stop(None) - # TODO(ericgribkoff) This del should not be required - del pair.server pair.channel.close() From a76d72e0a62d512f919f0fa79e24809427c9e4e7 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 14 Dec 2018 17:41:02 -0800 Subject: [PATCH 323/534] add tests --- src/python/grpcio_tests/tests/tests.json | 1 + .../tests/unit/_server_shutdown_scenarios.py | 113 ++++++++++++++++++ .../tests/unit/_server_shutdown_test.py | 87 ++++++++++++++ 3 files changed, 201 insertions(+) create mode 100644 src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py create mode 100644 src/python/grpcio_tests/tests/unit/_server_shutdown_test.py diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index b27e6f26938..f202a3f932f 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -57,6 +57,7 @@ "unit._reconnect_test.ReconnectTest", "unit._resource_exhausted_test.ResourceExhaustedTest", "unit._rpc_test.RPCTest", + "unit._server_shutdown_test.ServerShutdown", "unit._server_ssl_cert_config_test.ServerSSLCertConfigFetcherParamsChecks", "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestCertConfigReuse", "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestWithClientAuth", diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py new file mode 100644 index 00000000000..da8cef0c430 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py @@ -0,0 +1,113 @@ +# 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. +"""Defines a number of module-scope gRPC scenarios to test server shutdown.""" + +import argparse +import os +import threading +import time +import logging + +import grpc + +from concurrent import futures +from six.moves import queue + +WAIT_TIME = 1000 + +REQUEST = b'request' +RESPONSE = b'response' + +SERVER_RAISES_EXCEPTION = 'server_raises_exception' +SERVER_DEALLOCATED = 'server_deallocated' +SERVER_FORK_CAN_EXIT = 'server_fork_can_exit' + +FORK_EXIT = '/test/ForkExit' + + +class ForkExitHandler(object): + + def unary_unary(self, request, servicer_context): + pid = os.fork() + if pid == 0: + os._exit(0) + return RESPONSE + + def __init__(self): + self.request_streaming = None + self.response_streaming = None + self.request_deserializer = None + self.response_serializer = None + self.unary_stream = None + self.stream_unary = None + self.stream_stream = None + + +class GenericHandler(grpc.GenericRpcHandler): + + def service(self, handler_call_details): + if handler_call_details.method == FORK_EXIT: + return ForkExitHandler() + else: + return None + + +def run_server(port_queue,): + server = grpc.server( + futures.ThreadPoolExecutor(max_workers=10), + options=(('grpc.so_reuseport', 0),)) + port = server.add_insecure_port('[::]:0') + port_queue.put(port) + server.add_generic_rpc_handlers((GenericHandler(),)) + server.start() + # threading.Event.wait() does not exhibit the bug identified in + # https://github.com/grpc/grpc/issues/17093, sleep instead + time.sleep(WAIT_TIME) + + +def run_test(args): + if args.scenario == SERVER_RAISES_EXCEPTION: + server = grpc.server( + futures.ThreadPoolExecutor(max_workers=1), + options=(('grpc.so_reuseport', 0),)) + server.start() + raise Exception() + elif args.scenario == SERVER_DEALLOCATED: + server = grpc.server( + futures.ThreadPoolExecutor(max_workers=1), + options=(('grpc.so_reuseport', 0),)) + server.start() + server.__del__() + while server._state.stage != grpc._server._ServerStage.STOPPED: + pass + elif args.scenario == SERVER_FORK_CAN_EXIT: + port_queue = queue.Queue() + thread = threading.Thread(target=run_server, args=(port_queue,)) + thread.daemon = True + thread.start() + port = port_queue.get() + channel = grpc.insecure_channel('[::]:%d' % port) + multi_callable = channel.unary_unary(FORK_EXIT) + result, call = multi_callable.with_call(REQUEST, wait_for_ready=True) + os.wait() + else: + raise ValueError('unknown test scenario') + + +if __name__ == '__main__': + logging.basicConfig() + parser = argparse.ArgumentParser() + parser.add_argument('scenario', type=str) + args = parser.parse_args() + run_test(args) diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py new file mode 100644 index 00000000000..25d7f5e8198 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py @@ -0,0 +1,87 @@ +# 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. +"""Tests clean shutdown of server on various interpreter exit conditions. + +The tests in this module spawn a subprocess for each test case, the +test is considered successful if it doesn't hang/timeout. +""" + +import atexit +import os +import subprocess +import sys +import threading +import unittest +import logging + +from tests.unit import _server_shutdown_scenarios + +SCENARIO_FILE = os.path.abspath( + os.path.join( + os.path.dirname(os.path.realpath(__file__)), + '_server_shutdown_scenarios.py')) +INTERPRETER = sys.executable +BASE_COMMAND = [INTERPRETER, SCENARIO_FILE] + +processes = [] +process_lock = threading.Lock() + + +# Make sure we attempt to clean up any +# processes we may have left running +def cleanup_processes(): + with process_lock: + for process in processes: + try: + process.kill() + except Exception: # pylint: disable=broad-except + pass + + +atexit.register(cleanup_processes) + + +def wait(process): + with process_lock: + processes.append(process) + process.wait() + + +class ServerShutdown(unittest.TestCase): + + def test_deallocated_server_stops(self): + process = subprocess.Popen( + BASE_COMMAND + [_server_shutdown_scenarios.SERVER_DEALLOCATED], + stdout=sys.stdout, + stderr=sys.stderr) + wait(process) + + def test_server_exception_exits(self): + process = subprocess.Popen( + BASE_COMMAND + [_server_shutdown_scenarios.SERVER_RAISES_EXCEPTION], + stdout=sys.stdout, + stderr=sys.stderr) + wait(process) + + def test_server_fork_can_exit(self): + process = subprocess.Popen( + BASE_COMMAND + [_server_shutdown_scenarios.SERVER_FORK_CAN_EXIT], + stdout=sys.stdout, + stderr=sys.stderr) + wait(process) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) From 468ae0f48615a58d8f09b76ca142fee27563964a Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Sat, 15 Dec 2018 08:36:32 -0800 Subject: [PATCH 324/534] add tracking issue --- src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index 1b8d6790fb3..e89e02b171e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -128,8 +128,9 @@ cdef class Server: with nogil: grpc_server_cancel_all_calls(self.c_server) - # TODO(ericgribkoff) Determine what, if any, portion of this is safe to call - # from __dealloc__, and potentially remove backup_shutdown_queue. + # TODO(https://github.com/grpc/grpc/issues/17515) Determine what, if any, + # portion of this is safe to call from __dealloc__, and potentially remove + # backup_shutdown_queue. def destroy(self): if self.c_server != NULL: if not self.is_started: From 718084c6b4aac0099d52a0dcf4c529e5b46ee686 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Sun, 16 Dec 2018 19:03:18 -0800 Subject: [PATCH 325/534] disable fork test on windows --- .../grpcio_tests/tests/unit/_server_shutdown_scenarios.py | 2 +- src/python/grpcio_tests/tests/unit/_server_shutdown_test.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py index da8cef0c430..acbec0f77dd 100644 --- a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py @@ -63,7 +63,7 @@ class GenericHandler(grpc.GenericRpcHandler): return None -def run_server(port_queue,): +def run_server(port_queue): server = grpc.server( futures.ThreadPoolExecutor(max_workers=10), options=(('grpc.so_reuseport', 0),)) diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py index 25d7f5e8198..0e4591c5e56 100644 --- a/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py @@ -74,6 +74,7 @@ class ServerShutdown(unittest.TestCase): stderr=sys.stderr) wait(process) + @unittest.skipIf(os.name == 'nt', 'fork not supported on windows') def test_server_fork_can_exit(self): process = subprocess.Popen( BASE_COMMAND + [_server_shutdown_scenarios.SERVER_FORK_CAN_EXIT], From aa2e731508de93c2756aac782f166598569ddc44 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 17 Dec 2018 08:54:32 -0800 Subject: [PATCH 326/534] Fix new target --- CMakeLists.txt | 1 - Makefile | 6 +++--- build.yaml | 1 - tools/run_tests/generated/sources_and_headers.json | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 634844b28b9..8d67c9415da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11089,7 +11089,6 @@ target_link_libraries(bm_byte_buffer grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} diff --git a/Makefile b/Makefile index e1145f7b77c..f9d5ed41639 100644 --- a/Makefile +++ b/Makefile @@ -16089,17 +16089,17 @@ $(BINDIR)/$(CONFIG)/bm_byte_buffer: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_byte_buffer: $(PROTOBUF_DEP) $(BM_BYTE_BUFFER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_byte_buffer: $(PROTOBUF_DEP) $(BM_BYTE_BUFFER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_BYTE_BUFFER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_byte_buffer + $(Q) $(LDXX) $(LDFLAGS) $(BM_BYTE_BUFFER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_byte_buffer endif endif $(BM_BYTE_BUFFER_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_byte_buffer.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_byte_buffer.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_byte_buffer: $(BM_BYTE_BUFFER_OBJS:.o=.dep) diff --git a/build.yaml b/build.yaml index a8b7df84cc9..9e1f8d2c378 100644 --- a/build.yaml +++ b/build.yaml @@ -3904,7 +3904,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 54354395b2f..75b4fa47ef8 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -2706,7 +2706,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", From 951254151bbd43f56374e3608feaa9ff663332d2 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 17 Dec 2018 10:12:50 -0800 Subject: [PATCH 327/534] Revert "Metadata tutorial" --- examples/BUILD | 15 ---- examples/cpp/metadata/Makefile | 96 ------------------------- examples/cpp/metadata/README.md | 66 ----------------- examples/cpp/metadata/greeter_client.cc | 95 ------------------------ examples/cpp/metadata/greeter_server.cc | 94 ------------------------ 5 files changed, 366 deletions(-) delete mode 100644 examples/cpp/metadata/Makefile delete mode 100644 examples/cpp/metadata/README.md delete mode 100644 examples/cpp/metadata/greeter_client.cc delete mode 100644 examples/cpp/metadata/greeter_server.cc diff --git a/examples/BUILD b/examples/BUILD index 22f2f0a4f1a..0f18cfa9ba7 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -51,18 +51,3 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) - -cc_binary( - name = "metadata_client", - srcs = ["cpp/metadata/greeter_client.cc"], - defines = ["BAZEL_BUILD"], - deps = [":helloworld", "//:grpc++"], -) - -cc_binary( - name = "metadata_server", - srcs = ["cpp/metadata/greeter_server.cc"], - defines = ["BAZEL_BUILD"], - deps = [":helloworld", "//:grpc++"], -) - diff --git a/examples/cpp/metadata/Makefile b/examples/cpp/metadata/Makefile deleted file mode 100644 index 46be8bfaa3c..00000000000 --- a/examples/cpp/metadata/Makefile +++ /dev/null @@ -1,96 +0,0 @@ -# -# 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. -# - HOST_SYSTEM = $(shell uname | cut -f 1 -d_) -SYSTEM ?= $(HOST_SYSTEM) -CXX = g++ -CPPFLAGS += `pkg-config --cflags protobuf grpc` -CXXFLAGS += -std=c++11 -ifeq ($(SYSTEM),Darwin) -LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ - -lgrpc++_reflection\ - -ldl -else -LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ - -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ - -ldl -endif -PROTOC = protoc -GRPC_CPP_PLUGIN = grpc_cpp_plugin -GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` - PROTOS_PATH = ../../protos - vpath %.proto $(PROTOS_PATH) - all: system-check greeter_client greeter_server - greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o - $(CXX) $^ $(LDFLAGS) -o $@ - greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o - $(CXX) $^ $(LDFLAGS) -o $@ - .PRECIOUS: %.grpc.pb.cc -%.grpc.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< - .PRECIOUS: %.pb.cc -%.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< - clean: - rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server - # The following is to test your system and ensure a smoother experience. -# They are by no means necessary to actually compile a grpc-enabled software. - PROTOC_CMD = which $(PROTOC) -PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 -PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) -HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) -ifeq ($(HAS_PROTOC),true) -HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) -endif -HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) - SYSTEM_OK = false -ifeq ($(HAS_VALID_PROTOC),true) -ifeq ($(HAS_PLUGIN),true) -SYSTEM_OK = true -endif -endif - system-check: -ifneq ($(HAS_VALID_PROTOC),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have protoc 3.0.0 installed in your path." - @echo "Please install Google protocol buffers 3.0.0 and its compiler." - @echo "You can find it here:" - @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" - @echo - @echo "Here is what I get when trying to evaluate your version of protoc:" - @echo - -$(PROTOC) --version - @echo - @echo -endif -ifneq ($(HAS_PLUGIN),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have the grpc c++ protobuf plugin installed in your path." - @echo "Please install grpc. You can find it here:" - @echo - @echo " https://github.com/grpc/grpc" - @echo - @echo "Here is what I get when trying to detect if you have the plugin:" - @echo - -which $(GRPC_CPP_PLUGIN) - @echo - @echo -endif -ifneq ($(SYSTEM_OK),true) - @false -endif diff --git a/examples/cpp/metadata/README.md b/examples/cpp/metadata/README.md deleted file mode 100644 index 96ad3d19bdb..00000000000 --- a/examples/cpp/metadata/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Metadata Example - -## Overview - -This example shows you how to add custom headers on the client and server and -how to access them. - -Custom metadata must follow the "Custom-Metadata" format listed in -https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md, with the -exception of binary headers, which don't have to be base64 encoded. - -### Get the tutorial source code - The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: - ```sh -$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc -``` - Change your current directory to examples/cpp/metadata - ```sh -$ cd examples/cpp/metadata -``` - -### Generating gRPC code - To generate the client and server side interfaces: - ```sh -$ make helloworld.grpc.pb.cc helloworld.pb.cc -``` -Which internally invokes the proto-compiler as: - ```sh -$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto -$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto -``` -### Try it! -Build client and server: - -```sh -$ make -``` - -Run the server, which will listen on port 50051: - -```sh -$ ./greeter_server -``` - -Run the client (in a different terminal): - -```sh -$ ./greeter_client -``` - -If things go smoothly, you will see in the client terminal: - -"Client received initial metadata from server: initial metadata value" -"Client received trailing metadata from server: trailing metadata value" -"Client received message: Hello World" - - -And in the server terminal: - -"Header key: custom-bin , value: 01234567" -"Header key: custom-header , value: Custom Value" -"Header key: user-agent , value: grpc-c++/1.16.0-dev grpc-c/6.0.0-dev (linux; chttp2; gao)" - -We did not add the user-agent metadata as a custom header. This shows how -the gRPC framework adds some headers under the hood that may show up in the -metadata map. diff --git a/examples/cpp/metadata/greeter_client.cc b/examples/cpp/metadata/greeter_client.cc deleted file mode 100644 index 80494389937..00000000000 --- a/examples/cpp/metadata/greeter_client.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * Copyright 2015 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 -#include -#include - -#include - -#ifdef BAZEL_BUILD -#include "examples/protos/helloworld.grpc.pb.h" -#else -#include "helloworld.grpc.pb.h" -#endif - -using grpc::Channel; -using grpc::ClientContext; -using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; -using helloworld::Greeter; - -class CustomHeaderClient { - public: - CustomHeaderClient(std::shared_ptr channel) - : stub_(Greeter::NewStub(channel)) {} - - // Assembles the client's payload, sends it and presents the response back - // from the server. - std::string SayHello(const std::string& user) { - // Data we are sending to the server. - HelloRequest request; - request.set_name(user); - - // Container for the data we expect from the server. - HelloReply reply; - - // Context for the client. It could be used to convey extra information to - // the server and/or tweak certain RPC behaviors. - ClientContext context; - - // Setting custom metadata to be sent to the server - context.AddMetadata("custom-header", "Custom Value"); - - // Setting custom binary metadata - char bytes[8] = {'\0', '\1', '\2', '\3', - '\4', '\5', '\6', '\7'}; - context.AddMetadata("custom-bin", grpc::string(bytes, 8)); - - // The actual RPC. - Status status = stub_->SayHello(&context, request, &reply); - - // Act upon its status. - if (status.ok()) { - std::cout << "Client received initial metadata from server: " << context.GetServerInitialMetadata().find("custom-server-metadata")->second << std::endl; - std::cout << "Client received trailing metadata from server: " << context.GetServerTrailingMetadata().find("custom-trailing-metadata")->second << std::endl; - return reply.message(); - } else { - std::cout << status.error_code() << ": " << status.error_message() - << std::endl; - return "RPC failed"; - } - } - - private: - std::unique_ptr stub_; -}; - -int main(int argc, char** argv) { - // Instantiate the client. It requires a channel, out of which the actual RPCs - // are created. This channel models a connection to an endpoint (in this case, - // localhost at port 50051). We indicate that the channel isn't authenticated - // (use of InsecureChannelCredentials()). - CustomHeaderClient greeter(grpc::CreateChannel( - "localhost:50051", grpc::InsecureChannelCredentials())); - std::string user("world"); - std::string reply = greeter.SayHello(user); - std::cout << "Client received message: " << reply << std::endl; - return 0; -} diff --git a/examples/cpp/metadata/greeter_server.cc b/examples/cpp/metadata/greeter_server.cc deleted file mode 100644 index a9a4f33cb0b..00000000000 --- a/examples/cpp/metadata/greeter_server.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * Copyright 2015 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 -#include -#include - -#include - -#ifdef BAZEL_BUILD -#include "examples/protos/helloworld.grpc.pb.h" -#else -#include "helloworld.grpc.pb.h" -#endif - -using grpc::Server; -using grpc::ServerBuilder; -using grpc::ServerContext; -using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; -using helloworld::Greeter; - -// Logic and data behind the server's behavior. -class GreeterServiceImpl final : public Greeter::Service { - Status SayHello(ServerContext* context, const HelloRequest* request, - HelloReply* reply) override { - std::string prefix("Hello "); - - // Get the client's initial metadata - std::cout << "Client metadata: " << std::endl; - const std::multimap metadata = context->client_metadata(); - for (auto iter = metadata.begin(); iter != metadata.end(); ++iter) { - std::cout << "Header key: " << iter->first << ", value: "; - // Check for binary value - size_t isbin = iter->first.find("-bin"); - if ((isbin != std::string::npos) && (isbin + 4 == iter->first.size())) { - std::cout << std::hex; - for (auto c : iter->second) { - std::cout << static_cast(c); - } - std::cout << std::dec; - } else { - std::cout << iter->second; - } - std::cout << std::endl; - } - - context->AddInitialMetadata("custom-server-metadata", "initial metadata value"); - context->AddTrailingMetadata("custom-trailing-metadata", "trailing metadata value"); - reply->set_message(prefix + request->name()); - return Status::OK; - } -}; - -void RunServer() { - std::string server_address("0.0.0.0:50051"); - GreeterServiceImpl service; - - ServerBuilder builder; - // Listen on the given address without any authentication mechanism. - builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); - // Register "service" as the instance through which we'll communicate with - // clients. In this case it corresponds to an *synchronous* service. - builder.RegisterService(&service); - // Finally assemble the server. - std::unique_ptr server(builder.BuildAndStart()); - std::cout << "Server listening on " << server_address << std::endl; - - // Wait for the server to shutdown. Note that some other thread must be - // responsible for shutting down the server for this call to ever return. - server->Wait(); -} - -int main(int argc, char** argv) { - RunServer(); - - return 0; -} From 1bd231605a341bea7ac841b72be212bb8df12f25 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 17 Dec 2018 11:21:15 -0800 Subject: [PATCH 328/534] Revert "re-enable ExitTest" --- src/python/grpcio_tests/commands.py | 8 -------- src/python/grpcio_tests/tests/unit/_exit_test.py | 15 +-------------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 18413abab02..65e9a99950e 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -133,14 +133,6 @@ class TestGevent(setuptools.Command): # TODO(https://github.com/grpc/grpc/issues/15411) unpin gevent version # This test will stuck while running higher version of gevent 'unit._auth_context_test.AuthContextTest.testSessionResumption', - # TODO(https://github.com/grpc/grpc/issues/15411) enable these tests - 'unit._exit_test.ExitTest.test_in_flight_unary_unary_call', - 'unit._exit_test.ExitTest.test_in_flight_unary_stream_call', - 'unit._exit_test.ExitTest.test_in_flight_stream_unary_call', - 'unit._exit_test.ExitTest.test_in_flight_stream_stream_call', - 'unit._exit_test.ExitTest.test_in_flight_partial_unary_stream_call', - 'unit._exit_test.ExitTest.test_in_flight_partial_stream_unary_call', - 'unit._exit_test.ExitTest.test_in_flight_partial_stream_stream_call', # TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels', 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels_and_sockets', diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py index b429ee089f7..52265375799 100644 --- a/src/python/grpcio_tests/tests/unit/_exit_test.py +++ b/src/python/grpcio_tests/tests/unit/_exit_test.py @@ -71,6 +71,7 @@ def wait(process): process.wait() +@unittest.skip('https://github.com/grpc/grpc/issues/7311') class ExitTest(unittest.TestCase): def test_unstarted_server(self): @@ -129,8 +130,6 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_unary_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_UNARY_CALL], @@ -139,8 +138,6 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_STREAM_CALL], @@ -148,8 +145,6 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_UNARY_CALL], @@ -158,8 +153,6 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_STREAM_CALL], @@ -168,8 +161,6 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_partial_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -178,8 +169,6 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -189,8 +178,6 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + From 93151145c20e50816e38a73c167ed16e288eb4f6 Mon Sep 17 00:00:00 2001 From: hcaseyal Date: Mon, 17 Dec 2018 12:09:11 -0800 Subject: [PATCH 329/534] Revert "Revert "Metadata tutorial"" --- examples/BUILD | 15 ++++ examples/cpp/metadata/Makefile | 96 +++++++++++++++++++++++++ examples/cpp/metadata/README.md | 66 +++++++++++++++++ examples/cpp/metadata/greeter_client.cc | 95 ++++++++++++++++++++++++ examples/cpp/metadata/greeter_server.cc | 94 ++++++++++++++++++++++++ 5 files changed, 366 insertions(+) create mode 100644 examples/cpp/metadata/Makefile create mode 100644 examples/cpp/metadata/README.md create mode 100644 examples/cpp/metadata/greeter_client.cc create mode 100644 examples/cpp/metadata/greeter_server.cc diff --git a/examples/BUILD b/examples/BUILD index 0f18cfa9ba7..22f2f0a4f1a 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -51,3 +51,18 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) + +cc_binary( + name = "metadata_client", + srcs = ["cpp/metadata/greeter_client.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) + +cc_binary( + name = "metadata_server", + srcs = ["cpp/metadata/greeter_server.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) + diff --git a/examples/cpp/metadata/Makefile b/examples/cpp/metadata/Makefile new file mode 100644 index 00000000000..46be8bfaa3c --- /dev/null +++ b/examples/cpp/metadata/Makefile @@ -0,0 +1,96 @@ +# +# 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. +# + HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) +CXX = g++ +CPPFLAGS += `pkg-config --cflags protobuf grpc` +CXXFLAGS += -std=c++11 +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -lgrpc++_reflection\ + -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ + -ldl +endif +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + PROTOS_PATH = ../../protos + vpath %.proto $(PROTOS_PATH) + all: system-check greeter_client greeter_server + greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + .PRECIOUS: %.grpc.pb.cc +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + .PRECIOUS: %.pb.cc +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + # The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/examples/cpp/metadata/README.md b/examples/cpp/metadata/README.md new file mode 100644 index 00000000000..96ad3d19bdb --- /dev/null +++ b/examples/cpp/metadata/README.md @@ -0,0 +1,66 @@ +# Metadata Example + +## Overview + +This example shows you how to add custom headers on the client and server and +how to access them. + +Custom metadata must follow the "Custom-Metadata" format listed in +https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md, with the +exception of binary headers, which don't have to be base64 encoded. + +### Get the tutorial source code + The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: + ```sh +$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc +``` + Change your current directory to examples/cpp/metadata + ```sh +$ cd examples/cpp/metadata +``` + +### Generating gRPC code + To generate the client and server side interfaces: + ```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + ```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` +### Try it! +Build client and server: + +```sh +$ make +``` + +Run the server, which will listen on port 50051: + +```sh +$ ./greeter_server +``` + +Run the client (in a different terminal): + +```sh +$ ./greeter_client +``` + +If things go smoothly, you will see in the client terminal: + +"Client received initial metadata from server: initial metadata value" +"Client received trailing metadata from server: trailing metadata value" +"Client received message: Hello World" + + +And in the server terminal: + +"Header key: custom-bin , value: 01234567" +"Header key: custom-header , value: Custom Value" +"Header key: user-agent , value: grpc-c++/1.16.0-dev grpc-c/6.0.0-dev (linux; chttp2; gao)" + +We did not add the user-agent metadata as a custom header. This shows how +the gRPC framework adds some headers under the hood that may show up in the +metadata map. diff --git a/examples/cpp/metadata/greeter_client.cc b/examples/cpp/metadata/greeter_client.cc new file mode 100644 index 00000000000..80494389937 --- /dev/null +++ b/examples/cpp/metadata/greeter_client.cc @@ -0,0 +1,95 @@ +/* + * + * Copyright 2015 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class CustomHeaderClient { + public: + CustomHeaderClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + + // Setting custom metadata to be sent to the server + context.AddMetadata("custom-header", "Custom Value"); + + // Setting custom binary metadata + char bytes[8] = {'\0', '\1', '\2', '\3', + '\4', '\5', '\6', '\7'}; + context.AddMetadata("custom-bin", grpc::string(bytes, 8)); + + // The actual RPC. + Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. + if (status.ok()) { + std::cout << "Client received initial metadata from server: " << context.GetServerInitialMetadata().find("custom-server-metadata")->second << std::endl; + std::cout << "Client received trailing metadata from server: " << context.GetServerTrailingMetadata().find("custom-trailing-metadata")->second << std::endl; + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureChannelCredentials()). + CustomHeaderClient greeter(grpc::CreateChannel( + "localhost:50051", grpc::InsecureChannelCredentials())); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Client received message: " << reply << std::endl; + return 0; +} diff --git a/examples/cpp/metadata/greeter_server.cc b/examples/cpp/metadata/greeter_server.cc new file mode 100644 index 00000000000..a9a4f33cb0b --- /dev/null +++ b/examples/cpp/metadata/greeter_server.cc @@ -0,0 +1,94 @@ +/* + * + * Copyright 2015 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + std::string prefix("Hello "); + + // Get the client's initial metadata + std::cout << "Client metadata: " << std::endl; + const std::multimap metadata = context->client_metadata(); + for (auto iter = metadata.begin(); iter != metadata.end(); ++iter) { + std::cout << "Header key: " << iter->first << ", value: "; + // Check for binary value + size_t isbin = iter->first.find("-bin"); + if ((isbin != std::string::npos) && (isbin + 4 == iter->first.size())) { + std::cout << std::hex; + for (auto c : iter->second) { + std::cout << static_cast(c); + } + std::cout << std::dec; + } else { + std::cout << iter->second; + } + std::cout << std::endl; + } + + context->AddInitialMetadata("custom-server-metadata", "initial metadata value"); + context->AddTrailingMetadata("custom-trailing-metadata", "trailing metadata value"); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} From 7bd03aeb0d007e9c820d4d426c50accc85392b36 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 17 Dec 2018 14:24:35 -0800 Subject: [PATCH 330/534] Revert "Revert "re-enable ExitTest"" This reverts commit 1bd231605a341bea7ac841b72be212bb8df12f25. --- src/python/grpcio_tests/commands.py | 8 ++++++++ src/python/grpcio_tests/tests/unit/_exit_test.py | 15 ++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 65e9a99950e..18413abab02 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -133,6 +133,14 @@ class TestGevent(setuptools.Command): # TODO(https://github.com/grpc/grpc/issues/15411) unpin gevent version # This test will stuck while running higher version of gevent 'unit._auth_context_test.AuthContextTest.testSessionResumption', + # TODO(https://github.com/grpc/grpc/issues/15411) enable these tests + 'unit._exit_test.ExitTest.test_in_flight_unary_unary_call', + 'unit._exit_test.ExitTest.test_in_flight_unary_stream_call', + 'unit._exit_test.ExitTest.test_in_flight_stream_unary_call', + 'unit._exit_test.ExitTest.test_in_flight_stream_stream_call', + 'unit._exit_test.ExitTest.test_in_flight_partial_unary_stream_call', + 'unit._exit_test.ExitTest.test_in_flight_partial_stream_unary_call', + 'unit._exit_test.ExitTest.test_in_flight_partial_stream_stream_call', # TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels', 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels_and_sockets', diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py index 52265375799..b429ee089f7 100644 --- a/src/python/grpcio_tests/tests/unit/_exit_test.py +++ b/src/python/grpcio_tests/tests/unit/_exit_test.py @@ -71,7 +71,6 @@ def wait(process): process.wait() -@unittest.skip('https://github.com/grpc/grpc/issues/7311') class ExitTest(unittest.TestCase): def test_unstarted_server(self): @@ -130,6 +129,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_unary_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_UNARY_CALL], @@ -138,6 +139,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_STREAM_CALL], @@ -145,6 +148,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_UNARY_CALL], @@ -153,6 +158,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_STREAM_CALL], @@ -161,6 +168,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -169,6 +178,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -178,6 +189,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + From b1407a95c3183714557d753d704bd6b98e603258 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 17 Dec 2018 14:51:20 -0800 Subject: [PATCH 331/534] Improve grpclb trace logging. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 57 ++++++++++--------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index a9a5965ed1c..6671e708c84 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -525,8 +525,7 @@ void GrpcLb::BalancerCallState::Orphan() { void GrpcLb::BalancerCallState::StartQuery() { GPR_ASSERT(lb_call_ != nullptr); if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] Starting LB call (lb_calld: %p, lb_call: %p)", + gpr_log(GPR_INFO, "[grpclb %p] lb_calld=%p: Starting LB call %p", grpclb_policy_.get(), this, lb_call_); } // Create the ops. @@ -670,8 +669,9 @@ void GrpcLb::BalancerCallState::SendClientLoadReportLocked() { grpc_call_error call_error = grpc_call_start_batch_and_execute( lb_call_, &op, 1, &client_load_report_closure_); if (GPR_UNLIKELY(call_error != GRPC_CALL_OK)) { - gpr_log(GPR_ERROR, "[grpclb %p] call_error=%d", grpclb_policy_.get(), - call_error); + gpr_log(GPR_ERROR, + "[grpclb %p] lb_calld=%p call_error=%d sending client load report", + grpclb_policy_.get(), this, call_error); GPR_ASSERT(GRPC_CALL_OK == call_error); } } @@ -732,15 +732,17 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( &initial_response->client_stats_report_interval)); if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p] Received initial LB response message; " - "client load reporting interval = %" PRId64 " milliseconds", - grpclb_policy, lb_calld->client_stats_report_interval_); + "[grpclb %p] lb_calld=%p: Received initial LB response " + "message; client load reporting interval = %" PRId64 + " milliseconds", + grpclb_policy, lb_calld, + lb_calld->client_stats_report_interval_); } } else if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p] Received initial LB response message; client load " - "reporting NOT enabled", - grpclb_policy); + "[grpclb %p] lb_calld=%p: Received initial LB response message; " + "client load reporting NOT enabled", + grpclb_policy, lb_calld); } grpc_grpclb_initial_response_destroy(initial_response); lb_calld->seen_initial_response_ = true; @@ -750,15 +752,17 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( GPR_ASSERT(lb_calld->lb_call_ != nullptr); if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p] Serverlist with %" PRIuPTR " servers received", - grpclb_policy, serverlist->num_servers); + "[grpclb %p] lb_calld=%p: Serverlist with %" PRIuPTR + " servers received", + grpclb_policy, lb_calld, serverlist->num_servers); for (size_t i = 0; i < serverlist->num_servers; ++i) { grpc_resolved_address addr; ParseServer(serverlist->servers[i], &addr); char* ipport; grpc_sockaddr_to_string(&ipport, &addr, false); - gpr_log(GPR_INFO, "[grpclb %p] Serverlist[%" PRIuPTR "]: %s", - grpclb_policy, i, ipport); + gpr_log(GPR_INFO, + "[grpclb %p] lb_calld=%p: Serverlist[%" PRIuPTR "]: %s", + grpclb_policy, lb_calld, i, ipport); gpr_free(ipport); } } @@ -778,9 +782,9 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_, serverlist)) { if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p] Incoming server list identical to current, " - "ignoring.", - grpclb_policy); + "[grpclb %p] lb_calld=%p: Incoming server list identical to " + "current, ignoring.", + grpclb_policy, lb_calld); } grpc_grpclb_destroy_serverlist(serverlist); } else { // New serverlist. @@ -806,8 +810,9 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( char* response_slice_str = grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX); gpr_log(GPR_ERROR, - "[grpclb %p] Invalid LB response received: '%s'. Ignoring.", - grpclb_policy, response_slice_str); + "[grpclb %p] lb_calld=%p: Invalid LB response received: '%s'. " + "Ignoring.", + grpclb_policy, lb_calld, response_slice_str); gpr_free(response_slice_str); } grpc_slice_unref_internal(response_slice); @@ -838,9 +843,9 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( char* status_details = grpc_slice_to_c_string(lb_calld->lb_call_status_details_); gpr_log(GPR_INFO, - "[grpclb %p] Status from LB server received. Status = %d, details " - "= '%s', (lb_calld: %p, lb_call: %p), error '%s'", - grpclb_policy, lb_calld->lb_call_status_, status_details, lb_calld, + "[grpclb %p] lb_calld=%p: Status from LB server received. " + "Status = %d, details = '%s', (lb_call: %p), error '%s'", + grpclb_policy, lb_calld, lb_calld->lb_call_status_, status_details, lb_calld->lb_call_, grpc_error_string(error)); gpr_free(status_details); } @@ -1592,6 +1597,10 @@ void GrpcLb::CreateRoundRobinPolicyLocked(const Args& args) { this); return; } + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this, + rr_policy_.get()); + } // TODO(roth): We currently track this ref manually. Once the new // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. auto self = Ref(DEBUG_LOCATION, "on_rr_reresolution_requested"); @@ -1685,10 +1694,6 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { lb_policy_args.client_channel_factory = client_channel_factory(); lb_policy_args.args = args; CreateRoundRobinPolicyLocked(lb_policy_args); - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this, - rr_policy_.get()); - } } grpc_channel_args_destroy(args); } From 05d3ab2852cb2d7ce13f7ca059b36884e37175fd Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 17 Dec 2018 14:54:10 -0800 Subject: [PATCH 332/534] Address comments, improve tests --- .../grpcio_tests/tests/unit/BUILD.bazel | 1 + .../tests/unit/_server_shutdown_scenarios.py | 36 ++++++------------- .../tests/unit/_server_shutdown_test.py | 2 ++ 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index 4f850220f8f..7a910fd9feb 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -28,6 +28,7 @@ GRPCIO_TESTS_UNIT = [ # TODO(ghostwriternr): To be added later. # "_server_ssl_cert_config_test.py", "_server_test.py", + "_server_shutdown_test.py", "_session_cache_test.py", ] diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py index acbec0f77dd..1797e9bbfec 100644 --- a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py @@ -20,6 +20,7 @@ import time import logging import grpc +from tests.unit import test_common from concurrent import futures from six.moves import queue @@ -36,37 +37,24 @@ SERVER_FORK_CAN_EXIT = 'server_fork_can_exit' FORK_EXIT = '/test/ForkExit' -class ForkExitHandler(object): - - def unary_unary(self, request, servicer_context): - pid = os.fork() - if pid == 0: - os._exit(0) - return RESPONSE - - def __init__(self): - self.request_streaming = None - self.response_streaming = None - self.request_deserializer = None - self.response_serializer = None - self.unary_stream = None - self.stream_unary = None - self.stream_stream = None +def fork_and_exit(request, servicer_context): + pid = os.fork() + if pid == 0: + os._exit(0) + return RESPONSE class GenericHandler(grpc.GenericRpcHandler): def service(self, handler_call_details): if handler_call_details.method == FORK_EXIT: - return ForkExitHandler() + return grpc.unary_unary_rpc_method_handler(fork_and_exit) else: return None def run_server(port_queue): - server = grpc.server( - futures.ThreadPoolExecutor(max_workers=10), - options=(('grpc.so_reuseport', 0),)) + server = test_common.test_server() port = server.add_insecure_port('[::]:0') port_queue.put(port) server.add_generic_rpc_handlers((GenericHandler(),)) @@ -78,15 +66,11 @@ def run_server(port_queue): def run_test(args): if args.scenario == SERVER_RAISES_EXCEPTION: - server = grpc.server( - futures.ThreadPoolExecutor(max_workers=1), - options=(('grpc.so_reuseport', 0),)) + server = test_common.test_server() server.start() raise Exception() elif args.scenario == SERVER_DEALLOCATED: - server = grpc.server( - futures.ThreadPoolExecutor(max_workers=1), - options=(('grpc.so_reuseport', 0),)) + server = test_common.test_server() server.start() server.__del__() while server._state.stage != grpc._server._ServerStage.STOPPED: diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py index 0e4591c5e56..47446d65a51 100644 --- a/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py @@ -60,6 +60,8 @@ def wait(process): class ServerShutdown(unittest.TestCase): + # Currently we shut down a server (if possible) after the Python server + # instance is garbage collected. This behavior may change in the future. def test_deallocated_server_stops(self): process = subprocess.Popen( BASE_COMMAND + [_server_shutdown_scenarios.SERVER_DEALLOCATED], From 08a90f03d4d0ac846f517c9aeab7aeb05b1cfdca Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 17 Dec 2018 15:09:59 -0800 Subject: [PATCH 333/534] Remove the fake package dependency && temporarily skip the Channelz tests --- src/python/grpcio_tests/setup.py | 12 +++++++++--- .../tests/channelz/_channelz_servicer_test.py | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index f9cb9d0cec9..800b865da62 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -37,13 +37,19 @@ PACKAGE_DIRECTORIES = { } INSTALL_REQUIRES = ( - 'coverage>=4.0', 'enum34>=1.0.4', + 'coverage>=4.0', + 'enum34>=1.0.4', 'grpcio>={version}'.format(version=grpc_version.VERSION), - 'grpcio-channelz>={version}'.format(version=grpc_version.VERSION), + # TODO(https://github.com/pypa/warehouse/issues/5196) + # Re-enable it once we got the name back + # 'grpcio-channelz>={version}'.format(version=grpc_version.VERSION), 'grpcio-status>={version}'.format(version=grpc_version.VERSION), 'grpcio-tools>={version}'.format(version=grpc_version.VERSION), 'grpcio-health-checking>={version}'.format(version=grpc_version.VERSION), - 'oauth2client>=1.4.7', 'protobuf>=3.6.0', 'six>=1.10', 'google-auth>=1.0.0', + 'oauth2client>=1.4.7', + 'protobuf>=3.6.0', + 'six>=1.10', + 'google-auth>=1.0.0', 'requests>=2.14.2') if not PY3: diff --git a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py index 8ca51895224..d060a4973e4 100644 --- a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -93,6 +93,7 @@ def _close_channel_server_pairs(pairs): pair.channel.close() +@unittest.skip('https://github.com/pypa/warehouse/issues/5196') class ChannelzServicerTest(unittest.TestCase): def _send_successful_unary_unary(self, idx): From c52ae0d0005ccf98c6e734db34cd2634e5aa26ef Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 17 Dec 2018 13:27:42 -0800 Subject: [PATCH 334/534] Give the interceptors header files in include/grpcpp/support --- BUILD | 3 +++ CMakeLists.txt | 9 +++++++ Makefile | 9 +++++++ build.yaml | 3 +++ gRPC-C++.podspec | 3 +++ include/grpcpp/support/client_interceptor.h | 24 +++++++++++++++++++ include/grpcpp/support/interceptor.h | 24 +++++++++++++++++++ include/grpcpp/support/server_interceptor.h | 24 +++++++++++++++++++ .../client_interceptors_end2end_test.cc | 2 +- .../server_interceptors_end2end_test.cc | 2 +- tools/doxygen/Doxyfile.c++ | 3 +++ tools/doxygen/Doxyfile.c++.internal | 3 +++ .../generated/sources_and_headers.json | 6 +++++ 13 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 include/grpcpp/support/client_interceptor.h create mode 100644 include/grpcpp/support/interceptor.h create mode 100644 include/grpcpp/support/server_interceptor.h diff --git a/BUILD b/BUILD index fe93f1281ed..b9b39a37a7e 100644 --- a/BUILD +++ b/BUILD @@ -244,10 +244,13 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", + "include/grpcpp/support/interceptor.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", "include/grpcpp/support/status_code_enum.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index b6ceb50a5f1..378681ae20b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3034,10 +3034,13 @@ foreach(_hdr include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h include/grpcpp/support/client_callback.h + include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h + include/grpcpp/support/interceptor.h include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h + include/grpcpp/support/server_interceptor.h include/grpcpp/support/slice.h include/grpcpp/support/status.h include/grpcpp/support/status_code_enum.h @@ -3619,10 +3622,13 @@ foreach(_hdr include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h include/grpcpp/support/client_callback.h + include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h + include/grpcpp/support/interceptor.h include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h + include/grpcpp/support/server_interceptor.h include/grpcpp/support/slice.h include/grpcpp/support/status.h include/grpcpp/support/status_code_enum.h @@ -4571,10 +4577,13 @@ foreach(_hdr include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h include/grpcpp/support/client_callback.h + include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h + include/grpcpp/support/interceptor.h include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h + include/grpcpp/support/server_interceptor.h include/grpcpp/support/slice.h include/grpcpp/support/status.h include/grpcpp/support/status_code_enum.h diff --git a/Makefile b/Makefile index 7b4a1fb0d5e..c433ac4cfcb 100644 --- a/Makefile +++ b/Makefile @@ -5405,10 +5405,13 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/client_callback.h \ + include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ + include/grpcpp/support/interceptor.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ + include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ include/grpcpp/support/status_code_enum.h \ @@ -5999,10 +6002,13 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/client_callback.h \ + include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ + include/grpcpp/support/interceptor.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ + include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ include/grpcpp/support/status_code_enum.h \ @@ -6908,10 +6914,13 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/client_callback.h \ + include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ + include/grpcpp/support/interceptor.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ + include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ include/grpcpp/support/status_code_enum.h \ diff --git a/build.yaml b/build.yaml index 7f1f11a3c03..8e80cf3fb04 100644 --- a/build.yaml +++ b/build.yaml @@ -1365,10 +1365,13 @@ filegroups: - include/grpcpp/support/byte_buffer.h - include/grpcpp/support/channel_arguments.h - include/grpcpp/support/client_callback.h + - include/grpcpp/support/client_interceptor.h - include/grpcpp/support/config.h + - include/grpcpp/support/interceptor.h - include/grpcpp/support/proto_buffer_reader.h - include/grpcpp/support/proto_buffer_writer.h - include/grpcpp/support/server_callback.h + - include/grpcpp/support/server_interceptor.h - include/grpcpp/support/slice.h - include/grpcpp/support/status.h - include/grpcpp/support/status_code_enum.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 414e788a962..f918fe8ad9c 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -116,10 +116,13 @@ Pod::Spec.new do |s| 'include/grpcpp/support/byte_buffer.h', 'include/grpcpp/support/channel_arguments.h', 'include/grpcpp/support/client_callback.h', + 'include/grpcpp/support/client_interceptor.h', 'include/grpcpp/support/config.h', + 'include/grpcpp/support/interceptor.h', 'include/grpcpp/support/proto_buffer_reader.h', 'include/grpcpp/support/proto_buffer_writer.h', 'include/grpcpp/support/server_callback.h', + 'include/grpcpp/support/server_interceptor.h', 'include/grpcpp/support/slice.h', 'include/grpcpp/support/status.h', 'include/grpcpp/support/status_code_enum.h', diff --git a/include/grpcpp/support/client_interceptor.h b/include/grpcpp/support/client_interceptor.h new file mode 100644 index 00000000000..50810e3fe3c --- /dev/null +++ b/include/grpcpp/support/client_interceptor.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2015 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 GRPCPP_SUPPORT_CLIENT_INTERCEPTOR_H +#define GRPCPP_SUPPORT_CLIENT_INTERCEPTOR_H + +#include + +#endif // GRPCPP_SUPPORT_CLIENT_INTERCEPTOR_H diff --git a/include/grpcpp/support/interceptor.h b/include/grpcpp/support/interceptor.h new file mode 100644 index 00000000000..7ff79516bae --- /dev/null +++ b/include/grpcpp/support/interceptor.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2015 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 GRPCPP_SUPPORT_INTERCEPTOR_H +#define GRPCPP_SUPPORT_INTERCEPTOR_H + +#include + +#endif // GRPCPP_SUPPORT_INTERCEPTOR_H diff --git a/include/grpcpp/support/server_interceptor.h b/include/grpcpp/support/server_interceptor.h new file mode 100644 index 00000000000..b0a6229b667 --- /dev/null +++ b/include/grpcpp/support/server_interceptor.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2015 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 GRPCPP_SUPPORT_SERVER_INTERCEPTOR_H +#define GRPCPP_SUPPORT_SERVER_INTERCEPTOR_H + +#include + +#endif // GRPCPP_SUPPORT_SERVER_INTERCEPTOR_H diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 968b5d49d10..34f5b93cabc 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -23,11 +23,11 @@ #include #include #include -#include #include #include #include #include +#include #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 9460a7d6c64..4efe13fdec1 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -24,10 +24,10 @@ #include #include #include -#include #include #include #include +#include #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index a5f817997dc..1ab3a394b96 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1008,10 +1008,13 @@ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/client_callback.h \ +include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ +include/grpcpp/support/interceptor.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ +include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ include/grpcpp/support/status_code_enum.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 1535aa06d32..5f488d51940 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1010,10 +1010,13 @@ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/client_callback.h \ +include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ +include/grpcpp/support/interceptor.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ +include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ include/grpcpp/support/status_code_enum.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 40c49895fd7..ad8c894fde6 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11546,10 +11546,13 @@ "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", + "include/grpcpp/support/interceptor.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", "include/grpcpp/support/status_code_enum.h", @@ -11652,10 +11655,13 @@ "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", + "include/grpcpp/support/interceptor.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", "include/grpcpp/support/status_code_enum.h", From afc2fabe0c16efbf768c70f365688156b457619d Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 17 Dec 2018 16:10:06 -0800 Subject: [PATCH 335/534] Avoid taking refs on the stream by getting a copy of the context --- .../chttp2/transport/context_list.cc | 38 +++++++++++++------ .../transport/chttp2/transport/context_list.h | 35 ++++------------- 2 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc index f30d41c3326..df09809067d 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.cc +++ b/src/core/ext/transport/chttp2/transport/context_list.cc @@ -21,31 +21,47 @@ #include "src/core/ext/transport/chttp2/transport/context_list.h" namespace { -void (*write_timestamps_callback_g)(void*, grpc_core::Timestamps*) = nullptr; -} +void (*write_timestamps_callback_g)(void*, grpc_core::Timestamps*, + grpc_error* error) = nullptr; +void* (*get_copied_context_fn_g)(void*) = nullptr; +} // namespace namespace grpc_core { +void ContextList::Append(ContextList** head, grpc_chttp2_stream* s) { + if (get_copied_context_fn_g == nullptr || + write_timestamps_callback_g == nullptr) { + return; + } + /* Create a new element in the list and add it at the front */ + ContextList* elem = grpc_core::New(); + elem->trace_context_ = get_copied_context_fn_g(s->context); + elem->byte_offset_ = s->byte_counter; + elem->next_ = *head; + *head = elem; +} + void ContextList::Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error) { ContextList* head = static_cast(arg); ContextList* to_be_freed; while (head != nullptr) { - if (error == GRPC_ERROR_NONE && ts != nullptr) { - if (write_timestamps_callback_g) { - ts->byte_offset = static_cast(head->byte_offset_); - write_timestamps_callback_g(head->s_->context, ts); - } + if (write_timestamps_callback_g) { + ts->byte_offset = static_cast(head->byte_offset_); + write_timestamps_callback_g(head->trace_context_, ts, error); } - GRPC_CHTTP2_STREAM_UNREF(static_cast(head->s_), - "timestamp"); to_be_freed = head; head = head->next_; grpc_core::Delete(to_be_freed); } } -void grpc_http2_set_write_timestamps_callback( - void (*fn)(void*, grpc_core::Timestamps*)) { +void grpc_http2_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*, + grpc_error* error)) { write_timestamps_callback_g = fn; } + +void grpc_http2_set_fn_get_copied_context(void* (*fn)(void*)) { + get_copied_context_fn_g = fn; +} } /* namespace grpc_core */ diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h index d8701077494..5b9d2ab3784 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.h +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -31,42 +31,23 @@ class ContextList { public: /* Creates a new element with \a context as the value and appends it to the * list. */ - static void Append(ContextList** head, grpc_chttp2_stream* s) { - /* Make sure context is not already present */ - GRPC_CHTTP2_STREAM_REF(s, "timestamp"); - -#ifndef NDEBUG - ContextList* ptr = *head; - while (ptr != nullptr) { - if (ptr->s_ == s) { - GPR_ASSERT( - false && - "Trying to append a stream that is already present in the list"); - } - ptr = ptr->next_; - } -#endif - - /* Create a new element in the list and add it at the front */ - ContextList* elem = grpc_core::New(); - elem->s_ = s; - elem->byte_offset_ = s->byte_counter; - elem->next_ = *head; - *head = elem; - } + static void Append(ContextList** head, grpc_chttp2_stream* s); /* Executes a function \a fn with each context in the list and \a ts. It also - * frees up the entire list after this operation. */ + * frees up the entire list after this operation. It is intended as a callback + * and hence does not take a ref on \a error */ static void Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error); private: - grpc_chttp2_stream* s_ = nullptr; + void* trace_context_ = nullptr; ContextList* next_ = nullptr; size_t byte_offset_ = 0; }; -void grpc_http2_set_write_timestamps_callback( - void (*fn)(void*, grpc_core::Timestamps*)); +void grpc_http2_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*, + grpc_error* error)); +void grpc_http2_set_fn_get_copied_context(void* (*fn)(void*)); } /* namespace grpc_core */ #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H */ From 906cf5b428f31513321c8d2e3530aa7a03cca400 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 17 Dec 2018 16:15:46 -0800 Subject: [PATCH 336/534] Add error details on context list clearing --- .../ext/transport/chttp2/transport/chttp2_transport.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 9b6574b612d..3b7c48a72ca 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -170,9 +170,6 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { grpc_slice_buffer_destroy_internal(&outbuf); grpc_chttp2_hpack_compressor_destroy(&hpack_compressor); - grpc_core::ContextList::Execute(cl, nullptr, GRPC_ERROR_NONE); - cl = nullptr; - grpc_slice_buffer_destroy_internal(&read_buffer); grpc_chttp2_hpack_parser_destroy(&hpack_parser); grpc_chttp2_goaway_parser_destroy(&goaway_parser); @@ -569,6 +566,10 @@ static void close_transport_locked(grpc_chttp2_transport* t, grpc_error* error) { end_all_the_calls(t, GRPC_ERROR_REF(error)); cancel_pings(t, GRPC_ERROR_REF(error)); + // ContextList::Execute follows semantics of a callback function and does not + // need a ref on error + grpc_core::ContextList::Execute(cl, nullptr, error); + cl = nullptr; if (t->closed_with_error == GRPC_ERROR_NONE) { if (!grpc_error_has_clear_grpc_status(error)) { error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, From 6692429f31dc715e55fe37d95837b773494fcd99 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 17 Dec 2018 16:25:25 -0800 Subject: [PATCH 337/534] Download private key from KeyStore --- .../linux/pull_request/grpc_microbenchmark_diff.cfg | 8 ++++++++ .../internal_ci/linux/pull_request/grpc_trickle_diff.cfg | 8 ++++++++ .../macos/pull_request/grpc_ios_binary_size.cfg | 8 ++++++++ tools/run_tests/python_utils/check_on_pr.py | 4 ++-- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg b/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg index 47301d61415..3c62401cc3a 100644 --- a/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg @@ -17,6 +17,14 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/linux/grpc_microbenchmark_diff.sh" timeout_mins: 120 +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73836 + keyname: "grpc_checks_private_key" + } + } +} action { define_artifacts { regex: "**/*sponge_log.*" diff --git a/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg b/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg index 78358eac28e..69e44276625 100644 --- a/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg @@ -17,6 +17,14 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/linux/grpc_trickle_diff.sh" timeout_mins: 120 +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73836 + keyname: "grpc_checks_private_key" + } + } +} action { define_artifacts { regex: "**/*sponge_log.*" diff --git a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg index fb215bdf994..1c4f7b23109 100644 --- a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg @@ -18,6 +18,14 @@ build_file: "grpc/tools/internal_ci/macos/grpc_ios_binary_size.sh" timeout_mins: 60 gfile_resources: "/bigstore/grpc-testing-secrets/github_credentials/oauth_token.txt" +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73836 + keyname: "grpc_checks_private_key" + } + } +} action { define_artifacts { regex: "**/*sponge_log.*" diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index f756e4bdaa4..78f1dca817d 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -26,8 +26,8 @@ _GITHUB_REPO = 'grpc/grpc' _GITHUB_APP_ID = 22338 _INSTALLATION_ID = 519109 _GITHUB_APP_KEY = open( - os.environ['HOME'] + '/.ssh/google-grpc-checker.2018-12-13.private-key.pem', - 'r').read() + os.path.join(os.environ['KOKORO_KEYSTORE_DIR'], '73836_grpc_checks_private_key'), + 'rb').read() _ACCESS_TOKEN_CACHE = None From 915cd71b4a6aceb8003077e0e360ea7accbde38c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 17 Dec 2018 17:36:28 -0800 Subject: [PATCH 338/534] nullability revert --- src/objective-c/GRPCClient/GRPCCall.h | 32 +++++++++++++----------- src/objective-c/ProtoRPC/ProtoRPC.h | 9 +++---- src/objective-c/ProtoRPC/ProtoService.h | 33 +++++++++++++------------ 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 15b1c904498..6669067fbff 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -275,6 +275,9 @@ extern NSString *const kGRPCTrailersKey; NS_ASSUME_NONNULL_END +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" + /** * This interface is deprecated. Please use \a GRPCcall2. * @@ -282,7 +285,7 @@ NS_ASSUME_NONNULL_END */ @interface GRPCCall : GRXWriter -- (nonnull instancetype)init NS_UNAVAILABLE; +- (instancetype)init NS_UNAVAILABLE; /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of @@ -308,7 +311,7 @@ NS_ASSUME_NONNULL_END * * The property is initialized to an empty NSMutableDictionary. */ -@property(nonnull, atomic, readonly) NSMutableDictionary *requestHeaders; +@property(atomic, readonly) NSMutableDictionary *requestHeaders; /** * This dictionary is populated with the HTTP headers received from the server. This happens before @@ -319,7 +322,7 @@ NS_ASSUME_NONNULL_END * The value of this property is nil until all response headers are received, and will change before * any of -writeValue: or -writesFinishedWithError: are sent to the writeable. */ -@property(nullable, atomic, readonly) NSDictionary *responseHeaders; +@property(atomic, readonly) NSDictionary *responseHeaders; /** * Same as responseHeaders, but populated with the HTTP trailers received from the server before the @@ -328,7 +331,7 @@ NS_ASSUME_NONNULL_END * The value of this property is nil until all response trailers are received, and will change * before -writesFinishedWithError: is sent to the writeable. */ -@property(nullable, atomic, readonly) NSDictionary *responseTrailers; +@property(atomic, readonly) NSDictionary *responseTrailers; /** * The request writer has to write NSData objects into the provided Writeable. The server will @@ -341,9 +344,9 @@ NS_ASSUME_NONNULL_END * host parameter should not contain the scheme (http:// or https://), only the name or IP addr * and the port number, for example @"localhost:5050". */ -- (nullable instancetype)initWithHost:(nonnull NSString *)host - path:(nonnull NSString *)path - requestsWriter:(nonnull GRXWriter *)requestWriter; +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + requestsWriter:(GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -354,12 +357,10 @@ NS_ASSUME_NONNULL_END /** * The following methods are deprecated. */ -+ (void)setCallSafety:(GRPCCallSafety)callSafety - host:(nonnull NSString *)host - path:(nonnull NSString *)path; -@property(nullable, atomic, copy, readwrite) NSString *serverName; ++ (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path; +@property(atomic, copy, readwrite) NSString *serverName; @property NSTimeInterval timeout; -- (void)setResponseDispatchQueue:(nonnull dispatch_queue_t)queue; +- (void)setResponseDispatchQueue:(dispatch_queue_t)queue; @end @@ -370,11 +371,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (nullable id)objectForKeyedSubscript:(nonnull id)key; -- (void)setObject:(nonnull id)obj forKeyedSubscript:(nonnull id)key; +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)obj forKeyedSubscript:(id)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(nonnull id)key; +- (void)removeObjectForKey:(id)key; @end #pragma clang diagnostic push @@ -383,3 +384,4 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @interface NSMutableDictionary (GRPCRequestHeaders) @end #pragma clang diagnostic pop +#pragma clang diagnostic pop diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index e6ba1f66ca5..91a50d395af 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -142,11 +142,10 @@ __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC * addr and the port number, for example @"localhost:5050". */ - - (nullable instancetype)initWithHost : (nonnull NSString *)host method - : (nonnull GRPCProtoMethod *)method requestsWriter - : (nonnull GRXWriter *)requestsWriter responseClass - : (nonnull Class)responseClass responsesWriteable - : (nonnull id)responsesWriteable NS_DESIGNATED_INITIALIZER; + (instancetype)initWithHost : (NSString *)host method + : (GRPCProtoMethod *)method requestsWriter : (GRXWriter *)requestsWriter responseClass + : (Class)responseClass responsesWriteable + : (id)responsesWriteable NS_DESIGNATED_INITIALIZER; - (void)start; @end diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 70423ee9def..d76e96ce2a6 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -27,38 +27,41 @@ @class GRPCStreamingProtoCall; @protocol GRPCProtoResponseCallbacks; -NS_ASSUME_NONNULL_BEGIN +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService : NSObject - - (nullable instancetype)initWithHost : (NSString *)host packageName - : (NSString *)packageName serviceName : (NSString *)serviceName callOptions + (nullable instancetype)initWithHost : (nonnull NSString *)host packageName + : (nonnull NSString *)packageName serviceName : (nonnull NSString *)serviceName callOptions : (nullable GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName serviceName:(NSString *)serviceName; -- (nullable GRPCProtoCall *)RPCToMethod:(NSString *)method - requestsWriter:(GRXWriter *)requestsWriter - responseClass:(Class)responseClass - responsesWriteable:(id)responsesWriteable; +- (GRPCProtoCall *)RPCToMethod:(NSString *)method + requestsWriter:(GRXWriter *)requestsWriter + responseClass:(Class)responseClass + responsesWriteable:(id)responsesWriteable; -- (nullable GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method - message:(id)message - responseHandler:(id)handler +- (nullable GRPCUnaryProtoCall *)RPCToMethod:(nonnull NSString *)method + message:(nonnull id)message + responseHandler:(nonnull id)handler callOptions:(nullable GRPCCallOptions *)callOptions - responseClass:(Class)responseClass; + responseClass:(nonnull Class)responseClass; -- (nullable GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method - responseHandler:(id)handler +- (nullable GRPCStreamingProtoCall *)RPCToMethod:(nonnull NSString *)method + responseHandler:(nonnull id)handler callOptions:(nullable GRPCCallOptions *)callOptions - responseClass:(Class)responseClass; + responseClass:(nonnull Class)responseClass; @end +#pragma clang diagnostic pop + /** * This subclass is empty now. Eventually we'll remove ProtoService class * to avoid potential naming conflict @@ -69,5 +72,3 @@ __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoServ #pragma clang diagnostic pop @end - - NS_ASSUME_NONNULL_END From eafb1d527d8fc1f367215429fde9421aac876ef2 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 17 Dec 2018 18:14:58 -0800 Subject: [PATCH 339/534] Reorgnize dependencies and variables --- .../prepare_build_linux_perf_rc | 5 +++ .../helper_scripts/prepare_build_macos_rc | 4 ++- tools/run_tests/python_utils/check_on_pr.py | 35 ++++++++++--------- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc index dc3c75a6a12..8223e03abd5 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc @@ -34,4 +34,9 @@ fi sudo pip install tabulate +# Python dependencies for tools/run_tests/python_utils/check_on_pr.py +sudo -H pip install pyjwt cryptography requests + +ls -al "${KOKORO_KEYSTORE_DIR}/73836_grpc_checks_private_key" + git submodule update --init diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index bafe0d98c1a..b770808db99 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -31,6 +31,8 @@ date pip install google-api-python-client oauth2client --user python export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json +ls -al "${KOKORO_KEYSTORE_DIR}/73836_grpc_checks_private_key" + # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then set +x @@ -63,7 +65,7 @@ time pod repo update # needed by python # python time pip install virtualenv --user python -time pip install -U Mako six tox setuptools twisted pyyaml --user python +time pip install -U Mako six tox setuptools twisted pyyaml pyjwt cryptography requests --user python export PYTHONPATH=/Library/Python/3.4/site-packages # Install Python 3.7 diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index 78f1dca817d..d59f99b2520 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -25,21 +25,21 @@ _GITHUB_API_PREFIX = 'https://api.github.com' _GITHUB_REPO = 'grpc/grpc' _GITHUB_APP_ID = 22338 _INSTALLATION_ID = 519109 -_GITHUB_APP_KEY = open( - os.path.join(os.environ['KOKORO_KEYSTORE_DIR'], '73836_grpc_checks_private_key'), - 'rb').read() _ACCESS_TOKEN_CACHE = None def _jwt_token(): + github_app_key = open( + os.path.join(os.environ['KOKORO_KEYSTORE_DIR'], + '73836_grpc_checks_private_key'), 'rb').read() return jwt.encode( { 'iat': int(time.time()), 'exp': int(time.time() + 60 * 10), # expire in 10 minutes 'iss': _GITHUB_APP_ID, }, - _GITHUB_APP_KEY, + github_app_key, algorithm='RS256') @@ -90,25 +90,26 @@ def check_on_pr(name, summary, success=True): summary: A str in Markdown to be used as the detail information of the check. success: A bool indicates whether the check is succeed or not. """ + if 'KOKORO_GIT_COMMIT' not in os.environ: + print('Missing KOKORO_GIT_COMMIT env var: not checking') + return + if 'KOKORO_KEYSTORE_DIR' not in os.environ: + print('Missing KOKORO_KEYSTORE_DIR env var: not checking') + return if 'ghprbPullId' not in os.environ: - print('Missing ghprbPullId env var: not commenting') + print('Missing ghprbPullId env var: not checking') return - commit = _latest_commit() + completion_time = str( + datetime.datetime.utcnow().replace(microsecond=0).isoformat()) + 'Z' resp = _call( '/repos/%s/check-runs' % _GITHUB_REPO, method='POST', json={ - 'name': - name, - 'head_sha': - commit['sha'], - 'status': - 'completed', - 'completed_at': - '%sZ' % - datetime.datetime.utcnow().replace(microsecond=0).isoformat(), - 'conclusion': - 'success' if success else 'failure', + 'name': name, + 'head_sha': os.environ['KOKORO_GIT_COMMIT'], + 'status': 'completed', + 'completed_at': completion_time, + 'conclusion': 'success' if success else 'failure', 'output': { 'title': name, 'summary': summary, From 3347158533460f15bc1621a2ed0c6d298a82e339 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 17 Dec 2018 18:25:42 -0800 Subject: [PATCH 340/534] Use python2.7 -m pip instead of default pip --- tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc | 4 +--- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc index 8223e03abd5..ec1ec1179d3 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc @@ -35,8 +35,6 @@ fi sudo pip install tabulate # Python dependencies for tools/run_tests/python_utils/check_on_pr.py -sudo -H pip install pyjwt cryptography requests - -ls -al "${KOKORO_KEYSTORE_DIR}/73836_grpc_checks_private_key" +time python2.7 -m pip install pyjwt cryptography requests --user git submodule update --init diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index b770808db99..114dc2ef558 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -31,8 +31,6 @@ date pip install google-api-python-client oauth2client --user python export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json -ls -al "${KOKORO_KEYSTORE_DIR}/73836_grpc_checks_private_key" - # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then set +x From 8183fe12992ac36fd99b637422d6bf158e760036 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 17 Dec 2018 18:29:25 -0800 Subject: [PATCH 341/534] fix BUILD.bazel --- src/python/grpcio_tests/tests/unit/BUILD.bazel | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index 7a910fd9feb..1b462ec67a6 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -50,6 +50,11 @@ py_library( srcs = ["_exit_scenarios.py"], ) +py_library( + name = "_server_shutdown_scenarios", + srcs = ["_server_shutdown_scenarios.py"], +) + py_library( name = "_thread_pool", srcs = ["_thread_pool.py"], @@ -71,6 +76,7 @@ py_library( ":resources", ":test_common", ":_exit_scenarios", + ":_server_shutdown_scenarios", ":_thread_pool", ":_from_grpc_import_star", "//src/python/grpcio_tests/tests/unit/framework/common", From 3c49252d47f149c8b3262f9a1db83f11340e368b Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 17 Dec 2018 21:05:13 -0800 Subject: [PATCH 342/534] bazel docker image does not support ipv6 --- .../grpcio_tests/tests/unit/_server_shutdown_scenarios.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py index 1797e9bbfec..1d1fdba11ee 100644 --- a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py @@ -81,7 +81,7 @@ def run_test(args): thread.daemon = True thread.start() port = port_queue.get() - channel = grpc.insecure_channel('[::]:%d' % port) + channel = grpc.insecure_channel('localhost:%d' % port) multi_callable = channel.unary_unary(FORK_EXIT) result, call = multi_callable.with_call(REQUEST, wait_for_ready=True) os.wait() From 8c3df503ad59a6c66e1b1ab6257b52c508ec37dc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 17 Dec 2018 21:54:53 -0800 Subject: [PATCH 343/534] Fix compatibility test failures --- src/objective-c/GRPCClient/GRPCCall.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index cfd0de1a8a2..39e4967ec98 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -484,8 +484,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; callSafety:(GRPCCallSafety)safety requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { - // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. - NSAssert(host.length != 0 && path.length != 0, @"Neither host nor path can be nil."); + // Purposely using pointer rather than length (host.length == 0) for backwards compatibility. + NSAssert(host != nil && path != nil, @"Neither host nor path can be nil."); NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); NSAssert(requestWriter.state == GRXWriterStateNotStarted, @"The requests writer can't be already started."); From d36a13af3182495079bee65ff78e3e7e7f0d5901 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 17 Dec 2018 21:55:26 -0800 Subject: [PATCH 344/534] Try use alternative simulator for APIv2Tests --- src/objective-c/tests/run_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index e8c3e6ec2a4..f075d9baadd 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -187,7 +187,7 @@ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ -scheme APIv2Tests \ - -destination name="iPhone 8" \ + -destination name="iPhone X" \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ From eb9064db2fd38025dfa4fbe813de8798b5f1d0ed Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 18 Dec 2018 10:35:07 -0800 Subject: [PATCH 345/534] Clarify compression algorithm enum order --- include/grpc/impl/codegen/compression_types.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h index e35d8929678..f778b005b9b 100644 --- a/include/grpc/impl/codegen/compression_types.h +++ b/include/grpc/impl/codegen/compression_types.h @@ -52,7 +52,8 @@ extern "C" { "grpc.compression_enabled_algorithms_bitset" /** \} */ -/** The various compression algorithms supported by gRPC */ +/** The various compression algorithms supported by gRPC (not sorted by + * compression level) */ typedef enum { GRPC_COMPRESS_NONE = 0, GRPC_COMPRESS_DEFLATE, From 8bc8ff3dce507f912b8985fefaa22da1e2d95b6d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 18 Dec 2018 11:13:13 -0800 Subject: [PATCH 346/534] Fix nullability incompatibility --- src/compiler/objective_c_generator.cc | 11 +++++------ src/objective-c/ProtoRPC/ProtoRPC.h | 5 +++++ src/objective-c/ProtoRPC/ProtoService.m | 10 +++++++++- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc index 0a6b64f5952..af5398ec683 100644 --- a/src/compiler/objective_c_generator.cc +++ b/src/compiler/objective_c_generator.cc @@ -355,7 +355,7 @@ void PrintMethodImplementations(Printer* printer, "@implementation $service_class$\n\n" "// Designated initializer\n" "- (instancetype)initWithHost:(NSString *)host " - "callOptions:(GRPCCallOptions *_Nullable)callOptions{\n" + "callOptions:(GRPCCallOptions *_Nullable)callOptions {\n" " self = [super initWithHost:host\n" " packageName:@\"$package$\"\n" " serviceName:@\"$service_name$\"\n" @@ -363,10 +363,9 @@ void PrintMethodImplementations(Printer* printer, " return self;\n" "}\n\n" "- (instancetype)initWithHost:(NSString *)host {\n" - " return [self initWithHost:host\n" - " packageName:@\"$package$\"\n" - " serviceName:@\"$service_name$\"\n" - " callOptions:nil];\n" + " return [super initWithHost:host\n" + " packageName:@\"$package$\"\n" + " serviceName:@\"$service_name$\"];\n" "}\n\n"); printer.Print( @@ -381,7 +380,7 @@ void PrintMethodImplementations(Printer* printer, printer.Print( "#pragma mark - Class Methods\n\n" "+ (instancetype)serviceWithHost:(NSString *)host {\n" - " return [self serviceWithHost:host callOptions:nil];\n" + " return [[self alloc] initWithHost:host];\n" "}\n\n" "+ (instancetype)serviceWithHost:(NSString *)host " "callOptions:(GRPCCallOptions *_Nullable)callOptions {\n" diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 91a50d395af..8ce3421cc17 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -134,6 +134,9 @@ NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" + __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC : GRPCCall @@ -160,3 +163,5 @@ __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC #pragma clang diagnostic pop @end + +#pragma clang diagnostic pop diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m index 3d998bfaeb8..b7c7fadbcf0 100644 --- a/src/objective-c/ProtoRPC/ProtoService.m +++ b/src/objective-c/ProtoRPC/ProtoService.m @@ -61,7 +61,15 @@ - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName serviceName:(NSString *)serviceName { - return [self initWithHost:host packageName:packageName serviceName:serviceName callOptions:nil]; + // Do not call designated initializer here due to nullability incompatibility. This method is from + // old API and does not assert on nullability of the parameters. + if ((self = [super init])) { + _host = [host copy]; + _packageName = [packageName copy]; + _serviceName = [serviceName copy]; + _callOptions = nil; + } + return self; } - (GRPCProtoCall *)RPCToMethod:(NSString *)method From 9a7eec0c455b3f6db9c1d06e73398a330e2c0729 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 18 Dec 2018 11:36:09 -0800 Subject: [PATCH 347/534] Suppress compiler error by initializing sent_length --- src/core/lib/iomgr/tcp_posix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 211ae011cbc..c268c18664a 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -818,7 +818,7 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { struct msghdr msg; struct iovec iov[MAX_WRITE_IOVEC]; msg_iovlen_type iov_size; - ssize_t sent_length; + ssize_t sent_length = 0; size_t sending_length; size_t trailing; size_t unwind_slice_idx; From 71094e25c5355190eed4463cf3b1e48db053c6e0 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 18 Dec 2018 11:43:53 -0800 Subject: [PATCH 348/534] Remove dependency of grpc.framework.foundation.callable_util * Used in _channel.py, _server.py, and _utilities.py * This API can trace back to 4 years ago * The code change ensures the logging info is exactly the same --- src/python/grpcio/grpc/_channel.py | 9 +++++---- src/python/grpcio/grpc/_server.py | 7 ++++--- src/python/grpcio/grpc/_utilities.py | 16 +++++++++++----- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 96118badada..e8279db51fd 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -22,7 +22,6 @@ import grpc from grpc import _common from grpc import _grpcio_metadata from grpc._cython import cygrpc -from grpc.framework.foundation import callable_util _LOGGER = logging.getLogger(__name__) @@ -871,9 +870,11 @@ def _deliver(state, initial_connectivity, initial_callbacks): while True: for callback in callbacks: cygrpc.block_if_fork_in_progress(state) - callable_util.call_logging_exceptions( - callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE, - connectivity) + try: + callback(connectivity) + except Exception: # pylint: disable=broad-except + _LOGGER.exception( + _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE) with state.lock: callbacks = _deliveries(state) if callbacks: diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index eb750ef1a82..83ccf38232f 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -25,7 +25,6 @@ import grpc from grpc import _common from grpc import _interceptor from grpc._cython import cygrpc -from grpc.framework.foundation import callable_util _LOGGER = logging.getLogger(__name__) @@ -748,8 +747,10 @@ def _process_event_and_continue(state, event): else: rpc_state, callbacks = event.tag(event) for callback in callbacks: - callable_util.call_logging_exceptions(callback, - 'Exception calling callback!') + try: + callback() + except Exception: # pylint: disable=broad-except + _LOGGER.exception('Exception calling callback!') if rpc_state is not None: with state.lock: state.rpc_states.remove(rpc_state) diff --git a/src/python/grpcio/grpc/_utilities.py b/src/python/grpcio/grpc/_utilities.py index d90b34bcbd4..d1f465a83a6 100644 --- a/src/python/grpcio/grpc/_utilities.py +++ b/src/python/grpcio/grpc/_utilities.py @@ -16,12 +16,14 @@ import collections import threading import time +import logging import six import grpc from grpc import _common -from grpc.framework.foundation import callable_util + +_LOGGER = logging.getLogger(__name__) _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE = ( 'Exception calling connectivity future "done" callback!') @@ -98,8 +100,10 @@ class _ChannelReadyFuture(grpc.Future): return for done_callback in done_callbacks: - callable_util.call_logging_exceptions( - done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self) + try: + done_callback(self) + except Exception: # pylint: disable=broad-except + _LOGGER.exception(_DONE_CALLBACK_EXCEPTION_LOG_MESSAGE) def cancel(self): with self._condition: @@ -113,8 +117,10 @@ class _ChannelReadyFuture(grpc.Future): return False for done_callback in done_callbacks: - callable_util.call_logging_exceptions( - done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self) + try: + done_callback(self) + except Exception: # pylint: disable=broad-except + _LOGGER.exception(_DONE_CALLBACK_EXCEPTION_LOG_MESSAGE) return True From 233123ae3fa73b632c7b81b1131edb83c4fcf13a Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Fri, 14 Dec 2018 15:06:35 -0800 Subject: [PATCH 349/534] Improve metadata documentation for the user --- include/grpcpp/impl/codegen/client_context.h | 7 +++++++ include/grpcpp/impl/codegen/server_context.h | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 0a71f3d9b6a..5946488566e 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -200,6 +200,13 @@ class ClientContext { /// end in "-bin". /// \param meta_value The metadata value. If its value is binary, the key name /// must end in "-bin". + /// + /// Metadata must conform to the following format: + /// Custom-Metadata -> Binary-Header / ASCII-Header + /// Binary-Header -> {Header-Name "-bin" } {binary value} + /// ASCII-Header -> Header-Name ASCII-Value + /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . + /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII void AddMetadata(const grpc::string& meta_key, const grpc::string& meta_value); diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index ccb5925e7d8..affe61b547b 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -131,6 +131,13 @@ class ServerContext { /// end in "-bin". /// \param value The metadata value. If its value is binary, the key name /// must end in "-bin". + /// + /// Metadata must conform to the following format: + /// Custom-Metadata -> Binary-Header / ASCII-Header + /// Binary-Header -> {Header-Name "-bin" } {binary value} + /// ASCII-Header -> Header-Name ASCII-Value + /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . + /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII void AddInitialMetadata(const grpc::string& key, const grpc::string& value); /// Add the (\a key, \a value) pair to the initial metadata @@ -145,6 +152,13 @@ class ServerContext { /// it must end in "-bin". /// \param value The metadata value. If its value is binary, the key name /// must end in "-bin". + /// + /// Metadata must conform to the following format: + /// Custom-Metadata -> Binary-Header / ASCII-Header + /// Binary-Header -> {Header-Name "-bin" } {binary value} + /// ASCII-Header -> Header-Name ASCII-Value + /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . + /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII void AddTrailingMetadata(const grpc::string& key, const grpc::string& value); /// IsCancelled is always safe to call when using sync or callback API. From d5905834569d2d3c53e80722e4389cf03d689132 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 18 Dec 2018 12:10:20 -0800 Subject: [PATCH 350/534] Allow interceptor creators to return nullptr --- include/grpcpp/impl/codegen/client_interceptor.h | 15 +++++++++++++-- include/grpcpp/impl/codegen/server_interceptor.h | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index 2bae11a2516..da75bde499d 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -38,9 +38,17 @@ class InterceptorBatchMethodsImpl; namespace experimental { class ClientRpcInfo; +// A factory interface for creation of client interceptors. A vector of +// factories can be provided at channel creation which will be used to create a +// new vector of client interceptors per RPC. Client interceptor authors should +// create a subclass of ClientInterceptorFactorInterface which creates objects +// of their interceptors. class ClientInterceptorFactoryInterface { public: virtual ~ClientInterceptorFactoryInterface() {} + // Returns a pointer to an Interceptor object on successful creation, nullptr + // otherwise. If nullptr is returned, this server interceptor factory is + // ignored for the purposes of that RPC. virtual Interceptor* CreateClientInterceptor(ClientRpcInfo* info) = 0; }; } // namespace experimental @@ -120,8 +128,11 @@ class ClientRpcInfo { } for (auto it = creators.begin() + interceptor_pos; it != creators.end(); ++it) { - interceptors_.push_back(std::unique_ptr( - (*it)->CreateClientInterceptor(this))); + auto* interceptor = (*it)->CreateClientInterceptor(this); + if (interceptor != nullptr) { + interceptors_.push_back( + std::unique_ptr(interceptor)); + } } if (internal::g_global_client_interceptor_factory != nullptr) { interceptors_.push_back(std::unique_ptr( diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index afc3c198ccf..8652ec5c649 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -37,9 +37,17 @@ class InterceptorBatchMethodsImpl; namespace experimental { class ServerRpcInfo; +// A factory interface for creation of server interceptors. A vector of +// factories can be provided to ServerBuilder which will be used to create a new +// vector of server interceptors per RPC. Server interceptor authors should +// create a subclass of ServerInterceptorFactorInterface which creates objects +// of their interceptors. class ServerInterceptorFactoryInterface { public: virtual ~ServerInterceptorFactoryInterface() {} + // Returns a pointer to an Interceptor object on successful creation, nullptr + // otherwise. If nullptr is returned, this server interceptor factory is + // ignored for the purposes of that RPC. virtual Interceptor* CreateServerInterceptor(ServerRpcInfo* info) = 0; }; @@ -90,8 +98,11 @@ class ServerRpcInfo { std::unique_ptr>& creators) { for (const auto& creator : creators) { - interceptors_.push_back(std::unique_ptr( - creator->CreateServerInterceptor(this))); + auto* interceptor = creator->CreateServerInterceptor(this); + if (interceptor != nullptr) { + interceptors_.push_back( + std::unique_ptr(interceptor)); + } } } From 75077243de21f13889e32c77fdb5d94ba59c392e Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Tue, 18 Dec 2018 12:30:30 -0800 Subject: [PATCH 351/534] Add 1.17.1 to interop --- tools/interop_matrix/client_matrix.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 931beddb9cf..c0b08a59b26 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -104,6 +104,9 @@ LANG_RELEASE_MATRIX = { { 'v1.16.0': None }, + { + 'v1.17.1': None + }, ], 'go': [ { @@ -260,6 +263,9 @@ LANG_RELEASE_MATRIX = { { 'v1.16.0': None }, + { + 'v1.17.1': None + }, ], 'node': [ { @@ -354,6 +360,9 @@ LANG_RELEASE_MATRIX = { { 'v1.16.0': None }, + { + 'v1.17.1': None + }, ], 'php': [ { @@ -404,6 +413,9 @@ LANG_RELEASE_MATRIX = { { 'v1.16.0': None }, + { + 'v1.17.1': None + }, ], 'csharp': [ { @@ -459,6 +471,9 @@ LANG_RELEASE_MATRIX = { { 'v1.16.0': None }, + { + 'v1.17.1': None + }, ], } From a20263f64de839e4981ac3e05df328081438e453 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 18 Dec 2018 12:41:49 -0800 Subject: [PATCH 352/534] Add tests using NullInterceptorFactory --- .../client_interceptors_end2end_test.cc | 22 +++++++++++++++++++ test/cpp/end2end/interceptors_util.h | 16 ++++++++++++++ .../server_interceptors_end2end_test.cc | 3 +++ 3 files changed, 41 insertions(+) diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 968b5d49d10..033268a73d9 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -467,6 +467,28 @@ TEST_F(ClientInterceptorsEnd2endTest, EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } +TEST_F(ClientInterceptorsEnd2endTest, + ClientInterceptorFactoryAllowsNullptrReturn) { + ChannelArguments args; + DummyInterceptor::Reset(); + std::vector> + creators; + creators.push_back(std::unique_ptr( + new LoggingInterceptorFactory())); + // Add 20 dummy interceptors and 20 null interceptors + for (auto i = 0; i < 20; i++) { + creators.push_back(std::unique_ptr( + new DummyInterceptorFactory())); + creators.push_back( + std::unique_ptr(new NullInterceptorFactory())); + } + auto channel = server_->experimental().InProcessChannelWithInterceptors( + args, std::move(creators)); + MakeCallbackCall(channel); + // Make sure all 20 dummy interceptors were run + EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); +} + class ClientInterceptorsStreamingEnd2endTest : public ::testing::Test { protected: ClientInterceptorsStreamingEnd2endTest() { diff --git a/test/cpp/end2end/interceptors_util.h b/test/cpp/end2end/interceptors_util.h index d886e32494c..659e613d2eb 100644 --- a/test/cpp/end2end/interceptors_util.h +++ b/test/cpp/end2end/interceptors_util.h @@ -82,6 +82,22 @@ class DummyInterceptorFactory } }; +/* This interceptor factory returns nullptr on interceptor creation */ +class NullInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface, + public experimental::ServerInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return nullptr; + } + + virtual experimental::Interceptor* CreateServerInterceptor( + experimental::ServerRpcInfo* info) override { + return nullptr; + } +}; + class EchoTestServiceStreamingImpl : public EchoTestService::Service { public: ~EchoTestServiceStreamingImpl() override {} diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 9460a7d6c64..e837a2cd18e 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -176,9 +176,12 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { creators.push_back( std::unique_ptr( new LoggingInterceptorFactory())); + // Add 20 dummy interceptor factories and null interceptor factories for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); + creators.push_back(std::unique_ptr( + new NullInterceptorFactory())); } builder.experimental().SetInterceptorCreators(std::move(creators)); server_ = builder.BuildAndStart(); From 31a775b425eac37bb43c301cfb25e1f6a4bde106 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 18 Dec 2018 12:52:14 -0800 Subject: [PATCH 353/534] Add missing argument --- include/grpcpp/impl/codegen/call_op_set.h | 3 +-- include/grpcpp/impl/codegen/interceptor_common.h | 1 + test/cpp/end2end/client_interceptors_end2end_test.cc | 8 +++----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 3db9f48bffe..1c0ccbab527 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -340,12 +340,11 @@ class CallOpSendMessage { if (send_buf_.Valid()) { interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_SEND_MESSAGE); - // We had already registered failed_send_ earlier. No need to do it again. } send_buf_.Clear(); // The contents of the SendMessage value that was previously set // has had its references stolen by core's operations - interceptor_methods->SetSendMessage(nullptr); + interceptor_methods->SetSendMessage(nullptr, &failed_send_); } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 321691236be..b01706af8d9 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -403,6 +403,7 @@ class CancelInterceptorBatchMethods false && "It is illegal to call GetSendMessageStatus on a method which " "has a Cancel notification"); + return false; } std::multimap* GetSendInitialMetadata() override { diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 33773e3b3b9..c55eaab4d6f 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -580,11 +580,9 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingHijackingTest) { ChannelArguments args; - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); - creators->push_back( + std::vector> + creators; + creators.push_back( std::unique_ptr( new ClientStreamingRpcHijackingInterceptorFactory())); auto channel = experimental::CreateCustomChannelWithInterceptors( From 1438b17890b56f57b21e49bc7bcd4e5d589425cc Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 18 Dec 2018 14:14:42 -0800 Subject: [PATCH 354/534] Fix bug that was breaking subchannel reuse in grpclb. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 18 ++++---- test/cpp/end2end/grpclb_end2end_test.cc | 41 +++++++++++++++++++ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index a9a5965ed1c..49a1b2d6921 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -361,7 +361,9 @@ void lb_token_destroy(void* token) { } } int lb_token_cmp(void* token1, void* token2) { - return GPR_ICMP(token1, token2); + // Always indicate a match, since we don't want this channel arg to + // affect the subchannel's key in the index. + return 0; } const grpc_arg_pointer_vtable lb_token_arg_vtable = { lb_token_copy, lb_token_destroy, lb_token_cmp}; @@ -422,7 +424,7 @@ ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { grpc_resolved_address addr; ParseServer(server, &addr); // LB token processing. - void* lb_token; + grpc_mdelem lb_token; if (server->has_load_balance_token) { const size_t lb_token_max_length = GPR_ARRAY_SIZE(server->load_balance_token); @@ -430,9 +432,7 @@ ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { strnlen(server->load_balance_token, lb_token_max_length); grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( server->load_balance_token, lb_token_length); - lb_token = - (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr) - .payload; + lb_token = grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr); } else { char* uri = grpc_sockaddr_to_uri(&addr); gpr_log(GPR_INFO, @@ -440,14 +440,16 @@ ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { "be used instead", uri); gpr_free(uri); - lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; + lb_token = GRPC_MDELEM_LB_TOKEN_EMPTY; } // Add address. grpc_arg arg = grpc_channel_arg_pointer_create( - const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token, - &lb_token_arg_vtable); + const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), + (void*)lb_token.payload, &lb_token_arg_vtable); grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); addresses.emplace_back(addr, args); + // Clean up. + GRPC_MDELEM_UNREF(lb_token); } return addresses; } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 2eaacd429de..f739ed032bb 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -145,6 +146,7 @@ class BackendServiceImpl : public BackendService { IncreaseRequestCount(); const auto status = TestServiceImpl::Echo(context, request, response); IncreaseResponseCount(); + AddClient(context->peer()); return status; } @@ -157,9 +159,21 @@ class BackendServiceImpl : public BackendService { return prev; } + std::set clients() { + std::unique_lock lock(clients_mu_); + return clients_; + } + private: + void AddClient(const grpc::string& client) { + std::unique_lock lock(clients_mu_); + clients_.insert(client); + } + std::mutex mu_; bool shutdown_ = false; + std::mutex clients_mu_; + std::set clients_; }; grpc::string Ip4ToPackedString(const char* ip_str) { @@ -303,6 +317,11 @@ class BalancerServiceImpl : public BalancerService { auto* server = response.mutable_server_list()->add_servers(); server->set_ip_address(Ip4ToPackedString("127.0.0.1")); server->set_port(backend_port); + static int token_count = 0; + char* token; + gpr_asprintf(&token, "token%03d", ++token_count); + server->set_load_balance_token(token); + gpr_free(token); } return response; } @@ -675,6 +694,28 @@ TEST_F(SingleBalancerTest, Vanilla) { EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } +TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { + SetNextResolutionAllBalancers(); + // Same backend listed twice. + std::vector ports; + ports.push_back(backend_servers_[0].port_); + ports.push_back(backend_servers_[0].port_); + const size_t kNumRpcsPerAddress = 10; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(ports, {}), 0); + // We need to wait for the backend to come online. + WaitForBackend(0); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * ports.size()); + // Backend should have gotten 20 requests. + EXPECT_EQ(kNumRpcsPerAddress * 2, + backend_servers_[0].service_->request_count()); + // And they should have come from a single client port, because of + // subchannel sharing. + EXPECT_EQ(1UL, backends_[0]->clients().size()); + balancers_[0]->NotifyDoneWithServerlists(); +} + TEST_F(SingleBalancerTest, SecureNaming) { ResetStub(0, kApplicationTargetName_ + ";lb"); SetNextResolution({AddressData{balancer_servers_[0].port_, true, "lb"}}); From 886a932a1a09a567bd790ea949d9ccc9df86cdba Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 18 Dec 2018 14:24:58 -0800 Subject: [PATCH 355/534] Use KOKORO_GITHUB_PULL_REQUEST_NUMBER instead of ghprbPullId --- tools/run_tests/python_utils/check_on_pr.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index d59f99b2520..3f335c8ea93 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -71,8 +71,9 @@ def _call(url, method='GET', json=None): def _latest_commit(): - resp = _call('/repos/%s/pulls/%s/commits' % (_GITHUB_REPO, - os.environ['ghprbPullId'])) + resp = _call('/repos/%s/pulls/%s/commits' % + (_GITHUB_REPO, + os.environ['KOKORO_GITHUB_PULL_REQUEST_NUMBER'])) return resp.json()[-1] @@ -82,7 +83,7 @@ def check_on_pr(name, summary, success=True): The check runs are aggregated by their name, so newer check will update the older check with the same name. - Requires environment variable 'ghprbPullId' to indicate which pull request + Requires environment variable 'KOKORO_GITHUB_PULL_REQUEST_NUMBER' to indicate which pull request should be updated. Args: @@ -96,8 +97,8 @@ def check_on_pr(name, summary, success=True): if 'KOKORO_KEYSTORE_DIR' not in os.environ: print('Missing KOKORO_KEYSTORE_DIR env var: not checking') return - if 'ghprbPullId' not in os.environ: - print('Missing ghprbPullId env var: not checking') + if 'KOKORO_GITHUB_PULL_REQUEST_NUMBER' not in os.environ: + print('Missing KOKORO_GITHUB_PULL_REQUEST_NUMBER env var: not checking') return completion_time = str( datetime.datetime.utcnow().replace(microsecond=0).isoformat()) + 'Z' From d79b3fe3207f7bd064d584c6e15517680749e2d5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 18 Dec 2018 14:28:36 -0800 Subject: [PATCH 356/534] Fix test --- src/objective-c/tests/GRPCClientTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index b16720557f7..3ef046835e4 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -365,7 +365,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; GRXWriter *writer = [GRXWriter writerWithValue:[NSData data]]; // Try to set parameters to nil for GRPCCall. This should cause an exception @try { - (void)[[GRPCCall alloc] initWithHost:@"" path:@"" requestsWriter:writer]; + (void)[[GRPCCall alloc] initWithHost:nil path:nil requestsWriter:writer]; XCTFail(@"Did not receive an exception when parameters are nil"); } @catch (NSException *theException) { NSLog(@"Received exception as expected: %@", theException.name); From cfe08f35f30d272a8f2e851fb9e069498b264f5f Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 18 Dec 2018 12:52:26 -0800 Subject: [PATCH 357/534] Add comments explaining purpose and validity of interception API --- .../grpcpp/impl/codegen/client_interceptor.h | 15 ++ include/grpcpp/impl/codegen/interceptor.h | 130 ++++++++++++------ .../grpcpp/impl/codegen/server_interceptor.h | 14 ++ 3 files changed, 115 insertions(+), 44 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index 2bae11a2516..2eca596f1dc 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -50,11 +50,16 @@ extern experimental::ClientInterceptorFactoryInterface* g_global_client_interceptor_factory; } +/// ClientRpcInfo represents the state of a particular RPC as it +/// appears to an interceptor. It is created and owned by the library and +/// passed to the CreateClientInterceptor method of the application's +/// ClientInterceptorFactoryInterface implementation namespace experimental { class ClientRpcInfo { public: // TODO(yashykt): Stop default-constructing ClientRpcInfo and remove UNKNOWN // from the list of possible Types. + /// Type categorizes RPCs by unary or streaming type enum class Type { UNARY, CLIENT_STREAMING, @@ -65,13 +70,23 @@ class ClientRpcInfo { ~ClientRpcInfo(){}; + // Delete copy constructor but allow default move constructor ClientRpcInfo(const ClientRpcInfo&) = delete; ClientRpcInfo(ClientRpcInfo&&) = default; // Getter methods + + /// Return the fully-specified method name const char* method() const { return method_; } + + /// Return a pointer to the channel on which the RPC is being sent ChannelInterface* channel() { return channel_; } + + /// Return a pointer to the underlying ClientContext structure associated + /// with the RPC to support features that apply to it grpc::ClientContext* client_context() { return ctx_; } + + /// Return the type of the RPC (unary or a streaming flavor) Type type() const { return type_; } private: diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index e449e44a23b..46175cd73b8 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -31,99 +31,141 @@ class ChannelInterface; class Status; namespace experimental { -class InterceptedMessage { - public: - template - bool Extract(M* msg); // returns false if definitely invalid extraction - template - M* MutableExtract(); - uint64_t length(); // length on wire -}; +/// An enumeration of different possible points at which the \a Intercept +/// method of the \a Interceptor interface may be called. Any given call +/// to \a Intercept will include one or more of these hook points, and +/// each hook point makes certain types of information available to the +/// interceptor. +/// In these enumeration names, PRE_SEND means that an interception has taken +/// place between the time the application provided a certain type of data +/// (e.g., initial metadata, status) and the time that that data goes to the +/// other side. POST_SEND means that the data has been committed for going to +/// the other side (even if it has not yet been received at the other side). +/// PRE_RECV means an interception between the time that a certain +/// operation has been requested and it is available. POST_RECV means that a +/// result is available but has not yet been passed back to the application. enum class InterceptionHookPoints { - /* The first two in this list are for clients and servers */ + /// The first two in this list are for clients and servers PRE_SEND_INITIAL_METADATA, PRE_SEND_MESSAGE, - PRE_SEND_STATUS /* server only */, - PRE_SEND_CLOSE /* client only */, - /* The following three are for hijacked clients only and can only be - registered by the global interceptor */ + PRE_SEND_STATUS, // server only + PRE_SEND_CLOSE, // client only: WritesDone for stream; after write in unary + /// The following three are for hijacked clients only and can only be + /// registered by the global interceptor PRE_RECV_INITIAL_METADATA, PRE_RECV_MESSAGE, PRE_RECV_STATUS, - /* The following two are for all clients and servers */ + /// The following two are for all clients and servers POST_RECV_INITIAL_METADATA, POST_RECV_MESSAGE, - POST_RECV_STATUS /* client only */, - POST_RECV_CLOSE /* server only */, - /* This is a special hook point available to both clients and servers when - TryCancel() is performed. - - No other hook points will be present along with this. - - It is illegal for an interceptor to block/delay this operation. - - ALL interceptors see this hook point irrespective of whether the RPC was - hijacked or not. */ + POST_RECV_STATUS, // client only + POST_RECV_CLOSE, // server only + /// This is a special hook point available to both clients and servers when + /// TryCancel() is performed. + /// - No other hook points will be present along with this. + /// - It is illegal for an interceptor to block/delay this operation. + /// - ALL interceptors see this hook point irrespective of whether the + /// RPC was hijacked or not. PRE_SEND_CANCEL, NUM_INTERCEPTION_HOOKS }; +/// Class that is passed as an argument to the \a Intercept method +/// of the application's \a Interceptor interface implementation. It has five +/// purposes: +/// 1. Indicate which hook points are present at a specific interception +/// 2. Allow an interceptor to inform the library that an RPC should +/// continue to the next stage of its processing (which may be another +/// interceptor or the main path of the library) +/// 3. Allow an interceptor to hijack the processing of the RPC (only for +/// client-side RPCs with PRE_SEND_INITIAL_METADATA) so that it does not +/// proceed with normal processing beyond that stage +/// 4. Access the relevant fields of an RPC at each interception point +/// 5. Set some fields of an RPC at each interception point, when possible class InterceptorBatchMethods { public: virtual ~InterceptorBatchMethods(){}; - // Queries to check whether the current batch has an interception hook point - // of type \a type + /// Determine whether the current batch has an interception hook point + /// of type \a type virtual bool QueryInterceptionHookPoint(InterceptionHookPoints type) = 0; - // Calling this will signal that the interceptor is done intercepting the - // current batch of the RPC. - // Proceed is a no-op if the batch contains PRE_SEND_CANCEL. Simply returning - // from the Intercept method does the job of continuing the RPC in this case. + /// Signal that the interceptor is done intercepting the current batch of the + /// RPC. Every interceptor must either call Proceed or Hijack on each + /// interception. In most cases, only Proceed will be used. Explicit use of + /// Proceed is what enables interceptors to delay the processing of RPCs + /// while they perform other work. + /// Proceed is a no-op if the batch contains PRE_SEND_CANCEL. Simply returning + /// from the Intercept method does the job of continuing the RPC in this case. + /// This is because PRE_SEND_CANCEL is always in a separate batch and is not + /// allowed to be delayed. virtual void Proceed() = 0; - // Calling this indicates that the interceptor has hijacked the RPC (only - // valid if the batch contains send_initial_metadata on the client side) + /// Indicate that the interceptor has hijacked the RPC (only valid if the + /// batch contains send_initial_metadata on the client side). Later + /// interceptors in the interceptor list will not be called. Later batches + /// on the same RPC will go through interception, but only up to the point + /// of the hijacking interceptor. virtual void Hijack() = 0; - // Returns a modifable ByteBuffer holding serialized form of the message to be - // sent + /// Returns a modifable ByteBuffer holding the serialized form of the message + /// that is going to be sent. Valid for PRE_SEND_MESSAGE interceptions. + /// A return value of nullptr indicates that this ByteBuffer is not valid. virtual ByteBuffer* GetSendMessage() = 0; - // Returns a modifiable multimap of the initial metadata to be sent + /// Returns a modifiable multimap of the initial metadata to be sent. Valid + /// for PRE_SEND_INITIAL_METADATA interceptions. A value of nullptr indicates + /// that this field is not valid. virtual std::multimap* GetSendInitialMetadata() = 0; - // Returns the status to be sent + /// Returns the status to be sent. Valid for PRE_SEND_STATUS interceptions. virtual Status GetSendStatus() = 0; - // Modifies the status with \a status + /// Overwrites the status with \a status. Valid for PRE_SEND_STATUS + /// interceptions. virtual void ModifySendStatus(const Status& status) = 0; - // Returns a modifiable multimap of the trailing metadata to be sent + /// Returns a modifiable multimap of the trailing metadata to be sent. Valid + /// for PRE_SEND_STATUS interceptions. A value of nullptr indicates + /// that this field is not valid. virtual std::multimap* GetSendTrailingMetadata() = 0; - // Returns a pointer to the modifiable received message. Note that the message - // is already deserialized + /// Returns a pointer to the modifiable received message. Note that the + /// message is already deserialized but the type is not set; the interceptor + /// should static_cast to the appropriate type before using it. This is valid + /// for POST_RECV_MESSAGE interceptions; nullptr for not valid virtual void* GetRecvMessage() = 0; - // Returns a modifiable multimap of the received initial metadata + /// Returns a modifiable multimap of the received initial metadata. + /// Valid for POST_RECV_INITIAL_METADATA interceptions; nullptr if not valid virtual std::multimap* GetRecvInitialMetadata() = 0; - // Returns a modifiable view of the received status + /// Returns a modifiable view of the received status on POST_RECV_STATUS + /// interceptions; nullptr if not valid. virtual Status* GetRecvStatus() = 0; - // Returns a modifiable multimap of the received trailing metadata + /// Returns a modifiable multimap of the received trailing metadata on + /// POST_RECV_STATUS interceptions; nullptr if not valid virtual std::multimap* GetRecvTrailingMetadata() = 0; - // Gets an intercepted channel. When a call is started on this interceptor, - // only interceptors after the current interceptor are created from the - // factory objects registered with the channel. + /// Gets an intercepted channel. When a call is started on this interceptor, + /// only interceptors after the current interceptor are created from the + /// factory objects registered with the channel. This allows calls to be + /// started from interceptors without infinite regress through the interceptor + /// list. virtual std::unique_ptr GetInterceptedChannel() = 0; }; +/// Interface for an interceptor. Interceptor authors must create a class +/// that derives from this parent class. class Interceptor { public: virtual ~Interceptor() {} + /// The one public method of an Interceptor interface. Override this to + /// trigger the desired actions at the hook points described above. virtual void Intercept(InterceptorBatchMethods* methods) = 0; }; diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index afc3c198ccf..6664d09e4ac 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -43,19 +43,33 @@ class ServerInterceptorFactoryInterface { virtual Interceptor* CreateServerInterceptor(ServerRpcInfo* info) = 0; }; +/// ServerRpcInfo represents the state of a particular RPC as it +/// appears to an interceptor. It is created and owned by the library and +/// passed to the CreateServerInterceptor method of the application's +/// ServerInterceptorFactoryInterface implementation class ServerRpcInfo { public: + /// Type categorizes RPCs by unary or streaming type enum class Type { UNARY, CLIENT_STREAMING, SERVER_STREAMING, BIDI_STREAMING }; ~ServerRpcInfo(){}; + // Delete all copy and move constructors and assignments ServerRpcInfo(const ServerRpcInfo&) = delete; + ServerRpcInfo& operator=(const ServerRpcInfo&) = delete; ServerRpcInfo(ServerRpcInfo&&) = delete; ServerRpcInfo& operator=(ServerRpcInfo&&) = delete; // Getter methods + + /// Return the fully-specified method name const char* method() const { return method_; } + + /// Return the type of the RPC (unary or a streaming flavor) Type type() const { return type_; } + + /// Return a pointer to the underlying ServerContext structure associated + /// with the RPC to support features that apply to it grpc::ServerContext* server_context() { return ctx_; } private: From 09a173b4b612d1cb27d82490d83dd95e0aece203 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 18 Dec 2018 12:51:48 -0800 Subject: [PATCH 358/534] Remove now-unnecessary workarounds for alignment issues. --- .../ext/filters/client_channel/lb_policy.h | 6 -- .../composite/composite_credentials.cc | 61 ++++--------------- .../composite/composite_credentials.h | 43 +++---------- test/core/security/credentials_test.cc | 22 +++---- 4 files changed, 29 insertions(+), 103 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 6b76fe5d5d7..29b8c28be6a 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -205,12 +205,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_pollset_set* interested_parties_; /// Callback to force a re-resolution. grpc_closure* request_reresolution_; - - // Dummy classes needed for alignment issues. - // See https://github.com/grpc/grpc/issues/16032 for context. - // TODO(ncteisen): remove this as soon as the issue is resolved. - channelz::ChildRefsList dummy_list_foo; - channelz::ChildRefsList dummy_list_bar; }; } // namespace grpc_core diff --git a/src/core/lib/security/credentials/composite/composite_credentials.cc b/src/core/lib/security/credentials/composite/composite_credentials.cc index 85dcd4693bc..586bbed778e 100644 --- a/src/core/lib/security/credentials/composite/composite_credentials.cc +++ b/src/core/lib/security/credentials/composite/composite_credentials.cc @@ -35,44 +35,6 @@ static void composite_call_metadata_cb(void* arg, grpc_error* error); -grpc_call_credentials_array::~grpc_call_credentials_array() { - for (size_t i = 0; i < num_creds_; ++i) { - creds_array_[i].~RefCountedPtr(); - } - if (creds_array_ != nullptr) { - gpr_free(creds_array_); - } -} - -grpc_call_credentials_array::grpc_call_credentials_array( - const grpc_call_credentials_array& that) - : num_creds_(that.num_creds_) { - reserve(that.capacity_); - for (size_t i = 0; i < num_creds_; ++i) { - new (&creds_array_[i]) - grpc_core::RefCountedPtr(that.creds_array_[i]); - } -} - -void grpc_call_credentials_array::reserve(size_t capacity) { - if (capacity_ >= capacity) { - return; - } - grpc_core::RefCountedPtr* new_arr = - static_cast*>(gpr_malloc( - sizeof(grpc_core::RefCountedPtr) * capacity)); - if (creds_array_ != nullptr) { - for (size_t i = 0; i < num_creds_; ++i) { - new (&new_arr[i]) grpc_core::RefCountedPtr( - std::move(creds_array_[i])); - creds_array_[i].~RefCountedPtr(); - } - gpr_free(creds_array_); - } - creds_array_ = new_arr; - capacity_ = capacity; -} - namespace { struct grpc_composite_call_credentials_metadata_context { grpc_composite_call_credentials_metadata_context( @@ -103,13 +65,13 @@ static void composite_call_metadata_cb(void* arg, grpc_error* error) { grpc_composite_call_credentials_metadata_context* ctx = static_cast(arg); if (error == GRPC_ERROR_NONE) { - const grpc_call_credentials_array& inner = ctx->composite_creds->inner(); + const grpc_composite_call_credentials::CallCredentialsList& inner = + ctx->composite_creds->inner(); /* See if we need to get some more metadata. */ if (ctx->creds_index < inner.size()) { - if (inner.get(ctx->creds_index++) - ->get_request_metadata( - ctx->pollent, ctx->auth_md_context, ctx->md_array, - &ctx->internal_on_request_metadata, &error)) { + if (inner[ctx->creds_index++]->get_request_metadata( + ctx->pollent, ctx->auth_md_context, ctx->md_array, + &ctx->internal_on_request_metadata, &error)) { // Synchronous response, so call ourselves recursively. composite_call_metadata_cb(arg, error); GRPC_ERROR_UNREF(error); @@ -130,12 +92,11 @@ bool grpc_composite_call_credentials::get_request_metadata( ctx = grpc_core::New( this, pollent, auth_md_context, md_array, on_request_metadata); bool synchronous = true; - const grpc_call_credentials_array& inner = ctx->composite_creds->inner(); + const CallCredentialsList& inner = ctx->composite_creds->inner(); while (ctx->creds_index < inner.size()) { - if (inner.get(ctx->creds_index++) - ->get_request_metadata(ctx->pollent, ctx->auth_md_context, - ctx->md_array, - &ctx->internal_on_request_metadata, error)) { + if (inner[ctx->creds_index++]->get_request_metadata( + ctx->pollent, ctx->auth_md_context, ctx->md_array, + &ctx->internal_on_request_metadata, error)) { if (*error != GRPC_ERROR_NONE) break; } else { synchronous = false; // Async return. @@ -149,7 +110,7 @@ bool grpc_composite_call_credentials::get_request_metadata( void grpc_composite_call_credentials::cancel_get_request_metadata( grpc_credentials_mdelem_array* md_array, grpc_error* error) { for (size_t i = 0; i < inner_.size(); ++i) { - inner_.get(i)->cancel_get_request_metadata(md_array, GRPC_ERROR_REF(error)); + inner_[i]->cancel_get_request_metadata(md_array, GRPC_ERROR_REF(error)); } GRPC_ERROR_UNREF(error); } @@ -172,7 +133,7 @@ void grpc_composite_call_credentials::push_to_inner( auto composite_creds = static_cast(creds.get()); for (size_t i = 0; i < composite_creds->inner().size(); ++i) { - inner_.push_back(std::move(composite_creds->inner_.get_mutable(i))); + inner_.push_back(std::move(composite_creds->inner_[i])); } } diff --git a/src/core/lib/security/credentials/composite/composite_credentials.h b/src/core/lib/security/credentials/composite/composite_credentials.h index 6b7fca13708..7a1c7d5e42b 100644 --- a/src/core/lib/security/credentials/composite/composite_credentials.h +++ b/src/core/lib/security/credentials/composite/composite_credentials.h @@ -21,43 +21,10 @@ #include +#include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/credentials/credentials.h" -// TODO(soheil): Replace this with InlinedVector once #16032 is resolved. -class grpc_call_credentials_array { - public: - grpc_call_credentials_array() = default; - grpc_call_credentials_array(const grpc_call_credentials_array& that); - - ~grpc_call_credentials_array(); - - void reserve(size_t capacity); - - // Must reserve before pushing any data. - void push_back(grpc_core::RefCountedPtr cred) { - GPR_DEBUG_ASSERT(capacity_ > num_creds_); - new (&creds_array_[num_creds_++]) - grpc_core::RefCountedPtr(std::move(cred)); - } - - const grpc_core::RefCountedPtr& get(size_t i) const { - GPR_DEBUG_ASSERT(i < num_creds_); - return creds_array_[i]; - } - grpc_core::RefCountedPtr& get_mutable(size_t i) { - GPR_DEBUG_ASSERT(i < num_creds_); - return creds_array_[i]; - } - - size_t size() const { return num_creds_; } - - private: - grpc_core::RefCountedPtr* creds_array_ = nullptr; - size_t num_creds_ = 0; - size_t capacity_ = 0; -}; - /* -- Composite channel credentials. -- */ class grpc_composite_channel_credentials : public grpc_channel_credentials { @@ -97,6 +64,10 @@ class grpc_composite_channel_credentials : public grpc_channel_credentials { class grpc_composite_call_credentials : public grpc_call_credentials { public: + using CallCredentialsList = + grpc_core::InlinedVector, + 2>; + grpc_composite_call_credentials( grpc_core::RefCountedPtr creds1, grpc_core::RefCountedPtr creds2); @@ -111,13 +82,13 @@ class grpc_composite_call_credentials : public grpc_call_credentials { void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, grpc_error* error) override; - const grpc_call_credentials_array& inner() const { return inner_; } + const CallCredentialsList& inner() const { return inner_; } private: void push_to_inner(grpc_core::RefCountedPtr creds, bool is_composite); - grpc_call_credentials_array inner_; + CallCredentialsList inner_; }; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_COMPOSITE_COMPOSITE_CREDENTIALS_H \ diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index b3a81617865..b6555353359 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -465,14 +465,14 @@ static void test_oauth2_google_iam_composite_creds(void) { google_iam_creds->Unref(); GPR_ASSERT(strcmp(composite_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); - const grpc_call_credentials_array& creds_array = + const grpc_composite_call_credentials::CallCredentialsList& creds_list = static_cast(composite_creds) ->inner(); - GPR_ASSERT(creds_array.size() == 2); - GPR_ASSERT(strcmp(creds_array.get(0)->type(), - GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - GPR_ASSERT( - strcmp(creds_array.get(1)->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); + GPR_ASSERT(creds_list.size() == 2); + GPR_ASSERT(strcmp(creds_list[0]->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == + 0); + GPR_ASSERT(strcmp(creds_list[1]->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) == + 0); run_request_metadata_test(composite_creds, auth_md_ctx, state); composite_creds->Unref(); } @@ -492,13 +492,13 @@ class check_channel_oauth2_google_iam final : public grpc_channel_credentials { GPR_ASSERT(call_creds != nullptr); GPR_ASSERT( strcmp(call_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); - const grpc_call_credentials_array& creds_array = + const grpc_composite_call_credentials::CallCredentialsList& creds_list = static_cast(call_creds.get()) ->inner(); - GPR_ASSERT(strcmp(creds_array.get(0)->type(), - GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - GPR_ASSERT(strcmp(creds_array.get(1)->type(), - GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); + GPR_ASSERT( + strcmp(creds_list[0]->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); + GPR_ASSERT(strcmp(creds_list[1]->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) == + 0); return nullptr; } }; From 82797771679c93045876f48707c5cb46bfae4f53 Mon Sep 17 00:00:00 2001 From: easy Date: Wed, 19 Dec 2018 12:22:38 +1100 Subject: [PATCH 359/534] Destruct CensusContext to avoid leaking memory. Otherwise, the placement-new leaks context -> span_ -> impl_ which is a std::shared_ptr. --- src/cpp/ext/filters/census/context.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cpp/ext/filters/census/context.cc b/src/cpp/ext/filters/census/context.cc index 78fc69a8054..160590353a7 100644 --- a/src/cpp/ext/filters/census/context.cc +++ b/src/cpp/ext/filters/census/context.cc @@ -28,6 +28,9 @@ using ::opencensus::trace::SpanContext; void GenerateServerContext(absl::string_view tracing, absl::string_view stats, absl::string_view primary_role, absl::string_view method, CensusContext* context) { + // Destruct the current CensusContext to free the Span memory before + // overwriting it below. + context->~CensusContext(); GrpcTraceContext trace_ctxt; if (TraceContextEncoding::Decode(tracing, &trace_ctxt) != TraceContextEncoding::kEncodeDecodeFailure) { @@ -42,6 +45,9 @@ void GenerateServerContext(absl::string_view tracing, absl::string_view stats, void GenerateClientContext(absl::string_view method, CensusContext* ctxt, CensusContext* parent_ctxt) { + // Destruct the current CensusContext to free the Span memory before + // overwriting it below. + ctxt->~CensusContext(); if (parent_ctxt != nullptr) { SpanContext span_ctxt = parent_ctxt->Context(); Span span = parent_ctxt->Span(); From 3f57e3451bf4a3687e70e92fc218ea25ff7a17c9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 08:09:12 -0800 Subject: [PATCH 360/534] Try earlier APIv2Tests --- src/objective-c/tests/run_tests.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index f075d9baadd..aab80ded61b 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -176,7 +176,7 @@ xcodebuild \ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ - -scheme ChannelTests \ + -scheme APIv2Tests \ -destination name="iPhone 8" \ test \ | egrep -v "$XCODEBUILD_FILTER" \ @@ -186,11 +186,12 @@ xcodebuild \ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ - -scheme APIv2Tests \ - -destination name="iPhone X" \ + -scheme ChannelTests \ + -destination name="iPhone 8" \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ | egrep -v "(GPBDictionary|GPBArray)" - + exit 0 From 6211f4589b47620440ea60c614116398a7a1ab43 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 19 Dec 2018 08:34:13 -0800 Subject: [PATCH 361/534] removed unused traceback import --- src/python/grpcio_tests/commands.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 18413abab02..496bcfbcbff 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -22,7 +22,6 @@ import re import shutil import subprocess import sys -import traceback import setuptools from setuptools.command import build_ext From 25e73664136ea01e2b8a64149a97e782c57d9f7d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 09:16:26 -0800 Subject: [PATCH 362/534] Revert "Rename getTokenWithHandler" Since the renamed protocol is breaking people and is not general enough, we revert the rename and leave the work to interceptor This reverts commit 92db5fc72488f9d62b81ee311a79832df787f3ef. --- src/objective-c/GRPCClient/GRPCCall.m | 14 ++------------ src/objective-c/GRPCClient/GRPCCallOptions.h | 12 +----------- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 2 +- 4 files changed, 5 insertions(+), 25 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 39e4967ec98..9bcacac0dfc 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -885,7 +885,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(self) { self.isWaitingForToken = YES; } - void (^tokenHandler)(NSString *token) = ^(NSString *token) { + [_callOptions.authTokenProvider getTokenWithHandler:^(NSString *token) { @synchronized(self) { if (self.isWaitingForToken) { if (token) { @@ -895,17 +895,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; self.isWaitingForToken = NO; } } - }; - id authTokenProvider = _callOptions.authTokenProvider; - if ([authTokenProvider respondsToSelector:@selector(provideTokenToHandler:)]) { - [_callOptions.authTokenProvider provideTokenToHandler:tokenHandler]; - } else { - NSAssert([authTokenProvider respondsToSelector:@selector(getTokenWithHandler:)], - @"authTokenProvider has no usable method"); - if ([authTokenProvider respondsToSelector:@selector(getTokenWithHandler:)]) { - [_callOptions.authTokenProvider getTokenWithHandler:tokenHandler]; - } - } + }]; } else { [self startCallWithWriteable:writeable]; } diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index b866f268ee1..b5bf4c9eb6c 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -60,22 +60,12 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Implement this protocol to provide a token to gRPC when a call is initiated. */ -@protocol GRPCAuthorizationProtocol - -@optional +@protocol GRPCAuthorizationProtocol /** * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)provideTokenToHandler:(void (^)(NSString *_Nullable token))handler; - -/** - * This method is deprecated. Please use \a provideTokenToHandler. - * - * This method is called when gRPC is about to start the call. When OAuth token is acquired, - * \a handler is expected to be called with \a token being the new token to be used for this call. - */ - (void)getTokenWithHandler:(void (^)(NSString *_Nullable token))handler; @end diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index abf224c3cfd..48a38bd35ac 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -175,7 +175,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)writeMessage:(GPBMessage *)message { - NSAssert([message isKindOfClass:[GPBMessage class]], @"Parameter message must be a GPBMessage"); + NSAssert([message isKindOfClass:[GPBMessage class]]); if (![message isKindOfClass:[GPBMessage class]]) { NSLog(@"Failed to send a message that is non-proto."); return; diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index fd472aafebd..ca7bf472830 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -241,7 +241,7 @@ static const NSTimeInterval kTestTimeout = 16; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } -- (void)provideTokenToHandler:(void (^)(NSString *token))handler { +- (void)getTokenWithHandler:(void (^)(NSString *token))handler { dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); dispatch_sync(queue, ^{ handler(@"test-access-token"); From 72dc62ee2e20919b98939ee2e6337fd63a988f48 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 10:30:54 -0800 Subject: [PATCH 363/534] Revert "Try earlier APIv2Tests" This reverts commit 3f57e3451bf4a3687e70e92fc218ea25ff7a17c9. --- src/objective-c/tests/run_tests.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index aab80ded61b..f075d9baadd 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -176,7 +176,7 @@ xcodebuild \ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ - -scheme APIv2Tests \ + -scheme ChannelTests \ -destination name="iPhone 8" \ test \ | egrep -v "$XCODEBUILD_FILTER" \ @@ -186,12 +186,11 @@ xcodebuild \ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ - -scheme ChannelTests \ - -destination name="iPhone 8" \ + -scheme APIv2Tests \ + -destination name="iPhone X" \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ | egrep -v "(GPBDictionary|GPBArray)" - - exit 0 From 33a4b502c450fa05814992147679d0e77a23d4a5 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 13 Dec 2018 15:55:20 -0800 Subject: [PATCH 364/534] Add LB example --- examples/BUILD | 14 +++ examples/cpp/load_balancing/Makefile | 110 ++++++++++++++++++ examples/cpp/load_balancing/README.md | 64 ++++++++++ examples/cpp/load_balancing/greeter_client.cc | 90 ++++++++++++++ examples/cpp/load_balancing/greeter_server.cc | 72 ++++++++++++ 5 files changed, 350 insertions(+) create mode 100644 examples/cpp/load_balancing/Makefile create mode 100644 examples/cpp/load_balancing/README.md create mode 100644 examples/cpp/load_balancing/greeter_client.cc create mode 100644 examples/cpp/load_balancing/greeter_server.cc diff --git a/examples/BUILD b/examples/BUILD index 0f18cfa9ba7..525e6989ee8 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -51,3 +51,17 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) + +cc_binary( + name = "lb_client", + srcs = ["cpp/load_balancing/greeter_client.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) + +cc_binary( + name = "lb_server", + srcs = ["cpp/load_balancing/greeter_server.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) diff --git a/examples/cpp/load_balancing/Makefile b/examples/cpp/load_balancing/Makefile new file mode 100644 index 00000000000..7c8d0727705 --- /dev/null +++ b/examples/cpp/load_balancing/Makefile @@ -0,0 +1,110 @@ +# +# 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. +# + +HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) +CXX = g++ +CPPFLAGS += `pkg-config --cflags protobuf grpc` +CXXFLAGS += -std=c++11 +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -lgrpc++_reflection\ + -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ + -ldl +endif +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check greeter_client greeter_server + +greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + +greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + +.PRECIOUS: %.grpc.pb.cc +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + +.PRECIOUS: %.pb.cc +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + +clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif \ No newline at end of file diff --git a/examples/cpp/load_balancing/README.md b/examples/cpp/load_balancing/README.md new file mode 100644 index 00000000000..f48aca5307f --- /dev/null +++ b/examples/cpp/load_balancing/README.md @@ -0,0 +1,64 @@ +# gRPC C++ Load Balancing Tutorial + +### Prerequisite +Make sure you have run the [hello world example](../helloworld) or understood the basics of gRPC. We will not dive into the details that have been discussed in the hello world example. + +### Get the tutorial source code + +The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: + + +```sh +$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc +``` + +Change your current directory to examples/cpp/load_balancing + +```sh +$ cd examples/cpp/load_balancing/ +``` + +### Generating gRPC code + +To generate the client and server side interfaces: + +```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` + +### Writing a client and a server + +The client and the server can be based on the hello world example. + +Additionally, we can configure the load balancing policy. (To see what load balancing policies are available, check out [this folder](https://github.com/grpc/grpc/tree/master/src/core/ext/filters/client_channel/lb_policy).) + +In the client, set the load balancing policy of the channel via the channel arg (to, for example, Round Robin). + +```cpp + ChannelArguments args; + // Set the load balancing policy for the channel. + args.SetLoadBalancingPolicyName("round_robin"); + GreeterClient greeter(grpc::CreateCustomChannel( + "localhost:50051", grpc::InsecureChannelCredentials(), args)); +``` + +For a working example, refer to [greeter_client.cc](greeter_client.cc) and [greeter_server.cc](greeter_server.cc). + +Build and run the client and the server with the following commands. + +```sh +make +./greeter_server +``` + +```sh +./greeter_client +``` + +(Note that the case in this example is trivial because there is only one server resolved from the name.) \ No newline at end of file diff --git a/examples/cpp/load_balancing/greeter_client.cc b/examples/cpp/load_balancing/greeter_client.cc new file mode 100644 index 00000000000..5b08204a96b --- /dev/null +++ b/examples/cpp/load_balancing/greeter_client.cc @@ -0,0 +1,90 @@ +/* + * + * Copyright 2015 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + + // The actual RPC. + Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. + if (status.ok()) { + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureChannelCredentials()). + ChannelArguments args; + // Set the load balancing policy for the channel. + args.SetLoadBalancingPolicyName("round_robin"); + GreeterClient greeter(grpc::CreateCustomChannel( + "localhost:50051", grpc::InsecureChannelCredentials(), args)); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + return 0; +} diff --git a/examples/cpp/load_balancing/greeter_server.cc b/examples/cpp/load_balancing/greeter_server.cc new file mode 100644 index 00000000000..f36ad906a29 --- /dev/null +++ b/examples/cpp/load_balancing/greeter_server.cc @@ -0,0 +1,72 @@ +/* + * + * Copyright 2015 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + std::string prefix("Hello "); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} From 92123a4a333719fa3aa55b3db9f36c136e108a47 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 10:42:31 -0800 Subject: [PATCH 365/534] Rebuild APIv2Tests --- .../tests/Tests.xcodeproj/project.pbxproj | 398 +++++++++--------- .../xcschemes/APIv2Tests.xcscheme | 8 +- src/objective-c/tests/run_tests.sh | 2 +- 3 files changed, 208 insertions(+), 200 deletions(-) diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 6f24d3512f8..47b79a05345 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -16,7 +16,7 @@ 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 5E0282E9215AA697007AC99D /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; 5E0282EB215AA697007AC99D /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 5E10F5AA218CB0D2008BAB68 /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */; }; + 5E3B95A521CAC6C500C0A151 /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */; }; 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */; }; 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; @@ -66,10 +66,10 @@ 6C1A3F81CCF7C998B4813EFD /* libPods-InteropTestsCallOptions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */; }; 886717A79EFF774F356798E6 /* libPods-InteropTestsMultipleChannels.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */; }; 91D4B3C85B6D8562F409CB48 /* libPods-InteropTestsLocalSSLCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */; }; + 98478C9F42329DF769A45B6C /* libPods-APIv2Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */; }; BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */; }; C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */; }; CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */; }; - E7F4C80FC8FC667B7447BFE7 /* libPods-APIv2Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */; }; F15EF7852DC70770EFDB1D2C /* libPods-AllTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */; }; /* End PBXBuildFile section */ @@ -212,9 +212,9 @@ 5E0282E6215AA697007AC99D /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E0282E8215AA697007AC99D /* UnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnitTests.m; sourceTree = ""; }; 5E0282EA215AA697007AC99D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = APIv2Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = APIv2Tests.m; sourceTree = ""; }; - 5E10F5AB218CB0D2008BAB68 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5E3B95A221CAC6C500C0A151 /* APIv2Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = APIv2Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = APIv2Tests.m; sourceTree = ""; }; + 5E3B95A621CAC6C500C0A151 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsCallOptions.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsCallOptions.m; sourceTree = ""; }; 5E7D71B6210B9EC9001EA6BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -313,11 +313,11 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5E10F5A4218CB0D1008BAB68 /* Frameworks */ = { + 5E3B959F21CAC6C500C0A151 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E7F4C80FC8FC667B7447BFE7 /* libPods-APIv2Tests.a in Frameworks */, + 98478C9F42329DF769A45B6C /* libPods-APIv2Tests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -561,11 +561,11 @@ path = UnitTests; sourceTree = ""; }; - 5E10F5A8218CB0D1008BAB68 /* APIv2Tests */ = { + 5E3B95A321CAC6C500C0A151 /* APIv2Tests */ = { isa = PBXGroup; children = ( - 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */, - 5E10F5AB218CB0D2008BAB68 /* Info.plist */, + 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */, + 5E3B95A621CAC6C500C0A151 /* Info.plist */, ); path = APIv2Tests; sourceTree = ""; @@ -636,7 +636,7 @@ 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */, 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */, 5E0282E7215AA697007AC99D /* UnitTests */, - 5E10F5A8218CB0D1008BAB68 /* APIv2Tests */, + 5E3B95A321CAC6C500C0A151 /* APIv2Tests */, 635697C81B14FC11007A7283 /* Products */, 51E4650F34F854F41FF053B3 /* Pods */, 136D535E19727099B941D7B1 /* Frameworks */, @@ -662,7 +662,7 @@ 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */, 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */, 5E0282E6215AA697007AC99D /* UnitTests.xctest */, - 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */, + 5E3B95A221CAC6C500C0A151 /* APIv2Tests.xctest */, ); name = Products; sourceTree = ""; @@ -715,15 +715,15 @@ productReference = 5E0282E6215AA697007AC99D /* UnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 5E10F5A6218CB0D1008BAB68 /* APIv2Tests */ = { + 5E3B95A121CAC6C500C0A151 /* APIv2Tests */ = { isa = PBXNativeTarget; - buildConfigurationList = 5E10F5B0218CB0D2008BAB68 /* Build configuration list for PBXNativeTarget "APIv2Tests" */; + buildConfigurationList = 5E3B95A721CAC6C500C0A151 /* Build configuration list for PBXNativeTarget "APIv2Tests" */; buildPhases = ( - 031ADD72298D6C6979CB06DB /* [CP] Check Pods Manifest.lock */, - 5E10F5A3218CB0D1008BAB68 /* Sources */, - 5E10F5A4218CB0D1008BAB68 /* Frameworks */, - 5E10F5A5218CB0D1008BAB68 /* Resources */, - FBB92A8B11C52512E67791E8 /* [CP] Copy Pods Resources */, + EDDD3FA856BCA3443ED36D1E /* [CP] Check Pods Manifest.lock */, + 5E3B959E21CAC6C500C0A151 /* Sources */, + 5E3B959F21CAC6C500C0A151 /* Frameworks */, + 5E3B95A021CAC6C500C0A151 /* Resources */, + C17B826BBD02FDD4A5F355AF /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -731,7 +731,7 @@ ); name = APIv2Tests; productName = APIv2Tests; - productReference = 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */; + productReference = 5E3B95A221CAC6C500C0A151 /* APIv2Tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */ = { @@ -1043,7 +1043,7 @@ CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; }; - 5E10F5A6218CB0D1008BAB68 = { + 5E3B95A121CAC6C500C0A151 = { CreatedOnToolsVersion = 10.0; ProvisioningStyle = Automatic; }; @@ -1128,7 +1128,7 @@ 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */, 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */, 5E0282E5215AA697007AC99D /* UnitTests */, - 5E10F5A6218CB0D1008BAB68 /* APIv2Tests */, + 5E3B95A121CAC6C500C0A151 /* APIv2Tests */, ); }; /* End PBXProject section */ @@ -1141,7 +1141,7 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5E10F5A5218CB0D1008BAB68 /* Resources */ = { + 5E3B95A021CAC6C500C0A151 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -1271,24 +1271,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 031ADD72298D6C6979CB06DB /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-APIv2Tests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1721,6 +1703,28 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + C17B826BBD02FDD4A5F355AF /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; C2E09DC4BD239F71160F0CC1 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1793,25 +1797,29 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - F07941C0BAF6A7C67AA60C48 /* [CP] Check Pods Manifest.lock */ = { + EDDD3FA856BCA3443ED36D1E /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-UnitTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-APIv2Tests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - F3D5B2CDA172580341682830 /* [CP] Check Pods Manifest.lock */ = { + F07941C0BAF6A7C67AA60C48 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1822,14 +1830,14 @@ ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-InteropTestsLocalSSLCFStream-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-UnitTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */ = { + F3D5B2CDA172580341682830 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1840,29 +1848,29 @@ ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-CoreCronetEnd2EndTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-InteropTestsLocalSSLCFStream-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - FBB92A8B11C52512E67791E8 /* [CP] Copy Pods Resources */ = { + F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Check Pods Manifest.lock"; outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + "$(DERIVED_FILE_DIR)/Pods-CoreCronetEnd2EndTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -1876,11 +1884,11 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5E10F5A3218CB0D1008BAB68 /* Sources */ = { + 5E3B959E21CAC6C500C0A151 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5E10F5AA218CB0D2008BAB68 /* APIv2Tests.m in Sources */, + 5E3B95A521CAC6C500C0A151 /* APIv2Tests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2207,141 +2215,6 @@ }; name = Release; }; - 5E10F5AC218CB0D2008BAB68 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 5E10F5AD218CB0D2008BAB68 /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Test; - }; - 5E10F5AE218CB0D2008BAB68 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Cronet; - }; - 5E10F5AF218CB0D2008BAB68 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; 5E1228981E4D400F00E8504F /* Test */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2550,6 +2423,141 @@ }; name = Test; }; + 5E3B95A821CAC6C500C0A151 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5E3B95A921CAC6C500C0A151 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5E3B95AA21CAC6C500C0A151 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5E3B95AB21CAC6C500C0A151 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 5E7D71BB210B9EC9001EA6BA /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 3A98DF08852F60AF1D96481D /* Pods-InteropTestsCallOptions.debug.xcconfig */; @@ -3892,13 +3900,13 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5E10F5B0218CB0D2008BAB68 /* Build configuration list for PBXNativeTarget "APIv2Tests" */ = { + 5E3B95A721CAC6C500C0A151 /* Build configuration list for PBXNativeTarget "APIv2Tests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 5E10F5AC218CB0D2008BAB68 /* Debug */, - 5E10F5AD218CB0D2008BAB68 /* Test */, - 5E10F5AE218CB0D2008BAB68 /* Cronet */, - 5E10F5AF218CB0D2008BAB68 /* Release */, + 5E3B95A821CAC6C500C0A151 /* Debug */, + 5E3B95A921CAC6C500C0A151 /* Test */, + 5E3B95AA21CAC6C500C0A151 /* Cronet */, + 5E3B95AB21CAC6C500C0A151 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme index b444ddc2b67..e0d1d1fdcac 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "NO"> @@ -32,7 +32,7 @@ skipped = "NO"> @@ -55,7 +55,7 @@ @@ -73,7 +73,7 @@ diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index f075d9baadd..e8c3e6ec2a4 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -187,7 +187,7 @@ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ -scheme APIv2Tests \ - -destination name="iPhone X" \ + -destination name="iPhone 8" \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ From 1600fde6b69a361203cb47ef983e6b4aac873b6a Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 19 Dec 2018 12:22:00 -0800 Subject: [PATCH 366/534] Add Bazel targets for compression example --- examples/BUILD | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/examples/BUILD b/examples/BUILD index 1fa8102cd1d..c4f25d0de9f 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -79,3 +79,17 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) + +cc_binary( + name = "compression_client", + srcs = ["cpp/compression/greeter_client.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) + +cc_binary( + name = "compression_server", + srcs = ["cpp/compression/greeter_server.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) From ad8f04feca10075982208ef8a4c7ce92900d5077 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 19 Dec 2018 12:57:07 -0800 Subject: [PATCH 367/534] Fix compiler error --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 3b7c48a72ca..9e03c90ccb9 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -568,8 +568,8 @@ static void close_transport_locked(grpc_chttp2_transport* t, cancel_pings(t, GRPC_ERROR_REF(error)); // ContextList::Execute follows semantics of a callback function and does not // need a ref on error - grpc_core::ContextList::Execute(cl, nullptr, error); - cl = nullptr; + grpc_core::ContextList::Execute(t->cl, nullptr, error); + t->cl = nullptr; if (t->closed_with_error == GRPC_ERROR_NONE) { if (!grpc_error_has_clear_grpc_status(error)) { error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, From 1876d0d3669147e68c64d7916082de64025e9b6f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 13:06:34 -0800 Subject: [PATCH 368/534] ProtoRPC bug --- src/objective-c/ProtoRPC/ProtoRPC.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 48a38bd35ac..03e6839c5a0 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -175,7 +175,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)writeMessage:(GPBMessage *)message { - NSAssert([message isKindOfClass:[GPBMessage class]]); + NSAssert([message isKindOfClass:[GPBMessage class]], @"Parameter message must be a GPBMessage"); if (![message isKindOfClass:[GPBMessage class]]) { NSLog(@"Failed to send a message that is non-proto."); return; @@ -199,7 +199,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { @synchronized(self) { - if (initialMetadata != nil && [_handler respondsToSelector:@selector(initialMetadata:)]) { + if (initialMetadata != nil && [_handler respondsToSelector:@selector(didReceiveInitialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { From 0de27b5d2955c2d19a998e133580b721836676da Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 13:08:04 -0800 Subject: [PATCH 369/534] More fix ProtoRPC --- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 03e6839c5a0..053eaf47f2f 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -235,7 +235,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } [copiedHandler didCloseWithTrailingMetadata:nil - error:ErrorForBadProto(message, _responseClass, error)]; + error:ErrorForBadProto(message, self->_responseClass, error)]; }); [_call cancel]; _call = nil; From c5f84c5cb8830ad5ac4a9f097804308adce204be Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 14:09:56 -0800 Subject: [PATCH 370/534] Batch fix --- .../GRPCClient/private/GRPCWrappedCall.m | 4 ++++ src/objective-c/ProtoRPC/ProtoService.h | 6 +++--- src/objective-c/ProtoRPC/ProtoService.m | 13 +++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 1a848a4b7c3..7d7e77f6ba0 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -292,6 +292,10 @@ gpr_free(ops_array); NSAssert(error == GRPC_CALL_OK, @"Error starting a batch of operations: %i", error); + // To avoid compiler complaint when NSAssert is disabled. + if (error != GRPC_CALL_OK) { + return; + } } } } diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index d76e96ce2a6..900ec8d0e1e 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -25,7 +25,7 @@ @class GRPCProtoCall; @class GRPCUnaryProtoCall; @class GRPCStreamingProtoCall; -@protocol GRPCProtoResponseCallbacks; +@protocol GRPCProtoResponseHandler; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnullability-completeness" @@ -49,12 +49,12 @@ __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoServ - (nullable GRPCUnaryProtoCall *)RPCToMethod:(nonnull NSString *)method message:(nonnull id)message - responseHandler:(nonnull id)handler + responseHandler:(nonnull id)handler callOptions:(nullable GRPCCallOptions *)callOptions responseClass:(nonnull Class)responseClass; - (nullable GRPCStreamingProtoCall *)RPCToMethod:(nonnull NSString *)method - responseHandler:(nonnull id)handler + responseHandler:(nonnull id)handler callOptions:(nullable GRPCCallOptions *)callOptions responseClass:(nonnull Class)responseClass; diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m index b7c7fadbcf0..80a1f2f226c 100644 --- a/src/objective-c/ProtoRPC/ProtoService.m +++ b/src/objective-c/ProtoRPC/ProtoService.m @@ -58,11 +58,14 @@ return self; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" +// Do not call designated initializer here due to nullability incompatibility. This method is from +// old API and does not assert on nullability of the parameters. + - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName serviceName:(NSString *)serviceName { - // Do not call designated initializer here due to nullability incompatibility. This method is from - // old API and does not assert on nullability of the parameters. if ((self = [super init])) { _host = [host copy]; _packageName = [packageName copy]; @@ -72,6 +75,8 @@ return self; } +#pragma clang diagnostic pop + - (GRPCProtoCall *)RPCToMethod:(NSString *)method requestsWriter:(GRXWriter *)requestsWriter responseClass:(Class)responseClass @@ -87,7 +92,7 @@ - (GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method message:(id)message - responseHandler:(id)handler + responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { GRPCProtoMethod *methodName = @@ -104,7 +109,7 @@ } - (GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method - responseHandler:(id)handler + responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { GRPCProtoMethod *methodName = From f7ca97a6fedc4d20aab6a09b26b143a8996c9b48 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 14:15:12 -0800 Subject: [PATCH 371/534] clang-format --- src/objective-c/ProtoRPC/ProtoRPC.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 053eaf47f2f..0ab96a5ba2b 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -199,7 +199,8 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { @synchronized(self) { - if (initialMetadata != nil && [_handler respondsToSelector:@selector(didReceiveInitialMetadata:)]) { + if (initialMetadata != nil && + [_handler respondsToSelector:@selector(didReceiveInitialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { From c72a0af7816be07d3bec926f86288f9f97cb6cbd Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 16:19:48 -0800 Subject: [PATCH 372/534] change deployment target --- src/objective-c/tests/Tests.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 47b79a05345..b6762cc6001 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -2449,7 +2449,7 @@ ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -2483,7 +2483,7 @@ CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; @@ -2516,7 +2516,7 @@ CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; @@ -2549,7 +2549,7 @@ CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; From 6cf4622cd1a721704c70be2160b6454937771141 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 23:15:26 -0800 Subject: [PATCH 373/534] provide host --- src/objective-c/tests/run_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index e8c3e6ec2a4..8402809c097 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -188,6 +188,7 @@ xcodebuild \ -workspace Tests.xcworkspace \ -scheme APIv2Tests \ -destination name="iPhone 8" \ + HOST_PORT_LOCAL=localhost:5050 \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ From a022c8204c2d104d741e20e82bd2c89ad0e6788f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Dec 2018 18:20:48 +0100 Subject: [PATCH 374/534] csharp interop client: dont set override by default --- src/csharp/Grpc.IntegrationTesting/InteropClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs index e83a8a7274a..47503530820 100644 --- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs +++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs @@ -45,7 +45,7 @@ namespace Grpc.IntegrationTesting [Option("server_host", Default = "localhost")] public string ServerHost { get; set; } - [Option("server_host_override", Default = TestCredentials.DefaultHostOverride)] + [Option("server_host_override")] public string ServerHostOverride { get; set; } [Option("server_port", Required = true)] From 3458ede262ab9398d1baf0d0871b09444d1973a7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Dec 2018 18:29:44 +0100 Subject: [PATCH 375/534] dont set server_override for cloud_to_prod tests --- tools/run_tests/run_interop_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index d026145d66f..e015e0a1d14 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -776,7 +776,7 @@ def cloud_to_prod_jobspec(language, container_name = None cmdargs = [ '--server_host=%s' % server_host, - '--server_host_override=%s' % server_host, '--server_port=443', + '--server_port=443', '--test_case=%s' % test_case ] if transport_security == 'tls': From 2b028c8cecf3875665079adeafd974e592c6a638 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 10:37:08 +0100 Subject: [PATCH 376/534] do not use default server override for C++ interop client --- test/cpp/interop/client.cc | 2 +- test/cpp/interop/stress_test.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index a4b1a85f856..08aad0b0118 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -38,7 +38,7 @@ DEFINE_string(custom_credentials_type, "", "User provided credentials type."); DEFINE_bool(use_test_ca, false, "False to use SSL roots for google"); DEFINE_int32(server_port, 0, "Server port."); DEFINE_string(server_host, "localhost", "Server host to connect to"); -DEFINE_string(server_host_override, "foo.test.google.fr", +DEFINE_string(server_host_override, "", "Override the server host which is sent in HTTP header"); DEFINE_string( test_case, "large_unary", diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc index ebbd14beba2..3e00980a269 100644 --- a/test/cpp/interop/stress_test.cc +++ b/test/cpp/interop/stress_test.cc @@ -103,7 +103,7 @@ DEFINE_bool(use_alts, false, "Whether to use alts. Enable alts will disable tls."); DEFINE_bool(use_tls, false, "Whether to use tls."); DEFINE_bool(use_test_ca, false, "False to use SSL roots for google"); -DEFINE_string(server_host_override, "foo.test.google.fr", +DEFINE_string(server_host_override, "", "Override the server host which is sent in HTTP header"); using grpc::testing::ALTS; From f9e1cde01cd83ef6ee34a5ef734aa591f9095ed7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 10:43:17 +0100 Subject: [PATCH 377/534] yapf run_interop_tests.py --- tools/run_tests/run_interop_tests.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index e015e0a1d14..fe691fdbf5e 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -775,8 +775,7 @@ def cloud_to_prod_jobspec(language, """Creates jobspec for cloud-to-prod interop test""" container_name = None cmdargs = [ - '--server_host=%s' % server_host, - '--server_port=443', + '--server_host=%s' % server_host, '--server_port=443', '--test_case=%s' % test_case ] if transport_security == 'tls': From 4f261a071e8e49373bf6b26831cc4768e00ac38d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 10:44:09 +0100 Subject: [PATCH 378/534] do not use server override in python interop client by default --- src/python/grpcio_tests/tests/interop/client.py | 12 +++++++----- src/python/grpcio_tests/tests/stress/client.py | 1 - 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py index 698c37017f5..56cb29477c8 100644 --- a/src/python/grpcio_tests/tests/interop/client.py +++ b/src/python/grpcio_tests/tests/interop/client.py @@ -54,7 +54,6 @@ def _args(): help='replace platform root CAs with ca.pem') parser.add_argument( '--server_host_override', - default="foo.test.google.fr", type=str, help='the server host to which to claim to connect') parser.add_argument( @@ -100,10 +99,13 @@ def _stub(args): channel_credentials = grpc.composite_channel_credentials( channel_credentials, call_credentials) - channel = grpc.secure_channel(target, channel_credentials, (( - 'grpc.ssl_target_name_override', - args.server_host_override, - ),)) + channel_opts = None + if args.server_host_override: + channel_opts = (( + 'grpc.ssl_target_name_override', + args.server_host_override, + ),) + channel = grpc.secure_channel(target, channel_credentials, channel_opts) else: channel = grpc.insecure_channel(target) if args.test_case == "unimplemented_service": diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py index 41f2e1b6c2d..07aff15ed7e 100644 --- a/src/python/grpcio_tests/tests/stress/client.py +++ b/src/python/grpcio_tests/tests/stress/client.py @@ -71,7 +71,6 @@ def _args(): '--use_tls', help='Whether to use TLS', default=False, type=bool) parser.add_argument( '--server_host_override', - default="foo.test.google.fr", help='the server host to which to claim to connect', type=str) return parser.parse_args() From b4d4f2c46736294ed6ed2790074ceb92ceb29dd1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 10:58:55 +0100 Subject: [PATCH 379/534] do not use server override in php interop client by default --- src/php/tests/interop/interop_client.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index c865678f704..3e19c7ae339 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -538,7 +538,7 @@ function _makeStub($args) $test_case = $args['test_case']; - $host_override = 'foo.test.google.fr'; + $host_override = ''; if (array_key_exists('server_host_override', $args)) { $host_override = $args['server_host_override']; } @@ -565,7 +565,9 @@ function _makeStub($args) $ssl_credentials = Grpc\ChannelCredentials::createSsl(); } $opts['credentials'] = $ssl_credentials; - $opts['grpc.ssl_target_name_override'] = $host_override; + if (!empty($host_override)) { + $opts['grpc.ssl_target_name_override'] = $host_override; + } } else { $opts['credentials'] = Grpc\ChannelCredentials::createInsecure(); } From b904fdaa40f74498dcc5a6c6c75612599b79d7c6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 13:42:27 +0100 Subject: [PATCH 380/534] do not use server override in ruby interop client by default --- src/ruby/pb/test/client.rb | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb index b2303c6e142..03f3d9001aa 100755 --- a/src/ruby/pb/test/client.rb +++ b/src/ruby/pb/test/client.rb @@ -111,10 +111,13 @@ def create_stub(opts) if opts.secure creds = ssl_creds(opts.use_test_ca) stub_opts = { - channel_args: { - GRPC::Core::Channel::SSL_TARGET => opts.server_host_override - } + channel_args: {} } + unless opts.server_host_override.empty? + stub_opts[:channel_args].merge!({ + GRPC::Core::Channel::SSL_TARGET => opts.server_host_override + }) + end # Add service account creds if specified wants_creds = %w(all compute_engine_creds service_account_creds) @@ -603,7 +606,7 @@ class NamedTests if not op.metadata.has_key?(initial_metadata_key) fail AssertionError, "Expected initial metadata. None received" elsif op.metadata[initial_metadata_key] != metadata[initial_metadata_key] - fail AssertionError, + fail AssertionError, "Expected initial metadata: #{metadata[initial_metadata_key]}. "\ "Received: #{op.metadata[initial_metadata_key]}" end @@ -611,7 +614,7 @@ class NamedTests fail AssertionError, "Expected trailing metadata. None received" elsif op.trailing_metadata[trailing_metadata_key] != metadata[trailing_metadata_key] - fail AssertionError, + fail AssertionError, "Expected trailing metadata: #{metadata[trailing_metadata_key]}. "\ "Received: #{op.trailing_metadata[trailing_metadata_key]}" end @@ -639,7 +642,7 @@ class NamedTests fail AssertionError, "Expected trailing metadata. None received" elsif duplex_op.trailing_metadata[trailing_metadata_key] != metadata[trailing_metadata_key] - fail AssertionError, + fail AssertionError, "Expected trailing metadata: #{metadata[trailing_metadata_key]}. "\ "Received: #{duplex_op.trailing_metadata[trailing_metadata_key]}" end @@ -710,7 +713,7 @@ Args = Struct.new(:default_service_account, :server_host, :server_host_override, # validates the command line options, returning them as a Hash. def parse_args args = Args.new - args.server_host_override = 'foo.test.google.fr' + args.server_host_override = '' OptionParser.new do |opts| opts.on('--oauth_scope scope', 'Scope for OAuth tokens') { |v| args['oauth_scope'] = v } From dcb194c6e3836e57ca41ef13ab1ee633590a5af4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 20 Dec 2018 14:46:18 +0100 Subject: [PATCH 381/534] PHP interop client: do not append :443 to host name unless necessary $server_port is actually a string and appending the port number to server_host breaks jwt_token_creds testcase. --- src/php/tests/interop/interop_client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index 3e19c7ae339..19cbf21bc2b 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -530,7 +530,7 @@ function _makeStub($args) throw new Exception('Missing argument: --test_case is required'); } - if ($args['server_port'] === 443) { + if ($args['server_port'] === '443') { $server_address = $args['server_host']; } else { $server_address = $args['server_host'].':'.$args['server_port']; From 291b4f363bbf7226eb7a3bbd7ad620f5be67c625 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 20 Dec 2018 09:52:26 -0800 Subject: [PATCH 382/534] More test fix --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/tests/run_tests.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9bcacac0dfc..b0412cddb09 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -69,7 +69,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @implementation GRPCRequestOptions - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { - NSAssert(host.length != 0 && path.length != 0, @"Host and Path cannot be empty"); + NSAssert(host.length != 0 && path.length != 0, @"host and path cannot be empty"); if (host.length == 0 || path.length == 0) { return nil; } diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index 8402809c097..f6fea96920e 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -189,6 +189,7 @@ xcodebuild \ -scheme APIv2Tests \ -destination name="iPhone 8" \ HOST_PORT_LOCAL=localhost:5050 \ + HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ From 09f57c17ee22e344adad9d81be5747305a02d33e Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 20 Dec 2018 10:10:19 -0800 Subject: [PATCH 383/534] Refactor request routing code out of client_channel. --- BUILD | 2 + CMakeLists.txt | 6 + Makefile | 6 + build.yaml | 2 + config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + grpc.gyp | 4 + package.xml | 2 + .../filters/client_channel/client_channel.cc | 1035 +++-------------- .../ext/filters/client_channel/lb_policy.h | 7 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 8 +- .../lb_policy/pick_first/pick_first.cc | 8 +- .../lb_policy/round_robin/round_robin.cc | 8 +- .../client_channel/lb_policy/xds/xds.cc | 8 +- .../filters/client_channel/request_routing.cc | 936 +++++++++++++++ .../filters/client_channel/request_routing.h | 177 +++ .../client_channel/resolver_result_parsing.cc | 14 +- .../client_channel/resolver_result_parsing.h | 30 +- src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 3 + 24 files changed, 1361 insertions(+), 906 deletions(-) create mode 100644 src/core/ext/filters/client_channel/request_routing.cc create mode 100644 src/core/ext/filters/client_channel/request_routing.h diff --git a/BUILD b/BUILD index b9b39a37a7e..e3c765198b2 100644 --- a/BUILD +++ b/BUILD @@ -1056,6 +1056,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/proxy_mapper.cc", "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", + "src/core/ext/filters/client_channel/request_routing.cc", "src/core/ext/filters/client_channel/resolver.cc", "src/core/ext/filters/client_channel/resolver_registry.cc", "src/core/ext/filters/client_channel/resolver_result_parsing.cc", @@ -1079,6 +1080,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", + "src/core/ext/filters/client_channel/request_routing.h", "src/core/ext/filters/client_channel/resolver.h", "src/core/ext/filters/client_channel/resolver_factory.h", "src/core/ext/filters/client_channel/resolver_registry.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f34bf841d2..76886307813 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1210,6 +1210,7 @@ add_library(grpc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -1562,6 +1563,7 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -1935,6 +1937,7 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -2256,6 +2259,7 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -2589,6 +2593,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -3443,6 +3448,7 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc diff --git a/Makefile b/Makefile index 2ad3eb4c142..147e9505a33 100644 --- a/Makefile +++ b/Makefile @@ -3723,6 +3723,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ @@ -4069,6 +4070,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ @@ -4435,6 +4437,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ @@ -4743,6 +4746,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ @@ -5050,6 +5054,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ @@ -5881,6 +5886,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ diff --git a/build.yaml b/build.yaml index 830123110ac..9d73e31b2e5 100644 --- a/build.yaml +++ b/build.yaml @@ -584,6 +584,7 @@ filegroups: - src/core/ext/filters/client_channel/parse_address.h - src/core/ext/filters/client_channel/proxy_mapper.h - src/core/ext/filters/client_channel/proxy_mapper_registry.h + - src/core/ext/filters/client_channel/request_routing.h - src/core/ext/filters/client_channel/resolver.h - src/core/ext/filters/client_channel/resolver_factory.h - src/core/ext/filters/client_channel/resolver_registry.h @@ -608,6 +609,7 @@ filegroups: - src/core/ext/filters/client_channel/parse_address.cc - src/core/ext/filters/client_channel/proxy_mapper.cc - src/core/ext/filters/client_channel/proxy_mapper_registry.cc + - src/core/ext/filters/client_channel/request_routing.cc - src/core/ext/filters/client_channel/resolver.cc - src/core/ext/filters/client_channel/resolver_registry.cc - src/core/ext/filters/client_channel/resolver_result_parsing.cc diff --git a/config.m4 b/config.m4 index 16de5204bb2..25ffe2148ab 100644 --- a/config.m4 +++ b/config.m4 @@ -352,6 +352,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ diff --git a/config.w32 b/config.w32 index be10faab9cd..b6e71dd09a5 100644 --- a/config.w32 +++ b/config.w32 @@ -327,6 +327,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\parse_address.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " + + "src\\core\\ext\\filters\\client_channel\\request_routing.cc " + "src\\core\\ext\\filters\\client_channel\\resolver.cc " + "src\\core\\ext\\filters\\client_channel\\resolver_registry.cc " + "src\\core\\ext\\filters\\client_channel\\resolver_result_parsing.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index f918fe8ad9c..29a79dd47ab 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -355,6 +355,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', + 'src/core/ext/filters/client_channel/request_routing.h', 'src/core/ext/filters/client_channel/resolver.h', 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 0a78733f8da..f873bc693bc 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -349,6 +349,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', + 'src/core/ext/filters/client_channel/request_routing.h', 'src/core/ext/filters/client_channel/resolver.h', 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', @@ -791,6 +792,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', @@ -970,6 +972,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', + 'src/core/ext/filters/client_channel/request_routing.h', 'src/core/ext/filters/client_channel/resolver.h', 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', diff --git a/grpc.gemspec b/grpc.gemspec index 1ee7bec8e7d..3c680b044f7 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -285,6 +285,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/parse_address.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h ) + s.files += %w( src/core/ext/filters/client_channel/request_routing.h ) s.files += %w( src/core/ext/filters/client_channel/resolver.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_factory.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_registry.h ) @@ -730,6 +731,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/parse_address.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.cc ) + s.files += %w( src/core/ext/filters/client_channel/request_routing.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver_registry.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.cc ) diff --git a/grpc.gyp b/grpc.gyp index 641235eec20..80b6d0315a1 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -534,6 +534,7 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', @@ -794,6 +795,7 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', @@ -1035,6 +1037,7 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', @@ -1288,6 +1291,7 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', diff --git a/package.xml b/package.xml index 68fc7433cb4..2632fcb276b 100644 --- a/package.xml +++ b/package.xml @@ -290,6 +290,7 @@ + @@ -735,6 +736,7 @@ + diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 70aac472314..dd741f1e2de 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -35,10 +35,10 @@ #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" +#include "src/core/ext/filters/client_channel/request_routing.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" -#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/ext/filters/deadline/deadline_filter.h" #include "src/core/lib/backoff/backoff.h" @@ -63,7 +63,6 @@ #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" -using grpc_core::ServerAddressList; using grpc_core::internal::ClientChannelMethodParams; using grpc_core::internal::ClientChannelMethodParamsTable; using grpc_core::internal::ProcessedResolverResult; @@ -88,31 +87,18 @@ grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel"); struct external_connectivity_watcher; typedef struct client_channel_channel_data { - grpc_core::OrphanablePtr resolver; - bool started_resolving; + grpc_core::ManualConstructor request_router; + bool deadline_checking_enabled; - grpc_client_channel_factory* client_channel_factory; bool enable_retries; size_t per_rpc_retry_buffer_size; /** combiner protecting all variables below in this data structure */ grpc_combiner* combiner; - /** currently active load balancer */ - grpc_core::OrphanablePtr lb_policy; /** retry throttle data */ grpc_core::RefCountedPtr retry_throttle_data; /** maps method names to method_parameters structs */ grpc_core::RefCountedPtr method_params_table; - /** incoming resolver result - set by resolver.next() */ - grpc_channel_args* resolver_result; - /** a list of closures that are all waiting for resolver result to come in */ - grpc_closure_list waiting_for_resolver_result_closures; - /** resolver callback */ - grpc_closure on_resolver_result_changed; - /** connectivity state being tracked */ - grpc_connectivity_state_tracker state_tracker; - /** when an lb_policy arrives, should we try to exit idle */ - bool exit_idle_when_lb_policy_arrives; /** owning stack */ grpc_channel_stack* owning_stack; /** interested parties (owned) */ @@ -129,418 +115,40 @@ typedef struct client_channel_channel_data { grpc_core::UniquePtr info_lb_policy_name; /** service config in JSON form */ grpc_core::UniquePtr info_service_config_json; - /* backpointer to grpc_channel's channelz node */ - grpc_core::channelz::ClientChannelNode* channelz_channel; - /* caches if the last resolution event contained addresses */ - bool previous_resolution_contained_addresses; } channel_data; -typedef struct { - channel_data* chand; - /** used as an identifier, don't dereference it because the LB policy may be - * non-existing when the callback is run */ - grpc_core::LoadBalancingPolicy* lb_policy; - grpc_closure closure; -} reresolution_request_args; - -/** We create one watcher for each new lb_policy that is returned from a - resolver, to watch for state changes from the lb_policy. When a state - change is seen, we update the channel, and create a new watcher. */ -typedef struct { - channel_data* chand; - grpc_closure on_changed; - grpc_connectivity_state state; - grpc_core::LoadBalancingPolicy* lb_policy; -} lb_policy_connectivity_watcher; - -static void watch_lb_policy_locked(channel_data* chand, - grpc_core::LoadBalancingPolicy* lb_policy, - grpc_connectivity_state current_state); - -static const char* channel_connectivity_state_change_string( - grpc_connectivity_state state) { - switch (state) { - case GRPC_CHANNEL_IDLE: - return "Channel state change to IDLE"; - case GRPC_CHANNEL_CONNECTING: - return "Channel state change to CONNECTING"; - case GRPC_CHANNEL_READY: - return "Channel state change to READY"; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - return "Channel state change to TRANSIENT_FAILURE"; - case GRPC_CHANNEL_SHUTDOWN: - return "Channel state change to SHUTDOWN"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -static void set_channel_connectivity_state_locked(channel_data* chand, - grpc_connectivity_state state, - grpc_error* error, - const char* reason) { - /* TODO: Improve failure handling: - * - Make it possible for policies to return GRPC_CHANNEL_TRANSIENT_FAILURE. - * - Hand over pending picks from old policies during the switch that happens - * when resolver provides an update. */ - if (chand->lb_policy != nullptr) { - if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) { - /* cancel picks with wait_for_ready=false */ - chand->lb_policy->CancelMatchingPicksLocked( - /* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY, - /* check= */ 0, GRPC_ERROR_REF(error)); - } else if (state == GRPC_CHANNEL_SHUTDOWN) { - /* cancel all picks */ - chand->lb_policy->CancelMatchingPicksLocked(/* mask= */ 0, /* check= */ 0, - GRPC_ERROR_REF(error)); - } - } - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: setting connectivity state to %s", chand, - grpc_connectivity_state_name(state)); - } - if (chand->channelz_channel != nullptr) { - chand->channelz_channel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - channel_connectivity_state_change_string(state))); - } - grpc_connectivity_state_set(&chand->state_tracker, state, error, reason); -} - -static void on_lb_policy_state_changed_locked(void* arg, grpc_error* error) { - lb_policy_connectivity_watcher* w = - static_cast(arg); - /* check if the notification is for the latest policy */ - if (w->lb_policy == w->chand->lb_policy.get()) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: lb_policy=%p state changed to %s", w->chand, - w->lb_policy, grpc_connectivity_state_name(w->state)); - } - set_channel_connectivity_state_locked(w->chand, w->state, - GRPC_ERROR_REF(error), "lb_changed"); - if (w->state != GRPC_CHANNEL_SHUTDOWN) { - watch_lb_policy_locked(w->chand, w->lb_policy, w->state); - } - } - GRPC_CHANNEL_STACK_UNREF(w->chand->owning_stack, "watch_lb_policy"); - gpr_free(w); -} - -static void watch_lb_policy_locked(channel_data* chand, - grpc_core::LoadBalancingPolicy* lb_policy, - grpc_connectivity_state current_state) { - lb_policy_connectivity_watcher* w = - static_cast(gpr_malloc(sizeof(*w))); - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "watch_lb_policy"); - w->chand = chand; - GRPC_CLOSURE_INIT(&w->on_changed, on_lb_policy_state_changed_locked, w, - grpc_combiner_scheduler(chand->combiner)); - w->state = current_state; - w->lb_policy = lb_policy; - lb_policy->NotifyOnStateChangeLocked(&w->state, &w->on_changed); -} - -static void start_resolving_locked(channel_data* chand) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: starting name resolution", chand); - } - GPR_ASSERT(!chand->started_resolving); - chand->started_resolving = true; - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); - chand->resolver->NextLocked(&chand->resolver_result, - &chand->on_resolver_result_changed); -} - -// Invoked from the resolver NextLocked() callback when the resolver -// is shutting down. -static void on_resolver_shutdown_locked(channel_data* chand, - grpc_error* error) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: shutting down", chand); - } - if (chand->lb_policy != nullptr) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: shutting down lb_policy=%p", chand, - chand->lb_policy.get()); - } - grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - chand->lb_policy.reset(); - } - if (chand->resolver != nullptr) { - // This should never happen; it can only be triggered by a resolver - // implementation spotaneously deciding to report shutdown without - // being orphaned. This code is included just to be defensive. - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: spontaneous shutdown from resolver %p", - chand, chand->resolver.get()); - } - chand->resolver.reset(); - set_channel_connectivity_state_locked( - chand, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Resolver spontaneous shutdown", &error, 1), - "resolver_spontaneous_shutdown"); - } - grpc_closure_list_fail_all(&chand->waiting_for_resolver_result_closures, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Channel disconnected", &error, 1)); - GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures); - GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "resolver"); - grpc_channel_args_destroy(chand->resolver_result); - chand->resolver_result = nullptr; - GRPC_ERROR_UNREF(error); -} - -static void request_reresolution_locked(void* arg, grpc_error* error) { - reresolution_request_args* args = - static_cast(arg); - channel_data* chand = args->chand; - // If this invocation is for a stale LB policy, treat it as an LB shutdown - // signal. - if (args->lb_policy != chand->lb_policy.get() || error != GRPC_ERROR_NONE || - chand->resolver == nullptr) { - GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "re-resolution"); - gpr_free(args); - return; - } - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: started name re-resolving", chand); - } - chand->resolver->RequestReresolutionLocked(); - // Give back the closure to the LB policy. - chand->lb_policy->SetReresolutionClosureLocked(&args->closure); -} - -using TraceStringVector = grpc_core::InlinedVector; - -// Creates a new LB policy, replacing any previous one. -// If the new policy is created successfully, sets *connectivity_state and -// *connectivity_error to its initial connectivity state; otherwise, -// leaves them unchanged. -static void create_new_lb_policy_locked( - channel_data* chand, char* lb_policy_name, grpc_json* lb_config, - grpc_connectivity_state* connectivity_state, - grpc_error** connectivity_error, TraceStringVector* trace_strings) { - grpc_core::LoadBalancingPolicy::Args lb_policy_args; - lb_policy_args.combiner = chand->combiner; - lb_policy_args.client_channel_factory = chand->client_channel_factory; - lb_policy_args.args = chand->resolver_result; - lb_policy_args.lb_config = lb_config; - grpc_core::OrphanablePtr new_lb_policy = - grpc_core::LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - lb_policy_name, lb_policy_args); - if (GPR_UNLIKELY(new_lb_policy == nullptr)) { - gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); - if (chand->channelz_channel != nullptr) { - char* str; - gpr_asprintf(&str, "Could not create LB policy \'%s\'", lb_policy_name); - trace_strings->push_back(str); - } - } else { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: created new LB policy \"%s\" (%p)", chand, - lb_policy_name, new_lb_policy.get()); - } - if (chand->channelz_channel != nullptr) { - char* str; - gpr_asprintf(&str, "Created new LB policy \'%s\'", lb_policy_name); - trace_strings->push_back(str); - } - // Swap out the LB policy and update the fds in - // chand->interested_parties. - if (chand->lb_policy != nullptr) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: shutting down lb_policy=%p", chand, - chand->lb_policy.get()); - } - grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - chand->lb_policy->HandOffPendingPicksLocked(new_lb_policy.get()); - } - chand->lb_policy = std::move(new_lb_policy); - grpc_pollset_set_add_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - // Set up re-resolution callback. - reresolution_request_args* args = - static_cast(gpr_zalloc(sizeof(*args))); - args->chand = chand; - args->lb_policy = chand->lb_policy.get(); - GRPC_CLOSURE_INIT(&args->closure, request_reresolution_locked, args, - grpc_combiner_scheduler(chand->combiner)); - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "re-resolution"); - chand->lb_policy->SetReresolutionClosureLocked(&args->closure); - // Get the new LB policy's initial connectivity state and start a - // connectivity watch. - GRPC_ERROR_UNREF(*connectivity_error); - *connectivity_state = - chand->lb_policy->CheckConnectivityLocked(connectivity_error); - if (chand->exit_idle_when_lb_policy_arrives) { - chand->lb_policy->ExitIdleLocked(); - chand->exit_idle_when_lb_policy_arrives = false; - } - watch_lb_policy_locked(chand, chand->lb_policy.get(), *connectivity_state); - } -} - -static void maybe_add_trace_message_for_address_changes_locked( - channel_data* chand, TraceStringVector* trace_strings) { - const ServerAddressList* addresses = - grpc_core::FindServerAddressListChannelArg(chand->resolver_result); - const bool resolution_contains_addresses = - addresses != nullptr && addresses->size() > 0; - if (!resolution_contains_addresses && - chand->previous_resolution_contained_addresses) { - trace_strings->push_back(gpr_strdup("Address list became empty")); - } else if (resolution_contains_addresses && - !chand->previous_resolution_contained_addresses) { - trace_strings->push_back(gpr_strdup("Address list became non-empty")); - } - chand->previous_resolution_contained_addresses = - resolution_contains_addresses; -} - -static void concatenate_and_add_channel_trace_locked( - channel_data* chand, TraceStringVector* trace_strings) { - if (!trace_strings->empty()) { - gpr_strvec v; - gpr_strvec_init(&v); - gpr_strvec_add(&v, gpr_strdup("Resolution event: ")); - bool is_first = 1; - for (size_t i = 0; i < trace_strings->size(); ++i) { - if (!is_first) gpr_strvec_add(&v, gpr_strdup(", ")); - is_first = false; - gpr_strvec_add(&v, (*trace_strings)[i]); - } - char* flat; - size_t flat_len = 0; - flat = gpr_strvec_flatten(&v, &flat_len); - chand->channelz_channel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_new(flat, flat_len, gpr_free)); - gpr_strvec_destroy(&v); - } -} - -// Callback invoked when a resolver result is available. -static void on_resolver_result_changed_locked(void* arg, grpc_error* error) { +// Synchronous callback from chand->request_router to process a resolver +// result update. +static bool process_resolver_result_locked(void* arg, + const grpc_channel_args& args, + const char** lb_policy_name, + grpc_json** lb_policy_config) { channel_data* chand = static_cast(arg); + ProcessedResolverResult resolver_result(args, chand->enable_retries); + grpc_core::UniquePtr service_config_json = + resolver_result.service_config_json(); if (grpc_client_channel_trace.enabled()) { - const char* disposition = - chand->resolver_result != nullptr - ? "" - : (error == GRPC_ERROR_NONE ? " (transient error)" - : " (resolver shutdown)"); - gpr_log(GPR_INFO, - "chand=%p: got resolver result: resolver_result=%p error=%s%s", - chand, chand->resolver_result, grpc_error_string(error), - disposition); + gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", + chand, service_config_json.get()); } - // Handle shutdown. - if (error != GRPC_ERROR_NONE || chand->resolver == nullptr) { - on_resolver_shutdown_locked(chand, GRPC_ERROR_REF(error)); - return; - } - // Data used to set the channel's connectivity state. - bool set_connectivity_state = true; - // We only want to trace the address resolution in the follow cases: - // (a) Address resolution resulted in service config change. - // (b) Address resolution that causes number of backends to go from - // zero to non-zero. - // (c) Address resolution that causes number of backends to go from - // non-zero to zero. - // (d) Address resolution that causes a new LB policy to be created. - // - // we track a list of strings to eventually be concatenated and traced. - TraceStringVector trace_strings; - grpc_connectivity_state connectivity_state = GRPC_CHANNEL_TRANSIENT_FAILURE; - grpc_error* connectivity_error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy"); - // chand->resolver_result will be null in the case of a transient - // resolution error. In that case, we don't have any new result to - // process, which means that we keep using the previous result (if any). - if (chand->resolver_result == nullptr) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: resolver transient failure", chand); - } - // Don't override connectivity state if we already have an LB policy. - if (chand->lb_policy != nullptr) set_connectivity_state = false; - } else { - // Parse the resolver result. - ProcessedResolverResult resolver_result(chand->resolver_result, - chand->enable_retries); - chand->retry_throttle_data = resolver_result.retry_throttle_data(); - chand->method_params_table = resolver_result.method_params_table(); - grpc_core::UniquePtr service_config_json = - resolver_result.service_config_json(); - if (service_config_json != nullptr && grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", - chand, service_config_json.get()); - } - grpc_core::UniquePtr lb_policy_name = - resolver_result.lb_policy_name(); - grpc_json* lb_policy_config = resolver_result.lb_policy_config(); - // Check to see if we're already using the right LB policy. - // Note: It's safe to use chand->info_lb_policy_name here without - // taking a lock on chand->info_mu, because this function is the - // only thing that modifies its value, and it can only be invoked - // once at any given time. - bool lb_policy_name_changed = - chand->info_lb_policy_name == nullptr || - strcmp(chand->info_lb_policy_name.get(), lb_policy_name.get()) != 0; - if (chand->lb_policy != nullptr && !lb_policy_name_changed) { - // Continue using the same LB policy. Update with new addresses. - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: updating existing LB policy \"%s\" (%p)", - chand, lb_policy_name.get(), chand->lb_policy.get()); - } - chand->lb_policy->UpdateLocked(*chand->resolver_result, lb_policy_config); - // No need to set the channel's connectivity state; the existing - // watch on the LB policy will take care of that. - set_connectivity_state = false; - } else { - // Instantiate new LB policy. - create_new_lb_policy_locked(chand, lb_policy_name.get(), lb_policy_config, - &connectivity_state, &connectivity_error, - &trace_strings); - } - // Note: It's safe to use chand->info_service_config_json here without - // taking a lock on chand->info_mu, because this function is the - // only thing that modifies its value, and it can only be invoked - // once at any given time. - if (chand->channelz_channel != nullptr) { - if (((service_config_json == nullptr) != - (chand->info_service_config_json == nullptr)) || - (service_config_json != nullptr && - strcmp(service_config_json.get(), - chand->info_service_config_json.get()) != 0)) { - // TODO(ncteisen): might be worth somehow including a snippet of the - // config in the trace, at the risk of bloating the trace logs. - trace_strings.push_back(gpr_strdup("Service config changed")); - } - maybe_add_trace_message_for_address_changes_locked(chand, &trace_strings); - concatenate_and_add_channel_trace_locked(chand, &trace_strings); - } - // Swap out the data used by cc_get_channel_info(). - gpr_mu_lock(&chand->info_mu); - chand->info_lb_policy_name = std::move(lb_policy_name); - chand->info_service_config_json = std::move(service_config_json); - gpr_mu_unlock(&chand->info_mu); - // Clean up. - grpc_channel_args_destroy(chand->resolver_result); - chand->resolver_result = nullptr; - } - // Set the channel's connectivity state if needed. - if (set_connectivity_state) { - set_channel_connectivity_state_locked( - chand, connectivity_state, connectivity_error, "resolver_result"); - } else { - GRPC_ERROR_UNREF(connectivity_error); - } - // Invoke closures that were waiting for results and renew the watch. - GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures); - chand->resolver->NextLocked(&chand->resolver_result, - &chand->on_resolver_result_changed); + // Update channel state. + chand->retry_throttle_data = resolver_result.retry_throttle_data(); + chand->method_params_table = resolver_result.method_params_table(); + // Swap out the data used by cc_get_channel_info(). + gpr_mu_lock(&chand->info_mu); + chand->info_lb_policy_name = resolver_result.lb_policy_name(); + const bool service_config_changed = + ((service_config_json == nullptr) != + (chand->info_service_config_json == nullptr)) || + (service_config_json != nullptr && + strcmp(service_config_json.get(), + chand->info_service_config_json.get()) != 0); + chand->info_service_config_json = std::move(service_config_json); + gpr_mu_unlock(&chand->info_mu); + // Return results. + *lb_policy_name = chand->info_lb_policy_name.get(); + *lb_policy_config = resolver_result.lb_policy_config(); + return service_config_changed; } static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { @@ -550,15 +158,14 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { channel_data* chand = static_cast(elem->channel_data); if (op->on_connectivity_state_change != nullptr) { - grpc_connectivity_state_notify_on_state_change( - &chand->state_tracker, op->connectivity_state, - op->on_connectivity_state_change); + chand->request_router->NotifyOnConnectivityStateChange( + op->connectivity_state, op->on_connectivity_state_change); op->on_connectivity_state_change = nullptr; op->connectivity_state = nullptr; } if (op->send_ping.on_initiate != nullptr || op->send_ping.on_ack != nullptr) { - if (chand->lb_policy == nullptr) { + if (chand->request_router->lb_policy() == nullptr) { grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"); GRPC_CLOSURE_SCHED(op->send_ping.on_initiate, GRPC_ERROR_REF(error)); @@ -567,7 +174,8 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { grpc_error* error = GRPC_ERROR_NONE; grpc_core::LoadBalancingPolicy::PickState pick_state; // Pick must return synchronously, because pick_state.on_complete is null. - GPR_ASSERT(chand->lb_policy->PickLocked(&pick_state, &error)); + GPR_ASSERT( + chand->request_router->lb_policy()->PickLocked(&pick_state, &error)); if (pick_state.connected_subchannel != nullptr) { pick_state.connected_subchannel->Ping(op->send_ping.on_initiate, op->send_ping.on_ack); @@ -586,37 +194,14 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { } if (op->disconnect_with_error != GRPC_ERROR_NONE) { - if (chand->resolver != nullptr) { - set_channel_connectivity_state_locked( - chand, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(op->disconnect_with_error), "disconnect"); - chand->resolver.reset(); - if (!chand->started_resolving) { - grpc_closure_list_fail_all(&chand->waiting_for_resolver_result_closures, - GRPC_ERROR_REF(op->disconnect_with_error)); - GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures); - } - if (chand->lb_policy != nullptr) { - grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - chand->lb_policy.reset(); - } - } - GRPC_ERROR_UNREF(op->disconnect_with_error); + chand->request_router->ShutdownLocked(op->disconnect_with_error); } if (op->reset_connect_backoff) { - if (chand->resolver != nullptr) { - chand->resolver->ResetBackoffLocked(); - chand->resolver->RequestReresolutionLocked(); - } - if (chand->lb_policy != nullptr) { - chand->lb_policy->ResetBackoffLocked(); - } + chand->request_router->ResetConnectionBackoffLocked(); } GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "start_transport_op"); - GRPC_CLOSURE_SCHED(op->on_consumed, GRPC_ERROR_NONE); } @@ -667,12 +252,9 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); chand->owning_stack = args->channel_stack; - GRPC_CLOSURE_INIT(&chand->on_resolver_result_changed, - on_resolver_result_changed_locked, chand, - grpc_combiner_scheduler(chand->combiner)); + chand->deadline_checking_enabled = + grpc_deadline_checking_enabled(args->channel_args); chand->interested_parties = grpc_pollset_set_create(); - grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, - "client_channel"); grpc_client_channel_start_backup_polling(chand->interested_parties); // Record max per-RPC retry buffer size. const grpc_arg* arg = grpc_channel_args_find( @@ -682,8 +264,6 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, // Record enable_retries. arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_ENABLE_RETRIES); chand->enable_retries = grpc_channel_arg_get_bool(arg, true); - chand->channelz_channel = nullptr; - chand->previous_resolution_contained_addresses = false; // Record client channel factory. arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_CLIENT_CHANNEL_FACTORY); @@ -695,9 +275,7 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "client channel factory arg must be a pointer"); } - grpc_client_channel_factory_ref( - static_cast(arg->value.pointer.p)); - chand->client_channel_factory = + grpc_client_channel_factory* client_channel_factory = static_cast(arg->value.pointer.p); // Get server name to resolve, using proxy mapper if needed. arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI); @@ -713,39 +291,24 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, grpc_channel_args* new_args = nullptr; grpc_proxy_mappers_map_name(arg->value.string, args->channel_args, &proxy_name, &new_args); - // Instantiate resolver. - chand->resolver = grpc_core::ResolverRegistry::CreateResolver( - proxy_name != nullptr ? proxy_name : arg->value.string, - new_args != nullptr ? new_args : args->channel_args, - chand->interested_parties, chand->combiner); - if (proxy_name != nullptr) gpr_free(proxy_name); - if (new_args != nullptr) grpc_channel_args_destroy(new_args); - if (chand->resolver == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); - } - chand->deadline_checking_enabled = - grpc_deadline_checking_enabled(args->channel_args); - return GRPC_ERROR_NONE; + // Instantiate request router. + grpc_client_channel_factory_ref(client_channel_factory); + grpc_error* error = GRPC_ERROR_NONE; + chand->request_router.Init( + chand->owning_stack, chand->combiner, client_channel_factory, + chand->interested_parties, &grpc_client_channel_trace, + process_resolver_result_locked, chand, + proxy_name != nullptr ? proxy_name : arg->value.string /* target_uri */, + new_args != nullptr ? new_args : args->channel_args, &error); + gpr_free(proxy_name); + grpc_channel_args_destroy(new_args); + return error; } /* Destructor for channel_data */ static void cc_destroy_channel_elem(grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); - if (chand->resolver != nullptr) { - // The only way we can get here is if we never started resolving, - // because we take a ref to the channel stack when we start - // resolving and do not release it until the resolver callback is - // invoked after the resolver shuts down. - chand->resolver.reset(); - } - if (chand->client_channel_factory != nullptr) { - grpc_client_channel_factory_unref(chand->client_channel_factory); - } - if (chand->lb_policy != nullptr) { - grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - chand->lb_policy.reset(); - } + chand->request_router.Destroy(); // TODO(roth): Once we convert the filter API to C++, there will no // longer be any need to explicitly reset these smart pointer data members. chand->info_lb_policy_name.reset(); @@ -753,7 +316,6 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { chand->retry_throttle_data.reset(); chand->method_params_table.reset(); grpc_client_channel_stop_backup_polling(chand->interested_parties); - grpc_connectivity_state_destroy(&chand->state_tracker); grpc_pollset_set_destroy(chand->interested_parties); GRPC_COMBINER_UNREF(chand->combiner, "client_channel"); gpr_mu_destroy(&chand->info_mu); @@ -810,6 +372,7 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { // - add census stats for retries namespace { + struct call_data; // State used for starting a retryable batch on a subchannel call. @@ -894,12 +457,12 @@ struct subchannel_call_retry_state { bool completed_recv_initial_metadata : 1; bool started_recv_trailing_metadata : 1; bool completed_recv_trailing_metadata : 1; + // State for callback processing. subchannel_batch_data* recv_initial_metadata_ready_deferred_batch = nullptr; grpc_error* recv_initial_metadata_error = GRPC_ERROR_NONE; subchannel_batch_data* recv_message_ready_deferred_batch = nullptr; grpc_error* recv_message_error = GRPC_ERROR_NONE; subchannel_batch_data* recv_trailing_metadata_internal_batch = nullptr; - // State for callback processing. // NOTE: Do not move this next to the metadata bitfields above. That would // save space but will also result in a data race because compiler will // generate a 2 byte store which overwrites the meta-data fields upon @@ -908,12 +471,12 @@ struct subchannel_call_retry_state { }; // Pending batches stored in call data. -typedef struct { +struct pending_batch { // The pending batch. If nullptr, this slot is empty. grpc_transport_stream_op_batch* batch; // Indicates whether payload for send ops has been cached in call data. bool send_ops_cached; -} pending_batch; +}; /** Call data. Holds a pointer to grpc_subchannel_call and the associated machinery to create such a pointer. @@ -950,11 +513,8 @@ struct call_data { for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches); ++i) { GPR_ASSERT(pending_batches[i].batch == nullptr); } - for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) { - if (pick.subchannel_call_context[i].value != nullptr) { - pick.subchannel_call_context[i].destroy( - pick.subchannel_call_context[i].value); - } + if (have_request) { + request.Destroy(); } } @@ -981,12 +541,11 @@ struct call_data { // Set when we get a cancel_stream op. grpc_error* cancel_error = GRPC_ERROR_NONE; - grpc_core::LoadBalancingPolicy::PickState pick; + grpc_core::ManualConstructor request; + bool have_request = false; grpc_closure pick_closure; - grpc_closure pick_cancel_closure; grpc_polling_entity* pollent = nullptr; - bool pollent_added_to_interested_parties = false; // Batches are added to this list when received from above. // They are removed when we are done handling the batch (i.e., when @@ -1036,6 +595,7 @@ struct call_data { grpc_linked_mdelem* send_trailing_metadata_storage = nullptr; grpc_metadata_batch send_trailing_metadata; }; + } // namespace // Forward declarations. @@ -1438,8 +998,9 @@ static void do_retry(grpc_call_element* elem, "client_channel_call_retry"); calld->subchannel_call = nullptr; } - if (calld->pick.connected_subchannel != nullptr) { - calld->pick.connected_subchannel.reset(); + if (calld->have_request) { + calld->have_request = false; + calld->request.Destroy(); } // Compute backoff delay. grpc_millis next_attempt_time; @@ -1588,6 +1149,7 @@ static bool maybe_retry(grpc_call_element* elem, // namespace { + subchannel_batch_data::subchannel_batch_data(grpc_call_element* elem, call_data* calld, int refcount, bool set_on_complete) @@ -1628,6 +1190,7 @@ void subchannel_batch_data::destroy() { call_data* calld = static_cast(elem->call_data); GRPC_CALL_STACK_UNREF(calld->owning_call, "batch_data"); } + } // namespace // Creates a subchannel_batch_data object on the call's arena with the @@ -2644,17 +2207,18 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { const size_t parent_data_size = calld->enable_retries ? sizeof(subchannel_call_retry_state) : 0; const grpc_core::ConnectedSubchannel::CallArgs call_args = { - calld->pollent, // pollent - calld->path, // path - calld->call_start_time, // start_time - calld->deadline, // deadline - calld->arena, // arena - calld->pick.subchannel_call_context, // context - calld->call_combiner, // call_combiner - parent_data_size // parent_data_size + calld->pollent, // pollent + calld->path, // path + calld->call_start_time, // start_time + calld->deadline, // deadline + calld->arena, // arena + calld->request->pick()->subchannel_call_context, // context + calld->call_combiner, // call_combiner + parent_data_size // parent_data_size }; - grpc_error* new_error = calld->pick.connected_subchannel->CreateCall( - call_args, &calld->subchannel_call); + grpc_error* new_error = + calld->request->pick()->connected_subchannel->CreateCall( + call_args, &calld->subchannel_call); if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", chand, calld, calld->subchannel_call, grpc_error_string(new_error)); @@ -2666,7 +2230,8 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { if (parent_data_size > 0) { new (grpc_connected_subchannel_call_get_parent_data( calld->subchannel_call)) - subchannel_call_retry_state(calld->pick.subchannel_call_context); + subchannel_call_retry_state( + calld->request->pick()->subchannel_call_context); } pending_batches_resume(elem); } @@ -2678,7 +2243,7 @@ static void pick_done(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (GPR_UNLIKELY(calld->pick.connected_subchannel == nullptr)) { + if (GPR_UNLIKELY(calld->request->pick()->connected_subchannel == nullptr)) { // Failed to create subchannel. // If there was no error, this is an LB policy drop, in which case // we return an error; otherwise, we may retry. @@ -2707,135 +2272,27 @@ static void pick_done(void* arg, grpc_error* error) { } } -static void maybe_add_call_to_channel_interested_parties_locked( - grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (!calld->pollent_added_to_interested_parties) { - calld->pollent_added_to_interested_parties = true; - grpc_polling_entity_add_to_pollset_set(calld->pollent, - chand->interested_parties); - } -} - -static void maybe_del_call_from_channel_interested_parties_locked( - grpc_call_element* elem) { +// If the channel is in TRANSIENT_FAILURE and the call is not +// wait_for_ready=true, fails the call and returns true. +static bool fail_call_if_in_transient_failure(grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (calld->pollent_added_to_interested_parties) { - calld->pollent_added_to_interested_parties = false; - grpc_polling_entity_del_from_pollset_set(calld->pollent, - chand->interested_parties); + grpc_transport_stream_op_batch* batch = calld->pending_batches[0].batch; + if (chand->request_router->GetConnectivityState() == + GRPC_CHANNEL_TRANSIENT_FAILURE && + (batch->payload->send_initial_metadata.send_initial_metadata_flags & + GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) { + pending_batches_fail( + elem, + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "channel is in state TRANSIENT_FAILURE"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), + true /* yield_call_combiner */); + return true; } + return false; } -// Invoked when a pick is completed to leave the client_channel combiner -// and continue processing in the call combiner. -// If needed, removes the call's polling entity from chand->interested_parties. -static void pick_done_locked(grpc_call_element* elem, grpc_error* error) { - call_data* calld = static_cast(elem->call_data); - maybe_del_call_from_channel_interested_parties_locked(elem); - GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem, - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_SCHED(&calld->pick_closure, error); -} - -namespace grpc_core { - -// Performs subchannel pick via LB policy. -class LbPicker { - public: - // Starts a pick on chand->lb_policy. - static void StartLocked(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: starting pick on lb_policy=%p", - chand, calld, chand->lb_policy.get()); - } - // If this is a retry, use the send_initial_metadata payload that - // we've cached; otherwise, use the pending batch. The - // send_initial_metadata batch will be the first pending batch in the - // list, as set by get_batch_index() above. - calld->pick.initial_metadata = - calld->seen_send_initial_metadata - ? &calld->send_initial_metadata - : calld->pending_batches[0] - .batch->payload->send_initial_metadata.send_initial_metadata; - calld->pick.initial_metadata_flags = - calld->seen_send_initial_metadata - ? calld->send_initial_metadata_flags - : calld->pending_batches[0] - .batch->payload->send_initial_metadata - .send_initial_metadata_flags; - GRPC_CLOSURE_INIT(&calld->pick_closure, &LbPicker::DoneLocked, elem, - grpc_combiner_scheduler(chand->combiner)); - calld->pick.on_complete = &calld->pick_closure; - GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback"); - grpc_error* error = GRPC_ERROR_NONE; - const bool pick_done = chand->lb_policy->PickLocked(&calld->pick, &error); - if (GPR_LIKELY(pick_done)) { - // Pick completed synchronously. - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed synchronously", - chand, calld); - } - pick_done_locked(elem, error); - GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback"); - } else { - // Pick will be returned asynchronously. - // Add the polling entity from call_data to the channel_data's - // interested_parties, so that the I/O of the LB policy can be done - // under it. It will be removed in pick_done_locked(). - maybe_add_call_to_channel_interested_parties_locked(elem); - // Request notification on call cancellation. - GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback_cancel"); - grpc_call_combiner_set_notify_on_cancel( - calld->call_combiner, - GRPC_CLOSURE_INIT(&calld->pick_cancel_closure, - &LbPicker::CancelLocked, elem, - grpc_combiner_scheduler(chand->combiner))); - } - } - - private: - // Callback invoked by LoadBalancingPolicy::PickLocked() for async picks. - // Unrefs the LB policy and invokes pick_done_locked(). - static void DoneLocked(void* arg, grpc_error* error) { - grpc_call_element* elem = static_cast(arg); - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed asynchronously", - chand, calld); - } - pick_done_locked(elem, GRPC_ERROR_REF(error)); - GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback"); - } - - // Note: This runs under the client_channel combiner, but will NOT be - // holding the call combiner. - static void CancelLocked(void* arg, grpc_error* error) { - grpc_call_element* elem = static_cast(arg); - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - // Note: chand->lb_policy may have changed since we started our pick, - // in which case we will be cancelling the pick on a policy other than - // the one we started it on. However, this will just be a no-op. - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE && chand->lb_policy != nullptr)) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: cancelling pick from LB policy %p", chand, - calld, chand->lb_policy.get()); - } - chand->lb_policy->CancelPickLocked(&calld->pick, GRPC_ERROR_REF(error)); - } - GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback_cancel"); - } -}; - -} // namespace grpc_core - // Applies service config to the call. Must be invoked once we know // that the resolver has returned results to the channel. static void apply_service_config_to_call_locked(grpc_call_element* elem) { @@ -2892,224 +2349,66 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) { } } -// If the channel is in TRANSIENT_FAILURE and the call is not -// wait_for_ready=true, fails the call and returns true. -static bool fail_call_if_in_transient_failure(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - grpc_transport_stream_op_batch* batch = calld->pending_batches[0].batch; - if (grpc_connectivity_state_check(&chand->state_tracker) == - GRPC_CHANNEL_TRANSIENT_FAILURE && - (batch->payload->send_initial_metadata.send_initial_metadata_flags & - GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) { - pending_batches_fail( - elem, - grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "channel is in state TRANSIENT_FAILURE"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), - true /* yield_call_combiner */); - return true; - } - return false; -} - // Invoked once resolver results are available. -static void process_service_config_and_start_lb_pick_locked( - grpc_call_element* elem) { +static bool maybe_apply_service_config_to_call_locked(void* arg) { + grpc_call_element* elem = static_cast(arg); call_data* calld = static_cast(elem->call_data); // Only get service config data on the first attempt. if (GPR_LIKELY(calld->num_attempts_completed == 0)) { apply_service_config_to_call_locked(elem); // Check this after applying service config, since it may have // affected the call's wait_for_ready value. - if (fail_call_if_in_transient_failure(elem)) return; + if (fail_call_if_in_transient_failure(elem)) return false; } - // Start LB pick. - grpc_core::LbPicker::StartLocked(elem); + return true; } -namespace grpc_core { - -// Handles waiting for a resolver result. -// Used only for the first call on an idle channel. -class ResolverResultWaiter { - public: - explicit ResolverResultWaiter(grpc_call_element* elem) : elem_(elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: deferring pick pending resolver result", - chand, calld); - } - // Add closure to be run when a resolver result is available. - GRPC_CLOSURE_INIT(&done_closure_, &ResolverResultWaiter::DoneLocked, this, - grpc_combiner_scheduler(chand->combiner)); - AddToWaitingList(); - // Set cancellation closure, so that we abort if the call is cancelled. - GRPC_CLOSURE_INIT(&cancel_closure_, &ResolverResultWaiter::CancelLocked, - this, grpc_combiner_scheduler(chand->combiner)); - grpc_call_combiner_set_notify_on_cancel(calld->call_combiner, - &cancel_closure_); - } - - private: - // Adds closure_ to chand->waiting_for_resolver_result_closures. - void AddToWaitingList() { - channel_data* chand = static_cast(elem_->channel_data); - grpc_closure_list_append(&chand->waiting_for_resolver_result_closures, - &done_closure_, GRPC_ERROR_NONE); - } - - // Invoked when a resolver result is available. - static void DoneLocked(void* arg, grpc_error* error) { - ResolverResultWaiter* self = static_cast(arg); - // If CancelLocked() has already run, delete ourselves without doing - // anything. Note that the call stack may have already been destroyed, - // so it's not safe to access anything in elem_. - if (GPR_UNLIKELY(self->finished_)) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "call cancelled before resolver result"); - } - Delete(self); - return; - } - // Otherwise, process the resolver result. - grpc_call_element* elem = self->elem_; - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: resolver failed to return data", - chand, calld); - } - pick_done_locked(elem, GRPC_ERROR_REF(error)); - } else if (GPR_UNLIKELY(chand->resolver == nullptr)) { - // Shutting down. - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: resolver disconnected", chand, - calld); - } - pick_done_locked(elem, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); - } else if (GPR_UNLIKELY(chand->lb_policy == nullptr)) { - // Transient resolver failure. - // If call has wait_for_ready=true, try again; otherwise, fail. - uint32_t send_initial_metadata_flags = - calld->seen_send_initial_metadata - ? calld->send_initial_metadata_flags - : calld->pending_batches[0] - .batch->payload->send_initial_metadata - .send_initial_metadata_flags; - if (send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: resolver returned but no LB policy; " - "wait_for_ready=true; trying again", - chand, calld); - } - // Re-add ourselves to the waiting list. - self->AddToWaitingList(); - // Return early so that we don't set finished_ to true below. - return; - } else { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: resolver returned but no LB policy; " - "wait_for_ready=false; failing", - chand, calld); - } - pick_done_locked( - elem, - grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Name resolution failure"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); - } - } else { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: resolver returned, doing LB pick", - chand, calld); - } - process_service_config_and_start_lb_pick_locked(elem); - } - self->finished_ = true; - } - - // Invoked when the call is cancelled. - // Note: This runs under the client_channel combiner, but will NOT be - // holding the call combiner. - static void CancelLocked(void* arg, grpc_error* error) { - ResolverResultWaiter* self = static_cast(arg); - // If DoneLocked() has already run, delete ourselves without doing anything. - if (GPR_LIKELY(self->finished_)) { - Delete(self); - return; - } - // If we are being cancelled, immediately invoke pick_done_locked() - // to propagate the error back to the caller. - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - grpc_call_element* elem = self->elem_; - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: cancelling call waiting for name " - "resolution", - chand, calld); - } - // Note: Although we are not in the call combiner here, we are - // basically stealing the call combiner from the pending pick, so - // it's safe to call pick_done_locked() here -- we are essentially - // calling it here instead of calling it in DoneLocked(). - pick_done_locked(elem, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick cancelled", &error, 1)); - } - self->finished_ = true; - } - - grpc_call_element* elem_; - grpc_closure done_closure_; - grpc_closure cancel_closure_; - bool finished_ = false; -}; - -} // namespace grpc_core - static void start_pick_locked(void* arg, grpc_error* ignored) { grpc_call_element* elem = static_cast(arg); call_data* calld = static_cast(elem->call_data); channel_data* chand = static_cast(elem->channel_data); - GPR_ASSERT(calld->pick.connected_subchannel == nullptr); + GPR_ASSERT(!calld->have_request); GPR_ASSERT(calld->subchannel_call == nullptr); - if (GPR_LIKELY(chand->lb_policy != nullptr)) { - // We already have resolver results, so process the service config - // and start an LB pick. - process_service_config_and_start_lb_pick_locked(elem); - } else if (GPR_UNLIKELY(chand->resolver == nullptr)) { - pick_done_locked(elem, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); - } else { - // We do not yet have an LB policy, so wait for a resolver result. - if (GPR_UNLIKELY(!chand->started_resolving)) { - start_resolving_locked(chand); - } else { - // Normally, we want to do this check in - // process_service_config_and_start_lb_pick_locked(), so that we - // can honor the wait_for_ready setting in the service config. - // However, if the channel is in TRANSIENT_FAILURE at this point, that - // means that the resolver has returned a failure, so we're not going - // to get a service config right away. In that case, we fail the - // call now based on the wait_for_ready value passed in from the - // application. - if (fail_call_if_in_transient_failure(elem)) return; - } - // Create a new waiter, which will delete itself when done. - grpc_core::New(elem); - // Add the polling entity from call_data to the channel_data's - // interested_parties, so that the I/O of the resolver can be done - // under it. It will be removed in pick_done_locked(). - maybe_add_call_to_channel_interested_parties_locked(elem); + // Normally, we want to do this check until after we've processed the + // service config, so that we can honor the wait_for_ready setting in + // the service config. However, if the channel is in TRANSIENT_FAILURE + // and we don't have an LB policy at this point, that means that the + // resolver has returned a failure, so we're not going to get a service + // config right away. In that case, we fail the call now based on the + // wait_for_ready value passed in from the application. + if (chand->request_router->lb_policy() == nullptr && + fail_call_if_in_transient_failure(elem)) { + return; } + // If this is a retry, use the send_initial_metadata payload that + // we've cached; otherwise, use the pending batch. The + // send_initial_metadata batch will be the first pending batch in the + // list, as set by get_batch_index() above. + // TODO(roth): What if the LB policy needs to add something to the + // call's initial metadata, and then there's a retry? We don't want + // the new metadata to be added twice. We might need to somehow + // allocate the subchannel batch earlier so that we can give the + // subchannel's copy of the metadata batch (which is copied for each + // attempt) to the LB policy instead the one from the parent channel. + grpc_metadata_batch* initial_metadata = + calld->seen_send_initial_metadata + ? &calld->send_initial_metadata + : calld->pending_batches[0] + .batch->payload->send_initial_metadata.send_initial_metadata; + uint32_t* initial_metadata_flags = + calld->seen_send_initial_metadata + ? &calld->send_initial_metadata_flags + : &calld->pending_batches[0] + .batch->payload->send_initial_metadata + .send_initial_metadata_flags; + GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem, + grpc_schedule_on_exec_ctx); + calld->request.Init(calld->owning_call, calld->call_combiner, calld->pollent, + initial_metadata, initial_metadata_flags, + maybe_apply_service_config_to_call_locked, elem, + &calld->pick_closure); + calld->have_request = true; + chand->request_router->RouteCallLocked(calld->request.get()); } // @@ -3249,23 +2548,10 @@ const grpc_channel_filter grpc_client_channel_filter = { "client-channel", }; -static void try_to_connect_locked(void* arg, grpc_error* error_ignored) { - channel_data* chand = static_cast(arg); - if (chand->lb_policy != nullptr) { - chand->lb_policy->ExitIdleLocked(); - } else { - chand->exit_idle_when_lb_policy_arrives = true; - if (!chand->started_resolving && chand->resolver != nullptr) { - start_resolving_locked(chand); - } - } - GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "try_to_connect"); -} - void grpc_client_channel_set_channelz_node( grpc_channel_element* elem, grpc_core::channelz::ClientChannelNode* node) { channel_data* chand = static_cast(elem->channel_data); - chand->channelz_channel = node; + chand->request_router->set_channelz_node(node); } void grpc_client_channel_populate_child_refs( @@ -3273,17 +2559,22 @@ void grpc_client_channel_populate_child_refs( grpc_core::channelz::ChildRefsList* child_subchannels, grpc_core::channelz::ChildRefsList* child_channels) { channel_data* chand = static_cast(elem->channel_data); - if (chand->lb_policy != nullptr) { - chand->lb_policy->FillChildRefsForChannelz(child_subchannels, - child_channels); + if (chand->request_router->lb_policy() != nullptr) { + chand->request_router->lb_policy()->FillChildRefsForChannelz( + child_subchannels, child_channels); } } +static void try_to_connect_locked(void* arg, grpc_error* error_ignored) { + channel_data* chand = static_cast(arg); + chand->request_router->ExitIdleLocked(); + GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "try_to_connect"); +} + grpc_connectivity_state grpc_client_channel_check_connectivity_state( grpc_channel_element* elem, int try_to_connect) { channel_data* chand = static_cast(elem->channel_data); - grpc_connectivity_state out = - grpc_connectivity_state_check(&chand->state_tracker); + grpc_connectivity_state out = chand->request_router->GetConnectivityState(); if (out == GRPC_CHANNEL_IDLE && try_to_connect) { GRPC_CHANNEL_STACK_REF(chand->owning_stack, "try_to_connect"); GRPC_CLOSURE_SCHED( @@ -3328,19 +2619,19 @@ static void external_connectivity_watcher_list_append( } static void external_connectivity_watcher_list_remove( - channel_data* chand, external_connectivity_watcher* too_remove) { + channel_data* chand, external_connectivity_watcher* to_remove) { GPR_ASSERT( - lookup_external_connectivity_watcher(chand, too_remove->on_complete)); + lookup_external_connectivity_watcher(chand, to_remove->on_complete)); gpr_mu_lock(&chand->external_connectivity_watcher_list_mu); - if (too_remove == chand->external_connectivity_watcher_list_head) { - chand->external_connectivity_watcher_list_head = too_remove->next; + if (to_remove == chand->external_connectivity_watcher_list_head) { + chand->external_connectivity_watcher_list_head = to_remove->next; gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); return; } external_connectivity_watcher* w = chand->external_connectivity_watcher_list_head; while (w != nullptr) { - if (w->next == too_remove) { + if (w->next == to_remove) { w->next = w->next->next; gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); return; @@ -3392,15 +2683,15 @@ static void watch_connectivity_state_locked(void* arg, GRPC_CLOSURE_RUN(w->watcher_timer_init, GRPC_ERROR_NONE); GRPC_CLOSURE_INIT(&w->my_closure, on_external_watch_complete_locked, w, grpc_combiner_scheduler(w->chand->combiner)); - grpc_connectivity_state_notify_on_state_change(&w->chand->state_tracker, - w->state, &w->my_closure); + w->chand->request_router->NotifyOnConnectivityStateChange(w->state, + &w->my_closure); } else { GPR_ASSERT(w->watcher_timer_init == nullptr); found = lookup_external_connectivity_watcher(w->chand, w->on_complete); if (found) { GPR_ASSERT(found->on_complete == w->on_complete); - grpc_connectivity_state_notify_on_state_change( - &found->chand->state_tracker, nullptr, &found->my_closure); + found->chand->request_router->NotifyOnConnectivityStateChange( + nullptr, &found->my_closure); } grpc_polling_entity_del_from_pollset_set(&w->pollent, w->chand->interested_parties); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 29b8c28be6a..293d8e960cf 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -65,10 +65,10 @@ class LoadBalancingPolicy : public InternallyRefCounted { struct PickState { /// Initial metadata associated with the picking call. grpc_metadata_batch* initial_metadata = nullptr; - /// Bitmask used for selective cancelling. See + /// Pointer to bitmask used for selective cancelling. See /// \a CancelMatchingPicksLocked() and \a GRPC_INITIAL_METADATA_* in /// grpc_types.h. - uint32_t initial_metadata_flags = 0; + uint32_t* initial_metadata_flags = nullptr; /// Storage for LB token in \a initial_metadata, or nullptr if not used. grpc_linked_mdelem lb_token_mdelem_storage; /// Closure to run when pick is complete, if not completed synchronously. @@ -88,6 +88,9 @@ class LoadBalancingPolicy : public InternallyRefCounted { LoadBalancingPolicy(const LoadBalancingPolicy&) = delete; LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete; + /// Returns the name of the LB policy. + virtual const char* name() const GRPC_ABSTRACT; + /// Updates the policy with a new set of \a args and a new \a lb_config from /// the resolver. Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 3c4f0d6552f..ba40febd534 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -122,10 +122,14 @@ TraceFlag grpc_lb_glb_trace(false, "glb"); namespace { +constexpr char kGrpclb[] = "grpclb"; + class GrpcLb : public LoadBalancingPolicy { public: explicit GrpcLb(const Args& args); + const char* name() const override { return kGrpclb; } + void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; bool PickLocked(PickState* pick, grpc_error** error) override; @@ -1136,7 +1140,7 @@ void GrpcLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, pending_picks_ = nullptr; while (pp != nullptr) { PendingPick* next = pp->next; - if ((pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == + if ((*pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == initial_metadata_flags_eq) { // Note: pp is deleted in this callback. GRPC_CLOSURE_SCHED(&pp->on_complete, @@ -1819,7 +1823,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { return OrphanablePtr(New(args)); } - const char* name() const override { return "grpclb"; } + const char* name() const override { return kGrpclb; } }; } // namespace diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 74c17612a28..d6ff74ec7f7 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -43,10 +43,14 @@ namespace { // pick_first LB policy // +constexpr char kPickFirst[] = "pick_first"; + class PickFirst : public LoadBalancingPolicy { public: explicit PickFirst(const Args& args); + const char* name() const override { return kPickFirst; } + void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; bool PickLocked(PickState* pick, grpc_error** error) override; @@ -234,7 +238,7 @@ void PickFirst::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, pending_picks_ = nullptr; while (pick != nullptr) { PickState* next = pick->next; - if ((pick->initial_metadata_flags & initial_metadata_flags_mask) == + if ((*pick->initial_metadata_flags & initial_metadata_flags_mask) == initial_metadata_flags_eq) { GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -622,7 +626,7 @@ class PickFirstFactory : public LoadBalancingPolicyFactory { return OrphanablePtr(New(args)); } - const char* name() const override { return "pick_first"; } + const char* name() const override { return kPickFirst; } }; } // namespace diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 63089afbd78..3bcb33ef11c 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -53,10 +53,14 @@ namespace { // round_robin LB policy // +constexpr char kRoundRobin[] = "round_robin"; + class RoundRobin : public LoadBalancingPolicy { public: explicit RoundRobin(const Args& args); + const char* name() const override { return kRoundRobin; } + void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; bool PickLocked(PickState* pick, grpc_error** error) override; @@ -291,7 +295,7 @@ void RoundRobin::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, pending_picks_ = nullptr; while (pick != nullptr) { PickState* next = pick->next; - if ((pick->initial_metadata_flags & initial_metadata_flags_mask) == + if ((*pick->initial_metadata_flags & initial_metadata_flags_mask) == initial_metadata_flags_eq) { pick->connected_subchannel.reset(); GRPC_CLOSURE_SCHED(pick->on_complete, @@ -700,7 +704,7 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory { return OrphanablePtr(New(args)); } - const char* name() const override { return "round_robin"; } + const char* name() const override { return kRoundRobin; } }; } // namespace diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 3c25de2386c..8787f5bcc24 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -115,10 +115,14 @@ TraceFlag grpc_lb_xds_trace(false, "xds"); namespace { +constexpr char kXds[] = "xds_experimental"; + class XdsLb : public LoadBalancingPolicy { public: explicit XdsLb(const Args& args); + const char* name() const override { return kXds; } + void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; bool PickLocked(PickState* pick, grpc_error** error) override; @@ -1053,7 +1057,7 @@ void XdsLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, pending_picks_ = nullptr; while (pp != nullptr) { PendingPick* next = pp->next; - if ((pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == + if ((*pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == initial_metadata_flags_eq) { // Note: pp is deleted in this callback. GRPC_CLOSURE_SCHED(&pp->on_complete, @@ -1651,7 +1655,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { return OrphanablePtr(New(args)); } - const char* name() const override { return "xds_experimental"; } + const char* name() const override { return kXds; } }; } // namespace diff --git a/src/core/ext/filters/client_channel/request_routing.cc b/src/core/ext/filters/client_channel/request_routing.cc new file mode 100644 index 00000000000..f9a7e164e75 --- /dev/null +++ b/src/core/ext/filters/client_channel/request_routing.cc @@ -0,0 +1,936 @@ +/* + * + * Copyright 2015 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 + +#include "src/core/ext/filters/client_channel/request_routing.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/http_connect_handshaker.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" +#include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/retry_throttle.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/subchannel.h" +#include "src/core/ext/filters/deadline/deadline_filter.h" +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/status_util.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/error_utils.h" +#include "src/core/lib/transport/metadata.h" +#include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/transport/service_config.h" +#include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/status_metadata.h" + +namespace grpc_core { + +// +// RequestRouter::Request::ResolverResultWaiter +// + +// Handles waiting for a resolver result. +// Used only for the first call on an idle channel. +class RequestRouter::Request::ResolverResultWaiter { + public: + explicit ResolverResultWaiter(Request* request) + : request_router_(request->request_router_), + request_(request), + tracer_enabled_(request_router_->tracer_->enabled()) { + if (tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: deferring pick pending resolver " + "result", + request_router_, request); + } + // Add closure to be run when a resolver result is available. + GRPC_CLOSURE_INIT(&done_closure_, &DoneLocked, this, + grpc_combiner_scheduler(request_router_->combiner_)); + AddToWaitingList(); + // Set cancellation closure, so that we abort if the call is cancelled. + GRPC_CLOSURE_INIT(&cancel_closure_, &CancelLocked, this, + grpc_combiner_scheduler(request_router_->combiner_)); + grpc_call_combiner_set_notify_on_cancel(request->call_combiner_, + &cancel_closure_); + } + + private: + // Adds done_closure_ to + // request_router_->waiting_for_resolver_result_closures_. + void AddToWaitingList() { + grpc_closure_list_append( + &request_router_->waiting_for_resolver_result_closures_, &done_closure_, + GRPC_ERROR_NONE); + } + + // Invoked when a resolver result is available. + static void DoneLocked(void* arg, grpc_error* error) { + ResolverResultWaiter* self = static_cast(arg); + RequestRouter* request_router = self->request_router_; + // If CancelLocked() has already run, delete ourselves without doing + // anything. Note that the call stack may have already been destroyed, + // so it's not safe to access anything in state_. + if (GPR_UNLIKELY(self->finished_)) { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p: call cancelled before resolver result", + request_router); + } + Delete(self); + return; + } + // Otherwise, process the resolver result. + Request* request = self->request_; + if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: resolver failed to return data", + request_router, request); + } + GRPC_CLOSURE_RUN(request->on_route_done_, GRPC_ERROR_REF(error)); + } else if (GPR_UNLIKELY(request_router->resolver_ == nullptr)) { + // Shutting down. + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, "request_router=%p request=%p: resolver disconnected", + request_router, request); + } + GRPC_CLOSURE_RUN(request->on_route_done_, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); + } else if (GPR_UNLIKELY(request_router->lb_policy_ == nullptr)) { + // Transient resolver failure. + // If call has wait_for_ready=true, try again; otherwise, fail. + if (*request->pick_.initial_metadata_flags & + GRPC_INITIAL_METADATA_WAIT_FOR_READY) { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: resolver returned but no LB " + "policy; wait_for_ready=true; trying again", + request_router, request); + } + // Re-add ourselves to the waiting list. + self->AddToWaitingList(); + // Return early so that we don't set finished_ to true below. + return; + } else { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: resolver returned but no LB " + "policy; wait_for_ready=false; failing", + request_router, request); + } + GRPC_CLOSURE_RUN( + request->on_route_done_, + grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Name resolution failure"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); + } + } else { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: resolver returned, doing LB " + "pick", + request_router, request); + } + request->ProcessServiceConfigAndStartLbPickLocked(); + } + self->finished_ = true; + } + + // Invoked when the call is cancelled. + // Note: This runs under the client_channel combiner, but will NOT be + // holding the call combiner. + static void CancelLocked(void* arg, grpc_error* error) { + ResolverResultWaiter* self = static_cast(arg); + RequestRouter* request_router = self->request_router_; + // If DoneLocked() has already run, delete ourselves without doing anything. + if (self->finished_) { + Delete(self); + return; + } + Request* request = self->request_; + // If we are being cancelled, immediately invoke on_route_done_ + // to propagate the error back to the caller. + if (error != GRPC_ERROR_NONE) { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: cancelling call waiting for " + "name resolution", + request_router, request); + } + // Note: Although we are not in the call combiner here, we are + // basically stealing the call combiner from the pending pick, so + // it's safe to run on_route_done_ here -- we are essentially + // calling it here instead of calling it in DoneLocked(). + GRPC_CLOSURE_RUN(request->on_route_done_, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Pick cancelled", &error, 1)); + } + self->finished_ = true; + } + + RequestRouter* request_router_; + Request* request_; + const bool tracer_enabled_; + grpc_closure done_closure_; + grpc_closure cancel_closure_; + bool finished_ = false; +}; + +// +// RequestRouter::Request::AsyncPickCanceller +// + +// Handles the call combiner cancellation callback for an async LB pick. +class RequestRouter::Request::AsyncPickCanceller { + public: + explicit AsyncPickCanceller(Request* request) + : request_router_(request->request_router_), + request_(request), + tracer_enabled_(request_router_->tracer_->enabled()) { + GRPC_CALL_STACK_REF(request->owning_call_, "pick_callback_cancel"); + // Set cancellation closure, so that we abort if the call is cancelled. + GRPC_CLOSURE_INIT(&cancel_closure_, &CancelLocked, this, + grpc_combiner_scheduler(request_router_->combiner_)); + grpc_call_combiner_set_notify_on_cancel(request->call_combiner_, + &cancel_closure_); + } + + void MarkFinishedLocked() { + finished_ = true; + GRPC_CALL_STACK_UNREF(request_->owning_call_, "pick_callback_cancel"); + } + + private: + // Invoked when the call is cancelled. + // Note: This runs under the client_channel combiner, but will NOT be + // holding the call combiner. + static void CancelLocked(void* arg, grpc_error* error) { + AsyncPickCanceller* self = static_cast(arg); + Request* request = self->request_; + RequestRouter* request_router = self->request_router_; + if (!self->finished_) { + // Note: request_router->lb_policy_ may have changed since we started our + // pick, in which case we will be cancelling the pick on a policy other + // than the one we started it on. However, this will just be a no-op. + if (error != GRPC_ERROR_NONE && request_router->lb_policy_ != nullptr) { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: cancelling pick from LB " + "policy %p", + request_router, request, request_router->lb_policy_.get()); + } + request_router->lb_policy_->CancelPickLocked(&request->pick_, + GRPC_ERROR_REF(error)); + } + request->pick_canceller_ = nullptr; + GRPC_CALL_STACK_UNREF(request->owning_call_, "pick_callback_cancel"); + } + Delete(self); + } + + RequestRouter* request_router_; + Request* request_; + const bool tracer_enabled_; + grpc_closure cancel_closure_; + bool finished_ = false; +}; + +// +// RequestRouter::Request +// + +RequestRouter::Request::Request(grpc_call_stack* owning_call, + grpc_call_combiner* call_combiner, + grpc_polling_entity* pollent, + grpc_metadata_batch* send_initial_metadata, + uint32_t* send_initial_metadata_flags, + ApplyServiceConfigCallback apply_service_config, + void* apply_service_config_user_data, + grpc_closure* on_route_done) + : owning_call_(owning_call), + call_combiner_(call_combiner), + pollent_(pollent), + apply_service_config_(apply_service_config), + apply_service_config_user_data_(apply_service_config_user_data), + on_route_done_(on_route_done) { + pick_.initial_metadata = send_initial_metadata; + pick_.initial_metadata_flags = send_initial_metadata_flags; +} + +RequestRouter::Request::~Request() { + if (pick_.connected_subchannel != nullptr) { + pick_.connected_subchannel.reset(); + } + for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) { + if (pick_.subchannel_call_context[i].destroy != nullptr) { + pick_.subchannel_call_context[i].destroy( + pick_.subchannel_call_context[i].value); + } + } +} + +// Invoked once resolver results are available. +void RequestRouter::Request::ProcessServiceConfigAndStartLbPickLocked() { + // Get service config data if needed. + if (!apply_service_config_(apply_service_config_user_data_)) return; + // Start LB pick. + StartLbPickLocked(); +} + +void RequestRouter::Request::MaybeAddCallToInterestedPartiesLocked() { + if (!pollent_added_to_interested_parties_) { + pollent_added_to_interested_parties_ = true; + grpc_polling_entity_add_to_pollset_set( + pollent_, request_router_->interested_parties_); + } +} + +void RequestRouter::Request::MaybeRemoveCallFromInterestedPartiesLocked() { + if (pollent_added_to_interested_parties_) { + pollent_added_to_interested_parties_ = false; + grpc_polling_entity_del_from_pollset_set( + pollent_, request_router_->interested_parties_); + } +} + +// Starts a pick on the LB policy. +void RequestRouter::Request::StartLbPickLocked() { + if (request_router_->tracer_->enabled()) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: starting pick on lb_policy=%p", + request_router_, this, request_router_->lb_policy_.get()); + } + GRPC_CLOSURE_INIT(&on_pick_done_, &LbPickDoneLocked, this, + grpc_combiner_scheduler(request_router_->combiner_)); + pick_.on_complete = &on_pick_done_; + GRPC_CALL_STACK_REF(owning_call_, "pick_callback"); + grpc_error* error = GRPC_ERROR_NONE; + const bool pick_done = + request_router_->lb_policy_->PickLocked(&pick_, &error); + if (pick_done) { + // Pick completed synchronously. + if (request_router_->tracer_->enabled()) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: pick completed synchronously", + request_router_, this); + } + GRPC_CLOSURE_RUN(on_route_done_, error); + GRPC_CALL_STACK_UNREF(owning_call_, "pick_callback"); + } else { + // Pick will be returned asynchronously. + // Add the request's polling entity to the request_router's + // interested_parties, so that the I/O of the LB policy can be done + // under it. It will be removed in LbPickDoneLocked(). + MaybeAddCallToInterestedPartiesLocked(); + // Request notification on call cancellation. + // We allocate a separate object to track cancellation, since the + // cancellation closure might still be pending when we need to reuse + // the memory in which this Request object is stored for a subsequent + // retry attempt. + pick_canceller_ = New(this); + } +} + +// Callback invoked by LoadBalancingPolicy::PickLocked() for async picks. +// Unrefs the LB policy and invokes on_route_done_. +void RequestRouter::Request::LbPickDoneLocked(void* arg, grpc_error* error) { + Request* self = static_cast(arg); + RequestRouter* request_router = self->request_router_; + if (request_router->tracer_->enabled()) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: pick completed asynchronously", + request_router, self); + } + self->MaybeRemoveCallFromInterestedPartiesLocked(); + if (self->pick_canceller_ != nullptr) { + self->pick_canceller_->MarkFinishedLocked(); + } + GRPC_CLOSURE_RUN(self->on_route_done_, GRPC_ERROR_REF(error)); + GRPC_CALL_STACK_UNREF(self->owning_call_, "pick_callback"); +} + +// +// RequestRouter::LbConnectivityWatcher +// + +class RequestRouter::LbConnectivityWatcher { + public: + LbConnectivityWatcher(RequestRouter* request_router, + grpc_connectivity_state state, + LoadBalancingPolicy* lb_policy, + grpc_channel_stack* owning_stack, + grpc_combiner* combiner) + : request_router_(request_router), + state_(state), + lb_policy_(lb_policy), + owning_stack_(owning_stack) { + GRPC_CHANNEL_STACK_REF(owning_stack_, "LbConnectivityWatcher"); + GRPC_CLOSURE_INIT(&on_changed_, &OnLbPolicyStateChangedLocked, this, + grpc_combiner_scheduler(combiner)); + lb_policy_->NotifyOnStateChangeLocked(&state_, &on_changed_); + } + + ~LbConnectivityWatcher() { + GRPC_CHANNEL_STACK_UNREF(owning_stack_, "LbConnectivityWatcher"); + } + + private: + static void OnLbPolicyStateChangedLocked(void* arg, grpc_error* error) { + LbConnectivityWatcher* self = static_cast(arg); + // If the notification is not for the current policy, we're stale, + // so delete ourselves. + if (self->lb_policy_ != self->request_router_->lb_policy_.get()) { + Delete(self); + return; + } + // Otherwise, process notification. + if (self->request_router_->tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: lb_policy=%p state changed to %s", + self->request_router_, self->lb_policy_, + grpc_connectivity_state_name(self->state_)); + } + self->request_router_->SetConnectivityStateLocked( + self->state_, GRPC_ERROR_REF(error), "lb_changed"); + // If shutting down, terminate watch. + if (self->state_ == GRPC_CHANNEL_SHUTDOWN) { + Delete(self); + return; + } + // Renew watch. + self->lb_policy_->NotifyOnStateChangeLocked(&self->state_, + &self->on_changed_); + } + + RequestRouter* request_router_; + grpc_connectivity_state state_; + // LB policy address. No ref held, so not safe to dereference unless + // it happens to match request_router->lb_policy_. + LoadBalancingPolicy* lb_policy_; + grpc_channel_stack* owning_stack_; + grpc_closure on_changed_; +}; + +// +// RequestRounter::ReresolutionRequestHandler +// + +class RequestRouter::ReresolutionRequestHandler { + public: + ReresolutionRequestHandler(RequestRouter* request_router, + LoadBalancingPolicy* lb_policy, + grpc_channel_stack* owning_stack, + grpc_combiner* combiner) + : request_router_(request_router), + lb_policy_(lb_policy), + owning_stack_(owning_stack) { + GRPC_CHANNEL_STACK_REF(owning_stack_, "ReresolutionRequestHandler"); + GRPC_CLOSURE_INIT(&closure_, &OnRequestReresolutionLocked, this, + grpc_combiner_scheduler(combiner)); + lb_policy_->SetReresolutionClosureLocked(&closure_); + } + + private: + static void OnRequestReresolutionLocked(void* arg, grpc_error* error) { + ReresolutionRequestHandler* self = + static_cast(arg); + RequestRouter* request_router = self->request_router_; + // If this invocation is for a stale LB policy, treat it as an LB shutdown + // signal. + if (self->lb_policy_ != request_router->lb_policy_.get() || + error != GRPC_ERROR_NONE || request_router->resolver_ == nullptr) { + GRPC_CHANNEL_STACK_UNREF(request_router->owning_stack_, + "ReresolutionRequestHandler"); + Delete(self); + return; + } + if (request_router->tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: started name re-resolving", + request_router); + } + request_router->resolver_->RequestReresolutionLocked(); + // Give back the closure to the LB policy. + self->lb_policy_->SetReresolutionClosureLocked(&self->closure_); + } + + RequestRouter* request_router_; + // LB policy address. No ref held, so not safe to dereference unless + // it happens to match request_router->lb_policy_. + LoadBalancingPolicy* lb_policy_; + grpc_channel_stack* owning_stack_; + grpc_closure closure_; +}; + +// +// RequestRouter +// + +RequestRouter::RequestRouter( + grpc_channel_stack* owning_stack, grpc_combiner* combiner, + grpc_client_channel_factory* client_channel_factory, + grpc_pollset_set* interested_parties, TraceFlag* tracer, + ProcessResolverResultCallback process_resolver_result, + void* process_resolver_result_user_data, const char* target_uri, + const grpc_channel_args* args, grpc_error** error) + : owning_stack_(owning_stack), + combiner_(combiner), + client_channel_factory_(client_channel_factory), + interested_parties_(interested_parties), + tracer_(tracer), + process_resolver_result_(process_resolver_result), + process_resolver_result_user_data_(process_resolver_result_user_data) { + GRPC_CLOSURE_INIT(&on_resolver_result_changed_, + &RequestRouter::OnResolverResultChangedLocked, this, + grpc_combiner_scheduler(combiner)); + grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, + "request_router"); + grpc_channel_args* new_args = nullptr; + if (process_resolver_result == nullptr) { + grpc_arg arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION), 0); + new_args = grpc_channel_args_copy_and_add(args, &arg, 1); + } + resolver_ = ResolverRegistry::CreateResolver( + target_uri, (new_args == nullptr ? args : new_args), interested_parties_, + combiner_); + grpc_channel_args_destroy(new_args); + if (resolver_ == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); + } +} + +RequestRouter::~RequestRouter() { + if (resolver_ != nullptr) { + // The only way we can get here is if we never started resolving, + // because we take a ref to the channel stack when we start + // resolving and do not release it until the resolver callback is + // invoked after the resolver shuts down. + resolver_.reset(); + } + if (lb_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties_); + lb_policy_.reset(); + } + if (client_channel_factory_ != nullptr) { + grpc_client_channel_factory_unref(client_channel_factory_); + } + grpc_connectivity_state_destroy(&state_tracker_); +} + +namespace { + +const char* GetChannelConnectivityStateChangeString( + grpc_connectivity_state state) { + switch (state) { + case GRPC_CHANNEL_IDLE: + return "Channel state change to IDLE"; + case GRPC_CHANNEL_CONNECTING: + return "Channel state change to CONNECTING"; + case GRPC_CHANNEL_READY: + return "Channel state change to READY"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "Channel state change to TRANSIENT_FAILURE"; + case GRPC_CHANNEL_SHUTDOWN: + return "Channel state change to SHUTDOWN"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +} // namespace + +void RequestRouter::SetConnectivityStateLocked(grpc_connectivity_state state, + grpc_error* error, + const char* reason) { + if (lb_policy_ != nullptr) { + if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) { + // Cancel picks with wait_for_ready=false. + lb_policy_->CancelMatchingPicksLocked( + /* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY, + /* check= */ 0, GRPC_ERROR_REF(error)); + } else if (state == GRPC_CHANNEL_SHUTDOWN) { + // Cancel all picks. + lb_policy_->CancelMatchingPicksLocked(/* mask= */ 0, /* check= */ 0, + GRPC_ERROR_REF(error)); + } + } + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: setting connectivity state to %s", + this, grpc_connectivity_state_name(state)); + } + if (channelz_node_ != nullptr) { + channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string( + GetChannelConnectivityStateChangeString(state))); + } + grpc_connectivity_state_set(&state_tracker_, state, error, reason); +} + +void RequestRouter::StartResolvingLocked() { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: starting name resolution", this); + } + GPR_ASSERT(!started_resolving_); + started_resolving_ = true; + GRPC_CHANNEL_STACK_REF(owning_stack_, "resolver"); + resolver_->NextLocked(&resolver_result_, &on_resolver_result_changed_); +} + +// Invoked from the resolver NextLocked() callback when the resolver +// is shutting down. +void RequestRouter::OnResolverShutdownLocked(grpc_error* error) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: shutting down", this); + } + if (lb_policy_ != nullptr) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: shutting down lb_policy=%p", this, + lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties_); + lb_policy_.reset(); + } + if (resolver_ != nullptr) { + // This should never happen; it can only be triggered by a resolver + // implementation spotaneously deciding to report shutdown without + // being orphaned. This code is included just to be defensive. + if (tracer_->enabled()) { + gpr_log(GPR_INFO, + "request_router=%p: spontaneous shutdown from resolver %p", this, + resolver_.get()); + } + resolver_.reset(); + SetConnectivityStateLocked(GRPC_CHANNEL_SHUTDOWN, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Resolver spontaneous shutdown", &error, 1), + "resolver_spontaneous_shutdown"); + } + grpc_closure_list_fail_all(&waiting_for_resolver_result_closures_, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Channel disconnected", &error, 1)); + GRPC_CLOSURE_LIST_SCHED(&waiting_for_resolver_result_closures_); + GRPC_CHANNEL_STACK_UNREF(owning_stack_, "resolver"); + grpc_channel_args_destroy(resolver_result_); + resolver_result_ = nullptr; + GRPC_ERROR_UNREF(error); +} + +// Creates a new LB policy, replacing any previous one. +// If the new policy is created successfully, sets *connectivity_state and +// *connectivity_error to its initial connectivity state; otherwise, +// leaves them unchanged. +void RequestRouter::CreateNewLbPolicyLocked( + const char* lb_policy_name, grpc_json* lb_config, + grpc_connectivity_state* connectivity_state, + grpc_error** connectivity_error, TraceStringVector* trace_strings) { + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.combiner = combiner_; + lb_policy_args.client_channel_factory = client_channel_factory_; + lb_policy_args.args = resolver_result_; + lb_policy_args.lb_config = lb_config; + OrphanablePtr new_lb_policy = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(lb_policy_name, + lb_policy_args); + if (GPR_UNLIKELY(new_lb_policy == nullptr)) { + gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); + if (channelz_node_ != nullptr) { + char* str; + gpr_asprintf(&str, "Could not create LB policy \'%s\'", lb_policy_name); + trace_strings->push_back(str); + } + } else { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: created new LB policy \"%s\" (%p)", + this, lb_policy_name, new_lb_policy.get()); + } + if (channelz_node_ != nullptr) { + char* str; + gpr_asprintf(&str, "Created new LB policy \'%s\'", lb_policy_name); + trace_strings->push_back(str); + } + // Swap out the LB policy and update the fds in interested_parties_. + if (lb_policy_ != nullptr) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: shutting down lb_policy=%p", this, + lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties_); + lb_policy_->HandOffPendingPicksLocked(new_lb_policy.get()); + } + lb_policy_ = std::move(new_lb_policy); + grpc_pollset_set_add_pollset_set(lb_policy_->interested_parties(), + interested_parties_); + // Create re-resolution request handler for the new LB policy. It + // will delete itself when no longer needed. + New(this, lb_policy_.get(), owning_stack_, + combiner_); + // Get the new LB policy's initial connectivity state and start a + // connectivity watch. + GRPC_ERROR_UNREF(*connectivity_error); + *connectivity_state = + lb_policy_->CheckConnectivityLocked(connectivity_error); + if (exit_idle_when_lb_policy_arrives_) { + lb_policy_->ExitIdleLocked(); + exit_idle_when_lb_policy_arrives_ = false; + } + // Create new watcher. It will delete itself when done. + New(this, *connectivity_state, lb_policy_.get(), + owning_stack_, combiner_); + } +} + +void RequestRouter::MaybeAddTraceMessagesForAddressChangesLocked( + TraceStringVector* trace_strings) { + const ServerAddressList* addresses = + FindServerAddressListChannelArg(resolver_result_); + const bool resolution_contains_addresses = + addresses != nullptr && addresses->size() > 0; + if (!resolution_contains_addresses && + previous_resolution_contained_addresses_) { + trace_strings->push_back(gpr_strdup("Address list became empty")); + } else if (resolution_contains_addresses && + !previous_resolution_contained_addresses_) { + trace_strings->push_back(gpr_strdup("Address list became non-empty")); + } + previous_resolution_contained_addresses_ = resolution_contains_addresses; +} + +void RequestRouter::ConcatenateAndAddChannelTraceLocked( + TraceStringVector* trace_strings) const { + if (!trace_strings->empty()) { + gpr_strvec v; + gpr_strvec_init(&v); + gpr_strvec_add(&v, gpr_strdup("Resolution event: ")); + bool is_first = 1; + for (size_t i = 0; i < trace_strings->size(); ++i) { + if (!is_first) gpr_strvec_add(&v, gpr_strdup(", ")); + is_first = false; + gpr_strvec_add(&v, (*trace_strings)[i]); + } + char* flat; + size_t flat_len = 0; + flat = gpr_strvec_flatten(&v, &flat_len); + channelz_node_->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_new(flat, flat_len, gpr_free)); + gpr_strvec_destroy(&v); + } +} + +// Callback invoked when a resolver result is available. +void RequestRouter::OnResolverResultChangedLocked(void* arg, + grpc_error* error) { + RequestRouter* self = static_cast(arg); + if (self->tracer_->enabled()) { + const char* disposition = + self->resolver_result_ != nullptr + ? "" + : (error == GRPC_ERROR_NONE ? " (transient error)" + : " (resolver shutdown)"); + gpr_log(GPR_INFO, + "request_router=%p: got resolver result: resolver_result=%p " + "error=%s%s", + self, self->resolver_result_, grpc_error_string(error), + disposition); + } + // Handle shutdown. + if (error != GRPC_ERROR_NONE || self->resolver_ == nullptr) { + self->OnResolverShutdownLocked(GRPC_ERROR_REF(error)); + return; + } + // Data used to set the channel's connectivity state. + bool set_connectivity_state = true; + // We only want to trace the address resolution in the follow cases: + // (a) Address resolution resulted in service config change. + // (b) Address resolution that causes number of backends to go from + // zero to non-zero. + // (c) Address resolution that causes number of backends to go from + // non-zero to zero. + // (d) Address resolution that causes a new LB policy to be created. + // + // we track a list of strings to eventually be concatenated and traced. + TraceStringVector trace_strings; + grpc_connectivity_state connectivity_state = GRPC_CHANNEL_TRANSIENT_FAILURE; + grpc_error* connectivity_error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy"); + // resolver_result_ will be null in the case of a transient + // resolution error. In that case, we don't have any new result to + // process, which means that we keep using the previous result (if any). + if (self->resolver_result_ == nullptr) { + if (self->tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: resolver transient failure", self); + } + // Don't override connectivity state if we already have an LB policy. + if (self->lb_policy_ != nullptr) set_connectivity_state = false; + } else { + // Parse the resolver result. + const char* lb_policy_name = nullptr; + grpc_json* lb_policy_config = nullptr; + const bool service_config_changed = self->process_resolver_result_( + self->process_resolver_result_user_data_, *self->resolver_result_, + &lb_policy_name, &lb_policy_config); + GPR_ASSERT(lb_policy_name != nullptr); + // Check to see if we're already using the right LB policy. + const bool lb_policy_name_changed = + self->lb_policy_ == nullptr || + strcmp(self->lb_policy_->name(), lb_policy_name) != 0; + if (self->lb_policy_ != nullptr && !lb_policy_name_changed) { + // Continue using the same LB policy. Update with new addresses. + if (self->tracer_->enabled()) { + gpr_log(GPR_INFO, + "request_router=%p: updating existing LB policy \"%s\" (%p)", + self, lb_policy_name, self->lb_policy_.get()); + } + self->lb_policy_->UpdateLocked(*self->resolver_result_, lb_policy_config); + // No need to set the channel's connectivity state; the existing + // watch on the LB policy will take care of that. + set_connectivity_state = false; + } else { + // Instantiate new LB policy. + self->CreateNewLbPolicyLocked(lb_policy_name, lb_policy_config, + &connectivity_state, &connectivity_error, + &trace_strings); + } + // Add channel trace event. + if (self->channelz_node_ != nullptr) { + if (service_config_changed) { + // TODO(ncteisen): might be worth somehow including a snippet of the + // config in the trace, at the risk of bloating the trace logs. + trace_strings.push_back(gpr_strdup("Service config changed")); + } + self->MaybeAddTraceMessagesForAddressChangesLocked(&trace_strings); + self->ConcatenateAndAddChannelTraceLocked(&trace_strings); + } + // Clean up. + grpc_channel_args_destroy(self->resolver_result_); + self->resolver_result_ = nullptr; + } + // Set the channel's connectivity state if needed. + if (set_connectivity_state) { + self->SetConnectivityStateLocked(connectivity_state, connectivity_error, + "resolver_result"); + } else { + GRPC_ERROR_UNREF(connectivity_error); + } + // Invoke closures that were waiting for results and renew the watch. + GRPC_CLOSURE_LIST_SCHED(&self->waiting_for_resolver_result_closures_); + self->resolver_->NextLocked(&self->resolver_result_, + &self->on_resolver_result_changed_); +} + +void RequestRouter::RouteCallLocked(Request* request) { + GPR_ASSERT(request->pick_.connected_subchannel == nullptr); + request->request_router_ = this; + if (lb_policy_ != nullptr) { + // We already have resolver results, so process the service config + // and start an LB pick. + request->ProcessServiceConfigAndStartLbPickLocked(); + } else if (resolver_ == nullptr) { + GRPC_CLOSURE_RUN(request->on_route_done_, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); + } else { + // We do not yet have an LB policy, so wait for a resolver result. + if (!started_resolving_) { + StartResolvingLocked(); + } + // Create a new waiter, which will delete itself when done. + New(request); + // Add the request's polling entity to the request_router's + // interested_parties, so that the I/O of the resolver can be done + // under it. It will be removed in LbPickDoneLocked(). + request->MaybeAddCallToInterestedPartiesLocked(); + } +} + +void RequestRouter::ShutdownLocked(grpc_error* error) { + if (resolver_ != nullptr) { + SetConnectivityStateLocked(GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), + "disconnect"); + resolver_.reset(); + if (!started_resolving_) { + grpc_closure_list_fail_all(&waiting_for_resolver_result_closures_, + GRPC_ERROR_REF(error)); + GRPC_CLOSURE_LIST_SCHED(&waiting_for_resolver_result_closures_); + } + if (lb_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties_); + lb_policy_.reset(); + } + } + GRPC_ERROR_UNREF(error); +} + +grpc_connectivity_state RequestRouter::GetConnectivityState() { + return grpc_connectivity_state_check(&state_tracker_); +} + +void RequestRouter::NotifyOnConnectivityStateChange( + grpc_connectivity_state* state, grpc_closure* closure) { + grpc_connectivity_state_notify_on_state_change(&state_tracker_, state, + closure); +} + +void RequestRouter::ExitIdleLocked() { + if (lb_policy_ != nullptr) { + lb_policy_->ExitIdleLocked(); + } else { + exit_idle_when_lb_policy_arrives_ = true; + if (!started_resolving_ && resolver_ != nullptr) { + StartResolvingLocked(); + } + } +} + +void RequestRouter::ResetConnectionBackoffLocked() { + if (resolver_ != nullptr) { + resolver_->ResetBackoffLocked(); + resolver_->RequestReresolutionLocked(); + } + if (lb_policy_ != nullptr) { + lb_policy_->ResetBackoffLocked(); + } +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/request_routing.h b/src/core/ext/filters/client_channel/request_routing.h new file mode 100644 index 00000000000..0c671229c8e --- /dev/null +++ b/src/core/ext/filters/client_channel/request_routing.h @@ -0,0 +1,177 @@ +/* + * + * 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. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H + +#include + +#include "src/core/ext/filters/client_channel/client_channel_channelz.h" +#include "src/core/ext/filters/client_channel/client_channel_factory.h" +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/resolver.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/iomgr/call_combiner.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/metadata_batch.h" + +namespace grpc_core { + +class RequestRouter { + public: + class Request { + public: + // Synchronous callback that applies the service config to a call. + // Returns false if the call should be failed. + typedef bool (*ApplyServiceConfigCallback)(void* user_data); + + Request(grpc_call_stack* owning_call, grpc_call_combiner* call_combiner, + grpc_polling_entity* pollent, + grpc_metadata_batch* send_initial_metadata, + uint32_t* send_initial_metadata_flags, + ApplyServiceConfigCallback apply_service_config, + void* apply_service_config_user_data, grpc_closure* on_route_done); + + ~Request(); + + // TODO(roth): It seems a bit ugly to expose this member in a + // non-const way. Find a better API to avoid this. + LoadBalancingPolicy::PickState* pick() { return &pick_; } + + private: + friend class RequestRouter; + + class ResolverResultWaiter; + class AsyncPickCanceller; + + void ProcessServiceConfigAndStartLbPickLocked(); + void StartLbPickLocked(); + static void LbPickDoneLocked(void* arg, grpc_error* error); + + void MaybeAddCallToInterestedPartiesLocked(); + void MaybeRemoveCallFromInterestedPartiesLocked(); + + // Populated by caller. + grpc_call_stack* owning_call_; + grpc_call_combiner* call_combiner_; + grpc_polling_entity* pollent_; + ApplyServiceConfigCallback apply_service_config_; + void* apply_service_config_user_data_; + grpc_closure* on_route_done_; + LoadBalancingPolicy::PickState pick_; + + // Internal state. + RequestRouter* request_router_ = nullptr; + bool pollent_added_to_interested_parties_ = false; + grpc_closure on_pick_done_; + AsyncPickCanceller* pick_canceller_ = nullptr; + }; + + // Synchronous callback that takes the service config JSON string and + // LB policy name. + // Returns true if the service config has changed since the last result. + typedef bool (*ProcessResolverResultCallback)(void* user_data, + const grpc_channel_args& args, + const char** lb_policy_name, + grpc_json** lb_policy_config); + + RequestRouter(grpc_channel_stack* owning_stack, grpc_combiner* combiner, + grpc_client_channel_factory* client_channel_factory, + grpc_pollset_set* interested_parties, TraceFlag* tracer, + ProcessResolverResultCallback process_resolver_result, + void* process_resolver_result_user_data, const char* target_uri, + const grpc_channel_args* args, grpc_error** error); + + ~RequestRouter(); + + void set_channelz_node(channelz::ClientChannelNode* channelz_node) { + channelz_node_ = channelz_node; + } + + void RouteCallLocked(Request* request); + + // TODO(roth): Add methods to cancel picks. + + void ShutdownLocked(grpc_error* error); + + void ExitIdleLocked(); + void ResetConnectionBackoffLocked(); + + grpc_connectivity_state GetConnectivityState(); + void NotifyOnConnectivityStateChange(grpc_connectivity_state* state, + grpc_closure* closure); + + LoadBalancingPolicy* lb_policy() const { return lb_policy_.get(); } + + private: + using TraceStringVector = grpc_core::InlinedVector; + + class ReresolutionRequestHandler; + class LbConnectivityWatcher; + + void StartResolvingLocked(); + void OnResolverShutdownLocked(grpc_error* error); + void CreateNewLbPolicyLocked(const char* lb_policy_name, grpc_json* lb_config, + grpc_connectivity_state* connectivity_state, + grpc_error** connectivity_error, + TraceStringVector* trace_strings); + void MaybeAddTraceMessagesForAddressChangesLocked( + TraceStringVector* trace_strings); + void ConcatenateAndAddChannelTraceLocked( + TraceStringVector* trace_strings) const; + static void OnResolverResultChangedLocked(void* arg, grpc_error* error); + + void SetConnectivityStateLocked(grpc_connectivity_state state, + grpc_error* error, const char* reason); + + // Passed in from caller at construction time. + grpc_channel_stack* owning_stack_; + grpc_combiner* combiner_; + grpc_client_channel_factory* client_channel_factory_; + grpc_pollset_set* interested_parties_; + TraceFlag* tracer_; + + channelz::ClientChannelNode* channelz_node_ = nullptr; + + // Resolver and associated state. + OrphanablePtr resolver_; + ProcessResolverResultCallback process_resolver_result_; + void* process_resolver_result_user_data_; + bool started_resolving_ = false; + grpc_channel_args* resolver_result_ = nullptr; + bool previous_resolution_contained_addresses_ = false; + grpc_closure_list waiting_for_resolver_result_closures_; + grpc_closure on_resolver_result_changed_; + + // LB policy and associated state. + OrphanablePtr lb_policy_; + bool exit_idle_when_lb_policy_arrives_ = false; + + grpc_connectivity_state_tracker state_tracker_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H */ diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 22b06db45c4..9a0122e8ece 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -43,16 +43,16 @@ namespace grpc_core { namespace internal { ProcessedResolverResult::ProcessedResolverResult( - const grpc_channel_args* resolver_result, bool parse_retry) { + const grpc_channel_args& resolver_result, bool parse_retry) { ProcessServiceConfig(resolver_result, parse_retry); // If no LB config was found above, just find the LB policy name then. if (lb_policy_name_ == nullptr) ProcessLbPolicyName(resolver_result); } void ProcessedResolverResult::ProcessServiceConfig( - const grpc_channel_args* resolver_result, bool parse_retry) { + const grpc_channel_args& resolver_result, bool parse_retry) { const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result, GRPC_ARG_SERVICE_CONFIG); + grpc_channel_args_find(&resolver_result, GRPC_ARG_SERVICE_CONFIG); const char* service_config_json = grpc_channel_arg_get_string(channel_arg); if (service_config_json != nullptr) { service_config_json_.reset(gpr_strdup(service_config_json)); @@ -60,7 +60,7 @@ void ProcessedResolverResult::ProcessServiceConfig( if (service_config_ != nullptr) { if (parse_retry) { channel_arg = - grpc_channel_args_find(resolver_result, GRPC_ARG_SERVER_URI); + grpc_channel_args_find(&resolver_result, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(channel_arg); GPR_ASSERT(server_uri != nullptr); grpc_uri* uri = grpc_uri_parse(server_uri, true); @@ -78,7 +78,7 @@ void ProcessedResolverResult::ProcessServiceConfig( } void ProcessedResolverResult::ProcessLbPolicyName( - const grpc_channel_args* resolver_result) { + const grpc_channel_args& resolver_result) { // Prefer the LB policy name found in the service config. Note that this is // checking the deprecated loadBalancingPolicy field, rather than the new // loadBalancingConfig field. @@ -96,13 +96,13 @@ void ProcessedResolverResult::ProcessLbPolicyName( // Otherwise, find the LB policy name set by the client API. if (lb_policy_name_ == nullptr) { const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result, GRPC_ARG_LB_POLICY_NAME); + grpc_channel_args_find(&resolver_result, GRPC_ARG_LB_POLICY_NAME); lb_policy_name_.reset(gpr_strdup(grpc_channel_arg_get_string(channel_arg))); } // Special case: If at least one balancer address is present, we use // the grpclb policy, regardless of what the resolver has returned. const ServerAddressList* addresses = - FindServerAddressListChannelArg(resolver_result); + FindServerAddressListChannelArg(&resolver_result); if (addresses != nullptr) { bool found_balancer_address = false; for (size_t i = 0; i < addresses->size(); ++i) { diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index f1fb7406bcb..98a9d26c467 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -36,8 +36,7 @@ namespace internal { class ClientChannelMethodParams; // A table mapping from a method name to its method parameters. -typedef grpc_core::SliceHashTable< - grpc_core::RefCountedPtr> +typedef SliceHashTable> ClientChannelMethodParamsTable; // A container of processed fields from the resolver result. Simplifies the @@ -47,33 +46,30 @@ class ProcessedResolverResult { // Processes the resolver result and populates the relative members // for later consumption. Tries to parse retry parameters only if parse_retry // is true. - ProcessedResolverResult(const grpc_channel_args* resolver_result, + ProcessedResolverResult(const grpc_channel_args& resolver_result, bool parse_retry); // Getters. Any managed object's ownership is transferred. - grpc_core::UniquePtr service_config_json() { + UniquePtr service_config_json() { return std::move(service_config_json_); } - grpc_core::RefCountedPtr retry_throttle_data() { + RefCountedPtr retry_throttle_data() { return std::move(retry_throttle_data_); } - grpc_core::RefCountedPtr - method_params_table() { + RefCountedPtr method_params_table() { return std::move(method_params_table_); } - grpc_core::UniquePtr lb_policy_name() { - return std::move(lb_policy_name_); - } + UniquePtr lb_policy_name() { return std::move(lb_policy_name_); } grpc_json* lb_policy_config() { return lb_policy_config_; } private: // Finds the service config; extracts LB config and (maybe) retry throttle // params from it. - void ProcessServiceConfig(const grpc_channel_args* resolver_result, + void ProcessServiceConfig(const grpc_channel_args& resolver_result, bool parse_retry); // Finds the LB policy name (when no LB config was found). - void ProcessLbPolicyName(const grpc_channel_args* resolver_result); + void ProcessLbPolicyName(const grpc_channel_args& resolver_result); // Parses the service config. Intended to be used by // ServiceConfig::ParseGlobalParams. @@ -85,16 +81,16 @@ class ProcessedResolverResult { void ParseRetryThrottleParamsFromServiceConfig(const grpc_json* field); // Service config. - grpc_core::UniquePtr service_config_json_; - grpc_core::UniquePtr service_config_; + UniquePtr service_config_json_; + UniquePtr service_config_; // LB policy. grpc_json* lb_policy_config_ = nullptr; - grpc_core::UniquePtr lb_policy_name_; + UniquePtr lb_policy_name_; // Retry throttle data. char* server_name_ = nullptr; - grpc_core::RefCountedPtr retry_throttle_data_; + RefCountedPtr retry_throttle_data_; // Method params table. - grpc_core::RefCountedPtr method_params_table_; + RefCountedPtr method_params_table_; }; // The parameters of a method. diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index c6ca970beee..6a1fd676ca6 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -326,6 +326,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 5011e19b03a..ba2eaecafda 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -932,6 +932,8 @@ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper.h \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.h \ +src/core/ext/filters/client_channel/request_routing.cc \ +src/core/ext/filters/client_channel/request_routing.h \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver.h \ src/core/ext/filters/client_channel/resolver/README.md \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 46e5d54c851..336d499be9d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9840,6 +9840,7 @@ "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", + "src/core/ext/filters/client_channel/request_routing.h", "src/core/ext/filters/client_channel/resolver.h", "src/core/ext/filters/client_channel/resolver_factory.h", "src/core/ext/filters/client_channel/resolver_registry.h", @@ -9882,6 +9883,8 @@ "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", + "src/core/ext/filters/client_channel/request_routing.cc", + "src/core/ext/filters/client_channel/request_routing.h", "src/core/ext/filters/client_channel/resolver.cc", "src/core/ext/filters/client_channel/resolver.h", "src/core/ext/filters/client_channel/resolver_factory.h", From 05b61a5199dd69e33011ed0e677d9d43a77c01a4 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 20 Dec 2018 12:10:53 -0800 Subject: [PATCH 384/534] Use Pylint to lint gRPC Python examples --- .pylintrc-examples | 100 ++++++++++++++++++ .../helloworld/greeter_client_with_options.py | 2 +- tools/distrib/pylint_code.sh | 6 ++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 .pylintrc-examples diff --git a/.pylintrc-examples b/.pylintrc-examples new file mode 100644 index 00000000000..9480d6ea56a --- /dev/null +++ b/.pylintrc-examples @@ -0,0 +1,100 @@ +[MASTER] +ignore= + src/python/grpcio/grpc/beta, + src/python/grpcio/grpc/framework, + src/python/grpcio/grpc/framework/common, + src/python/grpcio/grpc/framework/foundation, + src/python/grpcio/grpc/framework/interfaces, + +[VARIABLES] + +# TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection +# not include "unused_" and "ignored_" by default? +dummy-variables-rgx=^ignored_|^unused_ + +[DESIGN] + +# NOTE(nathaniel): Not particularly attached to this value; it just seems to +# be what works for us at the moment (excepting the dead-code-walking Beta +# API). +max-args=6 + +[MISCELLANEOUS] + +# NOTE(nathaniel): We are big fans of "TODO(): " and +# "NOTE(): ". We do not allow "TODO:", +# "TODO():", "FIXME:", or anything else. +notes=FIXME,XXX + +[MESSAGES CONTROL] + +disable= + # -- START OF EXAMPLE-SPECIFIC SUPPRESSIONS -- + no-self-use, + unused-argument, + unused-variable, + # -- END OF EXAMPLE-SPECIFIC SUPPRESSIONS -- + + # TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279): + # Enable cyclic-import after a 1.7-or-later pylint release that + # recognizes our disable=cyclic-import suppressions. + cyclic-import, + # TODO(https://github.com/grpc/grpc/issues/8622): Enable this after the + # Beta API is removed. + duplicate-code, + # TODO(https://github.com/grpc/grpc/issues/261): Doesn't seem to + # understand enum and concurrent.futures; look into this later with the + # latest pylint version. + import-error, + # TODO(https://github.com/grpc/grpc/issues/261): Enable this one. + # Should take a little configuration but not much. + invalid-name, + # TODO(https://github.com/grpc/grpc/issues/261): This doesn't seem to + # work for now? Try with a later pylint? + locally-disabled, + # NOTE(nathaniel): What even is this? *Enabling* an inspection results + # in a warning? How does that encourage more analysis and coverage? + locally-enabled, + # NOTE(nathaniel): We don't write doc strings for most private code + # elements. + missing-docstring, + # NOTE(nathaniel): In numeric comparisons it is better to have the + # lesser (or lesser-or-equal-to) quantity on the left when the + # expression is true than it is to worry about which is an identifier + # and which a literal value. + misplaced-comparison-constant, + # NOTE(nathaniel): Our completely abstract interface classes don't have + # constructors. + no-init, + # TODO(https://github.com/grpc/grpc/issues/261): Doesn't yet play + # nicely with some of our code being implemented in Cython. Maybe in a + # later version? + no-name-in-module, + # TODO(https://github.com/grpc/grpc/issues/261): Suppress these where + # the odd shape of the authentication portion of the API forces them on + # us and enable everywhere else. + protected-access, + # NOTE(nathaniel): Pylint and I will probably never agree on this. + too-few-public-methods, + # NOTE(nathaniel): Pylint and I wil probably never agree on this for + # private classes. For public classes maybe? + too-many-instance-attributes, + # NOTE(nathaniel): Some of our modules have a lot of lines... of + # specification and documentation. Maybe if this were + # lines-of-code-based we would use it. + too-many-lines, + # TODO(https://github.com/grpc/grpc/issues/261): Maybe we could have + # this one if we extracted just a few more helper functions... + too-many-nested-blocks, + # TODO(https://github.com/grpc/grpc/issues/261): Disable unnecessary + # super-init requirement for abstract class implementations for now. + super-init-not-called, + # NOTE(nathaniel): A single statement that always returns program + # control is better than two statements the first of which sometimes + # returns program control and the second of which always returns + # program control. Probably generally, but definitely in the cases of + # if:/else: and for:/else:. + useless-else-on-loop, + no-else-return, + # NOTE(lidiz): Python 3 make object inheritance default, but not PY2 + useless-object-inheritance, diff --git a/examples/python/helloworld/greeter_client_with_options.py b/examples/python/helloworld/greeter_client_with_options.py index d15871b5195..e9ab5508ddd 100644 --- a/examples/python/helloworld/greeter_client_with_options.py +++ b/examples/python/helloworld/greeter_client_with_options.py @@ -11,7 +11,7 @@ # 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. -"""The Python implementation of the GRPC helloworld.Greeter client with channel options and call timeout parameters.""" +"""gRPC Python helloworld.Greeter client with channel options and call timeout parameters.""" from __future__ import print_function import logging diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh index 00507775031..abb37dde0ed 100755 --- a/tools/distrib/pylint_code.sh +++ b/tools/distrib/pylint_code.sh @@ -48,4 +48,10 @@ for dir in "${TEST_DIRS[@]}"; do $PYTHON -m pylint --rcfile=.pylintrc-tests -rn "$dir" || EXIT=1 done +find examples/python \ + -iname "*.py" \ + -not -name "*_pb2.py" \ + -not -name "*_pb2_grpc.py" \ + | xargs $PYTHON -m pylint --rcfile=.pylintrc-examples -rn + exit $EXIT From 1ac4a01a0edd9c1c790157d436b9c76e49b2c539 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 20 Dec 2018 12:13:08 -0800 Subject: [PATCH 385/534] Fix Complain of Higher Version Pylint --- src/python/grpcio_status/grpc_status/rpc_status.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio_status/grpc_status/rpc_status.py b/src/python/grpcio_status/grpc_status/rpc_status.py index e23a20968ec..87618fa5412 100644 --- a/src/python/grpcio_status/grpc_status/rpc_status.py +++ b/src/python/grpcio_status/grpc_status/rpc_status.py @@ -24,7 +24,7 @@ import grpc import google.protobuf # pylint: disable=unused-import from google.rpc import status_pb2 -_CODE_TO_GRPC_CODE_MAPPING = dict([(x.value[0], x) for x in grpc.StatusCode]) +_CODE_TO_GRPC_CODE_MAPPING = {x.value[0]: x for x in grpc.StatusCode} _GRPC_DETAILS_METADATA_KEY = 'grpc-status-details-bin' From 30e1991bf93e010964ccaf326081398ed3cd4e4e Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 20 Dec 2018 13:22:48 -0800 Subject: [PATCH 386/534] Update context list test --- test/core/transport/chttp2/context_list_test.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/core/transport/chttp2/context_list_test.cc b/test/core/transport/chttp2/context_list_test.cc index edbe658a89f..0379eaaee4c 100644 --- a/test/core/transport/chttp2/context_list_test.cc +++ b/test/core/transport/chttp2/context_list_test.cc @@ -36,8 +36,12 @@ namespace { const uint32_t kByteOffset = 123; -void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts) { +void* DummyArgsCopier(void* arg) { return arg; } + +void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts, + grpc_error* error) { ASSERT_NE(arg, nullptr); + EXPECT_EQ(error, GRPC_ERROR_NONE); EXPECT_EQ(ts->byte_offset, kByteOffset); gpr_atm* done = reinterpret_cast(arg); gpr_atm_rel_store(done, static_cast(1)); @@ -52,6 +56,7 @@ void discard_write(grpc_slice slice) {} TEST(ContextList, ExecuteFlushesList) { grpc_core::ContextList* list = nullptr; grpc_http2_set_write_timestamps_callback(TestExecuteFlushesListVerifier); + grpc_http2_set_fn_get_copied_context(DummyArgsCopier); const int kNumElems = 5; grpc_core::ExecCtx exec_ctx; grpc_stream_refcount ref; From d6dd6f25f4e900d6099098d5d1f0bd52f0581750 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 20 Dec 2018 15:37:30 -0800 Subject: [PATCH 387/534] Correctly reference the internal string for socket mutator arg --- src/cpp/common/channel_arguments.cc | 2 ++ test/cpp/common/channel_arguments_test.cc | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index 50ee9d871f0..214d72f853f 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -106,7 +106,9 @@ void ChannelArguments::SetSocketMutator(grpc_socket_mutator* mutator) { } if (!replaced) { + strings_.push_back(grpc::string(mutator_arg.key)); args_.push_back(mutator_arg); + args_.back().key = const_cast(strings_.back().c_str()); } } diff --git a/test/cpp/common/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc index 183d2afa783..12fd9784f47 100644 --- a/test/cpp/common/channel_arguments_test.cc +++ b/test/cpp/common/channel_arguments_test.cc @@ -209,6 +209,9 @@ TEST_F(ChannelArgumentsTest, SetSocketMutator) { channel_args_.SetSocketMutator(mutator0); EXPECT_TRUE(HasArg(arg0)); + // Exercise the copy constructor because we ran some sanity checks in it. + grpc::ChannelArguments new_args{channel_args_}; + channel_args_.SetSocketMutator(mutator1); EXPECT_TRUE(HasArg(arg1)); // arg0 is replaced by arg1 From b09ed93d02197235471e6e65df2df2cbeb506f50 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 20 Dec 2018 16:16:00 -0800 Subject: [PATCH 388/534] Revert changes to Context list cleanup --- .../transport/chttp2/transport/chttp2_transport.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 9e03c90ccb9..78833723a2c 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -170,6 +170,14 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { grpc_slice_buffer_destroy_internal(&outbuf); grpc_chttp2_hpack_compressor_destroy(&hpack_compressor); + grpc_error* error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"); + // ContextList::Execute follows semantics of a callback function and does not + // take a ref on error + grpc_core::ContextList::Execute(t->cl, nullptr, error); + GRPC_ERROR_UNREF(error); + t->cl = nullptr; + grpc_slice_buffer_destroy_internal(&read_buffer); grpc_chttp2_hpack_parser_destroy(&hpack_parser); grpc_chttp2_goaway_parser_destroy(&goaway_parser); @@ -566,10 +574,6 @@ static void close_transport_locked(grpc_chttp2_transport* t, grpc_error* error) { end_all_the_calls(t, GRPC_ERROR_REF(error)); cancel_pings(t, GRPC_ERROR_REF(error)); - // ContextList::Execute follows semantics of a callback function and does not - // need a ref on error - grpc_core::ContextList::Execute(t->cl, nullptr, error); - t->cl = nullptr; if (t->closed_with_error == GRPC_ERROR_NONE) { if (!grpc_error_has_clear_grpc_status(error)) { error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, From 810a93e783bb3bb8a3f736fefd46793241100481 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 21 Dec 2018 10:55:20 +0100 Subject: [PATCH 389/534] inject extra details to Bazel RBE links --- .../linux/grpc_bazel_on_foundry_base.sh | 1 + tools/remote_build/workspace_status_kokoro.sh | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100755 tools/remote_build/workspace_status_kokoro.sh diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index d35bbbd2756..4d7d4271d61 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -44,6 +44,7 @@ bazel \ --bazelrc=tools/remote_build/kokoro.bazelrc \ test \ --invocation_id="${BAZEL_INVOCATION_ID}" \ + --workspace_status_command=tools/remote_build/workspace_status_kokoro.sh \ $@ \ -- //test/... || FAILED="true" diff --git a/tools/remote_build/workspace_status_kokoro.sh b/tools/remote_build/workspace_status_kokoro.sh new file mode 100755 index 00000000000..8d5db7f8bd5 --- /dev/null +++ b/tools/remote_build/workspace_status_kokoro.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Copyright 2018 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. + +# Adds additional labels to results page for Bazel RBE builds on Kokoro + +# Provide a way to go from Bazel RBE links back to Kokoro job results +# which is important for debugging test infrastructure problems. +# TODO(jtattermusch): replace this workaround by something more user-friendly. +echo "KOKORO_RESULTSTORE_URL https://source.cloud.google.com/results/invocations/${KOKORO_BUILD_ID}" +echo "KOKORO_SPONGE_URL http://sponge.corp.google.com/${KOKORO_BUILD_ID}" + +echo "KOKORO_BUILD_NUMBER ${KOKORO_BUILD_NUMBER}" +echo "KOKORO_JOB_NAME ${KOKORO_JOB_NAME}" +echo "KOKORO_GITHUB_COMMIT ${KOKORO_GITHUB_COMMIT}" From c4c4b9152fb0359f2c1e47191c0c4f7195be859f Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 21 Dec 2018 10:57:54 -0800 Subject: [PATCH 390/534] WIP --- .../filters/client_channel/client_channel.cc | 93 +++------ .../ext/filters/client_channel/lb_policy.h | 5 + test/cpp/end2end/client_lb_end2end_test.cc | 178 ++++++++++-------- 3 files changed, 137 insertions(+), 139 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index fe1a5a2e4eb..cc34178d619 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -545,13 +545,6 @@ struct call_data { bool have_request = false; grpc_closure pick_closure; - // A closure to fork notifying the lb interceptor and run the original trailer - // interception callback. - grpc_closure recv_trailing_metadata_ready_for_lb; - // The original trailer interception callback. - grpc_closure* original_recv_trailing_metadata_ready = nullptr; - grpc_transport_stream_op_batch* recv_trailing_metadata_op_batch = nullptr; - grpc_polling_entity* pollent = nullptr; // Batches are added to this list when received from above. @@ -612,8 +605,6 @@ static void start_internal_recv_trailing_metadata(grpc_call_element* elem); static void on_complete(void* arg, grpc_error* error); static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored); static void start_pick_locked(void* arg, grpc_error* ignored); -static void maybe_intercept_trailing_metadata_for_lb( - grpc_call_element* arg, grpc_transport_stream_op_batch* batch); // // send op data caching @@ -736,6 +727,25 @@ static void free_cached_send_op_data_for_completed_batch( } } +// +// LB recv_trailing_metadata_ready handling +// + +void maybe_inject_recv_trailing_metadata_ready_for_lb( + const grpc_core::LoadBalancingPolicy::PickState& pick, + grpc_transport_stream_op_batch* batch) { + if (pick.recv_trailing_metadata_ready != nullptr) { + *pick.original_recv_trailing_metadata_ready = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + pick.recv_trailing_metadata_ready; + if (pick.recv_trailing_metadata != nullptr) { + *pick.recv_trailing_metadata = + batch->payload->recv_trailing_metadata.recv_trailing_metadata; + } + } +} + // // pending_batches management // @@ -860,6 +870,10 @@ static void pending_batches_fail(grpc_call_element* elem, grpc_error* error, pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { + if (batch->recv_trailing_metadata) { + maybe_inject_recv_trailing_metadata_ready_for_lb( + *calld->request->pick(), batch); + } batch->handler_private.extra_arg = calld; GRPC_CLOSURE_INIT(&batch->handler_private.closure, fail_pending_batch_in_call_combiner, batch, @@ -912,7 +926,10 @@ static void pending_batches_resume(grpc_call_element* elem) { pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { - maybe_intercept_trailing_metadata_for_lb(elem, batch); + if (batch->recv_trailing_metadata) { + maybe_inject_recv_trailing_metadata_ready_for_lb( + *calld->request->pick(), batch); + } batch->handler_private.extra_arg = calld->subchannel_call; GRPC_CLOSURE_INIT(&batch->handler_private.closure, resume_pending_batch_in_call_combiner, batch, @@ -1582,8 +1599,7 @@ static void run_closures_for_completed_call(subchannel_batch_data* batch_data, // Intercepts recv_trailing_metadata_ready callback for retries. // Commits the call and returns the trailing metadata up the stack. -static void recv_trailing_metadata_ready_for_retries( - void* arg, grpc_error* error) { +static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { subchannel_batch_data* batch_data = static_cast(arg); grpc_call_element* elem = batch_data->elem; channel_data* chand = static_cast(elem->channel_data); @@ -1603,16 +1619,6 @@ static void recv_trailing_metadata_ready_for_retries( grpc_mdelem* server_pushback_md = nullptr; grpc_metadata_batch* md_batch = batch_data->batch.payload->recv_trailing_metadata.recv_trailing_metadata; - // If the lb policy asks for the trailing metadata, set its receiving ptr - if (calld->pick.recv_trailing_metadata != nullptr) { - *calld->pick.recv_trailing_metadata = md_batch; - } - // We use GRPC_CLOSURE_RUN synchronously on the callback. In the case of - // a retry, we would have already freed the metadata before returning from - // this function. - GRPC_CLOSURE_RUN( - calld->pick.recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, &server_pushback_md); if (grpc_client_channel_trace.enabled()) { @@ -1948,11 +1954,13 @@ static void add_retriable_recv_trailing_metadata_op( batch_data->batch.payload->recv_trailing_metadata.collect_stats = &retry_state->collect_stats; GRPC_CLOSURE_INIT(&retry_state->recv_trailing_metadata_ready, - recv_trailing_metadata_ready_for_retries, batch_data, + recv_trailing_metadata_ready, batch_data, grpc_schedule_on_exec_ctx); batch_data->batch.payload->recv_trailing_metadata .recv_trailing_metadata_ready = &retry_state->recv_trailing_metadata_ready; + maybe_inject_recv_trailing_metadata_ready_for_lb(*calld->request->pick(), + &batch_data->batch); } // Helper function used to start a recv_trailing_metadata batch. This @@ -2222,45 +2230,6 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { // LB pick // -// The callback to intercept trailing metadata if retries is not enabled -static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { - grpc_call_element* elem = static_cast(arg); - call_data* calld = static_cast(elem->call_data); - if (calld->pick.recv_trailing_metadata != nullptr) { - *calld->pick.recv_trailing_metadata = - calld->recv_trailing_metadata_op_batch->payload - ->recv_trailing_metadata.recv_trailing_metadata; - } - GRPC_CLOSURE_SCHED( - calld->pick.recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); - GRPC_CLOSURE_SCHED( - calld->original_recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); - GRPC_ERROR_UNREF(error); -} - -// If needed, intercepts the recv_trailing_metadata_ready callback to return -// trailing metadata to the LB policy. -static void maybe_intercept_trailing_metadata_for_lb( - grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { - call_data* calld = static_cast(elem->call_data); - if (!batch->recv_trailing_metadata) { - return; - } - if (calld->pick.recv_trailing_metadata_ready != nullptr) { - calld->recv_trailing_metadata_op_batch = batch; - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_for_lb, - recv_trailing_metadata_ready_for_lb, - elem, - grpc_schedule_on_exec_ctx); - calld->original_recv_trailing_metadata_ready = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &calld->recv_trailing_metadata_ready_for_lb; - } -} - static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 709eee7de83..dea8f4fa69f 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -77,6 +77,11 @@ class LoadBalancingPolicy : public InternallyRefCounted { // Callback set by lb policy to be notified of trailing metadata. // The callback must be scheduled on grpc_schedule_on_exec_ctx. grpc_closure* recv_trailing_metadata_ready = nullptr; + // The address that will be set to point to the original + // recv_trailing_metadata_ready callback, to be invoked by the LB + // policy's recv_trailing_metadata_ready callback when complete. + // Must be non-null if recv_trailing_metadata_ready is non-null. + grpc_closure** original_recv_trailing_metadata_ready = nullptr; // If this is not nullptr, then the client channel will point it to the // call's trailing metadata before invoking recv_trailing_metadata_ready. // If this is nullptr, then the callback will still be called. diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index bdc4d8edf67..328f28e3db6 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -35,24 +35,25 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channelz.h" -#include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/error.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" -#include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/cpp/client/secure_credentials.h" #include "src/cpp/server/secure_server_credentials.h" @@ -61,7 +62,6 @@ #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" - #include using grpc::testing::EchoRequest; @@ -1231,22 +1231,32 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { EnableDefaultHealthCheckService(false); } +grpc_core::TraceFlag forwarding_lb_tracer(false, "forwarding_lb"); + // A minimal forwarding class to avoid implementing a standalone test LB. class ForwardingLoadBalancingPolicy : public grpc_core::LoadBalancingPolicy { public: - ForwardingLoadBalancingPolicy( - const Args& args, - const std::string& delegate_policy_name) - : grpc_core::LoadBalancingPolicy(args), args_{args} { - delegate_ = grpc_core::LoadBalancingPolicyRegistry - ::CreateLoadBalancingPolicy(delegate_policy_name.c_str(), args); - grpc_pollset_set_add_pollset_set( - delegate_->interested_parties(), - interested_parties()); + ForwardingLoadBalancingPolicy(const Args& args, + const std::string& delegate_policy_name) + : grpc_core::LoadBalancingPolicy(args) { + delegate_ = + grpc_core::LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + delegate_policy_name.c_str(), args); + grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), + interested_parties()); + // Give re-resolution closure to delegate. + GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, + OnDelegateRequestReresolutionLocked, this, + grpc_combiner_scheduler(combiner())); + Ref().release(); // held by callback. + delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); } - void UpdateLocked(const grpc_channel_args& args) override { - delegate_->UpdateLocked(args); + const char* name() const override { return delegate_->name(); } + + void UpdateLocked(const grpc_channel_args& args, + grpc_json* lb_config) override { + delegate_->UpdateLocked(args, lb_config); } bool PickLocked(PickState* pick, grpc_error** error) override { @@ -1260,10 +1270,8 @@ class ForwardingLoadBalancingPolicy : public grpc_core::LoadBalancingPolicy { void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, uint32_t initial_metadata_flags_eq, grpc_error* error) override { - delegate_->CancelMatchingPicksLocked( - initial_metadata_flags_mask, - initial_metadata_flags_eq, - error); + delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, + initial_metadata_flags_eq, error); } void NotifyOnStateChangeLocked(grpc_connectivity_state* state, @@ -1280,13 +1288,9 @@ class ForwardingLoadBalancingPolicy : public grpc_core::LoadBalancingPolicy { delegate_->HandOffPendingPicksLocked(new_policy); } - void ExitIdleLocked() override{ - delegate_->ExitIdleLocked(); - } + void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } - void ResetBackoffLocked() override { - delegate_->ResetBackoffLocked(); - } + void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } void FillChildRefsForChannelz( grpc_core::channelz::ChildRefsList* child_subchannels, @@ -1295,13 +1299,24 @@ class ForwardingLoadBalancingPolicy : public grpc_core::LoadBalancingPolicy { } protected: - void ShutdownLocked() override { - // noop - } - Args args_; + void ShutdownLocked() override { delegate_.reset(); } private: + static void OnDelegateRequestReresolutionLocked(void* arg, + grpc_error* error) { + ForwardingLoadBalancingPolicy* self = + static_cast(arg); + if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { + self->Unref(); + return; + } + self->TryReresolutionLocked(&forwarding_lb_tracer, GRPC_ERROR_NONE); + self->delegate_->SetReresolutionClosureLocked( + &self->on_delegate_request_reresolution_); + } + grpc_core::OrphanablePtr delegate_; + grpc_closure on_delegate_request_reresolution_; }; class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { @@ -1314,71 +1329,81 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { grpc_core::New(this))); } - void TearDown() override { - ClientLbEnd2endTest::TearDown(); - } + void TearDown() override { ClientLbEnd2endTest::TearDown(); } class InterceptTrailingLb : public ForwardingLoadBalancingPolicy { public: - InterceptTrailingLb( - const Args& args, - const std::string& delegate_lb_policy_name, - ClientLbInterceptTrailingMetadataTest* test) + InterceptTrailingLb(const Args& args, + const std::string& delegate_lb_policy_name, + ClientLbInterceptTrailingMetadataTest* test) : ForwardingLoadBalancingPolicy(args, delegate_lb_policy_name), - test_{test} { - } + test_(test) {} bool PickLocked(PickState* pick, grpc_error** error) override { bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); - // If these asserts fail, then we will need to add code to - // proxy the results to the delegate LB. - GPR_ASSERT(pick->recv_trailing_metadata == nullptr); - GPR_ASSERT(pick->recv_trailing_metadata_ready == nullptr); - // OK to add add callbacks for test - GRPC_CLOSURE_INIT( - &recv_trailing_metadata_ready_, - InterceptTrailingLb::RecordRecvTrailingMetadata, - this, - grpc_schedule_on_exec_ctx); - pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; - pick->recv_trailing_metadata = &recv_trailing_metadata_; + // Note: This assumes that the delegate policy does not + // intercepting recv_trailing_metadata. If we ever need to use + // this with a delegate policy that does, then we'll need to + // handle async pick returns separately. + new TrailingMetadataHandler(pick, test_); // deletes itself return ret; } - static void RecordRecvTrailingMetadata(void* arg, grpc_error* err) { - InterceptTrailingLb* lb = static_cast(arg); - GPR_ASSERT(err == GRPC_ERROR_NONE); - GPR_ASSERT(lb->recv_trailing_metadata_ != nullptr); - // an simple check to make sure the trailing metadata is valid - GPR_ASSERT(grpc_get_status_code_from_metadata( - lb->recv_trailing_metadata_->idx.named.grpc_status->md) == - grpc_status_code::GRPC_STATUS_OK); - GRPC_ERROR_UNREF(err); - lb->test_->ReportTrailerIntercepted(); - } - private: - grpc_closure recv_trailing_metadata_ready_; - grpc_metadata_batch* recv_trailing_metadata_; + class TrailingMetadataHandler { + public: + TrailingMetadataHandler(PickState* pick, + ClientLbInterceptTrailingMetadataTest* test) + : test_(test) { + GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, + RecordRecvTrailingMetadata, this, + grpc_schedule_on_exec_ctx); + pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; + pick->original_recv_trailing_metadata_ready = + &original_recv_trailing_metadata_ready_; + pick->recv_trailing_metadata = &recv_trailing_metadata_; + } + + private: + static void RecordRecvTrailingMetadata(void* arg, grpc_error* err) { + TrailingMetadataHandler* self = + static_cast(arg); + GPR_ASSERT(self->recv_trailing_metadata_ != nullptr); + // a simple check to make sure the trailing metadata is valid + GPR_ASSERT( + grpc_get_status_code_from_metadata( + self->recv_trailing_metadata_->idx.named.grpc_status->md) == + grpc_status_code::GRPC_STATUS_OK); + self->test_->ReportTrailerIntercepted(); + GRPC_CLOSURE_SCHED(self->original_recv_trailing_metadata_ready_, + GRPC_ERROR_REF(err)); + delete self; + } + + ClientLbInterceptTrailingMetadataTest* test_; + grpc_closure recv_trailing_metadata_ready_; + grpc_closure* original_recv_trailing_metadata_ready_ = nullptr; + grpc_metadata_batch* recv_trailing_metadata_ = nullptr; + }; + ClientLbInterceptTrailingMetadataTest* test_; }; // A factory for a test LB policy that intercepts trailing metadata. // The LB policy is implemented as a wrapper around a delegate LB policy. - class InterceptTrailingFactory : - public grpc_core::LoadBalancingPolicyFactory { + class InterceptTrailingFactory + : public grpc_core::LoadBalancingPolicyFactory { public: - InterceptTrailingFactory(ClientLbInterceptTrailingMetadataTest* test): - test_{test} {} + explicit InterceptTrailingFactory( + ClientLbInterceptTrailingMetadataTest* test) + : test_(test) {} grpc_core::OrphanablePtr CreateLoadBalancingPolicy( const grpc_core::LoadBalancingPolicy::Args& args) const override { return grpc_core::OrphanablePtr( grpc_core::New( - args, - /*delegate_lb_policy_name=*/ "pick_first", - test_)); + args, /*delegate_lb_policy_name=*/ "pick_first", test_)); } const char* name() const override { @@ -1394,14 +1419,14 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { trailers_intercepted_++; } - uint32_t trailers_intercepted() { + int trailers_intercepted() { std::unique_lock lock(mu_); return trailers_intercepted_; } private: std::mutex mu_; - uint32_t trailers_intercepted_ = 0; + int trailers_intercepted_ = 0; }; TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesDisabled) { @@ -1418,9 +1443,8 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesDisabled) { CheckRpcSendOk(stub, DEBUG_LOCATION); } // Check LB policy name for the channel. - EXPECT_EQ( - "intercept_trailing_metadata_lb", - channel->GetLoadBalancingPolicyName()); + EXPECT_EQ("intercept_trailing_metadata_lb", + channel->GetLoadBalancingPolicyName()); EXPECT_EQ(kNumServers, trailers_intercepted()); } From 15460eb3c9f58ba7f8a4db9bebff0aaa00b57d27 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 21 Dec 2018 13:36:59 -0800 Subject: [PATCH 391/534] Fix error --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 78833723a2c..7f4627fa773 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -174,9 +174,9 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"); // ContextList::Execute follows semantics of a callback function and does not // take a ref on error - grpc_core::ContextList::Execute(t->cl, nullptr, error); + grpc_core::ContextList::Execute(cl, nullptr, error); GRPC_ERROR_UNREF(error); - t->cl = nullptr; + cl = nullptr; grpc_slice_buffer_destroy_internal(&read_buffer); grpc_chttp2_hpack_parser_destroy(&hpack_parser); From 50eaf4671814f017ed44ce9a220025c87e1a1cc2 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 20 Dec 2018 17:35:12 -0800 Subject: [PATCH 392/534] Refactor benchmark initial channel wait for ready to be single threaded --- test/cpp/qps/client.h | 89 +++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 668d9419169..73f91eed2d8 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -429,13 +429,7 @@ class ClientImpl : public Client { config.server_targets(i % config.server_targets_size()), config, create_stub_, i); } - std::vector> connecting_threads; - for (auto& c : channels_) { - connecting_threads.emplace_back(c.WaitForReady()); - } - for (auto& t : connecting_threads) { - t->join(); - } + WaitForChannelsToConnect(); median_latency_collection_interval_seconds_ = config.median_latency_collection_interval_millis() / 1e3; ClientRequestCreator create_req(&request_, @@ -443,6 +437,61 @@ class ClientImpl : public Client { } virtual ~ClientImpl() {} + void WaitForChannelsToConnect() { + int connect_deadline_seconds = 10; + /* Allow optionally overriding connect_deadline in order + * to deal with benchmark environments in which the server + * can take a long time to become ready. */ + char* channel_connect_timeout_str = + gpr_getenv("QPS_WORKER_CHANNEL_CONNECT_TIMEOUT"); + if (channel_connect_timeout_str != nullptr && + strcmp(channel_connect_timeout_str, "") != 0) { + connect_deadline_seconds = atoi(channel_connect_timeout_str); + } + gpr_log(GPR_INFO, + "Waiting for up to %d seconds for all channels to connect", + connect_deadline_seconds); + gpr_free(channel_connect_timeout_str); + gpr_timespec connect_deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(connect_deadline_seconds, GPR_TIMESPAN)); + CompletionQueue cq; + size_t num_remaining = 0; + for (auto& c : channels_) { + if (!c.is_inproc()) { + Channel* channel = c.get_channel(); + grpc_connectivity_state last_observed = channel->GetState(true); + if (last_observed == GRPC_CHANNEL_READY) { + gpr_log(GPR_INFO, "Channel %p connected!", channel); + } else { + num_remaining++; + channel->NotifyOnStateChange(last_observed, connect_deadline, &cq, + channel); + } + } + } + while (num_remaining > 0) { + bool ok = false; + void* tag = nullptr; + cq.Next(&tag, &ok); + Channel* channel = static_cast(tag); + if (!ok) { + gpr_log(GPR_ERROR, "Channel %p failed to connect within the deadline", + channel); + abort(); + } else { + grpc_connectivity_state last_observed = channel->GetState(true); + if (last_observed == GRPC_CHANNEL_READY) { + gpr_log(GPR_INFO, "Channel %p connected!", channel); + num_remaining--; + } else { + channel->NotifyOnStateChange(last_observed, connect_deadline, &cq, + channel); + } + } + } + } + protected: const int cores_; RequestType request_; @@ -485,31 +534,7 @@ class ClientImpl : public Client { } Channel* get_channel() { return channel_.get(); } StubType* get_stub() { return stub_.get(); } - - std::unique_ptr WaitForReady() { - return std::unique_ptr(new std::thread([this]() { - if (!is_inproc_) { - int connect_deadline = 10; - /* Allow optionally overriding connect_deadline in order - * to deal with benchmark environments in which the server - * can take a long time to become ready. */ - char* channel_connect_timeout_str = - gpr_getenv("QPS_WORKER_CHANNEL_CONNECT_TIMEOUT"); - if (channel_connect_timeout_str != nullptr && - strcmp(channel_connect_timeout_str, "") != 0) { - connect_deadline = atoi(channel_connect_timeout_str); - } - gpr_log(GPR_INFO, - "Waiting for up to %d seconds for the channel %p to connect", - connect_deadline, channel_.get()); - gpr_free(channel_connect_timeout_str); - GPR_ASSERT(channel_->WaitForConnected(gpr_time_add( - gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(connect_deadline, GPR_TIMESPAN)))); - gpr_log(GPR_INFO, "Channel %p connected!", channel_.get()); - } - })); - } + bool is_inproc() { return is_inproc_; } private: void set_channel_args(const ClientConfig& config, ChannelArguments* args) { From 2f029bade0cdadcfdd955773bd43cc2f061cd3f7 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 19 Dec 2018 09:44:38 -0800 Subject: [PATCH 393/534] Clean up server and channel objects in tests --- .../health_check/_health_servicer_test.py | 8 +++-- .../reflection/_reflection_servicer_test.py | 8 +++-- .../grpcio_tests/tests/unit/_api_test.py | 1 + .../tests/unit/_auth_context_test.py | 6 ++-- .../tests/unit/_channel_connectivity_test.py | 6 +++- .../tests/unit/_channel_ready_future_test.py | 5 ++++ .../tests/unit/_compression_test.py | 5 ++++ .../tests/unit/_empty_message_test.py | 1 + .../unit/_error_message_encoding_test.py | 1 + .../tests/unit/_interceptor_test.py | 1 + .../tests/unit/_invalid_metadata_test.py | 3 ++ .../tests/unit/_invocation_defects_test.py | 1 + .../tests/unit/_metadata_code_details_test.py | 14 +++++---- .../tests/unit/_metadata_flags_test.py | 29 ++++++++++--------- .../grpcio_tests/tests/unit/_metadata_test.py | 1 + .../tests/unit/_reconnect_test.py | 2 ++ .../tests/unit/_resource_exhausted_test.py | 1 + .../grpcio_tests/tests/unit/_rpc_test.py | 1 + 18 files changed, 68 insertions(+), 26 deletions(-) diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index 350b5eebe5b..c1d9436c2fa 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -39,8 +39,12 @@ class HealthServicerTest(unittest.TestCase): health_pb2_grpc.add_HealthServicer_to_server(servicer, self._server) self._server.start() - channel = grpc.insecure_channel('localhost:%d' % port) - self._stub = health_pb2_grpc.HealthStub(channel) + self._channel = grpc.insecure_channel('localhost:%d' % port) + self._stub = health_pb2_grpc.HealthStub(self._channel) + + def tearDown(self): + self._server.stop(None) + self._channel.close() def test_empty_service(self): request = health_pb2.HealthCheckRequest() diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py index bcd9e14a386..560f6d3ddb3 100644 --- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py +++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py @@ -56,8 +56,12 @@ class ReflectionServicerTest(unittest.TestCase): port = self._server.add_insecure_port('[::]:0') self._server.start() - channel = grpc.insecure_channel('localhost:%d' % port) - self._stub = reflection_pb2_grpc.ServerReflectionStub(channel) + self._channel = grpc.insecure_channel('localhost:%d' % port) + self._stub = reflection_pb2_grpc.ServerReflectionStub(self._channel) + + def tearDown(self): + self._server.stop(None) + self._channel.close() def testFileByName(self): requests = ( diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py index 427894bfe9f..0dc6a8718c3 100644 --- a/src/python/grpcio_tests/tests/unit/_api_test.py +++ b/src/python/grpcio_tests/tests/unit/_api_test.py @@ -101,6 +101,7 @@ class ChannelTest(unittest.TestCase): def test_secure_channel(self): channel_credentials = grpc.ssl_channel_credentials() channel = grpc.secure_channel('google.com:443', channel_credentials) + channel.close() if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_auth_context_test.py b/src/python/grpcio_tests/tests/unit/_auth_context_test.py index b1b5bbdcab3..96c4e9ec76a 100644 --- a/src/python/grpcio_tests/tests/unit/_auth_context_test.py +++ b/src/python/grpcio_tests/tests/unit/_auth_context_test.py @@ -71,8 +71,8 @@ class AuthContextTest(unittest.TestCase): port = server.add_insecure_port('[::]:0') server.start() - channel = grpc.insecure_channel('localhost:%d' % port) - response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + with grpc.insecure_channel('localhost:%d' % port) as channel: + response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) server.stop(None) auth_data = pickle.loads(response) @@ -98,6 +98,7 @@ class AuthContextTest(unittest.TestCase): channel_creds, options=_PROPERTY_OPTIONS) response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + channel.close() server.stop(None) auth_data = pickle.loads(response) @@ -132,6 +133,7 @@ class AuthContextTest(unittest.TestCase): options=_PROPERTY_OPTIONS) response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + channel.close() server.stop(None) auth_data = pickle.loads(response) diff --git a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py index 727fb7d65fe..565bd39b3aa 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py @@ -75,6 +75,8 @@ class ChannelConnectivityTest(unittest.TestCase): channel.unsubscribe(callback.update) fifth_connectivities = callback.connectivities() + channel.close() + self.assertSequenceEqual((grpc.ChannelConnectivity.IDLE,), first_connectivities) self.assertNotIn(grpc.ChannelConnectivity.READY, second_connectivities) @@ -108,7 +110,8 @@ class ChannelConnectivityTest(unittest.TestCase): _ready_in_connectivities) second_callback.block_until_connectivities_satisfy( _ready_in_connectivities) - del channel + channel.close() + server.stop(None) self.assertSequenceEqual((grpc.ChannelConnectivity.IDLE,), first_connectivities) @@ -139,6 +142,7 @@ class ChannelConnectivityTest(unittest.TestCase): callback.block_until_connectivities_satisfy( _last_connectivity_is_not_ready) channel.unsubscribe(callback.update) + channel.close() self.assertFalse(thread_pool.was_used()) diff --git a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py index 345460ef40d..46a4eb9bb60 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py @@ -60,6 +60,8 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertTrue(ready_future.done()) self.assertFalse(ready_future.running()) + channel.close() + def test_immediately_connectable_channel_connectivity(self): thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) server = grpc.server(thread_pool, options=(('grpc.so_reuseport', 0),)) @@ -84,6 +86,9 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertFalse(ready_future.running()) self.assertFalse(thread_pool.was_used()) + channel.close() + server.stop(None) + if __name__ == '__main__': logging.basicConfig() diff --git a/src/python/grpcio_tests/tests/unit/_compression_test.py b/src/python/grpcio_tests/tests/unit/_compression_test.py index 876d8e827ea..87884a19dc0 100644 --- a/src/python/grpcio_tests/tests/unit/_compression_test.py +++ b/src/python/grpcio_tests/tests/unit/_compression_test.py @@ -77,6 +77,9 @@ class CompressionTest(unittest.TestCase): self._port = self._server.add_insecure_port('[::]:0') self._server.start() + def tearDown(self): + self._server.stop(None) + def testUnary(self): request = b'\x00' * 100 @@ -102,6 +105,7 @@ class CompressionTest(unittest.TestCase): response = multi_callable( request, metadata=[('grpc-internal-encoding-request', 'gzip')]) self.assertEqual(request, response) + compressed_channel.close() def testStreaming(self): request = b'\x00' * 100 @@ -115,6 +119,7 @@ class CompressionTest(unittest.TestCase): call = multi_callable(iter([request] * test_constants.STREAM_LENGTH)) for response in call: self.assertEqual(request, response) + compressed_channel.close() if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_empty_message_test.py b/src/python/grpcio_tests/tests/unit/_empty_message_test.py index 3e8393b53c3..f27ea422d0c 100644 --- a/src/python/grpcio_tests/tests/unit/_empty_message_test.py +++ b/src/python/grpcio_tests/tests/unit/_empty_message_test.py @@ -96,6 +96,7 @@ class EmptyMessageTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testUnaryUnary(self): response = self._channel.unary_unary(_UNARY_UNARY)(_REQUEST) diff --git a/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py b/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py index 6c551df3ec4..81de1dae1d1 100644 --- a/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py +++ b/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py @@ -71,6 +71,7 @@ class ErrorMessageEncodingTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testMessageEncoding(self): for message in _UNICODE_ERROR_MESSAGES: diff --git a/src/python/grpcio_tests/tests/unit/_interceptor_test.py b/src/python/grpcio_tests/tests/unit/_interceptor_test.py index 99db0ac58b1..a647e5e720c 100644 --- a/src/python/grpcio_tests/tests/unit/_interceptor_test.py +++ b/src/python/grpcio_tests/tests/unit/_interceptor_test.py @@ -337,6 +337,7 @@ class InterceptorTest(unittest.TestCase): def tearDown(self): self._server.stop(None) self._server_pool.shutdown(wait=True) + self._channel.close() def testTripleRequestMessagesClientInterceptor(self): diff --git a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py index 0ff49490d5f..7ed7c838936 100644 --- a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py +++ b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py @@ -62,6 +62,9 @@ class InvalidMetadataTest(unittest.TestCase): self._stream_unary = _stream_unary_multi_callable(self._channel) self._stream_stream = _stream_stream_multi_callable(self._channel) + def tearDown(self): + self._channel.close() + def testUnaryRequestBlockingUnaryResponse(self): request = b'\x07\x08' metadata = (('InVaLiD', 'UnaryRequestBlockingUnaryResponse'),) diff --git a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py index 00949e22366..e89b521cc5c 100644 --- a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py +++ b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py @@ -215,6 +215,7 @@ class InvocationDefectsTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testIterableStreamRequestBlockingUnaryResponse(self): requests = [b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)] diff --git a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py index 0dafab827a8..a63664ac5d0 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py @@ -198,8 +198,8 @@ class MetadataCodeDetailsTest(unittest.TestCase): port = self._server.add_insecure_port('[::]:0') self._server.start() - channel = grpc.insecure_channel('localhost:{}'.format(port)) - self._unary_unary = channel.unary_unary( + self._channel = grpc.insecure_channel('localhost:{}'.format(port)) + self._unary_unary = self._channel.unary_unary( '/'.join(( '', _SERVICE, @@ -208,17 +208,17 @@ class MetadataCodeDetailsTest(unittest.TestCase): request_serializer=_REQUEST_SERIALIZER, response_deserializer=_RESPONSE_DESERIALIZER, ) - self._unary_stream = channel.unary_stream('/'.join(( + self._unary_stream = self._channel.unary_stream('/'.join(( '', _SERVICE, _UNARY_STREAM, )),) - self._stream_unary = channel.stream_unary('/'.join(( + self._stream_unary = self._channel.stream_unary('/'.join(( '', _SERVICE, _STREAM_UNARY, )),) - self._stream_stream = channel.stream_stream( + self._stream_stream = self._channel.stream_stream( '/'.join(( '', _SERVICE, @@ -228,6 +228,10 @@ class MetadataCodeDetailsTest(unittest.TestCase): response_deserializer=_RESPONSE_DESERIALIZER, ) + def tearDown(self): + self._server.stop(None) + self._channel.close() + def testSuccessfulUnaryUnary(self): self._servicer.set_details(_DETAILS) diff --git a/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py b/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py index 2d352e99d4a..7b32b5b5f3e 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py @@ -187,13 +187,14 @@ class MetadataFlagsTest(unittest.TestCase): def test_call_wait_for_ready_default(self): for perform_call in _ALL_CALL_CASES: - self.check_connection_does_failfast(perform_call, - create_dummy_channel()) + with create_dummy_channel() as channel: + self.check_connection_does_failfast(perform_call, channel) def test_call_wait_for_ready_disabled(self): for perform_call in _ALL_CALL_CASES: - self.check_connection_does_failfast( - perform_call, create_dummy_channel(), wait_for_ready=False) + with create_dummy_channel() as channel: + self.check_connection_does_failfast( + perform_call, channel, wait_for_ready=False) def test_call_wait_for_ready_enabled(self): # To test the wait mechanism, Python thread is required to make @@ -210,16 +211,16 @@ class MetadataFlagsTest(unittest.TestCase): wg.done() def test_call(perform_call): - try: - channel = grpc.insecure_channel(addr) - channel.subscribe(wait_for_transient_failure) - perform_call(channel, wait_for_ready=True) - except BaseException as e: # pylint: disable=broad-except - # If the call failed, the thread would be destroyed. The channel - # object can be collected before calling the callback, which - # will result in a deadlock. - wg.done() - unhandled_exceptions.put(e, True) + with grpc.insecure_channel(addr) as channel: + try: + channel.subscribe(wait_for_transient_failure) + perform_call(channel, wait_for_ready=True) + except BaseException as e: # pylint: disable=broad-except + # If the call failed, the thread would be destroyed. The + # channel object can be collected before calling the + # callback, which will result in a deadlock. + wg.done() + unhandled_exceptions.put(e, True) test_threads = [] for perform_call in _ALL_CALL_CASES: diff --git a/src/python/grpcio_tests/tests/unit/_metadata_test.py b/src/python/grpcio_tests/tests/unit/_metadata_test.py index 777ab683e36..892df3df08f 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_test.py @@ -186,6 +186,7 @@ class MetadataTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testUnaryUnary(self): multi_callable = self._channel.unary_unary(_UNARY_UNARY) diff --git a/src/python/grpcio_tests/tests/unit/_reconnect_test.py b/src/python/grpcio_tests/tests/unit/_reconnect_test.py index f6d4fcbd0a5..d4ea126e2b5 100644 --- a/src/python/grpcio_tests/tests/unit/_reconnect_test.py +++ b/src/python/grpcio_tests/tests/unit/_reconnect_test.py @@ -98,6 +98,8 @@ class ReconnectTest(unittest.TestCase): server.add_insecure_port('[::]:{}'.format(port)) server.start() self.assertEqual(_RESPONSE, multi_callable(_REQUEST)) + server.stop(None) + channel.close() if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py index 4fead8fcd54..517c2d2f97b 100644 --- a/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py +++ b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py @@ -148,6 +148,7 @@ class ResourceExhaustedTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testUnaryUnary(self): multi_callable = self._channel.unary_unary(_UNARY_UNARY) diff --git a/src/python/grpcio_tests/tests/unit/_rpc_test.py b/src/python/grpcio_tests/tests/unit/_rpc_test.py index a768d6c7c1c..a99121cee57 100644 --- a/src/python/grpcio_tests/tests/unit/_rpc_test.py +++ b/src/python/grpcio_tests/tests/unit/_rpc_test.py @@ -193,6 +193,7 @@ class RPCTest(unittest.TestCase): def tearDown(self): self._server.stop(None) + self._channel.close() def testUnrecognizedMethod(self): request = b'abc' From b6b745f22dd66748fbcb2e7c0d10dc83be84d63a Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 21 Dec 2018 14:16:59 -0800 Subject: [PATCH 394/534] disable broken gevent test --- src/python/grpcio_tests/commands.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 496bcfbcbff..d5327711d33 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -133,6 +133,7 @@ class TestGevent(setuptools.Command): # This test will stuck while running higher version of gevent 'unit._auth_context_test.AuthContextTest.testSessionResumption', # TODO(https://github.com/grpc/grpc/issues/15411) enable these tests + 'unit._metadata_flags_test', 'unit._exit_test.ExitTest.test_in_flight_unary_unary_call', 'unit._exit_test.ExitTest.test_in_flight_unary_stream_call', 'unit._exit_test.ExitTest.test_in_flight_stream_unary_call', From 40f22bfc94304e382be770352ca0e7efd0b1c57d Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 21 Dec 2018 15:09:17 -0800 Subject: [PATCH 395/534] move ForwardingLoadBalancingPolicy to its own library --- CMakeLists.txt | 43 ++++++ Makefile | 60 +++++++- build.yaml | 11 ++ grpc.gyp | 9 ++ test/core/util/BUILD | 10 ++ .../util/forwarding_load_balancing_policy.cc | 25 ++++ .../util/forwarding_load_balancing_policy.h | 129 ++++++++++++++++++ test/cpp/end2end/BUILD | 1 + test/cpp/end2end/client_lb_end2end_test.cc | 104 ++------------ .../generated/sources_and_headers.json | 19 +++ 10 files changed, 312 insertions(+), 99 deletions(-) create mode 100644 test/core/util/forwarding_load_balancing_policy.cc create mode 100644 test/core/util/forwarding_load_balancing_policy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 76886307813..c0ae76d9d71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2824,6 +2824,48 @@ target_link_libraries(test_tcp_server ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_library(forwarding_load_balancing_policy + test/core/util/forwarding_load_balancing_policy.cc +) + +if(WIN32 AND MSVC) + set_target_properties(forwarding_load_balancing_policy PROPERTIES COMPILE_PDB_NAME "forwarding_load_balancing_policy" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if (gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/forwarding_load_balancing_policy.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + + +target_include_directories(forwarding_load_balancing_policy + PUBLIC $ $ + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(forwarding_load_balancing_policy + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) add_library(grpc++ @@ -12444,6 +12486,7 @@ target_link_libraries(client_lb_end2end_test grpc++ grpc gpr + forwarding_load_balancing_policy ${_gRPC_GFLAGS_LIBRARIES} ) diff --git a/Makefile b/Makefile index 147e9505a33..a0ed0384380 100644 --- a/Makefile +++ b/Makefile @@ -1424,9 +1424,9 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc ifeq ($(EMBED_OPENSSL),true) -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a else -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a endif @@ -5254,6 +5254,55 @@ endif endif +LIBFORWARDING_LOAD_BALANCING_POLICY_SRC = \ + test/core/util/forwarding_load_balancing_policy.cc \ + +PUBLIC_HEADERS_CXX += \ + +LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBFORWARDING_LOAD_BALANCING_POLICY_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a: openssl_dep_error + + +else + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS:.o=.dep) +endif +endif + + LIBGRPC++_SRC = \ src/cpp/client/insecure_credentials.cc \ src/cpp/client/secure_credentials.cc \ @@ -17477,16 +17526,16 @@ $(BINDIR)/$(CONFIG)/client_lb_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_lb_end2end_test: $(PROTOBUF_DEP) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_lb_end2end_test: $(PROTOBUF_DEP) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_lb_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_lb_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a deps_client_lb_end2end_test: $(CLIENT_LB_END2END_TEST_OBJS:.o=.dep) @@ -25258,6 +25307,7 @@ test/core/end2end/tests/call_creds.cc: $(OPENSSL_DEP) test/core/security/oauth2_utils.cc: $(OPENSSL_DEP) test/core/tsi/alts/crypt/gsec_test_util.cc: $(OPENSSL_DEP) test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc: $(OPENSSL_DEP) +test/core/util/forwarding_load_balancing_policy.cc: $(OPENSSL_DEP) test/core/util/reconnect_server.cc: $(OPENSSL_DEP) test/core/util/test_tcp_server.cc: $(OPENSSL_DEP) test/cpp/end2end/test_health_check_service_impl.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 9d73e31b2e5..b58367f3332 100644 --- a/build.yaml +++ b/build.yaml @@ -1638,6 +1638,16 @@ libs: - grpc_test_util - grpc - gpr +- name: forwarding_load_balancing_policy + build: private + language: c++ + headers: + - test/core/util/forwarding_load_balancing_policy.h + src: + - test/core/util/forwarding_load_balancing_policy.cc + uses: + - grpc_base + - grpc_client_channel - name: grpc++ build: all language: c++ @@ -4449,6 +4459,7 @@ targets: - grpc++ - grpc - gpr + - forwarding_load_balancing_policy - name: codegen_test_full gtest: true build: test diff --git a/grpc.gyp b/grpc.gyp index 80b6d0315a1..9aea11efa2e 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1365,6 +1365,15 @@ 'test/core/util/test_tcp_server.cc', ], }, + { + 'target_name': 'forwarding_load_balancing_policy', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'test/core/util/forwarding_load_balancing_policy.cc', + ], + }, { 'target_name': 'grpc++', 'type': 'static_library', diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 226e41aea7c..8d50dd2bbac 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -154,3 +154,13 @@ sh_library( name = "run_with_poller_sh", srcs = ["run_with_poller.sh"], ) + +grpc_cc_library( + name = "forwarding_load_balancing_policy", + testonly = 1, + srcs = ["forwarding_load_balancing_policy.cc"], + hdrs = ["forwarding_load_balancing_policy.h"], + deps = [ + "//:grpc", + ], +) diff --git a/test/core/util/forwarding_load_balancing_policy.cc b/test/core/util/forwarding_load_balancing_policy.cc new file mode 100644 index 00000000000..e2755bfed0c --- /dev/null +++ b/test/core/util/forwarding_load_balancing_policy.cc @@ -0,0 +1,25 @@ +/* + * + * 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 "test/core/util/forwarding_load_balancing_policy.h" + +namespace grpc_core { + +TraceFlag grpc_trace_forwarding_lb(false, "forwarding_lb"); + +} // namespace grpc_core diff --git a/test/core/util/forwarding_load_balancing_policy.h b/test/core/util/forwarding_load_balancing_policy.h new file mode 100644 index 00000000000..aeb89803c35 --- /dev/null +++ b/test/core/util/forwarding_load_balancing_policy.h @@ -0,0 +1,129 @@ +/* + * + * 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 + +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channelz.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/transport/connectivity_state.h" + +#ifndef GRPC_TEST_CORE_UTIL_FORWARDING_LOAD_BALANCING_POLICY_H +#define GRPC_TEST_CORE_UTIL_FORWARDING_LOAD_BALANCING_POLICY_H + +namespace grpc_core { + +extern TraceFlag grpc_trace_forwarding_lb; + +// A minimal forwarding class to avoid implementing a standalone test LB. +class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { + public: + ForwardingLoadBalancingPolicy(const Args& args, + const std::string& delegate_policy_name) + : LoadBalancingPolicy(args) { + delegate_ = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + delegate_policy_name.c_str(), args); + grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), + interested_parties()); + // Give re-resolution closure to delegate. + GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, + OnDelegateRequestReresolutionLocked, this, + grpc_combiner_scheduler(combiner())); + Ref().release(); // held by callback. + delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); + } + + const char* name() const override { return delegate_->name(); } + + void UpdateLocked(const grpc_channel_args& args, + grpc_json* lb_config) override { + delegate_->UpdateLocked(args, lb_config); + } + + bool PickLocked(PickState* pick, grpc_error** error) override { + return delegate_->PickLocked(pick, error); + } + + void CancelPickLocked(PickState* pick, grpc_error* error) override { + delegate_->CancelPickLocked(pick, error); + } + + void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) override { + delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, + initial_metadata_flags_eq, error); + } + + void NotifyOnStateChangeLocked(grpc_connectivity_state* state, + grpc_closure* closure) override { + delegate_->NotifyOnStateChangeLocked(state, closure); + } + + grpc_connectivity_state CheckConnectivityLocked( + grpc_error** connectivity_error) override { + return delegate_->CheckConnectivityLocked(connectivity_error); + } + + void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { + delegate_->HandOffPendingPicksLocked(new_policy); + } + + void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } + + void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } + + void FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) override { + delegate_->FillChildRefsForChannelz(child_subchannels, child_channels); + } + + private: + void ShutdownLocked() override { delegate_.reset(); } + + static void OnDelegateRequestReresolutionLocked(void* arg, + grpc_error* error) { + ForwardingLoadBalancingPolicy* self = + static_cast(arg); + if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { + self->Unref(); + return; + } + self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); + self->delegate_->SetReresolutionClosureLocked( + &self->on_delegate_request_reresolution_); + } + + OrphanablePtr delegate_; + grpc_closure on_delegate_request_reresolution_; +}; + +} // namespace grpc_core + +#endif // GRPC_TEST_CORE_UTIL_FORWARDING_LOAD_BALANCING_POLICY_H diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 762d2302afc..ae204f580b3 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -387,6 +387,7 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", + "//test/core/util:forwarding_load_balancing_policy", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 328f28e3db6..2d474f71982 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -42,6 +42,7 @@ #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channelz.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/debug_location.h" @@ -59,6 +60,7 @@ #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" +#include "test/core/util/forwarding_load_balancing_policy.h" #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" @@ -1231,94 +1233,6 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { EnableDefaultHealthCheckService(false); } -grpc_core::TraceFlag forwarding_lb_tracer(false, "forwarding_lb"); - -// A minimal forwarding class to avoid implementing a standalone test LB. -class ForwardingLoadBalancingPolicy : public grpc_core::LoadBalancingPolicy { - public: - ForwardingLoadBalancingPolicy(const Args& args, - const std::string& delegate_policy_name) - : grpc_core::LoadBalancingPolicy(args) { - delegate_ = - grpc_core::LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - delegate_policy_name.c_str(), args); - grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), - interested_parties()); - // Give re-resolution closure to delegate. - GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, - OnDelegateRequestReresolutionLocked, this, - grpc_combiner_scheduler(combiner())); - Ref().release(); // held by callback. - delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); - } - - const char* name() const override { return delegate_->name(); } - - void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override { - delegate_->UpdateLocked(args, lb_config); - } - - bool PickLocked(PickState* pick, grpc_error** error) override { - return delegate_->PickLocked(pick, error); - } - - void CancelPickLocked(PickState* pick, grpc_error* error) override { - delegate_->CancelPickLocked(pick, error); - } - - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override { - delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, error); - } - - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override { - delegate_->NotifyOnStateChangeLocked(state, closure); - } - - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override { - return delegate_->CheckConnectivityLocked(connectivity_error); - } - - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { - delegate_->HandOffPendingPicksLocked(new_policy); - } - - void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } - - void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } - - void FillChildRefsForChannelz( - grpc_core::channelz::ChildRefsList* child_subchannels, - grpc_core::channelz::ChildRefsList* ignored) override { - delegate_->FillChildRefsForChannelz(child_subchannels, ignored); - } - - protected: - void ShutdownLocked() override { delegate_.reset(); } - - private: - static void OnDelegateRequestReresolutionLocked(void* arg, - grpc_error* error) { - ForwardingLoadBalancingPolicy* self = - static_cast(arg); - if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { - self->Unref(); - return; - } - self->TryReresolutionLocked(&forwarding_lb_tracer, GRPC_ERROR_NONE); - self->delegate_->SetReresolutionClosureLocked( - &self->on_delegate_request_reresolution_); - } - - grpc_core::OrphanablePtr delegate_; - grpc_closure on_delegate_request_reresolution_; -}; - class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { protected: void SetUp() override { @@ -1331,12 +1245,14 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { void TearDown() override { ClientLbEnd2endTest::TearDown(); } - class InterceptTrailingLb : public ForwardingLoadBalancingPolicy { + class InterceptRecvTrailingMetadataLoadBalancingPolicy + : public grpc_core::ForwardingLoadBalancingPolicy { public: - InterceptTrailingLb(const Args& args, - const std::string& delegate_lb_policy_name, - ClientLbInterceptTrailingMetadataTest* test) - : ForwardingLoadBalancingPolicy(args, delegate_lb_policy_name), + InterceptRecvTrailingMetadataLoadBalancingPolicy( + const Args& args, const std::string& delegate_lb_policy_name, + ClientLbInterceptTrailingMetadataTest* test) + : grpc_core::ForwardingLoadBalancingPolicy(args, + delegate_lb_policy_name), test_(test) {} bool PickLocked(PickState* pick, grpc_error** error) override { @@ -1402,7 +1318,7 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { CreateLoadBalancingPolicy( const grpc_core::LoadBalancingPolicy::Args& args) const override { return grpc_core::OrphanablePtr( - grpc_core::New( + grpc_core::New( args, /*delegate_lb_policy_name=*/ "pick_first", test_)); } diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 336d499be9d..64d59495ae1 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3297,6 +3297,7 @@ }, { "deps": [ + "forwarding_load_balancing_policy", "gpr", "grpc", "grpc++", @@ -7032,6 +7033,24 @@ "third_party": false, "type": "lib" }, + { + "deps": [ + "grpc_base", + "grpc_client_channel" + ], + "headers": [ + "test/core/util/forwarding_load_balancing_policy.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "forwarding_load_balancing_policy", + "src": [ + "test/core/util/forwarding_load_balancing_policy.cc", + "test/core/util/forwarding_load_balancing_policy.h" + ], + "third_party": false, + "type": "lib" + }, { "deps": [ "gpr", From 08dc0ade6790087702a9b7a01b6565e5d8b03832 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 21 Dec 2018 15:49:15 -0800 Subject: [PATCH 396/534] Fix bazel build for fling, memory_usage test --- test/core/fling/BUILD | 12 ++++++------ test/core/memory_usage/BUILD | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/test/core/fling/BUILD b/test/core/fling/BUILD index 5c6930cc85b..0c16b2a8799 100644 --- a/test/core/fling/BUILD +++ b/test/core/fling/BUILD @@ -21,7 +21,7 @@ licenses(["notice"]) # Apache v2 load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_cc_binary( - name = "client", + name = "fling_client", testonly = 1, srcs = ["client.cc"], language = "C++", @@ -34,7 +34,7 @@ grpc_cc_binary( ) grpc_cc_binary( - name = "server", + name = "fling_server", testonly = 1, srcs = ["server.cc"], language = "C++", @@ -50,8 +50,8 @@ grpc_cc_test( name = "fling", srcs = ["fling_test.cc"], data = [ - ":client", - ":server", + ":fling_client", + ":fling_server", ], deps = [ "//:gpr", @@ -65,8 +65,8 @@ grpc_cc_test( name = "fling_stream", srcs = ["fling_stream_test.cc"], data = [ - ":client", - ":server", + ":fling_client", + ":fling_server", ], deps = [ "//:gpr", diff --git a/test/core/memory_usage/BUILD b/test/core/memory_usage/BUILD index 2fe94dfa120..dd185e6577b 100644 --- a/test/core/memory_usage/BUILD +++ b/test/core/memory_usage/BUILD @@ -12,14 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") +load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_test", "grpc_package") grpc_package(name = "test/core/memory_usage") licenses(["notice"]) # Apache v2 -grpc_cc_library( - name = "client", +grpc_cc_binary( + name = "memory_usage_client", testonly = 1, srcs = ["client.cc"], deps = [ @@ -29,8 +29,8 @@ grpc_cc_library( ], ) -grpc_cc_library( - name = "server", +grpc_cc_binary( + name = "memory_usage_server", testonly = 1, srcs = ["server.cc"], deps = [ @@ -45,8 +45,8 @@ grpc_cc_test( name = "memory_usage_test", srcs = ["memory_usage_test.cc"], data = [ - ":client", - ":server", + ":memory_usage_client", + ":memory_usage_server", ], language = "C++", deps = [ From 2e017da58aeb335e79f7bbf0797aad45a59d293b Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 21 Dec 2018 18:14:08 -0500 Subject: [PATCH 397/534] Add microbenchmarks for grpc_timer This helps assessing upcoming changes. --- CMakeLists.txt | 48 +++++++ Makefile | 49 ++++++++ build.yaml | 21 ++++ test/cpp/microbenchmarks/BUILD | 7 ++ test/cpp/microbenchmarks/bm_timer.cc | 118 ++++++++++++++++++ .../generated/sources_and_headers.json | 21 ++++ tools/run_tests/generated/tests.json | 22 ++++ 7 files changed, 286 insertions(+) create mode 100644 test/cpp/microbenchmarks/bm_timer.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 76886307813..d3ebb5d1773 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -576,6 +576,9 @@ endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_pollset) endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_timer) +endif() add_dependencies(buildtests_cxx byte_stream_test) add_dependencies(buildtests_cxx channel_arguments_test) add_dependencies(buildtests_cxx channel_filter_test) @@ -11748,6 +11751,51 @@ target_link_libraries(bm_pollset ) +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_timer + test/cpp/microbenchmarks/bm_timer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_timer + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(bm_timer + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_test_util_unsecure + grpc_test_util_unsecure + grpc++_unsecure + grpc_unsecure + gpr + grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 147e9505a33..b8a1c921862 100644 --- a/Makefile +++ b/Makefile @@ -1150,6 +1150,7 @@ bm_fullstack_trickle: $(BINDIR)/$(CONFIG)/bm_fullstack_trickle bm_fullstack_unary_ping_pong: $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong bm_metadata: $(BINDIR)/$(CONFIG)/bm_metadata bm_pollset: $(BINDIR)/$(CONFIG)/bm_pollset +bm_timer: $(BINDIR)/$(CONFIG)/bm_timer byte_stream_test: $(BINDIR)/$(CONFIG)/byte_stream_test channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test @@ -1661,6 +1662,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_metadata \ $(BINDIR)/$(CONFIG)/bm_pollset \ + $(BINDIR)/$(CONFIG)/bm_timer \ $(BINDIR)/$(CONFIG)/byte_stream_test \ $(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_filter_test \ @@ -1846,6 +1848,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_metadata \ $(BINDIR)/$(CONFIG)/bm_pollset \ + $(BINDIR)/$(CONFIG)/bm_timer \ $(BINDIR)/$(CONFIG)/byte_stream_test \ $(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_filter_test \ @@ -2296,6 +2299,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/bm_metadata || ( echo test bm_metadata failed ; exit 1 ) $(E) "[RUN] Testing bm_pollset" $(Q) $(BINDIR)/$(CONFIG)/bm_pollset || ( echo test bm_pollset failed ; exit 1 ) + $(E) "[RUN] Testing bm_timer" + $(Q) $(BINDIR)/$(CONFIG)/bm_timer || ( echo test bm_timer failed ; exit 1 ) $(E) "[RUN] Testing byte_stream_test" $(Q) $(BINDIR)/$(CONFIG)/byte_stream_test || ( echo test byte_stream_test failed ; exit 1 ) $(E) "[RUN] Testing channel_arguments_test" @@ -16747,6 +16752,50 @@ endif endif +BM_TIMER_SRC = \ + test/cpp/microbenchmarks/bm_timer.cc \ + +BM_TIMER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_TIMER_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_timer: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/bm_timer: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_timer: $(PROTOBUF_DEP) $(BM_TIMER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_TIMER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_timer + +endif + +endif + +$(BM_TIMER_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_timer.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + +deps_bm_timer: $(BM_TIMER_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_TIMER_OBJS:.o=.dep) +endif +endif + + BYTE_STREAM_TEST_SRC = \ test/core/transport/byte_stream_test.cc \ diff --git a/build.yaml b/build.yaml index 9d73e31b2e5..a41decd84f7 100644 --- a/build.yaml +++ b/build.yaml @@ -4230,6 +4230,27 @@ targets: - mac - linux - posix +- name: bm_timer + build: test + language: c++ + src: + - test/cpp/microbenchmarks/bm_timer.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure + - grpc_test_util_unsecure + - grpc++_unsecure + - grpc_unsecure + - gpr + - grpc++_test_config + benchmark: true + defaults: benchmark + platforms: + - mac + - linux + - posix + uses_polling: false - name: byte_stream_test gtest: true build: test diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index b5890bece73..a29462f78fc 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -189,3 +189,10 @@ grpc_cc_binary( "//src/proto/grpc/testing:echo_proto", ], ) + +grpc_cc_binary( + name = "bm_timer", + testonly = 1, + srcs = ["bm_timer.cc"], + deps = [":helpers"], +) diff --git a/test/cpp/microbenchmarks/bm_timer.cc b/test/cpp/microbenchmarks/bm_timer.cc new file mode 100644 index 00000000000..f5a411251b5 --- /dev/null +++ b/test/cpp/microbenchmarks/bm_timer.cc @@ -0,0 +1,118 @@ +/* + * + * Copyright 2017 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 +#include +#include +#include + +#include +#include +#include +#include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" + +#include "src/core/lib/iomgr/timer.h" + +namespace grpc { +namespace testing { + +auto& force_library_initialization = Library::get(); + +struct TimerClosure { + grpc_timer timer; + grpc_closure closure; +}; + +static void BM_InitCancelTimer(benchmark::State& state) { + constexpr int kTimerCount = 1024; + TrackCounters track_counters; + grpc_core::ExecCtx exec_ctx; + std::vector timer_closures(kTimerCount); + int i = 0; + while (state.KeepRunning()) { + TimerClosure* timer_closure = &timer_closures[i++ % kTimerCount]; + GRPC_CLOSURE_INIT(&timer_closure->closure, + [](void* /*args*/, grpc_error* /*err*/) {}, nullptr, + grpc_schedule_on_exec_ctx); + grpc_timer_init(&timer_closure->timer, GRPC_MILLIS_INF_FUTURE, + &timer_closure->closure); + grpc_timer_cancel(&timer_closure->timer); + exec_ctx.Flush(); + } + track_counters.Finish(state); +} +BENCHMARK(BM_InitCancelTimer); + +static void BM_TimerBatch(benchmark::State& state) { + constexpr int kTimerCount = 1024; + const bool check = state.range(0); + const bool reverse = state.range(1); + + const grpc_millis start = + reverse ? GRPC_MILLIS_INF_FUTURE : GRPC_MILLIS_INF_FUTURE - kTimerCount; + const grpc_millis end = + reverse ? GRPC_MILLIS_INF_FUTURE - kTimerCount : GRPC_MILLIS_INF_FUTURE; + const grpc_millis increment = reverse ? -1 : 1; + + TrackCounters track_counters; + grpc_core::ExecCtx exec_ctx; + std::vector timer_closures(kTimerCount); + while (state.KeepRunning()) { + for (grpc_millis deadline = start; deadline != end; deadline += increment) { + TimerClosure* timer_closure = &timer_closures[deadline % kTimerCount]; + GRPC_CLOSURE_INIT(&timer_closure->closure, + [](void* /*args*/, grpc_error* /*err*/) {}, nullptr, + grpc_schedule_on_exec_ctx); + + grpc_timer_init(&timer_closure->timer, deadline, &timer_closure->closure); + } + if (check) { + grpc_millis next; + grpc_timer_check(&next); + } + for (grpc_millis deadline = start; deadline != end; deadline += increment) { + TimerClosure* timer_closure = &timer_closures[deadline % kTimerCount]; + grpc_timer_cancel(&timer_closure->timer); + } + exec_ctx.Flush(); + } + track_counters.Finish(state); +} +BENCHMARK(BM_TimerBatch) + ->Args({/*check=*/false, /*reverse=*/false}) + ->Args({/*check=*/false, /*reverse=*/true}) + ->Args({/*check=*/true, /*reverse=*/false}) + ->Args({/*check=*/true, /*reverse=*/true}) + ->ThreadRange(1, 128); + +} // namespace testing +} // namespace grpc + +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 336d499be9d..8d1bca22be9 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3005,6 +3005,27 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "benchmark", + "gpr", + "grpc++_test_config", + "grpc++_test_util_unsecure", + "grpc++_unsecure", + "grpc_benchmark", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "bm_timer", + "src": [ + "test/cpp/microbenchmarks/bm_timer.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 3a348e4a92f..e35d4db2767 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3715,6 +3715,28 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_timer", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, From 5ac6ab67e4278b977dde50891f6aed6cb0e9e078 Mon Sep 17 00:00:00 2001 From: xtao Date: Sat, 22 Dec 2018 09:49:22 +0800 Subject: [PATCH 398/534] * Fixed issue(17563) "Freeing heap block containing an active critical section." reported by Application Verifier on Windows. --- src/core/lib/iomgr/resource_quota.cc | 1 + src/core/lib/transport/metadata.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/src/core/lib/iomgr/resource_quota.cc b/src/core/lib/iomgr/resource_quota.cc index 7e4b3c9b2ff..61c366098e1 100644 --- a/src/core/lib/iomgr/resource_quota.cc +++ b/src/core/lib/iomgr/resource_quota.cc @@ -665,6 +665,7 @@ void grpc_resource_quota_unref_internal(grpc_resource_quota* resource_quota) { GPR_ASSERT(resource_quota->num_threads_allocated == 0); GRPC_COMBINER_UNREF(resource_quota->combiner, "resource_quota"); gpr_free(resource_quota->name); + gpr_mu_destroy(&resource_quota->thread_count_mu); gpr_free(resource_quota); } } diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index 60af22393ef..30482a1b3b1 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -187,6 +187,7 @@ static void gc_mdtab(mdtab_shard* shard) { ((destroy_user_data_func)gpr_atm_no_barrier_load( &md->destroy_user_data))(user_data); } + gpr_mu_destroy(&md->mu_user_data); gpr_free(md); *prev_next = next; num_freed++; From 7bb853ebdd0b6e057de447147ad60ebf42e0903d Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Fri, 21 Dec 2018 22:40:38 -0800 Subject: [PATCH 399/534] Addressed PR comments. Made Client::Thread public and removed use of void ptr to refer it. Avoided overloading of NextIssue TIme by renaming it NextRPCIssueTime --- test/cpp/qps/client.h | 116 ++++++++++++++++---------------- test/cpp/qps/client_callback.cc | 18 ++--- 2 files changed, 67 insertions(+), 67 deletions(-) diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 0b9837660be..4b8ac9bd94e 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -251,64 +251,6 @@ class Client { return static_cast(gpr_atm_acq_load(&thread_pool_done_)); } - protected: - bool closed_loop_; - gpr_atm thread_pool_done_; - double median_latency_collection_interval_seconds_; // In seconds - - void StartThreads(size_t num_threads) { - gpr_atm_rel_store(&thread_pool_done_, static_cast(false)); - threads_remaining_ = num_threads; - for (size_t i = 0; i < num_threads; i++) { - threads_.emplace_back(new Thread(this, i)); - } - } - - void EndThreads() { - MaybeStartRequests(); - threads_.clear(); - } - - virtual void DestroyMultithreading() = 0; - - void SetupLoadTest(const ClientConfig& config, size_t num_threads) { - // Set up the load distribution based on the number of threads - const auto& load = config.load_params(); - - std::unique_ptr random_dist; - switch (load.load_case()) { - case LoadParams::kClosedLoop: - // Closed-loop doesn't use random dist at all - break; - case LoadParams::kPoisson: - random_dist.reset( - new ExpDist(load.poisson().offered_load() / num_threads)); - break; - default: - GPR_ASSERT(false); - } - - // Set closed_loop_ based on whether or not random_dist is set - if (!random_dist) { - closed_loop_ = true; - } else { - closed_loop_ = false; - // set up interarrival timer according to random dist - interarrival_timer_.init(*random_dist, num_threads); - const auto now = gpr_now(GPR_CLOCK_MONOTONIC); - for (size_t i = 0; i < num_threads; i++) { - next_time_.push_back(gpr_time_add( - now, - gpr_time_from_nanos(interarrival_timer_.next(i), GPR_TIMESPAN))); - } - } - } - - std::function NextIssuer(int thread_idx) { - return closed_loop_ ? std::function() - : std::bind(&Client::NextIssueTime, this, thread_idx); - } - class Thread { public: Thread(Client* client, size_t idx) @@ -387,6 +329,64 @@ class Client { double interval_start_time_; }; + protected: + bool closed_loop_; + gpr_atm thread_pool_done_; + double median_latency_collection_interval_seconds_; // In seconds + + void StartThreads(size_t num_threads) { + gpr_atm_rel_store(&thread_pool_done_, static_cast(false)); + threads_remaining_ = num_threads; + for (size_t i = 0; i < num_threads; i++) { + threads_.emplace_back(new Thread(this, i)); + } + } + + void EndThreads() { + MaybeStartRequests(); + threads_.clear(); + } + + virtual void DestroyMultithreading() = 0; + + void SetupLoadTest(const ClientConfig& config, size_t num_threads) { + // Set up the load distribution based on the number of threads + const auto& load = config.load_params(); + + std::unique_ptr random_dist; + switch (load.load_case()) { + case LoadParams::kClosedLoop: + // Closed-loop doesn't use random dist at all + break; + case LoadParams::kPoisson: + random_dist.reset( + new ExpDist(load.poisson().offered_load() / num_threads)); + break; + default: + GPR_ASSERT(false); + } + + // Set closed_loop_ based on whether or not random_dist is set + if (!random_dist) { + closed_loop_ = true; + } else { + closed_loop_ = false; + // set up interarrival timer according to random dist + interarrival_timer_.init(*random_dist, num_threads); + const auto now = gpr_now(GPR_CLOCK_MONOTONIC); + for (size_t i = 0; i < num_threads; i++) { + next_time_.push_back(gpr_time_add( + now, + gpr_time_from_nanos(interarrival_timer_.next(i), GPR_TIMESPAN))); + } + } + } + + std::function NextIssuer(int thread_idx) { + return closed_loop_ ? std::function() + : std::bind(&Client::NextIssueTime, this, thread_idx); + } + virtual void ThreadFunc(size_t thread_idx, Client::Thread* t) = 0; std::vector> threads_; diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index 1880f46d43d..4a06325f2b7 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -90,7 +90,7 @@ class CallbackClient } } - gpr_timespec NextIssueTime() { + gpr_timespec NextRPCIssueTime() { std::lock_guard l(next_issue_time_mu_); return Client::NextIssueTime(0); } @@ -166,7 +166,7 @@ class CallbackUnaryClient final : public CallbackClient { private: void ScheduleRpc(Thread* t, size_t vector_idx) { if (!closed_loop_) { - gpr_timespec next_issue_time = NextIssueTime(); + gpr_timespec next_issue_time = NextRPCIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time ctx_[vector_idx]->alarm_.experimental().Set( @@ -221,13 +221,13 @@ class CallbackStreamingClient : public CallbackClient { } ~CallbackStreamingClient() {} - void AddHistogramEntry(double start_, bool ok, void* thread_ptr) { + void AddHistogramEntry(double start_, bool ok, Thread* thread_ptr) { // Update Histogram with data from the callback run HistogramEntry entry; if (ok) { entry.set_value((UsageTimer::Now() - start_) * 1e9); } - ((Client::Thread*)thread_ptr)->UpdateHistogram(&entry); + thread_ptr->UpdateHistogram(&entry); } int messages_per_stream() { return messages_per_stream_; } @@ -297,7 +297,7 @@ class CallbackStreamingPingPongReactor final if (client_->ThreadCompleted()) return; if (!client_->IsClosedLoop()) { - gpr_timespec next_issue_time = client_->NextIssueTime(); + gpr_timespec next_issue_time = client_->NextRPCIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time ctx_->alarm_.experimental().Set(next_issue_time, @@ -307,13 +307,13 @@ class CallbackStreamingPingPongReactor final } } - void set_thread_ptr(void* ptr) { thread_ptr_ = ptr; } + void set_thread_ptr(Client::Thread* ptr) { thread_ptr_ = ptr; } CallbackStreamingPingPongClient* client_; std::unique_ptr ctx_; - void* thread_ptr_; // Needed to update histogram entries - double start_; // Track message start time - int messages_issued_; // Messages issued by this stream + Client::Thread* thread_ptr_; // Needed to update histogram entries + double start_; // Track message start time + int messages_issued_; // Messages issued by this stream }; class CallbackStreamingPingPongClientImpl final From 25e13ac79b67383765c0b786c7647af97676539a Mon Sep 17 00:00:00 2001 From: Max Vorobev Date: Mon, 24 Dec 2018 16:10:27 +0300 Subject: [PATCH 400/534] Fix incompatible_bzl_disallow_load_after_statement, deprecated attribute usage --- bazel/cc_grpc_library.bzl | 2 +- bazel/generate_cc.bzl | 2 +- bazel/grpc_build_system.bzl | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bazel/cc_grpc_library.bzl b/bazel/cc_grpc_library.bzl index 32885657141..6bfcd653f51 100644 --- a/bazel/cc_grpc_library.bzl +++ b/bazel/cc_grpc_library.bzl @@ -1,6 +1,6 @@ """Generates and compiles C++ grpc stubs from proto_library rules.""" -load("//:bazel/generate_cc.bzl", "generate_cc") +load("//bazel:generate_cc.bzl", "generate_cc") def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, generate_mocks = False, use_external = False, **kwargs): """Generates C++ grpc classes from a .proto file. diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index ae747aa42ca..2f14071f92d 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -83,7 +83,7 @@ _generate_cc = rule( attrs = { "srcs": attr.label_list( mandatory = True, - non_empty = True, + allow_empty = False, providers = ["proto"], ), "plugin": attr.label( diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 65fe5a10aa2..caeafc76b69 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -23,6 +23,8 @@ # each change must be ported from one to the other. # +load("//bazel:cc_grpc_library.bzl", "cc_grpc_library") + # The set of pollers to test against if a test exercises polling POLLERS = ["epollex", "epoll1", "poll", "poll-cv"] @@ -111,7 +113,6 @@ def grpc_proto_plugin(name, srcs = [], deps = []): deps = deps, ) -load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library") def grpc_proto_library( name, From 00763bc3eaff1523a70e5e791924c16abd2fe526 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Mon, 30 Jul 2018 17:22:25 -0700 Subject: [PATCH 401/534] Support named scope id's with ipv6 resolver on posix --- BUILD | 3 + CMakeLists.txt | 102 +++++++++++++- Makefile | 106 +++++++++++++-- build.yaml | 38 +++++- config.m4 | 2 + config.w32 | 2 + gRPC-C++.podspec | 2 + gRPC-Core.podspec | 4 + grpc.gemspec | 3 + grpc.gyp | 8 ++ package.xml | 3 + .../filters/client_channel/parse_address.cc | 29 +++- src/core/lib/iomgr/grpc_if_nametoindex.h | 30 +++++ .../lib/iomgr/grpc_if_nametoindex_posix.cc | 41 ++++++ .../iomgr/grpc_if_nametoindex_unsupported.cc | 37 +++++ src/python/grpcio/grpc_core_dependencies.py | 2 + test/core/client_channel/BUILD | 11 ++ .../parse_address_with_named_scope_id_test.cc | 126 ++++++++++++++++++ test/core/iomgr/BUILD | 19 ++- test/core/iomgr/resolve_address_posix_test.cc | 81 ++++++++++- tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core.internal | 3 + .../generated/sources_and_headers.json | 38 +++++- tools/run_tests/generated/tests.json | 54 +++++++- 24 files changed, 717 insertions(+), 28 deletions(-) create mode 100644 src/core/lib/iomgr/grpc_if_nametoindex.h create mode 100644 src/core/lib/iomgr/grpc_if_nametoindex_posix.cc create mode 100644 src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc create mode 100644 test/core/client_channel/parse_address_with_named_scope_id_test.cc diff --git a/BUILD b/BUILD index e3c765198b2..5a9e46acf9e 100644 --- a/BUILD +++ b/BUILD @@ -732,6 +732,8 @@ grpc_cc_library( "src/core/lib/iomgr/iomgr_posix.cc", "src/core/lib/iomgr/iomgr_windows.cc", "src/core/lib/iomgr/is_epollexclusive_available.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_posix.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc", "src/core/lib/iomgr/load_file.cc", "src/core/lib/iomgr/lockfree_event.cc", "src/core/lib/iomgr/network_status_tracker.cc", @@ -873,6 +875,7 @@ grpc_cc_library( "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/gevent_util.h", + "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index d3ebb5d1773..9e07a204b71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -371,11 +371,17 @@ add_dependencies(buildtests_c murmur_hash_test) add_dependencies(buildtests_c no_server_test) add_dependencies(buildtests_c num_external_connectivity_watchers_test) add_dependencies(buildtests_c parse_address_test) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c parse_address_with_named_scope_id_test) +endif() add_dependencies(buildtests_c percent_encoding_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_dependencies(buildtests_c resolve_address_posix_test) +add_dependencies(buildtests_c resolve_address_using_ares_resolver_posix_test) endif() add_dependencies(buildtests_c resolve_address_using_ares_resolver_test) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c resolve_address_using_native_resolver_posix_test) +endif() add_dependencies(buildtests_c resolve_address_using_native_resolver_test) add_dependencies(buildtests_c resource_quota_test) add_dependencies(buildtests_c secure_channel_create_test) @@ -989,6 +995,8 @@ add_library(grpc src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc @@ -1411,6 +1419,8 @@ add_library(grpc_cronet src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc @@ -1817,6 +1827,8 @@ add_library(grpc_test_util src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc @@ -2139,6 +2151,8 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc @@ -2438,6 +2452,8 @@ add_library(grpc_unsecure src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc @@ -3323,6 +3339,8 @@ add_library(grpc++_cronet src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc @@ -9132,6 +9150,42 @@ target_link_libraries(parse_address_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(parse_address_with_named_scope_id_test + test/core/client_channel/parse_address_with_named_scope_id_test.cc +) + + +target_include_directories(parse_address_with_named_scope_id_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(parse_address_with_named_scope_id_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(parse_address_with_named_scope_id_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(parse_address_with_named_scope_id_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) add_executable(percent_encoding_test test/core/slice/percent_encoding_test.cc @@ -9168,12 +9222,12 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_executable(resolve_address_posix_test +add_executable(resolve_address_using_ares_resolver_posix_test test/core/iomgr/resolve_address_posix_test.cc ) -target_include_directories(resolve_address_posix_test +target_include_directories(resolve_address_using_ares_resolver_posix_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${_gRPC_SSL_INCLUDE_DIR} @@ -9186,7 +9240,7 @@ target_include_directories(resolve_address_posix_test PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) -target_link_libraries(resolve_address_posix_test +target_link_libraries(resolve_address_using_ares_resolver_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc @@ -9195,8 +9249,8 @@ target_link_libraries(resolve_address_posix_test # avoid dependency on libstdc++ if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(resolve_address_posix_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(resolve_address_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + set_target_properties(resolve_address_using_ares_resolver_posix_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(resolve_address_using_ares_resolver_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) endif() endif() @@ -9236,6 +9290,42 @@ target_link_libraries(resolve_address_using_ares_resolver_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(resolve_address_using_native_resolver_posix_test + test/core/iomgr/resolve_address_posix_test.cc +) + + +target_include_directories(resolve_address_using_native_resolver_posix_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(resolve_address_using_native_resolver_posix_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(resolve_address_using_native_resolver_posix_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(resolve_address_using_native_resolver_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) add_executable(resolve_address_using_native_resolver_test test/core/iomgr/resolve_address_test.cc diff --git a/Makefile b/Makefile index b8a1c921862..9e8e06c5491 100644 --- a/Makefile +++ b/Makefile @@ -1076,11 +1076,13 @@ nanopb_fuzzer_serverlist_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test no_server_test: $(BINDIR)/$(CONFIG)/no_server_test num_external_connectivity_watchers_test: $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test parse_address_test: $(BINDIR)/$(CONFIG)/parse_address_test +parse_address_with_named_scope_id_test: $(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test percent_decode_fuzzer: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer percent_encoding_test: $(BINDIR)/$(CONFIG)/percent_encoding_test -resolve_address_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_posix_test +resolve_address_using_ares_resolver_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test resolve_address_using_ares_resolver_test: $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test +resolve_address_using_native_resolver_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test resolve_address_using_native_resolver_test: $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test resource_quota_test: $(BINDIR)/$(CONFIG)/resource_quota_test secure_channel_create_test: $(BINDIR)/$(CONFIG)/secure_channel_create_test @@ -1527,9 +1529,11 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/no_server_test \ $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test \ $(BINDIR)/$(CONFIG)/parse_address_test \ + $(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test \ $(BINDIR)/$(CONFIG)/percent_encoding_test \ - $(BINDIR)/$(CONFIG)/resolve_address_posix_test \ + $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test \ $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test \ + $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test \ $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test \ $(BINDIR)/$(CONFIG)/resource_quota_test \ $(BINDIR)/$(CONFIG)/secure_channel_create_test \ @@ -2129,12 +2133,16 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test || ( echo test num_external_connectivity_watchers_test failed ; exit 1 ) $(E) "[RUN] Testing parse_address_test" $(Q) $(BINDIR)/$(CONFIG)/parse_address_test || ( echo test parse_address_test failed ; exit 1 ) + $(E) "[RUN] Testing parse_address_with_named_scope_id_test" + $(Q) $(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test || ( echo test parse_address_with_named_scope_id_test failed ; exit 1 ) $(E) "[RUN] Testing percent_encoding_test" $(Q) $(BINDIR)/$(CONFIG)/percent_encoding_test || ( echo test percent_encoding_test failed ; exit 1 ) - $(E) "[RUN] Testing resolve_address_posix_test" - $(Q) $(BINDIR)/$(CONFIG)/resolve_address_posix_test || ( echo test resolve_address_posix_test failed ; exit 1 ) + $(E) "[RUN] Testing resolve_address_using_ares_resolver_posix_test" + $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test || ( echo test resolve_address_using_ares_resolver_posix_test failed ; exit 1 ) $(E) "[RUN] Testing resolve_address_using_ares_resolver_test" $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test || ( echo test resolve_address_using_ares_resolver_test failed ; exit 1 ) + $(E) "[RUN] Testing resolve_address_using_native_resolver_posix_test" + $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test || ( echo test resolve_address_using_native_resolver_posix_test failed ; exit 1 ) $(E) "[RUN] Testing resolve_address_using_native_resolver_test" $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test || ( echo test resolve_address_using_native_resolver_test failed ; exit 1 ) $(E) "[RUN] Testing resource_quota_test" @@ -3504,6 +3512,8 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ @@ -3920,6 +3930,8 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ @@ -4319,6 +4331,8 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ @@ -4628,6 +4642,8 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ @@ -4901,6 +4917,8 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ @@ -5763,6 +5781,8 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ @@ -13988,6 +14008,38 @@ endif endif +PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_SRC = \ + test/core/client_channel/parse_address_with_named_scope_id_test.cc \ + +PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test: $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/client_channel/parse_address_with_named_scope_id_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_parse_address_with_named_scope_id_test: $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS:.o=.dep) +endif +endif + + PERCENT_DECODE_FUZZER_SRC = \ test/core/slice/percent_decode_fuzzer.cc \ @@ -14084,34 +14136,34 @@ endif endif -RESOLVE_ADDRESS_POSIX_TEST_SRC = \ +RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_SRC = \ test/core/iomgr/resolve_address_posix_test.cc \ -RESOLVE_ADDRESS_POSIX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RESOLVE_ADDRESS_POSIX_TEST_SRC)))) +RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/resolve_address_posix_test: openssl_dep_error +$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/resolve_address_posix_test: $(RESOLVE_ADDRESS_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_posix_test + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test endif $(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_resolve_address_posix_test: $(RESOLVE_ADDRESS_POSIX_TEST_OBJS:.o=.dep) +deps_resolve_address_using_ares_resolver_posix_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(RESOLVE_ADDRESS_POSIX_TEST_OBJS:.o=.dep) +-include $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS:.o=.dep) endif endif @@ -14148,6 +14200,38 @@ endif endif +RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_SRC = \ + test/core/iomgr/resolve_address_posix_test.cc \ + +RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_resolve_address_using_native_resolver_posix_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS:.o=.dep) +endif +endif + + RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_SRC = \ test/core/iomgr/resolve_address_test.cc \ diff --git a/build.yaml b/build.yaml index a41decd84f7..3985668532d 100644 --- a/build.yaml +++ b/build.yaml @@ -276,6 +276,8 @@ filegroups: - src/core/lib/iomgr/gethostname_fallback.cc - src/core/lib/iomgr/gethostname_host_name_max.cc - src/core/lib/iomgr/gethostname_sysconf.cc + - src/core/lib/iomgr/grpc_if_nametoindex_posix.cc + - src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc - src/core/lib/iomgr/internal_errqueue.cc - src/core/lib/iomgr/iocp_windows.cc - src/core/lib/iomgr/iomgr.cc @@ -452,6 +454,7 @@ filegroups: - src/core/lib/iomgr/exec_ctx.h - src/core/lib/iomgr/executor.h - src/core/lib/iomgr/gethostname.h + - src/core/lib/iomgr/grpc_if_nametoindex.h - src/core/lib/iomgr/internal_errqueue.h - src/core/lib/iomgr/iocp_windows.h - src/core/lib/iomgr/iomgr.h @@ -3241,6 +3244,20 @@ targets: - grpc - gpr uses_polling: false +- name: parse_address_with_named_scope_id_test + build: test + language: c + src: + - test/core/client_channel/parse_address_with_named_scope_id_test.cc + deps: + - grpc_test_util + - grpc + - gpr + platforms: + - mac + - linux + - posix + uses_polling: false - name: percent_decode_fuzzer build: fuzzer language: c @@ -3275,7 +3292,7 @@ targets: - grpc - gpr uses_polling: false -- name: resolve_address_posix_test +- name: resolve_address_using_ares_resolver_posix_test build: test language: c src: @@ -3284,6 +3301,8 @@ targets: - grpc_test_util - grpc - gpr + args: + - --resolver=ares exclude_iomgrs: - uv platforms: @@ -3301,6 +3320,23 @@ targets: - gpr args: - --resolver=ares +- name: resolve_address_using_native_resolver_posix_test + build: test + language: c + src: + - test/core/iomgr/resolve_address_posix_test.cc + deps: + - grpc_test_util + - grpc + - gpr + args: + - --resolver=native + exclude_iomgrs: + - uv + platforms: + - mac + - linux + - posix - name: resolve_address_using_native_resolver_test build: test language: c diff --git a/config.m4 b/config.m4 index 25ffe2148ab..3c3c0210d87 100644 --- a/config.m4 +++ b/config.m4 @@ -128,6 +128,8 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ diff --git a/config.w32 b/config.w32 index b6e71dd09a5..f87859ad09f 100644 --- a/config.w32 +++ b/config.w32 @@ -103,6 +103,8 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\gethostname_fallback.cc " + "src\\core\\lib\\iomgr\\gethostname_host_name_max.cc " + "src\\core\\lib\\iomgr\\gethostname_sysconf.cc " + + "src\\core\\lib\\iomgr\\grpc_if_nametoindex_posix.cc " + + "src\\core\\lib\\iomgr\\grpc_if_nametoindex_unsupported.cc " + "src\\core\\lib\\iomgr\\internal_errqueue.cc " + "src\\core\\lib\\iomgr\\iocp_windows.cc " + "src\\core\\lib\\iomgr\\iomgr.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 29a79dd47ab..cdea73abc8b 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -423,6 +423,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', @@ -616,6 +617,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f873bc693bc..6c97dc42dc8 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -417,6 +417,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', @@ -571,6 +572,8 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', @@ -1040,6 +1043,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', diff --git a/grpc.gemspec b/grpc.gemspec index 3c680b044f7..42b1db35b4d 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -353,6 +353,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/exec_ctx.h ) s.files += %w( src/core/lib/iomgr/executor.h ) s.files += %w( src/core/lib/iomgr/gethostname.h ) + s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex.h ) s.files += %w( src/core/lib/iomgr/internal_errqueue.h ) s.files += %w( src/core/lib/iomgr/iocp_windows.h ) s.files += %w( src/core/lib/iomgr/iomgr.h ) @@ -507,6 +508,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/gethostname_fallback.cc ) s.files += %w( src/core/lib/iomgr/gethostname_host_name_max.cc ) s.files += %w( src/core/lib/iomgr/gethostname_sysconf.cc ) + s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex_posix.cc ) + s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc ) s.files += %w( src/core/lib/iomgr/internal_errqueue.cc ) s.files += %w( src/core/lib/iomgr/iocp_windows.cc ) s.files += %w( src/core/lib/iomgr/iomgr.cc ) diff --git a/grpc.gyp b/grpc.gyp index 80b6d0315a1..13b9c1bc78b 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -310,6 +310,8 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', @@ -672,6 +674,8 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', @@ -914,6 +918,8 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', @@ -1133,6 +1139,8 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', diff --git a/package.xml b/package.xml index 2632fcb276b..6c1d902abcd 100644 --- a/package.xml +++ b/package.xml @@ -358,6 +358,7 @@ + @@ -512,6 +513,8 @@ + + diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc index 707beb88769..c5e1ed811bc 100644 --- a/src/core/ext/filters/client_channel/parse_address.cc +++ b/src/core/ext/filters/client_channel/parse_address.cc @@ -19,6 +19,7 @@ #include #include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/lib/iomgr/grpc_if_nametoindex.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/socket_utils.h" @@ -35,6 +36,11 @@ #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#ifdef GRPC_POSIX_SOCKET +#include +#include +#endif + #ifdef GRPC_HAVE_UNIX_SOCKET bool grpc_parse_unix(const grpc_uri* uri, @@ -69,7 +75,12 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, // Split host and port. char* host; char* port; - if (!gpr_split_host_port(hostport, &host, &port)) return false; + if (!gpr_split_host_port(hostport, &host, &port)) { + if (log_errors) { + gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport); + } + return false; + } // Parse IP address. memset(addr, 0, sizeof(*addr)); addr->len = static_cast(sizeof(grpc_sockaddr_in)); @@ -115,7 +126,12 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, // Split host and port. char* host; char* port; - if (!gpr_split_host_port(hostport, &host, &port)) return false; + if (!gpr_split_host_port(hostport, &host, &port)) { + if (log_errors) { + gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport); + } + return false; + } // Parse IP address. memset(addr, 0, sizeof(*addr)); addr->len = static_cast(sizeof(grpc_sockaddr_in6)); @@ -150,10 +166,13 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, if (gpr_parse_bytes_to_uint32(host_end + 1, strlen(host) - host_without_scope_len - 1, &sin6_scope_id) == 0) { - if (log_errors) { - gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1); + if ((sin6_scope_id = grpc_if_nametoindex(host_end + 1)) == 0) { + gpr_log(GPR_ERROR, + "Invalid interface name: '%s'. " + "Non-numeric and failed if_nametoindex.", + host_end + 1); + goto done; } - goto done; } // Handle "sin6_scope_id" being type "u_long". See grpc issue #10027. in6->sin6_scope_id = sin6_scope_id; diff --git a/src/core/lib/iomgr/grpc_if_nametoindex.h b/src/core/lib/iomgr/grpc_if_nametoindex.h new file mode 100644 index 00000000000..ed9612dcb93 --- /dev/null +++ b/src/core/lib/iomgr/grpc_if_nametoindex.h @@ -0,0 +1,30 @@ +/* + * + * Copyright 2015 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_CORE_LIB_IOMGR_GRPC_IF_NAMETOINDEX_H +#define GRPC_CORE_LIB_IOMGR_GRPC_IF_NAMETOINDEX_H + +#include + +#include + +/* Returns the interface index corresponding to the interface "name" provided. + * Returns non-zero upon success, and zero upon failure. */ +uint32_t grpc_if_nametoindex(char* name); + +#endif /* GRPC_CORE_LIB_IOMGR_GRPC_IF_NAMETOINDEX_H */ diff --git a/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc b/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc new file mode 100644 index 00000000000..8f9137455d2 --- /dev/null +++ b/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc @@ -0,0 +1,41 @@ +/* + * + * Copyright 2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/iomgr/port.h" + +#ifdef GRPC_POSIX_SOCKET + +#include "src/core/lib/iomgr/grpc_if_nametoindex.h" + +#include +#include + +#include + +uint32_t grpc_if_nametoindex(char* name) { + uint32_t out = if_nametoindex(name); + if (out == 0) { + gpr_log(GPR_DEBUG, "if_nametoindex failed for name %s. errno %d", name, + errno); + } + return out; +} + +#endif /* GRPC_POSIX_SOCKET */ diff --git a/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc b/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc new file mode 100644 index 00000000000..1faaaa6e420 --- /dev/null +++ b/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc @@ -0,0 +1,37 @@ +/* + * + * Copyright 2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/iomgr/port.h" + +#ifndef GRPC_POSIX_SOCKET + +#include "src/core/lib/iomgr/grpc_if_nametoindex.h" + +#include + +uint32_t grpc_if_nametoindex(char* name) { + gpr_log(GPR_DEBUG, + "Not attempting to convert interface name %s to index for current " + "platform.", + name); + return 0; +} + +#endif /* GRPC_POSIX_SOCKET */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 6a1fd676ca6..06de23903cb 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -102,6 +102,8 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD index 04485f5240f..57e5191af4c 100644 --- a/test/core/client_channel/BUILD +++ b/test/core/client_channel/BUILD @@ -43,6 +43,17 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "parse_address_with_named_scope_id_test", + srcs = ["parse_address_with_named_scope_id_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "uri_parser_test", srcs = ["uri_parser_test.cc"], diff --git a/test/core/client_channel/parse_address_with_named_scope_id_test.cc b/test/core/client_channel/parse_address_with_named_scope_id_test.cc new file mode 100644 index 00000000000..bfafa745178 --- /dev/null +++ b/test/core/client_channel/parse_address_with_named_scope_id_test.cc @@ -0,0 +1,126 @@ +/* + * + * Copyright 2017 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 "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/socket_utils.h" + +#include +#include +#ifdef GRPC_HAVE_UNIX_SOCKET +#include +#endif + +#include +#include +#include + +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/socket_utils.h" +#include "test/core/util/test_config.h" + +static void test_grpc_parse_ipv6_parity_with_getaddrinfo( + const char* target, const struct sockaddr_in6 result_from_getaddrinfo) { + // Get the sockaddr that gRPC's ipv6 resolver resolves this too. + grpc_core::ExecCtx exec_ctx; + grpc_uri* uri = grpc_uri_parse(target, 0); + grpc_resolved_address addr; + GPR_ASSERT(1 == grpc_parse_ipv6(uri, &addr)); + grpc_sockaddr_in6* result_from_grpc_parser = + reinterpret_cast(addr.addr); + // Compare the sockaddr returned from gRPC's ipv6 resolver with that returned + // from getaddrinfo. + GPR_ASSERT(result_from_grpc_parser->sin6_family == AF_INET6); + GPR_ASSERT(result_from_getaddrinfo.sin6_family == AF_INET6); + GPR_ASSERT(memcmp(&result_from_grpc_parser->sin6_addr, + &result_from_getaddrinfo.sin6_addr, sizeof(in6_addr)) == 0); + GPR_ASSERT(result_from_grpc_parser->sin6_scope_id == + result_from_getaddrinfo.sin6_scope_id); + GPR_ASSERT(result_from_grpc_parser->sin6_scope_id != 0); + // TODO: compare sin6_flow_info fields? parse_ipv6 zero's this field as is. + // Cleanup + grpc_uri_destroy(uri); +} + +struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) { + grpc_uri* uri = grpc_uri_parse(uri_text, 0); + char* host = nullptr; + char* port = nullptr; + gpr_split_host_port(uri->path, &host, &port); + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_NUMERICHOST; + struct addrinfo* result; + int res = getaddrinfo(host, port, &hints, &result); + if (res != 0) { + gpr_log(GPR_ERROR, + "getaddrinfo failed to resolve host:%s port:%s. Error: %d.", host, + port, res); + abort(); + } + size_t num_addrs_from_getaddrinfo = 0; + for (struct addrinfo* resp = result; resp != nullptr; resp = resp->ai_next) { + num_addrs_from_getaddrinfo++; + } + GPR_ASSERT(num_addrs_from_getaddrinfo == 1); + GPR_ASSERT(result->ai_family == AF_INET6); + struct sockaddr_in6 out = + *reinterpret_cast(result->ai_addr); + // Cleanup + freeaddrinfo(result); + gpr_free(host); + gpr_free(port); + grpc_uri_destroy(uri); + return out; +} + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + char* arbitrary_interface_name = static_cast(gpr_zalloc(IF_NAMESIZE)); + // Per RFC 3493, an interface index is a "small positive integer starts at 1". + // Probe candidate interface index numbers until we find one that the + // system recognizes, and then use that for the test. + for (size_t i = 1; i < 65536; i++) { + if (if_indextoname(i, arbitrary_interface_name) != nullptr) { + gpr_log( + GPR_DEBUG, + "Found interface at index %d named %s. Will use this for the test", + (int)i, arbitrary_interface_name); + break; + } + } + GPR_ASSERT(strlen(arbitrary_interface_name) > 0); + char* target = nullptr; + gpr_asprintf(&target, "ipv6:[fe80::1234%%%s]:12345", + arbitrary_interface_name); + struct sockaddr_in6 result_from_getaddrinfo = + resolve_with_gettaddrinfo(target); + // Run the test + gpr_log(GPR_DEBUG, + "Run test_grpc_parse_ipv6_parity_with_getaddrinfo with target: %s", + target); + test_grpc_parse_ipv6_parity_with_getaddrinfo(target, result_from_getaddrinfo); + // Cleanup + gpr_free(target); + gpr_free(arbitrary_interface_name); + grpc_shutdown(); +} diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index e920ceacf00..5acf269988b 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -128,8 +128,25 @@ grpc_cc_test( ) grpc_cc_test( - name = "resolve_address_posix_test", + name = "resolve_address_using_ares_resolver_posix_test", srcs = ["resolve_address_posix_test.cc"], + args = [ + "--resolver=ares", + ], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "resolve_address_using_native_resolver_posix_test", + srcs = ["resolve_address_posix_test.cc"], + args = [ + "--resolver=native", + ], language = "C++", deps = [ "//:gpr", diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc index 5785c73e225..826c7e1fafa 100644 --- a/test/core/iomgr/resolve_address_posix_test.cc +++ b/test/core/iomgr/resolve_address_posix_test.cc @@ -18,12 +18,14 @@ #include "src/core/lib/iomgr/resolve_address.h" +#include #include #include #include #include #include +#include #include #include @@ -33,6 +35,7 @@ #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" +#include "test/core/util/cmdline.h" #include "test/core/util/test_config.h" static gpr_timespec test_deadline(void) { @@ -117,12 +120,18 @@ static void must_succeed(void* argsp, grpc_error* err) { GPR_ASSERT(args->addrs != nullptr); GPR_ASSERT(args->addrs->naddrs > 0); gpr_atm_rel_store(&args->done_atm, 1); + gpr_mu_lock(args->mu); + GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); + gpr_mu_unlock(args->mu); } static void must_fail(void* argsp, grpc_error* err) { args_struct* args = static_cast(argsp); GPR_ASSERT(err != GRPC_ERROR_NONE); gpr_atm_rel_store(&args->done_atm, 1); + gpr_mu_lock(args->mu); + GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); + gpr_mu_unlock(args->mu); } static void test_unix_socket(void) { @@ -159,22 +168,92 @@ static void test_unix_socket_path_name_too_long(void) { args_finish(&args); } +static void resolve_address_must_succeed(const char* target) { + grpc_core::ExecCtx exec_ctx; + args_struct args; + args_init(&args); + poll_pollset_until_request_done(&args); + grpc_resolve_address( + target, "1" /* port number */, args.pollset_set, + GRPC_CLOSURE_CREATE(must_succeed, &args, grpc_schedule_on_exec_ctx), + &args.addrs); + grpc_core::ExecCtx::Get()->Flush(); + args_finish(&args); +} + +static void test_named_and_numeric_scope_ids(void) { + char* arbitrary_interface_name = static_cast(gpr_zalloc(IF_NAMESIZE)); + int interface_index = 0; + // Probe candidate interface index numbers until we find one that the + // system recognizes, and then use that for the test. + for (size_t i = 1; i < 65536; i++) { + if (if_indextoname(i, arbitrary_interface_name) != nullptr) { + gpr_log( + GPR_DEBUG, + "Found interface at index %d named %s. Will use this for the test", + (int)i, arbitrary_interface_name); + interface_index = (int)i; + break; + } + } + GPR_ASSERT(strlen(arbitrary_interface_name) > 0); + // Test resolution of an ipv6 address with a named scope ID + gpr_log(GPR_DEBUG, "test resolution with a named scope ID"); + char* target_with_named_scope_id = nullptr; + gpr_asprintf(&target_with_named_scope_id, "fe80::1234%%%s", + arbitrary_interface_name); + resolve_address_must_succeed(target_with_named_scope_id); + gpr_free(target_with_named_scope_id); + gpr_free(arbitrary_interface_name); + // Test resolution of an ipv6 address with a numeric scope ID + gpr_log(GPR_DEBUG, "test resolution with a numeric scope ID"); + char* target_with_numeric_scope_id = nullptr; + gpr_asprintf(&target_with_numeric_scope_id, "fe80::1234%%%d", + interface_index); + resolve_address_must_succeed(target_with_numeric_scope_id); + gpr_free(target_with_numeric_scope_id); +} + int main(int argc, char** argv) { + // First set the resolver type based off of --resolver + const char* resolver_type = nullptr; + gpr_cmdline* cl = gpr_cmdline_create("resolve address test"); + gpr_cmdline_add_string(cl, "resolver", "Resolver type (ares or native)", + &resolver_type); + // In case that there are more than one argument on the command line, + // --resolver will always be the first one, so only parse the first argument + // (other arguments may be unknown to cl) + gpr_cmdline_parse(cl, argc > 2 ? 2 : argc, argv); + const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER"); + if (cur_resolver != nullptr && strlen(cur_resolver) != 0) { + gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s", + cur_resolver); + } + if (gpr_stricmp(resolver_type, "native") == 0) { + gpr_setenv("GRPC_DNS_RESOLVER", "native"); + } else if (gpr_stricmp(resolver_type, "ares") == 0) { + gpr_setenv("GRPC_DNS_RESOLVER", "ares"); + } else { + gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native"); + abort(); + } grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; - char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + test_named_and_numeric_scope_ids(); // c-ares resolver doesn't support UDS (ability for native DNS resolver // to handle this is only expected to be used by servers, which // unconditionally use the native DNS resolver). + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) { test_unix_socket(); test_unix_socket_path_name_too_long(); } gpr_free(resolver_env); } + gpr_cmdline_destroy(cl); grpc_shutdown(); return 0; diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 5f488d51940..08741168275 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1100,6 +1100,7 @@ src/core/lib/iomgr/ev_posix.h \ src/core/lib/iomgr/exec_ctx.h \ src/core/lib/iomgr/executor.h \ src/core/lib/iomgr/gethostname.h \ +src/core/lib/iomgr/grpc_if_nametoindex.h \ src/core/lib/iomgr/internal_errqueue.h \ src/core/lib/iomgr/iocp_windows.h \ src/core/lib/iomgr/iomgr.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index ba2eaecafda..38d17b6f21f 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1214,6 +1214,9 @@ src/core/lib/iomgr/gethostname.h \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ +src/core/lib/iomgr/grpc_if_nametoindex.h \ +src/core/lib/iomgr/grpc_if_nametoindex_posix.cc \ +src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/internal_errqueue.h \ src/core/lib/iomgr/iocp_windows.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8d1bca22be9..1478ac2cd5e 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -1722,6 +1722,22 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "parse_address_with_named_scope_id_test", + "src": [ + "test/core/client_channel/parse_address_with_named_scope_id_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -1779,7 +1795,7 @@ "headers": [], "is_filegroup": false, "language": "c", - "name": "resolve_address_posix_test", + "name": "resolve_address_using_ares_resolver_posix_test", "src": [ "test/core/iomgr/resolve_address_posix_test.cc" ], @@ -1802,6 +1818,22 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "resolve_address_using_native_resolver_posix_test", + "src": [ + "test/core/iomgr/resolve_address_posix_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -9371,6 +9403,8 @@ "src/core/lib/iomgr/gethostname_fallback.cc", "src/core/lib/iomgr/gethostname_host_name_max.cc", "src/core/lib/iomgr/gethostname_sysconf.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_posix.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc", "src/core/lib/iomgr/internal_errqueue.cc", "src/core/lib/iomgr/iocp_windows.cc", "src/core/lib/iomgr/iomgr.cc", @@ -9548,6 +9582,7 @@ "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", + "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", @@ -9701,6 +9736,7 @@ "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", + "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index e35d4db2767..f2d0cab5ede 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -2057,6 +2057,28 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "parse_address_with_named_scope_id_test", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, @@ -2082,7 +2104,9 @@ "uses_polling": false }, { - "args": [], + "args": [ + "--resolver=ares" + ], "benchmark": false, "ci_platforms": [ "linux", @@ -2097,7 +2121,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "resolve_address_posix_test", + "name": "resolve_address_using_ares_resolver_posix_test", "platforms": [ "linux", "mac", @@ -2131,6 +2155,32 @@ ], "uses_polling": true }, + { + "args": [ + "--resolver=native" + ], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "gtest": false, + "language": "c", + "name": "resolve_address_using_native_resolver_posix_test", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": true + }, { "args": [ "--resolver=native" From 39ac83a49ea73f619edbfd7ebde47f12d67a18f3 Mon Sep 17 00:00:00 2001 From: Tommy Chen Date: Wed, 26 Dec 2018 11:17:48 -0800 Subject: [PATCH 402/534] ruby-sigint ready to be merged! --- examples/ruby/greeter_server.rb | 5 +- .../ruby/route_guide/route_guide_server.rb | 5 +- .../end2end/graceful_sig_handling_client.rb | 61 ++++++++++++++ .../end2end/graceful_sig_handling_driver.rb | 83 +++++++++++++++++++ src/ruby/end2end/graceful_sig_stop_client.rb | 78 +++++++++++++++++ src/ruby/end2end/graceful_sig_stop_driver.rb | 62 ++++++++++++++ src/ruby/lib/grpc/generic/rpc_server.rb | 61 ++++++++++++++ .../helper_scripts/run_ruby_end2end_tests.sh | 2 + 8 files changed, 355 insertions(+), 2 deletions(-) create mode 100755 src/ruby/end2end/graceful_sig_handling_client.rb create mode 100755 src/ruby/end2end/graceful_sig_handling_driver.rb create mode 100755 src/ruby/end2end/graceful_sig_stop_client.rb create mode 100755 src/ruby/end2end/graceful_sig_stop_driver.rb diff --git a/examples/ruby/greeter_server.rb b/examples/ruby/greeter_server.rb index dca61714b88..52904297426 100755 --- a/examples/ruby/greeter_server.rb +++ b/examples/ruby/greeter_server.rb @@ -39,7 +39,10 @@ def main s = GRPC::RpcServer.new s.add_http2_port('0.0.0.0:50051', :this_port_is_insecure) s.handle(GreeterServer) - s.run_till_terminated + # Runs the server with SIGHUP, SIGINT and SIGQUIT signal handlers to + # gracefully shutdown. + # User could also choose to run server via call to run_till_terminated + s.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT']) end main diff --git a/examples/ruby/route_guide/route_guide_server.rb b/examples/ruby/route_guide/route_guide_server.rb index 5eb268b5336..ffcebd8418d 100755 --- a/examples/ruby/route_guide/route_guide_server.rb +++ b/examples/ruby/route_guide/route_guide_server.rb @@ -172,7 +172,10 @@ def main s.add_http2_port(port, :this_port_is_insecure) GRPC.logger.info("... running insecurely on #{port}") s.handle(ServerImpl.new(feature_db)) - s.run_till_terminated + # Runs the server with SIGHUP, SIGINT and SIGQUIT signal handlers to + # gracefully shutdown. + # User could also choose to run server via call to run_till_terminated + s.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT']) end main diff --git a/src/ruby/end2end/graceful_sig_handling_client.rb b/src/ruby/end2end/graceful_sig_handling_client.rb new file mode 100755 index 00000000000..14a67a62ccc --- /dev/null +++ b/src/ruby/end2end/graceful_sig_handling_client.rb @@ -0,0 +1,61 @@ +#!/usr/bin/env ruby + +# Copyright 2015 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. + +require_relative './end2end_common' + +# Test client. Sends RPC's as normal but process also has signal handlers +class SigHandlingClientController < ClientControl::ClientController::Service + def initialize(stub) + @stub = stub + end + + def do_echo_rpc(req, _) + response = @stub.echo(Echo::EchoRequest.new(request: req.request)) + fail 'bad response' unless response.response == req.request + ClientControl::Void.new + end +end + +def main + client_control_port = '' + server_port = '' + OptionParser.new do |opts| + opts.on('--client_control_port=P', String) do |p| + client_control_port = p + end + opts.on('--server_port=P', String) do |p| + server_port = p + end + end.parse! + + # Allow a few seconds to be safe. + srv = new_rpc_server_for_testing + srv.add_http2_port("0.0.0.0:#{client_control_port}", + :this_port_is_insecure) + stub = Echo::EchoServer::Stub.new("localhost:#{server_port}", + :this_channel_is_insecure) + control_service = SigHandlingClientController.new(stub) + srv.handle(control_service) + server_thread = Thread.new do + srv.run_till_terminated_or_interrupted(['int']) + end + srv.wait_till_running + # send a first RPC to notify the parent process that we've started + stub.echo(Echo::EchoRequest.new(request: 'client/child started')) + server_thread.join +end + +main diff --git a/src/ruby/end2end/graceful_sig_handling_driver.rb b/src/ruby/end2end/graceful_sig_handling_driver.rb new file mode 100755 index 00000000000..e12ae284858 --- /dev/null +++ b/src/ruby/end2end/graceful_sig_handling_driver.rb @@ -0,0 +1,83 @@ +#!/usr/bin/env ruby + +# Copyright 2016 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# smoke test for a grpc-using app that receives and +# handles process-ending signals + +require_relative './end2end_common' + +# A service that calls back it's received_rpc_callback +# upon receiving an RPC. Used for synchronization/waiting +# for child process to start. +class ClientStartedService < Echo::EchoServer::Service + def initialize(received_rpc_callback) + @received_rpc_callback = received_rpc_callback + end + + def echo(echo_req, _) + @received_rpc_callback.call unless @received_rpc_callback.nil? + @received_rpc_callback = nil + Echo::EchoReply.new(response: echo_req.request) + end +end + +def main + STDERR.puts 'start server' + client_started = false + client_started_mu = Mutex.new + client_started_cv = ConditionVariable.new + received_rpc_callback = proc do + client_started_mu.synchronize do + client_started = true + client_started_cv.signal + end + end + + client_started_service = ClientStartedService.new(received_rpc_callback) + server_runner = ServerRunner.new(client_started_service) + server_port = server_runner.run + STDERR.puts 'start client' + control_stub, client_pid = start_client('graceful_sig_handling_client.rb', server_port) + + client_started_mu.synchronize do + client_started_cv.wait(client_started_mu) until client_started + end + + control_stub.do_echo_rpc( + ClientControl::DoEchoRpcRequest.new(request: 'hello')) + + STDERR.puts 'killing client' + Process.kill('SIGINT', client_pid) + Process.wait(client_pid) + client_exit_status = $CHILD_STATUS + + if client_exit_status.exited? + if client_exit_status.exitstatus != 0 + STDERR.puts 'Client did not close gracefully' + exit(1) + end + else + STDERR.puts 'Client did not close gracefully' + exit(1) + end + + STDERR.puts 'Client ended gracefully' + + # no need to call cleanup, client should already be dead + server_runner.stop +end + +main diff --git a/src/ruby/end2end/graceful_sig_stop_client.rb b/src/ruby/end2end/graceful_sig_stop_client.rb new file mode 100755 index 00000000000..b672dc3f2ac --- /dev/null +++ b/src/ruby/end2end/graceful_sig_stop_client.rb @@ -0,0 +1,78 @@ +#!/usr/bin/env ruby + +# Copyright 2015 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. + +require_relative './end2end_common' + +# Test client. Sends RPC's as normal but process also has signal handlers +class SigHandlingClientController < ClientControl::ClientController::Service + def initialize(srv, stub) + @srv = srv + @stub = stub + end + + def do_echo_rpc(req, _) + response = @stub.echo(Echo::EchoRequest.new(request: req.request)) + fail 'bad response' unless response.response == req.request + ClientControl::Void.new + end + + def shutdown(_, _) + # Spawn a new thread because RpcServer#stop is + # synchronous and blocks until either this RPC has finished, + # or the server's "poll_period" seconds have passed. + @shutdown_thread = Thread.new do + @srv.stop + end + ClientControl::Void.new + end + + def join_shutdown_thread + @shutdown_thread.join + end +end + +def main + client_control_port = '' + server_port = '' + OptionParser.new do |opts| + opts.on('--client_control_port=P', String) do |p| + client_control_port = p + end + opts.on('--server_port=P', String) do |p| + server_port = p + end + end.parse! + + # The "shutdown" RPC should end very quickly. + # Allow a few seconds to be safe. + srv = new_rpc_server_for_testing(poll_period: 3) + srv.add_http2_port("0.0.0.0:#{client_control_port}", + :this_port_is_insecure) + stub = Echo::EchoServer::Stub.new("localhost:#{server_port}", + :this_channel_is_insecure) + control_service = SigHandlingClientController.new(srv, stub) + srv.handle(control_service) + server_thread = Thread.new do + srv.run_till_terminated_or_interrupted(['int']) + end + srv.wait_till_running + # send a first RPC to notify the parent process that we've started + stub.echo(Echo::EchoRequest.new(request: 'client/child started')) + server_thread.join + control_service.join_shutdown_thread +end + +main diff --git a/src/ruby/end2end/graceful_sig_stop_driver.rb b/src/ruby/end2end/graceful_sig_stop_driver.rb new file mode 100755 index 00000000000..7a132403ebf --- /dev/null +++ b/src/ruby/end2end/graceful_sig_stop_driver.rb @@ -0,0 +1,62 @@ +#!/usr/bin/env ruby + +# Copyright 2016 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# smoke test for a grpc-using app that receives and +# handles process-ending signals + +require_relative './end2end_common' + +# A service that calls back it's received_rpc_callback +# upon receiving an RPC. Used for synchronization/waiting +# for child process to start. +class ClientStartedService < Echo::EchoServer::Service + def initialize(received_rpc_callback) + @received_rpc_callback = received_rpc_callback + end + + def echo(echo_req, _) + @received_rpc_callback.call unless @received_rpc_callback.nil? + @received_rpc_callback = nil + Echo::EchoReply.new(response: echo_req.request) + end +end + +def main + STDERR.puts 'start server' + client_started = false + client_started_mu = Mutex.new + client_started_cv = ConditionVariable.new + received_rpc_callback = proc do + client_started_mu.synchronize do + client_started = true + client_started_cv.signal + end + end + + client_started_service = ClientStartedService.new(received_rpc_callback) + server_runner = ServerRunner.new(client_started_service) + server_port = server_runner.run + STDERR.puts 'start client' + control_stub, client_pid = start_client('./graceful_sig_stop_client.rb', server_port) + + client_started_mu.synchronize do + client_started_cv.wait(client_started_mu) until client_started + end + + cleanup(control_stub, client_pid, server_runner) +end + +main diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index 3b5a0ce27f3..f0f73dc56ea 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -240,6 +240,13 @@ module GRPC # the call has no impact if the server is already stopped, otherwise # server's current call loop is it's last. def stop + # if called via run_till_terminated_or_interrupted, + # signal stop_server_thread and dont do anything + if @stop_server.nil? == false && @stop_server == false + @stop_server = true + @stop_server_cv.broadcast + return + end @run_mutex.synchronize do fail 'Cannot stop before starting' if @running_state == :not_started return if @running_state != :running @@ -354,6 +361,60 @@ module GRPC alias_method :run_till_terminated, :run + # runs the server with signal handlers + # @param signals + # List of String, Integer or both representing signals that the user + # would like to send to the server for graceful shutdown + # @param wait_interval (optional) + # Integer seconds that user would like stop_server_thread to poll + # stop_server + def run_till_terminated_or_interrupted(signals, wait_interval = 60) + @stop_server = false + @stop_server_mu = Mutex.new + @stop_server_cv = ConditionVariable.new + + @stop_server_thread = Thread.new do + loop do + break if @stop_server + @stop_server_mu.synchronize do + @stop_server_cv.wait(@stop_server_mu, wait_interval) + end + end + + # stop is surrounded by mutex, should handle multiple calls to stop + # correctly + stop + end + + valid_signals = Signal.list + + # register signal handlers + signals.each do |sig| + # input validation + if sig.class == String + sig.upcase! + if sig.start_with?('SIG') + # cut out the SIG prefix to see if valid signal + sig = sig[3..-1] + end + end + + # register signal traps for all valid signals + if valid_signals.value?(sig) || valid_signals.key?(sig) + Signal.trap(sig) do + @stop_server = true + @stop_server_cv.broadcast + end + else + fail "#{sig} not a valid signal" + end + end + + run + + @stop_server_thread.join + end + # Sends RESOURCE_EXHAUSTED if there are too many unprocessed jobs def available?(an_rpc) return an_rpc if @pool.ready_for_work? diff --git a/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh b/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh index 7ff877e8306..1c48ed20ba6 100755 --- a/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh +++ b/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh @@ -30,4 +30,6 @@ time ruby src/ruby/end2end/multiple_killed_watching_threads_driver.rb || EXIT_CO time ruby src/ruby/end2end/load_grpc_with_gc_stress_driver.rb || EXIT_CODE=1 time ruby src/ruby/end2end/client_memory_usage_driver.rb || EXIT_CODE=1 time ruby src/ruby/end2end/package_with_underscore_checker.rb || EXIT_CODE=1 +time ruby src/ruby/end2end/graceful_sig_handling_driver.rb || EXIT_CODE=1 +time ruby src/ruby/end2end/graceful_sig_stop_driver.rb || EXIT_CODE=1 exit $EXIT_CODE From 71e7e6ddc73175df0793748e290e29321934fd7c Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 26 Dec 2018 12:29:52 -0800 Subject: [PATCH 403/534] Add Watch method to health check service --- .../grpc_health/v1/health.py | 76 +++++++- .../health_check/_health_servicer_test.py | 174 ++++++++++++++++-- 2 files changed, 223 insertions(+), 27 deletions(-) diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py index 05836594281..75c480b0a7a 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -23,15 +23,61 @@ from grpc_health.v1 import health_pb2_grpc as _health_pb2_grpc SERVICE_NAME = _health_pb2.DESCRIPTOR.services_by_name['Health'].full_name +class _Watcher(): + + def __init__(self): + self._condition = threading.Condition() + self._responses = list() + self._open = True + + def __iter__(self): + return self + + def _next(self): + with self._condition: + while not self._responses and self._open: + self._condition.wait() + if self._responses: + return self._responses.pop(0) + else: + raise StopIteration() + + def next(self): + return self._next() + + def __next__(self): + return self._next() + + def add(self, response): + with self._condition: + self._responses.append(response) + self._condition.notify() + + def close(self): + with self._condition: + self._open = False + self._condition.notify() + + class HealthServicer(_health_pb2_grpc.HealthServicer): """Servicer handling RPCs for service statuses.""" def __init__(self): - self._server_status_lock = threading.Lock() + self._lock = threading.RLock() self._server_status = {} + self._watchers = {} + + def _on_close_callback(self, watcher, service): + + def callback(): + with self._lock: + self._watchers[service].remove(watcher) + watcher.close() + + return callback def Check(self, request, context): - with self._server_status_lock: + with self._lock: status = self._server_status.get(request.service) if status is None: context.set_code(grpc.StatusCode.NOT_FOUND) @@ -39,14 +85,30 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): else: return _health_pb2.HealthCheckResponse(status=status) + def Watch(self, request, context): + service = request.service + with self._lock: + status = self._server_status.get(service) + if status is None: + status = _health_pb2.HealthCheckResponse.SERVICE_UNKNOWN # pylint: disable=no-member + watcher = _Watcher() + watcher.add(_health_pb2.HealthCheckResponse(status=status)) + if service not in self._watchers: + self._watchers[service] = set() + self._watchers[service].add(watcher) + context.add_callback(self._on_close_callback(watcher, service)) + return watcher + def set(self, service, status): """Sets the status of a service. Args: - service: string, the name of the service. - NOTE, '' must be set. - status: HealthCheckResponse.status enum value indicating - the status of the service + service: string, the name of the service. NOTE, '' must be set. + status: HealthCheckResponse.status enum value indicating the status of + the service """ - with self._server_status_lock: + with self._lock: self._server_status[service] = status + if service in self._watchers: + for watcher in self._watchers[service]: + watcher.add(_health_pb2.HealthCheckResponse(status=status)) diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index c1d9436c2fa..657ceef1e48 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -13,6 +13,7 @@ # limitations under the License. """Tests of grpc_health.v1.health.""" +import threading import unittest import grpc @@ -22,21 +23,36 @@ from grpc_health.v1 import health_pb2_grpc from tests.unit import test_common +from six.moves import queue + +_QUEUE_TIMEOUT_S = 5 + +_SERVING_SERVICE = 'grpc.test.TestServiceServing' +_UNKNOWN_SERVICE = 'grpc.test.TestServiceUnknown' +_NOT_SERVING_SERVICE = 'grpc.test.TestServiceNotServing' +_WATCH_SERVICE = 'grpc.test.WatchService' + + +def _consume_responses(response_iterator, response_queue): + for response in response_iterator: + response_queue.put(response) + class HealthServicerTest(unittest.TestCase): def setUp(self): - servicer = health.HealthServicer() - servicer.set('', health_pb2.HealthCheckResponse.SERVING) - servicer.set('grpc.test.TestServiceServing', - health_pb2.HealthCheckResponse.SERVING) - servicer.set('grpc.test.TestServiceUnknown', - health_pb2.HealthCheckResponse.UNKNOWN) - servicer.set('grpc.test.TestServiceNotServing', - health_pb2.HealthCheckResponse.NOT_SERVING) + self._servicer = health.HealthServicer() + self._servicer.set('', health_pb2.HealthCheckResponse.SERVING) + self._servicer.set(_SERVING_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + self._servicer.set(_UNKNOWN_SERVICE, + health_pb2.HealthCheckResponse.UNKNOWN) + self._servicer.set(_NOT_SERVING_SERVICE, + health_pb2.HealthCheckResponse.NOT_SERVING) self._server = test_common.test_server() port = self._server.add_insecure_port('[::]:0') - health_pb2_grpc.add_HealthServicer_to_server(servicer, self._server) + health_pb2_grpc.add_HealthServicer_to_server(self._servicer, + self._server) self._server.start() self._channel = grpc.insecure_channel('localhost:%d' % port) @@ -46,37 +62,155 @@ class HealthServicerTest(unittest.TestCase): self._server.stop(None) self._channel.close() - def test_empty_service(self): + def test_check_empty_service(self): request = health_pb2.HealthCheckRequest() resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status) - def test_serving_service(self): - request = health_pb2.HealthCheckRequest( - service='grpc.test.TestServiceServing') + def test_check_serving_service(self): + request = health_pb2.HealthCheckRequest(service=_SERVING_SERVICE) resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status) - def test_unknown_serivce(self): - request = health_pb2.HealthCheckRequest( - service='grpc.test.TestServiceUnknown') + def test_check_unknown_serivce(self): + request = health_pb2.HealthCheckRequest(service=_UNKNOWN_SERVICE) resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.UNKNOWN, resp.status) - def test_not_serving_service(self): - request = health_pb2.HealthCheckRequest( - service='grpc.test.TestServiceNotServing') + def test_check_not_serving_service(self): + request = health_pb2.HealthCheckRequest(service=_NOT_SERVING_SERVICE) resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, resp.status) - def test_not_found_service(self): + def test_check_not_found_service(self): request = health_pb2.HealthCheckRequest(service='not-found') with self.assertRaises(grpc.RpcError) as context: resp = self._stub.Check(request) self.assertEqual(grpc.StatusCode.NOT_FOUND, context.exception.code()) + def test_watch_empty_service(self): + request = health_pb2.HealthCheckRequest(service='') + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response.status) + + rendezvous.cancel() + thread.join() + self.assertTrue(response_queue.empty()) + + def test_watch_new_service(self): + request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response.status) + + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response.status) + + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.NOT_SERVING) + response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, + response.status) + + rendezvous.cancel() + thread.join() + self.assertTrue(response_queue.empty()) + + def test_watch_service_isolation(self): + request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response.status) + + self._servicer.set('some-other-service', + health_pb2.HealthCheckResponse.SERVING) + with self.assertRaises(queue.Empty) as context: + response_queue.get(timeout=_QUEUE_TIMEOUT_S) + + rendezvous.cancel() + thread.join() + self.assertTrue(response_queue.empty()) + + def test_two_watchers(self): + request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) + response_queue1 = queue.Queue() + response_queue2 = queue.Queue() + rendezvous1 = self._stub.Watch(request) + rendezvous2 = self._stub.Watch(request) + thread1 = threading.Thread( + target=_consume_responses, args=(rendezvous1, response_queue1)) + thread2 = threading.Thread( + target=_consume_responses, args=(rendezvous2, response_queue2)) + thread1.start() + thread2.start() + + response1 = response_queue1.get(timeout=_QUEUE_TIMEOUT_S) + response2 = response_queue2.get(timeout=_QUEUE_TIMEOUT_S) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response1.status) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response2.status) + + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + response1 = response_queue1.get(timeout=_QUEUE_TIMEOUT_S) + response2 = response_queue2.get(timeout=_QUEUE_TIMEOUT_S) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response1.status) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response2.status) + + rendezvous1.cancel() + rendezvous2.cancel() + thread1.join() + thread2.join() + self.assertTrue(response_queue1.empty()) + self.assertTrue(response_queue2.empty()) + + def test_cancelled_watch_removed_from_watch_list(self): + request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response.status) + + rendezvous.cancel() + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + thread.join() + self.assertFalse(self._servicer._watchers[_WATCH_SERVICE], + 'watch set should be empty') + self.assertTrue(response_queue.empty()) + def test_health_service_name(self): self.assertEqual(health.SERVICE_NAME, 'grpc.health.v1.Health') From b74af8c70bad274c4955a0e242c725409872342d Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 26 Dec 2018 15:04:38 -0800 Subject: [PATCH 404/534] skip test with gevent --- src/python/grpcio_tests/commands.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index d5327711d33..582ce898dee 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -141,6 +141,7 @@ class TestGevent(setuptools.Command): 'unit._exit_test.ExitTest.test_in_flight_partial_unary_stream_call', 'unit._exit_test.ExitTest.test_in_flight_partial_stream_unary_call', 'unit._exit_test.ExitTest.test_in_flight_partial_stream_stream_call', + 'health_check._health_servicer_test.HealthServicerTest.test_cancelled_watch_removed_from_watch_list', # TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels', 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels_and_sockets', From e678187996bb7239315f30d9e50734c50ee4027b Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 27 Dec 2018 09:39:53 -0800 Subject: [PATCH 405/534] use test constants, fix formatting --- .../grpc_health/v1/health.py | 10 +++---- .../health_check/_health_servicer_test.py | 27 +++++++++---------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py index 75c480b0a7a..0a5bbb5504c 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -102,11 +102,11 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): def set(self, service, status): """Sets the status of a service. - Args: - service: string, the name of the service. NOTE, '' must be set. - status: HealthCheckResponse.status enum value indicating the status of - the service - """ + Args: + service: string, the name of the service. NOTE, '' must be set. + status: HealthCheckResponse.status enum value indicating the status of + the service + """ with self._lock: self._server_status[service] = status if service in self._watchers: diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index 657ceef1e48..bf90fa15c0e 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -22,11 +22,10 @@ from grpc_health.v1 import health_pb2 from grpc_health.v1 import health_pb2_grpc from tests.unit import test_common +from tests.unit.framework.common import test_constants from six.moves import queue -_QUEUE_TIMEOUT_S = 5 - _SERVING_SERVICE = 'grpc.test.TestServiceServing' _UNKNOWN_SERVICE = 'grpc.test.TestServiceUnknown' _NOT_SERVING_SERVICE = 'grpc.test.TestServiceNotServing' @@ -98,7 +97,7 @@ class HealthServicerTest(unittest.TestCase): target=_consume_responses, args=(rendezvous, response_queue)) thread.start() - response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) self.assertEqual(health_pb2.HealthCheckResponse.SERVING, response.status) @@ -114,19 +113,19 @@ class HealthServicerTest(unittest.TestCase): target=_consume_responses, args=(rendezvous, response_queue)) thread.start() - response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, response.status) self._servicer.set(_WATCH_SERVICE, health_pb2.HealthCheckResponse.SERVING) - response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) self.assertEqual(health_pb2.HealthCheckResponse.SERVING, response.status) self._servicer.set(_WATCH_SERVICE, health_pb2.HealthCheckResponse.NOT_SERVING) - response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, response.status) @@ -142,14 +141,14 @@ class HealthServicerTest(unittest.TestCase): target=_consume_responses, args=(rendezvous, response_queue)) thread.start() - response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, response.status) self._servicer.set('some-other-service', health_pb2.HealthCheckResponse.SERVING) - with self.assertRaises(queue.Empty) as context: - response_queue.get(timeout=_QUEUE_TIMEOUT_S) + with self.assertRaises(queue.Empty): + response_queue.get(timeout=test_constants.SHORT_TIMEOUT) rendezvous.cancel() thread.join() @@ -168,8 +167,8 @@ class HealthServicerTest(unittest.TestCase): thread1.start() thread2.start() - response1 = response_queue1.get(timeout=_QUEUE_TIMEOUT_S) - response2 = response_queue2.get(timeout=_QUEUE_TIMEOUT_S) + response1 = response_queue1.get(timeout=test_constants.SHORT_TIMEOUT) + response2 = response_queue2.get(timeout=test_constants.SHORT_TIMEOUT) self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, response1.status) self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, @@ -177,8 +176,8 @@ class HealthServicerTest(unittest.TestCase): self._servicer.set(_WATCH_SERVICE, health_pb2.HealthCheckResponse.SERVING) - response1 = response_queue1.get(timeout=_QUEUE_TIMEOUT_S) - response2 = response_queue2.get(timeout=_QUEUE_TIMEOUT_S) + response1 = response_queue1.get(timeout=test_constants.SHORT_TIMEOUT) + response2 = response_queue2.get(timeout=test_constants.SHORT_TIMEOUT) self.assertEqual(health_pb2.HealthCheckResponse.SERVING, response1.status) self.assertEqual(health_pb2.HealthCheckResponse.SERVING, @@ -199,7 +198,7 @@ class HealthServicerTest(unittest.TestCase): target=_consume_responses, args=(rendezvous, response_queue)) thread.start() - response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, response.status) From 4e3e46df2249bbd6ba8f3330c0a44ca508d0f35c Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 27 Dec 2018 11:53:54 -0800 Subject: [PATCH 406/534] fix test --- src/python/grpcio_tests/tests/health_check/BUILD.bazel | 1 + .../tests/health_check/_health_servicer_test.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/python/grpcio_tests/tests/health_check/BUILD.bazel b/src/python/grpcio_tests/tests/health_check/BUILD.bazel index 19e1e1b2e1e..77bc61aa30e 100644 --- a/src/python/grpcio_tests/tests/health_check/BUILD.bazel +++ b/src/python/grpcio_tests/tests/health_check/BUILD.bazel @@ -9,6 +9,7 @@ py_test( "//src/python/grpcio/grpc:grpcio", "//src/python/grpcio_health_checking/grpc_health/v1:grpc_health", "//src/python/grpcio_tests/tests/unit:test_common", + "//src/python/grpcio_tests/tests/unit/framework/common:common", ], imports = ["../../",], ) diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index bf90fa15c0e..35794987bc8 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -14,6 +14,7 @@ """Tests of grpc_health.v1.health.""" import threading +import time import unittest import grpc @@ -206,6 +207,11 @@ class HealthServicerTest(unittest.TestCase): self._servicer.set(_WATCH_SERVICE, health_pb2.HealthCheckResponse.SERVING) thread.join() + + # Wait, if necessary, for serving thread to process client cancellation + timeout = time.time() + test_constants.SHORT_TIMEOUT + while time.time() < timeout and self._servicer._watchers[_WATCH_SERVICE]: + time.sleep(1) self.assertFalse(self._servicer._watchers[_WATCH_SERVICE], 'watch set should be empty') self.assertTrue(response_queue.empty()) From dd4830eae80143f5b0a9a3a1a024af4cf60e7d02 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 21 Dec 2018 13:44:20 -0800 Subject: [PATCH 407/534] Make gRPC version string available as grpc.__version__ --- doc/python/sphinx/grpc.rst | 5 ++++ src/python/grpcio/grpc/__init__.py | 5 ++++ src/python/grpcio_tests/tests/tests.json | 1 + .../grpcio_tests/tests/unit/BUILD.bazel | 1 + .../grpcio_tests/tests/unit/_version_test.py | 30 +++++++++++++++++++ 5 files changed, 42 insertions(+) create mode 100644 src/python/grpcio_tests/tests/unit/_version_test.py diff --git a/doc/python/sphinx/grpc.rst b/doc/python/sphinx/grpc.rst index bd2df9596b0..f534d25c639 100644 --- a/doc/python/sphinx/grpc.rst +++ b/doc/python/sphinx/grpc.rst @@ -19,6 +19,11 @@ Go to `gRPC Python Examples Date: Thu, 27 Dec 2018 15:21:12 -0800 Subject: [PATCH 408/534] Free grpc_channel_args after creation --- .../grpc/_cython/_cygrpc/arguments.pxd.pxi | 13 ++++--- .../grpc/_cython/_cygrpc/arguments.pyx.pxi | 37 +++++++++++-------- .../grpc/_cython/_cygrpc/channel.pyx.pxi | 9 ++--- .../grpc/_cython/_cygrpc/server.pxd.pxi | 1 - .../grpc/_cython/_cygrpc/server.pyx.pxi | 8 ++-- 5 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi index e0e068e4524..01b82374845 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi @@ -28,19 +28,22 @@ cdef tuple _wrap_grpc_arg(grpc_arg arg) cdef grpc_arg _unwrap_grpc_arg(tuple wrapped_arg) -cdef class _ArgumentProcessor: +cdef class _ChannelArg: cdef grpc_arg c_argument cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references) except * -cdef class _ArgumentsProcessor: +cdef class _ChannelArgs: cdef readonly tuple _arguments - cdef list _argument_processors + cdef list _channel_args cdef readonly list _references cdef grpc_channel_args _c_arguments - cdef grpc_channel_args *c(self, grpc_arg_pointer_vtable *vtable) except * - cdef un_c(self) + cdef void _c(self, grpc_arg_pointer_vtable *vtable) except * + cdef grpc_channel_args *c_args(self) except * + + @staticmethod + cdef _ChannelArgs from_args(object arguments, grpc_arg_pointer_vtable * vtable) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi index b7a4277ff64..bf12871015d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi @@ -50,7 +50,7 @@ cdef grpc_arg _unwrap_grpc_arg(tuple wrapped_arg): return wrapped.arg -cdef class _ArgumentProcessor: +cdef class _ChannelArg: cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references) except *: key, value = argument @@ -82,27 +82,34 @@ cdef class _ArgumentProcessor: 'Expected int, bytes, or behavior, got {}'.format(type(value))) -cdef class _ArgumentsProcessor: +cdef class _ChannelArgs: def __cinit__(self, arguments): self._arguments = () if arguments is None else tuple(arguments) - self._argument_processors = [] + self._channel_args = [] self._references = [] + self._c_arguments.arguments = NULL - cdef grpc_channel_args *c(self, grpc_arg_pointer_vtable *vtable) except *: + cdef void _c(self, grpc_arg_pointer_vtable *vtable) except *: self._c_arguments.arguments_length = len(self._arguments) - if self._c_arguments.arguments_length == 0: - return NULL - else: + if self._c_arguments.arguments_length != 0: self._c_arguments.arguments = gpr_malloc( self._c_arguments.arguments_length * sizeof(grpc_arg)) for index, argument in enumerate(self._arguments): - argument_processor = _ArgumentProcessor() - argument_processor.c(argument, vtable, self._references) - self._c_arguments.arguments[index] = argument_processor.c_argument - self._argument_processors.append(argument_processor) - return &self._c_arguments - - cdef un_c(self): - if self._arguments: + channel_arg = _ChannelArg() + channel_arg.c(argument, vtable, self._references) + self._c_arguments.arguments[index] = channel_arg.c_argument + self._channel_args.append(channel_arg) + + cdef grpc_channel_args *c_args(self) except *: + return &self._c_arguments + + def __dealloc__(self): + if self._c_arguments.arguments != NULL: gpr_free(self._c_arguments.arguments) + + @staticmethod + cdef _ChannelArgs from_args(object arguments, grpc_arg_pointer_vtable * vtable): + cdef _ChannelArgs channel_args = _ChannelArgs(arguments) + channel_args._c(vtable) + return channel_args diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index 135d224095e..70d4abb7308 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -423,16 +423,15 @@ cdef class Channel: self._vtable.copy = &_copy_pointer self._vtable.destroy = &_destroy_pointer self._vtable.cmp = &_compare_pointer - cdef _ArgumentsProcessor arguments_processor = _ArgumentsProcessor( - arguments) - cdef grpc_channel_args *c_arguments = arguments_processor.c(&self._vtable) + cdef _ChannelArgs channel_args = _ChannelArgs.from_args( + arguments, &self._vtable) if channel_credentials is None: self._state.c_channel = grpc_insecure_channel_create( - target, c_arguments, NULL) + target, channel_args.c_args(), NULL) else: c_channel_credentials = channel_credentials.c() self._state.c_channel = grpc_secure_channel_create( - c_channel_credentials, target, c_arguments, NULL) + c_channel_credentials, target, channel_args.c_args(), NULL) grpc_channel_credentials_release(c_channel_credentials) self._state.c_call_completion_queue = ( grpc_completion_queue_create_for_next(NULL)) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi index 52cfccb6779..4a6fbe0f96c 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi @@ -16,7 +16,6 @@ cdef class Server: cdef grpc_arg_pointer_vtable _vtable - cdef readonly _ArgumentsProcessor _arguments_processor cdef grpc_server *c_server cdef bint is_started # start has been called cdef bint is_shutting_down # shutdown has been called diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index e89e02b171e..d72648a35d0 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -29,11 +29,9 @@ cdef class Server: self._vtable.copy = &_copy_pointer self._vtable.destroy = &_destroy_pointer self._vtable.cmp = &_compare_pointer - cdef _ArgumentsProcessor arguments_processor = _ArgumentsProcessor( - arguments) - cdef grpc_channel_args *c_arguments = arguments_processor.c(&self._vtable) - self.c_server = grpc_server_create(c_arguments, NULL) - arguments_processor.un_c() + cdef _ChannelArgs channel_args = _ChannelArgs.from_args( + arguments, &self._vtable) + self.c_server = grpc_server_create(channel_args.c_args(), NULL) self.references.append(arguments) self.is_started = False self.is_shutting_down = False From aecc5f7285faedec634c99aff0b48eea86d3861a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 28 Dec 2018 16:03:20 -0800 Subject: [PATCH 409/534] Add client interceptor test for bidi streaming hijacking interceptor --- .../client_interceptors_end2end_test.cc | 91 +++++++++++++++++++ test/cpp/end2end/interceptors_util.cc | 10 ++ test/cpp/end2end/interceptors_util.h | 3 + 3 files changed, 104 insertions(+) diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 8abf4eb3f49..ab387aa9144 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -270,6 +270,84 @@ class HijackingInterceptorMakesAnotherCallFactory } }; +class BidiStreamingRpcHijackingInterceptor : public experimental::Interceptor { + public: + BidiStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) { + info_ = info; + } + + virtual void Intercept(experimental::InterceptorBatchMethods* methods) { + bool hijack = false; + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + CheckMetadata(*methods->GetSendInitialMetadata(), "testkey", "testvalue"); + hijack = true; + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + EchoRequest req; + auto* buffer = methods->GetSendMessage(); + auto copied_buffer = *buffer; + EXPECT_TRUE( + SerializationTraits::Deserialize(&copied_buffer, &req) + .ok()); + EXPECT_EQ(req.message().find("Hello"), 0); + msg = req.message(); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { + // Got nothing to do here for now + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_STATUS)) { + CheckMetadata(*methods->GetRecvTrailingMetadata(), "testkey", + "testvalue"); + auto* status = methods->GetRecvStatus(); + EXPECT_EQ(status->ok(), true); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { + EchoResponse* resp = + static_cast(methods->GetRecvMessage()); + resp->set_message(msg); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { + EXPECT_EQ(static_cast(methods->GetRecvMessage()) + ->message() + .find("Hello"), + 0); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { + auto* map = methods->GetRecvTrailingMetadata(); + // insert the metadata that we want + EXPECT_EQ(map->size(), static_cast(0)); + map->insert(std::make_pair("testkey", "testvalue")); + auto* status = methods->GetRecvStatus(); + *status = Status(StatusCode::OK, ""); + } + if (hijack) { + methods->Hijack(); + } else { + methods->Proceed(); + } + } + + private: + experimental::ClientRpcInfo* info_; + grpc::string msg; +}; + +class BidiStreamingRpcHijackingInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return new BidiStreamingRpcHijackingInterceptor(info); + } +}; + class LoggingInterceptor : public experimental::Interceptor { public: LoggingInterceptor(experimental::ClientRpcInfo* info) { info_ = info; } @@ -546,6 +624,19 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } +TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingHijackingTest) { + ChannelArguments args; + DummyInterceptor::Reset(); + std::vector> + creators; + creators.push_back( + std::unique_ptr( + new BidiStreamingRpcHijackingInterceptorFactory())); + auto channel = experimental::CreateCustomChannelWithInterceptors( + server_address_, InsecureChannelCredentials(), args, std::move(creators)); + MakeBidiStreamingCall(channel); +} + TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); diff --git a/test/cpp/end2end/interceptors_util.cc b/test/cpp/end2end/interceptors_util.cc index e0ad7d1526c..900f02b5f36 100644 --- a/test/cpp/end2end/interceptors_util.cc +++ b/test/cpp/end2end/interceptors_util.cc @@ -132,6 +132,16 @@ bool CheckMetadata(const std::multimap& map, return false; } +bool CheckMetadata(const std::multimap& map, + const string& key, const string& value) { + for (const auto& pair : map) { + if (pair.first == key && pair.second == value) { + return true; + } + } + return false; +} + std::vector> CreateDummyClientInterceptors() { std::vector> diff --git a/test/cpp/end2end/interceptors_util.h b/test/cpp/end2end/interceptors_util.h index 659e613d2eb..419845e5f61 100644 --- a/test/cpp/end2end/interceptors_util.h +++ b/test/cpp/end2end/interceptors_util.h @@ -165,6 +165,9 @@ void MakeCallbackCall(const std::shared_ptr& channel); bool CheckMetadata(const std::multimap& map, const string& key, const string& value); +bool CheckMetadata(const std::multimap& map, + const string& key, const string& value); + std::vector> CreateDummyClientInterceptors(); From 4aeba4252893755ff13b2cc0edfcc954c6d04a6b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 28 Dec 2018 17:27:38 -0800 Subject: [PATCH 410/534] Provide GetOriginalSendMessage for some APIs --- include/grpcpp/impl/codegen/call_op_set.h | 29 +++++++++++++++++-- include/grpcpp/impl/codegen/client_callback.h | 6 ++-- .../grpcpp/impl/codegen/client_unary_call.h | 2 +- include/grpcpp/impl/codegen/interceptor.h | 6 ++++ .../grpcpp/impl/codegen/interceptor_common.h | 16 +++++++++- include/grpcpp/impl/codegen/server_callback.h | 8 ++--- include/grpcpp/impl/codegen/sync_stream.h | 10 +++---- .../client_interceptors_end2end_test.cc | 5 ++++ 8 files changed, 66 insertions(+), 16 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index b2100c68b7f..ddee5280cb3 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -303,6 +303,18 @@ class CallOpSendMessage { template Status SendMessage(const M& message) GRPC_MUST_USE_RESULT; + /// Send \a message using \a options for the write. The \a options are cleared + /// after use. This form of SendMessage allows gRPC to reference \a message + /// beyond the lifetime of SendMessage. + template + Status SendMessage(const M* message, + WriteOptions options) GRPC_MUST_USE_RESULT; + + /// This form of SendMessage allows gRPC to reference \a message beyond the + /// lifetime of SendMessage. + template + Status SendMessage(const M* message) GRPC_MUST_USE_RESULT; + protected: void AddOp(grpc_op* ops, size_t* nops) { if (!send_buf_.Valid() || hijacked_) return; @@ -321,14 +333,14 @@ class CallOpSendMessage { if (!send_buf_.Valid()) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE); - interceptor_methods->SetSendMessage(&send_buf_); + interceptor_methods->SetSendMessage(&send_buf_, msg_); } void SetFinishInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { // The contents of the SendMessage value that was previously set // has had its references stolen by core's operations - interceptor_methods->SetSendMessage(nullptr); + interceptor_methods->SetSendMessage(nullptr, nullptr); } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { @@ -336,6 +348,7 @@ class CallOpSendMessage { } private: + const void* msg_ = nullptr; // The original non-serialized message bool hijacked_ = false; ByteBuffer send_buf_; WriteOptions write_options_; @@ -362,6 +375,18 @@ Status CallOpSendMessage::SendMessage(const M& message) { return SendMessage(message, WriteOptions()); } +template +Status CallOpSendMessage::SendMessage(const M* message, WriteOptions options) { + msg_ = message; + return SendMessage(*message, options); +} + +template +Status CallOpSendMessage::SendMessage(const M* message) { + msg_ = message; + return SendMessage(*message, WriteOptions()); +} + template class CallOpRecvMessage { public: diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 66cf9b7754c..f164db19ec7 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -73,7 +73,7 @@ class CallbackUnaryCallImpl { CallbackWithStatusTag(call.call(), on_completion, ops); // TODO(vjpai): Unify code with sync API as much as possible - Status s = ops->SendMessage(*request); + Status s = ops->SendMessage(request); if (!s.ok()) { tag->force_run(s); return; @@ -341,7 +341,7 @@ class ClientCallbackReaderWriterImpl start_corked_ = false; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*msg).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); if (options.is_last_message()) { options.set_buffer_hint(); @@ -650,7 +650,7 @@ class ClientCallbackWriterImpl start_corked_ = false; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*msg).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); if (options.is_last_message()) { options.set_buffer_hint(); diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index 5151839412b..f34da234824 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -57,7 +57,7 @@ class BlockingUnaryCallImpl { CallOpRecvInitialMetadata, CallOpRecvMessage, CallOpClientSendClose, CallOpClientRecvStatus> ops; - status_ = ops.SendMessage(request); + status_ = ops.SendMessage(&request); if (!status_.ok()) { return; } diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 46175cd73b8..a83d285d130 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -111,6 +111,12 @@ class InterceptorBatchMethods { /// A return value of nullptr indicates that this ByteBuffer is not valid. virtual ByteBuffer* GetSendMessage() = 0; + /// Returns a non-modifiable pointer to the original non-serialized form of + /// the message. Valid for PRE_SEND_MESSAGE interceptions. A return value of + /// nullptr indicates that this field is not valid. Also note that this is + /// only supported for sync and callback APIs at the present moment. + virtual const void* GetOriginalSendMessage() = 0; + /// Returns a modifiable multimap of the initial metadata to be sent. Valid /// for PRE_SEND_INITIAL_METADATA interceptions. A value of nullptr indicates /// that this field is not valid. diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index d0aa23cb0a0..bf936368d4c 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -81,6 +81,8 @@ class InterceptorBatchMethodsImpl ByteBuffer* GetSendMessage() override { return send_message_; } + const void* GetOriginalSendMessage() override { return orig_send_message_; } + std::multimap* GetSendInitialMetadata() override { return send_initial_metadata_; } @@ -115,7 +117,10 @@ class InterceptorBatchMethodsImpl return recv_trailing_metadata_->map(); } - void SetSendMessage(ByteBuffer* buf) { send_message_ = buf; } + void SetSendMessage(ByteBuffer* buf, const void* msg) { + send_message_ = buf; + orig_send_message_ = msg; + } void SetSendInitialMetadata( std::multimap* metadata) { @@ -334,6 +339,7 @@ class InterceptorBatchMethodsImpl std::function callback_; ByteBuffer* send_message_ = nullptr; + const void* orig_send_message_ = nullptr; std::multimap* send_initial_metadata_; @@ -386,6 +392,14 @@ class CancelInterceptorBatchMethods return nullptr; } + const void* GetOriginalSendMessage() override { + GPR_CODEGEN_ASSERT( + false && + "It is illegal to call GetOriginalSendMessage on a method which " + "has a Cancel notification"); + return nullptr; + } + std::multimap* GetSendInitialMetadata() override { GPR_CODEGEN_ASSERT(false && "It is illegal to call GetSendInitialMetadata on a " diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 1854f6ef2f5..b28b7fd9315 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -642,7 +642,7 @@ class CallbackServerStreamingHandler : public MethodHandler { ctx_->sent_initial_metadata_ = true; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*resp, options).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(resp, options).ok()); call_.PerformOps(&write_ops_); } @@ -652,7 +652,7 @@ class CallbackServerStreamingHandler : public MethodHandler { // Don't send any message if the status is bad if (s.ok()) { // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(*resp, options).ok()); + GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(resp, options).ok()); } Finish(std::move(s)); } @@ -804,7 +804,7 @@ class CallbackBidiHandler : public MethodHandler { ctx_->sent_initial_metadata_ = true; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*resp, options).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(resp, options).ok()); call_.PerformOps(&write_ops_); } @@ -813,7 +813,7 @@ class CallbackBidiHandler : public MethodHandler { // Don't send any message if the status is bad if (s.ok()) { // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(*resp, options).ok()); + GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(resp, options).ok()); } Finish(std::move(s)); } diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index 6981076f04e..4645ea3e2f5 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -253,7 +253,7 @@ class ClientReader final : public ClientReaderInterface { ops.SendInitialMetadata(&context->send_initial_metadata_, context->initial_metadata_flags()); // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(ops.SendMessage(request).ok()); + GPR_CODEGEN_ASSERT(ops.SendMessage(&request).ok()); ops.ClientSendClose(); call_.PerformOps(&ops); cq_.Pluck(&ops); @@ -331,7 +331,7 @@ class ClientWriter : public ClientWriterInterface { context_->initial_metadata_flags()); context_->set_initial_metadata_corked(false); } - if (!ops.SendMessage(msg, options).ok()) { + if (!ops.SendMessage(&msg, options).ok()) { return false; } @@ -502,7 +502,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { context_->initial_metadata_flags()); context_->set_initial_metadata_corked(false); } - if (!ops.SendMessage(msg, options).ok()) { + if (!ops.SendMessage(&msg, options).ok()) { return false; } @@ -656,7 +656,7 @@ class ServerWriter final : public ServerWriterInterface { options.set_buffer_hint(); } - if (!ctx_->pending_ops_.SendMessage(msg, options).ok()) { + if (!ctx_->pending_ops_.SendMessage(&msg, options).ok()) { return false; } if (!ctx_->sent_initial_metadata_) { @@ -734,7 +734,7 @@ class ServerReaderWriterBody final { if (options.is_last_message()) { options.set_buffer_hint(); } - if (!ctx_->pending_ops_.SendMessage(msg, options).ok()) { + if (!ctx_->pending_ops_.SendMessage(&msg, options).ok()) { return false; } if (!ctx_->sent_initial_metadata_) { diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 8abf4eb3f49..3414ebe64e2 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -293,6 +293,11 @@ class LoggingInterceptor : public experimental::Interceptor { SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); EXPECT_TRUE(req.message().find("Hello") == 0); + EXPECT_EQ( + static_cast(methods->GetOriginalSendMessage()) + ->message() + .find("Hello"), + 0); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { From f0e960714e84a1893edc9c971eac6d1df21f3f8c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 2 Jan 2019 17:22:40 +0100 Subject: [PATCH 411/534] Revert "Revert "basic tcp_trace support for windows"" This reverts commit f438d72e6c5e5bd839a255322fb91c416822f629. --- src/core/lib/iomgr/tcp_windows.cc | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 4b5250803d1..aaf9fb4ea8a 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -42,6 +42,7 @@ #include "src/core/lib/iomgr/tcp_windows.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" #if defined(__MSYS__) && defined(GPR_ARCH_64) /* Nasty workaround for nasty bug when using the 64 bits msys compiler @@ -182,6 +183,10 @@ static void on_read(void* tcpp, grpc_error* error) { grpc_slice sub; grpc_winsocket_callback_info* info = &socket->read_info; + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p on_read", tcp); + } + GRPC_ERROR_REF(error); if (error == GRPC_ERROR_NONE) { @@ -194,7 +199,21 @@ static void on_read(void* tcpp, grpc_error* error) { if (info->bytes_transfered != 0 && !tcp->shutting_down) { sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); grpc_slice_buffer_add(tcp->read_slices, sub); + + if (grpc_tcp_trace.enabled()) { + size_t i; + for (i = 0; i < tcp->read_slices->count; i++) { + char* dump = grpc_dump_slice(tcp->read_slices->slices[i], + GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_INFO, "READ %p (peer=%s): %s", tcp, tcp->peer_string, + dump); + gpr_free(dump); + } + } } else { + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp); + } grpc_slice_unref_internal(tcp->read_slice); error = tcp->shutting_down ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -219,6 +238,10 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, DWORD flags = 0; WSABUF buffer; + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p win_read", tcp); + } + if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -275,6 +298,10 @@ static void on_write(void* tcpp, grpc_error* error) { grpc_winsocket_callback_info* info = &handle->write_info; grpc_closure* cb; + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p on_write", tcp); + } + GRPC_ERROR_REF(error); gpr_mu_lock(&tcp->mu); @@ -308,6 +335,16 @@ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, WSABUF* buffers = local_buffers; size_t len; + if (grpc_tcp_trace.enabled()) { + size_t i; + for (i = 0; i < slices->count; i++) { + char* data = + grpc_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_INFO, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data); + gpr_free(data); + } + } + if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( From 12aae4f7bbf996c121550e5934b6da9f52578ef7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 2 Jan 2019 17:23:00 +0100 Subject: [PATCH 412/534] Revert "Revert "better slice management for win_read"" This reverts commit a050ae8ddc3a64151b344fd1a4d438db9dea2acb. --- src/core/lib/iomgr/tcp_windows.cc | 57 ++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index aaf9fb4ea8a..86ee1010cf7 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -113,7 +113,10 @@ typedef struct grpc_tcp { grpc_closure* read_cb; grpc_closure* write_cb; - grpc_slice read_slice; + + /* garbage after the last read */ + grpc_slice_buffer last_read_buffer; + grpc_slice_buffer* write_slices; grpc_slice_buffer* read_slices; @@ -132,6 +135,7 @@ static void tcp_free(grpc_tcp* tcp) { grpc_winsocket_destroy(tcp->socket); gpr_mu_destroy(&tcp->mu); gpr_free(tcp->peer_string); + grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); if (tcp->shutting_down) GRPC_ERROR_UNREF(tcp->shutdown_error); gpr_free(tcp); @@ -180,7 +184,6 @@ static void on_read(void* tcpp, grpc_error* error) { grpc_tcp* tcp = (grpc_tcp*)tcpp; grpc_closure* cb = tcp->read_cb; grpc_winsocket* socket = tcp->socket; - grpc_slice sub; grpc_winsocket_callback_info* info = &socket->read_info; if (grpc_tcp_trace.enabled()) { @@ -194,11 +197,19 @@ static void on_read(void* tcpp, grpc_error* error) { char* utf8_message = gpr_format_message(info->wsa_error); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(utf8_message); gpr_free(utf8_message); - grpc_slice_unref_internal(tcp->read_slice); + grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); } else { if (info->bytes_transfered != 0 && !tcp->shutting_down) { - sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); - grpc_slice_buffer_add(tcp->read_slices, sub); + GPR_ASSERT((size_t)info->bytes_transfered <= tcp->read_slices->length); + if (static_cast(info->bytes_transfered) != + tcp->read_slices->length) { + grpc_slice_buffer_trim_end( + tcp->read_slices, + tcp->read_slices->length - + static_cast(info->bytes_transfered), + &tcp->last_read_buffer); + } + GPR_ASSERT((size_t)info->bytes_transfered == tcp->read_slices->length); if (grpc_tcp_trace.enabled()) { size_t i; @@ -214,7 +225,7 @@ static void on_read(void* tcpp, grpc_error* error) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp); } - grpc_slice_unref_internal(tcp->read_slice); + grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); error = tcp->shutting_down ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "TCP stream shutting down", &tcp->shutdown_error, 1) @@ -228,6 +239,8 @@ static void on_read(void* tcpp, grpc_error* error) { GRPC_CLOSURE_SCHED(cb, error); } +#define DEFAULT_TARGET_READ_SIZE 8192 +#define MAX_WSABUF_COUNT 16 static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, grpc_closure* cb) { grpc_tcp* tcp = (grpc_tcp*)ep; @@ -236,7 +249,8 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, int status; DWORD bytes_read = 0; DWORD flags = 0; - WSABUF buffer; + WSABUF buffers[MAX_WSABUF_COUNT]; + size_t i; if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p win_read", tcp); @@ -252,18 +266,27 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, tcp->read_cb = cb; tcp->read_slices = read_slices; grpc_slice_buffer_reset_and_unref_internal(read_slices); + grpc_slice_buffer_swap(read_slices, &tcp->last_read_buffer); - tcp->read_slice = GRPC_SLICE_MALLOC(8192); + if (tcp->read_slices->length < DEFAULT_TARGET_READ_SIZE / 2 && + tcp->read_slices->count < MAX_WSABUF_COUNT) { + // TODO(jtattermusch): slice should be allocated using resource quota + grpc_slice_buffer_add(tcp->read_slices, + GRPC_SLICE_MALLOC(DEFAULT_TARGET_READ_SIZE)); + } - buffer.len = (ULONG)GRPC_SLICE_LENGTH( - tcp->read_slice); // we know slice size fits in 32bit. - buffer.buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slice); + GPR_ASSERT(tcp->read_slices->count <= MAX_WSABUF_COUNT); + for (i = 0; i < tcp->read_slices->count; i++) { + buffers[i].len = (ULONG)GRPC_SLICE_LENGTH( + tcp->read_slices->slices[i]); // we know slice size fits in 32bit. + buffers[i].buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slices->slices[i]); + } TCP_REF(tcp, "read"); /* First let's try a synchronous, non-blocking read. */ - status = - WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, NULL, NULL); + status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count, + &bytes_read, &flags, NULL, NULL); info->wsa_error = status == 0 ? 0 : WSAGetLastError(); /* Did we get data immediately ? Yay. */ @@ -275,8 +298,8 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, /* Otherwise, let's retry, by queuing a read. */ memset(&tcp->socket->read_info.overlapped, 0, sizeof(OVERLAPPED)); - status = WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, - &info->overlapped, NULL); + status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count, + &bytes_read, &flags, &info->overlapped, NULL); if (status != 0) { int wsa_error = WSAGetLastError(); @@ -330,7 +353,7 @@ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, unsigned i; DWORD bytes_sent; int status; - WSABUF local_buffers[16]; + WSABUF local_buffers[MAX_WSABUF_COUNT]; WSABUF* allocated = NULL; WSABUF* buffers = local_buffers; size_t len; @@ -449,6 +472,7 @@ static void win_shutdown(grpc_endpoint* ep, grpc_error* why) { static void win_destroy(grpc_endpoint* ep) { grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = (grpc_tcp*)ep; + grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); TCP_UNREF(tcp, "destroy"); } @@ -500,6 +524,7 @@ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, GRPC_CLOSURE_INIT(&tcp->on_read, on_read, tcp, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&tcp->on_write, on_write, tcp, grpc_schedule_on_exec_ctx); tcp->peer_string = gpr_strdup(peer_string); + grpc_slice_buffer_init(&tcp->last_read_buffer); tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string); /* Tell network status tracking code about the new endpoint */ grpc_network_status_register_endpoint(&tcp->base); From 80e2022cbe117313c53fc89be388c213342a058f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 2 Jan 2019 17:20:03 +0100 Subject: [PATCH 413/534] use stderr buffering for "+trace" windows tests --- test/core/end2end/fixtures/h2_full+trace.cc | 9 +++++++++ test/core/end2end/fixtures/h2_sockpair+trace.cc | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc index 2bbad487013..ce8f6bf13a5 100644 --- a/test/core/end2end/fixtures/h2_full+trace.cc +++ b/test/core/end2end/fixtures/h2_full+trace.cc @@ -113,6 +113,15 @@ int main(int argc, char** argv) { g_fixture_slowdown_factor = 10; #endif +#ifdef GPR_WINDOWS + /* on Windows, writing logs to stderr is very slow + when stderr is redirected to a disk file. + The "trace" tests fixtures generates large amount + of logs, so setting a buffer for stderr prevents certain + test cases from timing out. */ + setvbuf(stderr, NULL, _IOLBF, 1024); +#endif + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc index 45f78b59642..4494d5c4746 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.cc +++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc @@ -140,6 +140,15 @@ int main(int argc, char** argv) { g_fixture_slowdown_factor = 10; #endif +#ifdef GPR_WINDOWS + /* on Windows, writing logs to stderr is very slow + when stderr is redirected to a disk file. + The "trace" tests fixtures generates large amount + of logs, so setting a buffer for stderr prevents certain + test cases from timing out. */ + setvbuf(stderr, NULL, _IOLBF, 1024); +#endif + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); From 9c5ca8365c650c8891ef222b43edb1514e7d36f3 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 2 Jan 2019 23:03:30 +0100 Subject: [PATCH 414/534] Revert "Implement a lock-free fast path for queue_call_request()" --- src/core/lib/surface/server.cc | 104 +++++++++++++-------------------- 1 file changed, 41 insertions(+), 63 deletions(-) diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 67b38e6f0c0..7ae6e51a5fb 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -194,13 +194,10 @@ struct call_data { }; struct request_matcher { - request_matcher(grpc_server* server); - ~request_matcher(); - grpc_server* server; - std::atomic pending_head{nullptr}; - call_data* pending_tail = nullptr; - gpr_locked_mpscq* requests_per_cq = nullptr; + call_data* pending_head; + call_data* pending_tail; + gpr_locked_mpscq* requests_per_cq; }; struct registered_method { @@ -349,30 +346,22 @@ static void channel_broadcaster_shutdown(channel_broadcaster* cb, * request_matcher */ -namespace { -request_matcher::request_matcher(grpc_server* server) : server(server) { - requests_per_cq = static_cast( - gpr_malloc(sizeof(*requests_per_cq) * server->cq_count)); - for (size_t i = 0; i < server->cq_count; i++) { - gpr_locked_mpscq_init(&requests_per_cq[i]); - } -} - -request_matcher::~request_matcher() { +static void request_matcher_init(request_matcher* rm, grpc_server* server) { + memset(rm, 0, sizeof(*rm)); + rm->server = server; + rm->requests_per_cq = static_cast( + gpr_malloc(sizeof(*rm->requests_per_cq) * server->cq_count)); for (size_t i = 0; i < server->cq_count; i++) { - GPR_ASSERT(gpr_locked_mpscq_pop(&requests_per_cq[i]) == nullptr); - gpr_locked_mpscq_destroy(&requests_per_cq[i]); + gpr_locked_mpscq_init(&rm->requests_per_cq[i]); } - gpr_free(requests_per_cq); -} -} // namespace - -static void request_matcher_init(request_matcher* rm, grpc_server* server) { - new (rm) request_matcher(server); } static void request_matcher_destroy(request_matcher* rm) { - rm->~request_matcher(); + for (size_t i = 0; i < rm->server->cq_count; i++) { + GPR_ASSERT(gpr_locked_mpscq_pop(&rm->requests_per_cq[i]) == nullptr); + gpr_locked_mpscq_destroy(&rm->requests_per_cq[i]); + } + gpr_free(rm->requests_per_cq); } static void kill_zombie(void* elem, grpc_error* error) { @@ -381,10 +370,9 @@ static void kill_zombie(void* elem, grpc_error* error) { } static void request_matcher_zombify_all_pending_calls(request_matcher* rm) { - call_data* calld; - while ((calld = rm->pending_head.load(std::memory_order_relaxed)) != - nullptr) { - rm->pending_head.store(calld->pending_next, std::memory_order_relaxed); + while (rm->pending_head) { + call_data* calld = rm->pending_head; + rm->pending_head = calld->pending_next; gpr_atm_no_barrier_store(&calld->state, ZOMBIED); GRPC_CLOSURE_INIT( &calld->kill_zombie_closure, kill_zombie, @@ -582,9 +570,8 @@ static void publish_new_rpc(void* arg, grpc_error* error) { } gpr_atm_no_barrier_store(&calld->state, PENDING); - if (rm->pending_head.load(std::memory_order_relaxed) == nullptr) { - rm->pending_head.store(calld, std::memory_order_relaxed); - rm->pending_tail = calld; + if (rm->pending_head == nullptr) { + rm->pending_tail = rm->pending_head = calld; } else { rm->pending_tail->pending_next = calld; rm->pending_tail = calld; @@ -1448,39 +1435,30 @@ static grpc_call_error queue_call_request(grpc_server* server, size_t cq_idx, rm = &rc->data.registered.method->matcher; break; } - - // Fast path: if there is no pending request to be processed, immediately - // return. - if (!gpr_locked_mpscq_push(&rm->requests_per_cq[cq_idx], &rc->request_link) || - // Note: We are reading the pending_head without holding the server's call - // mutex. Even if we read a non-null value here due to reordering, - // we will check it below again after grabbing the lock. - rm->pending_head.load(std::memory_order_relaxed) == nullptr) { - return GRPC_CALL_OK; - } - // Slow path: This was the first queued request and there are pendings: - // We need to lock and start matching calls. - gpr_mu_lock(&server->mu_call); - while ((calld = rm->pending_head.load(std::memory_order_relaxed)) != - nullptr) { - rc = reinterpret_cast( - gpr_locked_mpscq_pop(&rm->requests_per_cq[cq_idx])); - if (rc == nullptr) break; - rm->pending_head.store(calld->pending_next, std::memory_order_relaxed); - gpr_mu_unlock(&server->mu_call); - if (!gpr_atm_full_cas(&calld->state, PENDING, ACTIVATED)) { - // Zombied Call - GRPC_CLOSURE_INIT( - &calld->kill_zombie_closure, kill_zombie, - grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0), - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_SCHED(&calld->kill_zombie_closure, GRPC_ERROR_NONE); - } else { - publish_call(server, calld, cq_idx, rc); - } + if (gpr_locked_mpscq_push(&rm->requests_per_cq[cq_idx], &rc->request_link)) { + /* this was the first queued request: we need to lock and start + matching calls */ gpr_mu_lock(&server->mu_call); + while ((calld = rm->pending_head) != nullptr) { + rc = reinterpret_cast( + gpr_locked_mpscq_pop(&rm->requests_per_cq[cq_idx])); + if (rc == nullptr) break; + rm->pending_head = calld->pending_next; + gpr_mu_unlock(&server->mu_call); + if (!gpr_atm_full_cas(&calld->state, PENDING, ACTIVATED)) { + // Zombied Call + GRPC_CLOSURE_INIT( + &calld->kill_zombie_closure, kill_zombie, + grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0), + grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_SCHED(&calld->kill_zombie_closure, GRPC_ERROR_NONE); + } else { + publish_call(server, calld, cq_idx, rc); + } + gpr_mu_lock(&server->mu_call); + } + gpr_mu_unlock(&server->mu_call); } - gpr_mu_unlock(&server->mu_call); return GRPC_CALL_OK; } From 69e99a827555ce69cb796589189dab4fc6a9375f Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 2 Jan 2019 14:24:30 -0800 Subject: [PATCH 415/534] Add clang fallthrough annotation --- test/core/memory_usage/server.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index 7424797e6f5..c79d661a422 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -295,6 +295,7 @@ int main(int argc, char** argv) { /* fallthrough */ // no break here since we want to continue to case // FLING_SERVER_SEND_STATUS_SNAPSHOT to destroy the snapshot call + [[fallthrough]]; case FLING_SERVER_SEND_STATUS_SNAPSHOT: grpc_byte_buffer_destroy(payload_buffer); grpc_byte_buffer_destroy(terminal_buffer); From c6261f4b918a88f5b1fc5cd60e1e2b44e8f83a76 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 2 Jan 2019 14:46:52 -0800 Subject: [PATCH 416/534] Rename new SendMessage types to SendMessagePtr --- include/grpcpp/impl/codegen/call_op_set.h | 11 +++--- include/grpcpp/impl/codegen/client_callback.h | 8 ++--- .../grpcpp/impl/codegen/client_unary_call.h | 2 +- .../grpcpp/impl/codegen/method_handler_impl.h | 4 +-- include/grpcpp/impl/codegen/server_callback.h | 12 +++---- include/grpcpp/impl/codegen/sync_stream.h | 10 +++--- .../client_interceptors_end2end_test.cc | 6 ++-- .../server_interceptors_end2end_test.cc | 35 ++++++++++++++++++- 8 files changed, 61 insertions(+), 27 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index ddee5280cb3..310bea93ca7 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -307,13 +307,13 @@ class CallOpSendMessage { /// after use. This form of SendMessage allows gRPC to reference \a message /// beyond the lifetime of SendMessage. template - Status SendMessage(const M* message, - WriteOptions options) GRPC_MUST_USE_RESULT; + Status SendMessagePtr(const M* message, + WriteOptions options) GRPC_MUST_USE_RESULT; /// This form of SendMessage allows gRPC to reference \a message beyond the /// lifetime of SendMessage. template - Status SendMessage(const M* message) GRPC_MUST_USE_RESULT; + Status SendMessagePtr(const M* message) GRPC_MUST_USE_RESULT; protected: void AddOp(grpc_op* ops, size_t* nops) { @@ -376,13 +376,14 @@ Status CallOpSendMessage::SendMessage(const M& message) { } template -Status CallOpSendMessage::SendMessage(const M* message, WriteOptions options) { +Status CallOpSendMessage::SendMessagePtr(const M* message, + WriteOptions options) { msg_ = message; return SendMessage(*message, options); } template -Status CallOpSendMessage::SendMessage(const M* message) { +Status CallOpSendMessage::SendMessagePtr(const M* message) { msg_ = message; return SendMessage(*message, WriteOptions()); } diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index f164db19ec7..c20e8458106 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -73,7 +73,7 @@ class CallbackUnaryCallImpl { CallbackWithStatusTag(call.call(), on_completion, ops); // TODO(vjpai): Unify code with sync API as much as possible - Status s = ops->SendMessage(request); + Status s = ops->SendMessagePtr(request); if (!s.ok()) { tag->force_run(s); return; @@ -341,7 +341,7 @@ class ClientCallbackReaderWriterImpl start_corked_ = false; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg).ok()); if (options.is_last_message()) { options.set_buffer_hint(); @@ -524,7 +524,7 @@ class ClientCallbackReaderImpl : context_(context), call_(call), reactor_(reactor) { this->BindReactor(reactor); // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(start_ops_.SendMessage(*request).ok()); + GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); start_ops_.ClientSendClose(); } @@ -650,7 +650,7 @@ class ClientCallbackWriterImpl start_corked_ = false; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg).ok()); if (options.is_last_message()) { options.set_buffer_hint(); diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index f34da234824..b9f8e1663f1 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -57,7 +57,7 @@ class BlockingUnaryCallImpl { CallOpRecvInitialMetadata, CallOpRecvMessage, CallOpClientSendClose, CallOpClientRecvStatus> ops; - status_ = ops.SendMessage(&request); + status_ = ops.SendMessagePtr(&request); if (!status_.ok()) { return; } diff --git a/include/grpcpp/impl/codegen/method_handler_impl.h b/include/grpcpp/impl/codegen/method_handler_impl.h index dd53f975f68..094286294c2 100644 --- a/include/grpcpp/impl/codegen/method_handler_impl.h +++ b/include/grpcpp/impl/codegen/method_handler_impl.h @@ -79,7 +79,7 @@ class RpcMethodHandler : public MethodHandler { ops.set_compression_level(param.server_context->compression_level()); } if (status.ok()) { - status = ops.SendMessage(rsp); + status = ops.SendMessagePtr(&rsp); } ops.ServerSendStatus(¶m.server_context->trailing_metadata_, status); param.call->PerformOps(&ops); @@ -139,7 +139,7 @@ class ClientStreamingHandler : public MethodHandler { } } if (status.ok()) { - status = ops.SendMessage(rsp); + status = ops.SendMessagePtr(&rsp); } ops.ServerSendStatus(¶m.server_context->trailing_metadata_, status); param.call->PerformOps(&ops); diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index b28b7fd9315..a0e59215dd6 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -320,7 +320,7 @@ class CallbackUnaryHandler : public MethodHandler { // The response is dropped if the status is not OK. if (s.ok()) { finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_ops_.SendMessage(resp_)); + finish_ops_.SendMessagePtr(&resp_)); } else { finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); } @@ -449,7 +449,7 @@ class CallbackClientStreamingHandler : public MethodHandler { // The response is dropped if the status is not OK. if (s.ok()) { finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_ops_.SendMessage(resp_)); + finish_ops_.SendMessagePtr(&resp_)); } else { finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); } @@ -642,7 +642,7 @@ class CallbackServerStreamingHandler : public MethodHandler { ctx_->sent_initial_metadata_ = true; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(resp, options).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); call_.PerformOps(&write_ops_); } @@ -652,7 +652,7 @@ class CallbackServerStreamingHandler : public MethodHandler { // Don't send any message if the status is bad if (s.ok()) { // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(resp, options).ok()); + GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); } Finish(std::move(s)); } @@ -804,7 +804,7 @@ class CallbackBidiHandler : public MethodHandler { ctx_->sent_initial_metadata_ = true; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(resp, options).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); call_.PerformOps(&write_ops_); } @@ -813,7 +813,7 @@ class CallbackBidiHandler : public MethodHandler { // Don't send any message if the status is bad if (s.ok()) { // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(resp, options).ok()); + GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); } Finish(std::move(s)); } diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index 4645ea3e2f5..d9edad42153 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -253,7 +253,7 @@ class ClientReader final : public ClientReaderInterface { ops.SendInitialMetadata(&context->send_initial_metadata_, context->initial_metadata_flags()); // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(ops.SendMessage(&request).ok()); + GPR_CODEGEN_ASSERT(ops.SendMessagePtr(&request).ok()); ops.ClientSendClose(); call_.PerformOps(&ops); cq_.Pluck(&ops); @@ -331,7 +331,7 @@ class ClientWriter : public ClientWriterInterface { context_->initial_metadata_flags()); context_->set_initial_metadata_corked(false); } - if (!ops.SendMessage(&msg, options).ok()) { + if (!ops.SendMessagePtr(&msg, options).ok()) { return false; } @@ -502,7 +502,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { context_->initial_metadata_flags()); context_->set_initial_metadata_corked(false); } - if (!ops.SendMessage(&msg, options).ok()) { + if (!ops.SendMessagePtr(&msg, options).ok()) { return false; } @@ -656,7 +656,7 @@ class ServerWriter final : public ServerWriterInterface { options.set_buffer_hint(); } - if (!ctx_->pending_ops_.SendMessage(&msg, options).ok()) { + if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { return false; } if (!ctx_->sent_initial_metadata_) { @@ -734,7 +734,7 @@ class ServerReaderWriterBody final { if (options.is_last_message()) { options.set_buffer_hint(); } - if (!ctx_->pending_ops_.SendMessage(&msg, options).ok()) { + if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { return false; } if (!ctx_->sent_initial_metadata_) { diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 3414ebe64e2..1ed1fb686dc 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -292,12 +292,12 @@ class LoggingInterceptor : public experimental::Interceptor { EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); - EXPECT_TRUE(req.message().find("Hello") == 0); + EXPECT_TRUE(req.message().find("Hello") == 0u); EXPECT_EQ( static_cast(methods->GetOriginalSendMessage()) ->message() .find("Hello"), - 0); + 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { @@ -313,7 +313,7 @@ class LoggingInterceptor : public experimental::Interceptor { experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { EchoResponse* resp = static_cast(methods->GetRecvMessage()); - EXPECT_TRUE(resp->message().find("Hello") == 0); + EXPECT_TRUE(resp->message().find("Hello") == 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_STATUS)) { diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 53d8c4dc960..28f51bb2fce 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -73,7 +73,7 @@ class LoggingInterceptor : public experimental::Interceptor { type == experimental::ServerRpcInfo::Type::BIDI_STREAMING)); } - virtual void Intercept(experimental::InterceptorBatchMethods* methods) { + void Intercept(experimental::InterceptorBatchMethods* methods) override { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { auto* map = methods->GetSendInitialMetadata(); @@ -142,6 +142,33 @@ class LoggingInterceptorFactory } }; +// Test if GetOriginalSendMessage works as expected +class GetOriginalSendMessageTester : public experimental::Interceptor { + public: + GetOriginalSendMessageTester(experimental::ServerRpcInfo* info) {} + + void Intercept(experimental::InterceptorBatchMethods* methods) override { + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + EXPECT_EQ( + static_cast(methods->GetOriginalSendMessage()) + ->message() + .find("Hello"), + 0u); + } + methods->Proceed(); + } +}; + +class GetOriginalSendMessageTesterFactory + : public experimental::ServerInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateServerInterceptor( + experimental::ServerRpcInfo* info) override { + return new GetOriginalSendMessageTester(info); + } +}; + void MakeBidiStreamingCall(const std::shared_ptr& channel) { auto stub = grpc::testing::EchoTestService::NewStub(channel); ClientContext ctx; @@ -176,6 +203,9 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { creators.push_back( std::unique_ptr( new LoggingInterceptorFactory())); + creators.push_back( + std::unique_ptr( + new GetOriginalSendMessageTesterFactory())); // Add 20 dummy interceptor factories and null interceptor factories for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( @@ -216,6 +246,9 @@ class ServerInterceptorsEnd2endSyncStreamingTest : public ::testing::Test { creators.push_back( std::unique_ptr( new LoggingInterceptorFactory())); + creators.push_back( + std::unique_ptr( + new GetOriginalSendMessageTesterFactory())); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); From 1f3829180c32c8c2ee1a3d546d6c2bcb3287e312 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 2 Jan 2019 15:52:42 -0800 Subject: [PATCH 417/534] Fix missing ConnectivityMonitor usage --- src/objective-c/GRPCClient/GRPCCall.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index b0412cddb09..83c6edc6e3f 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -841,6 +841,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self sendHeaders]; [self invokeCall]; + + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; + } } - (void)startWithWriteable:(id)writeable { From 3af464f29cb7701a432518a71b0615c47ba58077 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 3 Jan 2019 08:19:51 -0800 Subject: [PATCH 418/534] return targets to library --- test/core/memory_usage/BUILD | 6 +++--- test/core/memory_usage/server.cc | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/test/core/memory_usage/BUILD b/test/core/memory_usage/BUILD index dd185e6577b..38b088c75c7 100644 --- a/test/core/memory_usage/BUILD +++ b/test/core/memory_usage/BUILD @@ -12,13 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_test", "grpc_package") +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") grpc_package(name = "test/core/memory_usage") licenses(["notice"]) # Apache v2 -grpc_cc_binary( +grpc_cc_library( name = "memory_usage_client", testonly = 1, srcs = ["client.cc"], @@ -29,7 +29,7 @@ grpc_cc_binary( ], ) -grpc_cc_binary( +grpc_cc_library( name = "memory_usage_server", testonly = 1, srcs = ["server.cc"], diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index c79d661a422..7424797e6f5 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -295,7 +295,6 @@ int main(int argc, char** argv) { /* fallthrough */ // no break here since we want to continue to case // FLING_SERVER_SEND_STATUS_SNAPSHOT to destroy the snapshot call - [[fallthrough]]; case FLING_SERVER_SEND_STATUS_SNAPSHOT: grpc_byte_buffer_destroy(payload_buffer); grpc_byte_buffer_destroy(terminal_buffer); From 67f523ce13a3d6c8adf02530173679cf1dc0ddd6 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 28 Dec 2018 07:55:36 -0800 Subject: [PATCH 419/534] Add support for ruby 2.6.0 binary package builds, drop 2.1 and 2.0 binary package builds; pin bundler to 1.17.3 where necessary --- Rakefile | 6 +-- templates/tools/dockerfile/ruby_deps.include | 14 +++---- third_party/rake-compiler-dock/Dockerfile | 3 +- tools/distrib/build_ruby_environment_macos.sh | 2 +- .../distribtest/ruby_centos6_x64/Dockerfile | 15 +++++-- .../distribtest/ruby_centos7_x64/Dockerfile | 18 +++++++- .../distribtest/ruby_fedora20_x64/Dockerfile | 21 +++++++++- .../distribtest/ruby_fedora21_x64/Dockerfile | 19 ++++++++- .../ruby_jessie_x64_ruby_2_2/Dockerfile | 40 ++++++++++++++++++ .../ruby_jessie_x64_ruby_2_3/Dockerfile | 41 +++++++++++++++++++ .../ruby_jessie_x64_ruby_2_4/Dockerfile | 40 ++++++++++++++++++ .../ruby_jessie_x64_ruby_2_5/Dockerfile | 40 ++++++++++++++++++ .../Dockerfile | 14 +++---- .../grpc_artifact_linux_x64/Dockerfile | 2 +- .../grpc_artifact_linux_x86/Dockerfile | 2 +- .../interoptest/grpc_interop_ruby/Dockerfile | 14 +++---- .../grpc_interop_ruby/build_interop.sh | 2 +- .../test/ruby_jessie_x64/Dockerfile | 14 +++---- .../helper_scripts/prepare_build_macos_rc | 2 +- .../artifacts/distribtest_targets.py | 8 ++-- 20 files changed, 267 insertions(+), 50 deletions(-) create mode 100644 tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile create mode 100644 tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_3/Dockerfile create mode 100644 tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_4/Dockerfile create mode 100644 tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_5/Dockerfile rename tools/dockerfile/distribtest/{ruby_jessie_x64_ruby_2_0_0 => ruby_jessie_x64_ruby_2_6}/Dockerfile (73%) diff --git a/Rakefile b/Rakefile index 0068a3b8e4f..d604f7935b1 100755 --- a/Rakefile +++ b/Rakefile @@ -105,7 +105,7 @@ task 'dlls' do env_comp = "CC=#{opt[:cross]}-gcc " env_comp += "CXX=#{opt[:cross]}-g++ " env_comp += "LD=#{opt[:cross]}-gcc " - docker_for_windows "gem update --system --no-ri --no-doc && #{env} #{env_comp} make -j #{out} && #{opt[:cross]}-strip -x -S #{out} && cp #{out} #{opt[:out]}" + docker_for_windows "gem update --system --no-document && #{env} #{env_comp} make -j #{out} && #{opt[:cross]}-strip -x -S #{out} && cp #{out} #{opt[:out]}" end end @@ -124,10 +124,10 @@ task 'gem:native' do "invoked on macos with ruby #{RUBY_VERSION}. The ruby macos artifact " \ "build should be running on ruby 2.5." end - system "rake cross native gem RUBY_CC_VERSION=2.5.0:2.4.0:2.3.0:2.2.2:2.1.6:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}" + system "rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}" else Rake::Task['dlls'].execute - docker_for_windows "gem update --system --no-ri --no-doc && bundle && rake cross native gem RUBY_CC_VERSION=2.5.0:2.4.0:2.3.0:2.2.2:2.1.6:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}" + docker_for_windows "gem update --system --no-document && bundle && rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}" end end diff --git a/templates/tools/dockerfile/ruby_deps.include b/templates/tools/dockerfile/ruby_deps.include index a8ee3ec7dc6..c2d330988c6 100644 --- a/templates/tools/dockerfile/ruby_deps.include +++ b/templates/tools/dockerfile/ruby_deps.include @@ -2,13 +2,13 @@ # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.1" -RUN /bin/bash -l -c "rvm use --default ruby-2.1" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +# Install Ruby 2.5 +RUN /bin/bash -l -c "rvm install ruby-2.5" +RUN /bin/bash -l -c "rvm use --default ruby-2.5" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" diff --git a/third_party/rake-compiler-dock/Dockerfile b/third_party/rake-compiler-dock/Dockerfile index 06c721c39ba..44eddc82e80 100644 --- a/third_party/rake-compiler-dock/Dockerfile +++ b/third_party/rake-compiler-dock/Dockerfile @@ -1,8 +1,7 @@ -FROM larskanis/rake-compiler-dock:0.6.2 +FROM larskanis/rake-compiler-dock-mri:0.7.0 RUN find / -name rbconfig.rb | while read f ; do sed -i 's/0x0501/0x0600/' $f ; done RUN find / -name win32.h | while read f ; do sed -i 's/gettimeofday/rb_gettimeofday/' $f ; done -RUN sed -i 's/defined.__MINGW64__.$/1/' /usr/local/rake-compiler/ruby/i686-w64-mingw32/ruby-2.0.0-p645/include/ruby-2.0.0/ruby/win32.h RUN find / -name libwinpthread.dll.a | xargs rm RUN find / -name libwinpthread-1.dll | xargs rm RUN find / -name *msvcrt-ruby*.dll.a | while read f ; do n=`echo $f | sed s/.dll//` ; mv $f $n ; done diff --git a/tools/distrib/build_ruby_environment_macos.sh b/tools/distrib/build_ruby_environment_macos.sh index 9e3e3b46f80..c2c0dcde6bd 100644 --- a/tools/distrib/build_ruby_environment_macos.sh +++ b/tools/distrib/build_ruby_environment_macos.sh @@ -49,7 +49,7 @@ EOF MAKE="make -j8" -for v in 2.5.0 2.4.0 2.3.0 2.2.2 2.1.6 2.0.0-p645 ; do +for v in 2.6.0 2.5.0 2.4.0 2.3.0 2.2.2 ; do ccache -c rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=x86_64-darwin11 MAKE="$MAKE" done diff --git a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile index c3d6e03f6a1..b53ffc22d4f 100644 --- a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile @@ -19,10 +19,19 @@ RUN yum install -y curl RUN yum install -y tar which # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 # Running the installation twice to work around docker issue when using overlay. # https://github.com/docker/docker/issues/10180 -RUN (curl -sSL https://get.rvm.io | bash -s stable --ruby) || (curl -sSL https://get.rvm.io | bash -s stable --ruby) +RUN (/bin/bash -l -c "rvm install ruby-2.2.10") || (/bin/bash -l -c "rvm install ruby-2.2.10") +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install --update bundler" diff --git a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile index 73207e4210d..72235bfba7f 100644 --- a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile @@ -14,6 +14,20 @@ FROM centos:7 -RUN yum install -y ruby +RUN yum update && yum install -y curl tar which -RUN gem install bundler +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 +RUN /bin/bash -l -c "rvm install ruby-2.2.10" +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile index 200c5c28033..3d688a889f0 100644 --- a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile @@ -14,6 +14,23 @@ FROM fedora:20 -RUN yum clean all && yum update -y && yum install -y ruby findutils +# distro-sync and install openssl, per https://github.com/fedora-cloud/docker-brew-fedora/issues/19 +RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y openssl gnupg which findutils -RUN gem install bundler +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 +# Running the installation twice to work around docker issue when using overlay. +# https://github.com/docker/docker/issues/10180 +RUN (/bin/bash -l -c "rvm install ruby-2.2.10") || (/bin/bash -l -c "rvm install ruby-2.2.10") +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile index e1177fd99af..8044adf15dc 100644 --- a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile @@ -19,6 +19,21 @@ FROM fedora:21 # https://github.com/docker/docker/issues/10180 RUN yum install -y yum-plugin-ovl -RUN yum clean all && yum update -y && yum install -y ruby findutils +# distro-sync and install openssl, per https://github.com/fedora-cloud/docker-brew-fedora/issues/19 +RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y openssl gnupg which findutils tar -RUN gem install bundler +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 +RUN /bin/bash -l -c "rvm install ruby-2.2.10" +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile new file mode 100644 index 00000000000..337fc3b5d8e --- /dev/null +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile @@ -0,0 +1,40 @@ +# Copyright 2015 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. + +FROM debian:jessie + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + curl \ + gcc && apt-get clean + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 +RUN /bin/bash -l -c "rvm install ruby-2.2.10" +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_3/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_3/Dockerfile new file mode 100644 index 00000000000..9deff0661b7 --- /dev/null +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_3/Dockerfile @@ -0,0 +1,41 @@ +# Copyright 2015 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. + +FROM debian:jessie + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + curl \ + gcc && apt-get clean + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem update --system" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_4/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_4/Dockerfile new file mode 100644 index 00000000000..55b1b1e731d --- /dev/null +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_4/Dockerfile @@ -0,0 +1,40 @@ +# Copyright 2015 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. + +FROM debian:jessie + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + curl \ + gcc && apt-get clean + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.4 +RUN /bin/bash -l -c "rvm install ruby-2.4.5" +RUN /bin/bash -l -c "rvm use --default ruby-2.4.5" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.4.5' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_5/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_5/Dockerfile new file mode 100644 index 00000000000..bed4b3a93ef --- /dev/null +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_5/Dockerfile @@ -0,0 +1,40 @@ +# Copyright 2015 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. + +FROM debian:jessie + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + curl \ + gcc && apt-get clean + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.5 +RUN /bin/bash -l -c "rvm install ruby-2.5.3" +RUN /bin/bash -l -c "rvm use --default ruby-2.5.3" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5.3' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_0_0/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_6/Dockerfile similarity index 73% rename from tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_0_0/Dockerfile rename to tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_6/Dockerfile index ff43c92c9e5..af1839eba93 100644 --- a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_0_0/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_6/Dockerfile @@ -23,16 +23,16 @@ RUN apt-get update && apt-get install -y \ # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.0" -RUN /bin/bash -l -c "rvm use --default ruby-2.0" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +# Install Ruby 2.6 +RUN /bin/bash -l -c "rvm install ruby-2.6.0" +RUN /bin/bash -l -c "rvm use --default ruby-2.6.0" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.0' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.6.0' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile index 7ec061ebe58..e3e549f9874 100644 --- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile @@ -58,7 +58,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.1" RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-ri --no-rdoc" ################## diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile index f81d8e5ba02..ec4fcbae368 100644 --- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile @@ -58,7 +58,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.1" RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-ri --no-rdoc" ################## # C# dependencies (needed to build grpc_csharp_ext) diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile index 97c146bb53a..1f6f03edd89 100644 --- a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile @@ -68,16 +68,16 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.1" -RUN /bin/bash -l -c "rvm use --default ruby-2.1" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +# Install Ruby 2.5 +RUN /bin/bash -l -c "rvm install ruby-2.5" +RUN /bin/bash -l -c "rvm use --default ruby-2.5" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh index b6b122ef0fd..67f66090ae9 100755 --- a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh @@ -27,7 +27,7 @@ ${name}') cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc -rvm --default use ruby-2.1 +rvm --default use ruby-2.5 # build Ruby interop client and server (cd src/ruby && gem update bundler && bundle && rake compile) diff --git a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile index 321b501de21..cf6a5b254f1 100644 --- a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile @@ -72,16 +72,16 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.1" -RUN /bin/bash -l -c "rvm use --default ruby-2.1" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +# Install Ruby 2.5 +RUN /bin/bash -l -c "rvm install ruby-2.5" +RUN /bin/bash -l -c "rvm use --default ruby-2.5" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index ce054ac2594..632db5ae145 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -42,7 +42,7 @@ source $HOME/.rvm/scripts/rvm set -e # rvm commands are very verbose time rvm install 2.5.0 rvm use 2.5.0 --default -time gem install bundler --no-ri --no-doc +time gem install bundler -v 1.17.3 --no-ri --no-doc time gem install cocoapods --version 1.3.1 --no-ri --no-doc time gem install rake-compiler --no-ri --no-doc rvm osx-ssl-certs status all diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py index e02f4bffcd4..fd68a4dc747 100644 --- a/tools/run_tests/artifacts/distribtest_targets.py +++ b/tools/run_tests/artifacts/distribtest_targets.py @@ -336,9 +336,11 @@ def targets(): PythonDistribTest('linux', 'x64', 'ubuntu1404', source=True), PythonDistribTest('linux', 'x64', 'ubuntu1604', source=True), RubyDistribTest('linux', 'x64', 'wheezy'), - RubyDistribTest('linux', 'x64', 'jessie'), - RubyDistribTest('linux', 'x86', 'jessie'), - RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_0_0'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_2'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_3'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_4'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_5'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_6'), RubyDistribTest('linux', 'x64', 'centos6'), RubyDistribTest('linux', 'x64', 'centos7'), RubyDistribTest('linux', 'x64', 'fedora20'), From 50c60f03ba84b4e1b1d31819a295ef4e1076907b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 3 Jan 2019 12:21:19 -0800 Subject: [PATCH 420/534] Rename GetSendMessage to GetSerializedSendMessage and GetOriginalSendMessage to GetSendMessage --- include/grpcpp/impl/codegen/interceptor.h | 4 +-- .../grpcpp/impl/codegen/interceptor_common.h | 8 +++--- .../client_interceptors_end2end_test.cc | 15 ++++++----- .../server_interceptors_end2end_test.cc | 25 +++++++++---------- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index a83d285d130..5a9a3a44e6e 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -109,13 +109,13 @@ class InterceptorBatchMethods { /// Returns a modifable ByteBuffer holding the serialized form of the message /// that is going to be sent. Valid for PRE_SEND_MESSAGE interceptions. /// A return value of nullptr indicates that this ByteBuffer is not valid. - virtual ByteBuffer* GetSendMessage() = 0; + virtual ByteBuffer* GetSerializedSendMessage() = 0; /// Returns a non-modifiable pointer to the original non-serialized form of /// the message. Valid for PRE_SEND_MESSAGE interceptions. A return value of /// nullptr indicates that this field is not valid. Also note that this is /// only supported for sync and callback APIs at the present moment. - virtual const void* GetOriginalSendMessage() = 0; + virtual const void* GetSendMessage() = 0; /// Returns a modifiable multimap of the initial metadata to be sent. Valid /// for PRE_SEND_INITIAL_METADATA interceptions. A value of nullptr indicates diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index bf936368d4c..4b7eaefee1b 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -79,9 +79,9 @@ class InterceptorBatchMethodsImpl hooks_[static_cast(type)] = true; } - ByteBuffer* GetSendMessage() override { return send_message_; } + ByteBuffer* GetSerializedSendMessage() override { return send_message_; } - const void* GetOriginalSendMessage() override { return orig_send_message_; } + const void* GetSendMessage() override { return orig_send_message_; } std::multimap* GetSendInitialMetadata() override { return send_initial_metadata_; @@ -385,14 +385,14 @@ class CancelInterceptorBatchMethods "Cancel notification"); } - ByteBuffer* GetSendMessage() override { + ByteBuffer* GetSerializedSendMessage() override { GPR_CODEGEN_ASSERT(false && "It is illegal to call GetSendMessage on a method which " "has a Cancel notification"); return nullptr; } - const void* GetOriginalSendMessage() override { + const void* GetSendMessage() override { GPR_CODEGEN_ASSERT( false && "It is illegal to call GetOriginalSendMessage on a method which " diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 1ed1fb686dc..3db709e956e 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -68,7 +68,7 @@ class HijackingInterceptor : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; - auto* buffer = methods->GetSendMessage(); + auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) @@ -173,7 +173,7 @@ class HijackingInterceptorMakesAnotherCall : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; - auto* buffer = methods->GetSendMessage(); + auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) @@ -287,17 +287,16 @@ class LoggingInterceptor : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; - auto* buffer = methods->GetSendMessage(); + auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); EXPECT_TRUE(req.message().find("Hello") == 0u); - EXPECT_EQ( - static_cast(methods->GetOriginalSendMessage()) - ->message() - .find("Hello"), - 0u); + EXPECT_EQ(static_cast(methods->GetSendMessage()) + ->message() + .find("Hello"), + 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 28f51bb2fce..09e855b0d01 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -83,7 +83,7 @@ class LoggingInterceptor : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; - auto* buffer = methods->GetSendMessage(); + auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) @@ -142,30 +142,29 @@ class LoggingInterceptorFactory } }; -// Test if GetOriginalSendMessage works as expected -class GetOriginalSendMessageTester : public experimental::Interceptor { +// Test if GetSendMessage works as expected +class GetSendMessageTester : public experimental::Interceptor { public: - GetOriginalSendMessageTester(experimental::ServerRpcInfo* info) {} + GetSendMessageTester(experimental::ServerRpcInfo* info) {} void Intercept(experimental::InterceptorBatchMethods* methods) override { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { - EXPECT_EQ( - static_cast(methods->GetOriginalSendMessage()) - ->message() - .find("Hello"), - 0u); + EXPECT_EQ(static_cast(methods->GetSendMessage()) + ->message() + .find("Hello"), + 0u); } methods->Proceed(); } }; -class GetOriginalSendMessageTesterFactory +class GetSendMessageTesterFactory : public experimental::ServerInterceptorFactoryInterface { public: virtual experimental::Interceptor* CreateServerInterceptor( experimental::ServerRpcInfo* info) override { - return new GetOriginalSendMessageTester(info); + return new GetSendMessageTester(info); } }; @@ -205,7 +204,7 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { new LoggingInterceptorFactory())); creators.push_back( std::unique_ptr( - new GetOriginalSendMessageTesterFactory())); + new GetSendMessageTesterFactory())); // Add 20 dummy interceptor factories and null interceptor factories for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( @@ -248,7 +247,7 @@ class ServerInterceptorsEnd2endSyncStreamingTest : public ::testing::Test { new LoggingInterceptorFactory())); creators.push_back( std::unique_ptr( - new GetOriginalSendMessageTesterFactory())); + new GetSendMessageTesterFactory())); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); From e894d78c35f4836567c75054fdeb044a3397385c Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Thu, 3 Jan 2019 18:18:48 +0000 Subject: [PATCH 421/534] Fix artifact dockerfiles rvm installation; keep bundler pinned --- tools/dockerfile/grpc_artifact_linux_x64/Dockerfile | 2 +- tools/dockerfile/grpc_artifact_linux_x86/Dockerfile | 2 +- tools/run_tests/artifacts/build_artifact_ruby.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile index e3e549f9874..f247cc9ca54 100644 --- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile @@ -49,7 +49,7 @@ RUN apt-get update && apt-get install -y \ # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable # Install Ruby 2.1 diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile index ec4fcbae368..e403f75b594 100644 --- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile @@ -49,7 +49,7 @@ RUN apt-get update && apt-get install -y \ # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable # Install Ruby 2.1 diff --git a/tools/run_tests/artifacts/build_artifact_ruby.sh b/tools/run_tests/artifacts/build_artifact_ruby.sh index c910374376d..09423ce5391 100755 --- a/tools/run_tests/artifacts/build_artifact_ruby.sh +++ b/tools/run_tests/artifacts/build_artifact_ruby.sh @@ -38,7 +38,7 @@ fi set +ex rvm use default -gem install bundler --update +gem install bundler -v 1.17.3 tools/run_tests/helper_scripts/bundle_install_wrapper.sh From cab4774d95b9fa53f3cfe3bf58fb07dbc8f7650f Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 28 Dec 2018 15:54:43 -0800 Subject: [PATCH 422/534] Add a way to avoid if_nametoindex function for non-posix linux platforms that don't support it --- include/grpc/impl/codegen/port_platform.h | 4 ++++ src/core/lib/iomgr/grpc_if_nametoindex_posix.cc | 5 +++-- src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc | 5 +++-- src/core/lib/iomgr/port.h | 1 + 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 031c0c36aef..bd81635f58c 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -465,6 +465,10 @@ typedef unsigned __int64 uint64_t; #define GRPC_ARES 1 #endif +#ifndef GRPC_IF_NAMETOINDEX +#define GRPC_IF_NAMETOINDEX 1 +#endif + #ifndef GRPC_MUST_USE_RESULT #if defined(__GNUC__) && !defined(__MINGW32__) #define GRPC_MUST_USE_RESULT __attribute__((warn_unused_result)) diff --git a/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc b/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc index 8f9137455d2..f1ba20dcec7 100644 --- a/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc +++ b/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc @@ -20,7 +20,7 @@ #include "src/core/lib/iomgr/port.h" -#ifdef GRPC_POSIX_SOCKET +#if GRPC_IF_NAMETOINDEX == 1 && defined(GRPC_POSIX_SOCKET_IF_NAMETOINDEX) #include "src/core/lib/iomgr/grpc_if_nametoindex.h" @@ -38,4 +38,5 @@ uint32_t grpc_if_nametoindex(char* name) { return out; } -#endif /* GRPC_POSIX_SOCKET */ +#endif /* GRPC_IF_NAMETOINDEX == 1 && \ + defined(GRPC_POSIX_SOCKET_IF_NAMETOINDEX) */ diff --git a/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc b/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc index 1faaaa6e420..08644cccf3e 100644 --- a/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc +++ b/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc @@ -20,7 +20,7 @@ #include "src/core/lib/iomgr/port.h" -#ifndef GRPC_POSIX_SOCKET +#if GRPC_IF_NAMETOINDEX == 0 || !defined(GRPC_POSIX_SOCKET_IF_NAMETOINDEX) #include "src/core/lib/iomgr/grpc_if_nametoindex.h" @@ -34,4 +34,5 @@ uint32_t grpc_if_nametoindex(char* name) { return 0; } -#endif /* GRPC_POSIX_SOCKET */ +#endif /* GRPC_IF_NAMETOINDEX == 0 || \ + !defined(GRPC_POSIX_SOCKET_IF_NAMETOINDEX) */ diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index c8046b21dcd..7b6ca1bc0e1 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -184,6 +184,7 @@ #define GRPC_POSIX_SOCKET_EV_EPOLLEX 1 #define GRPC_POSIX_SOCKET_EV_POLL 1 #define GRPC_POSIX_SOCKET_EV_EPOLL1 1 +#define GRPC_POSIX_SOCKET_IF_NAMETOINDEX 1 #define GRPC_POSIX_SOCKET_IOMGR 1 #define GRPC_POSIX_SOCKET_RESOLVE_ADDRESS 1 #define GRPC_POSIX_SOCKET_SOCKADDR 1 From ec2d03d409ebb65daa252e6c280e3bec4fe96b69 Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Thu, 3 Jan 2019 14:28:38 -0800 Subject: [PATCH 423/534] restore the newline --- tools/doxygen/Doxyfile.c++ | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 8c890f2ba3f..1ab3a394b96 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -2623,3 +2623,4 @@ GENERATE_LEGEND = YES # This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES + From d99f2f03074ef978b593ec0fdbe6295cd0235500 Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Thu, 3 Jan 2019 15:33:33 -0800 Subject: [PATCH 424/534] Bump version to v1.19.x --- BUILD | 4 ++-- build.yaml | 4 ++-- doc/g_stands_for.md | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/BUILD b/BUILD index e3c765198b2..cd23d9c91fa 100644 --- a/BUILD +++ b/BUILD @@ -64,11 +64,11 @@ config_setting( ) # This should be updated along with build.yaml -g_stands_for = "goose" +g_stands_for = "gold" core_version = "7.0.0-dev" -version = "1.18.0-dev" +version = "1.19.0-dev" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index a41decd84f7..4ccc452ed5b 100644 --- a/build.yaml +++ b/build.yaml @@ -13,8 +13,8 @@ settings: '#09': Per-language overrides are possible with (eg) ruby_version tag here '#10': See the expand_version.py for all the quirks here core_version: 7.0.0-dev - g_stands_for: goose - version: 1.18.0-dev + g_stands_for: gold + version: 1.19.0-dev filegroups: - name: alts_proto headers: diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index 1e49b4d3f17..7bc8a003b5d 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -17,4 +17,5 @@ - 1.15 'g' stands for ['glider'](https://github.com/grpc/grpc/tree/v1.15.x) - 1.16 'g' stands for ['gao'](https://github.com/grpc/grpc/tree/v1.16.x) - 1.17 'g' stands for ['gizmo'](https://github.com/grpc/grpc/tree/v1.17.x) -- 1.18 'g' stands for ['goose'](https://github.com/grpc/grpc/tree/master) +- 1.18 'g' stands for ['goose'](https://github.com/grpc/grpc/tree/v1.18.x) +- 1.19 'g' stands for ['gold'](https://github.com/grpc/grpc/tree/master) From 94d55876438a8178aae85ded57e3d04ff3f298c5 Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Thu, 3 Jan 2019 15:35:20 -0800 Subject: [PATCH 425/534] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 4 ++-- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/core/lib/surface/version.cc | 2 +- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 4 ++-- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 32 files changed, 36 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48d3d11d238..7e4dddab5ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.18.0-dev") +set(PACKAGE_VERSION "1.19.0-dev") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index b8a1c921862..ce56482a0df 100644 --- a/Makefile +++ b/Makefile @@ -438,8 +438,8 @@ Q = @ endif CORE_VERSION = 7.0.0-dev -CPP_VERSION = 1.18.0-dev -CSHARP_VERSION = 1.18.0-dev +CPP_VERSION = 1.19.0-dev +CSHARP_VERSION = 1.19.0-dev CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 29a79dd47ab..e830958f799 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,7 +23,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.18.0-dev' + # version = '1.19.0-dev' version = '0.0.6-dev' s.version = version s.summary = 'gRPC C++ library' @@ -31,7 +31,7 @@ Pod::Spec.new do |s| s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.18.0-dev' + grpc_version = '1.19.0-dev' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 240afbff7e6..7ddef6aa441 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.18.0-dev' + version = '1.19.0-dev' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 13fe3e0b9c0..7bf53799de8 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.18.0-dev' + version = '1.19.0-dev' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index e132ad41b40..34bec88c8b4 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.18.0-dev' + version = '1.19.0-dev' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 940a1ac6217..8e284866b3d 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.18.0-dev' + version = '1.19.0-dev' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 2632fcb276b..d86c204746c 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.18.0dev - 1.18.0dev + 1.19.0dev + 1.19.0dev beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 4829cc80a53..70d7580becb 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -25,4 +25,4 @@ const char* grpc_version_string(void) { return "7.0.0-dev"; } -const char* grpc_g_stands_for(void) { return "goose"; } +const char* grpc_g_stands_for(void) { return "gold"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 55da89e6c83..358131c7c4c 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.18.0-dev"; } +grpc::string Version() { return "1.19.0-dev"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 4fffe4f6448..52ab2215ebe 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.18.0-dev + 1.19.0-dev 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 633880189ce..8f3be310ee7 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.18.0.0"; + public const string CurrentAssemblyFileVersion = "1.19.0.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.18.0-dev"; + public const string CurrentVersion = "1.19.0-dev"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 76d4f143901..fef1a43bb88 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.18.0-dev +set VERSION=1.19.0-dev @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 3334d24c115..6b66b941a8d 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.18.0-dev +set VERSION=1.19.0-dev @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 55ca6048bc3..659cfebbdc0 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.18.0-dev' + v = '1.19.0-dev' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 0be0e3c9a00..5e089fde316 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.18.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.19.0-dev" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index f2fd692070b..54f95ad16a8 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.18.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.19.0-dev" #define GRPC_C_VERSION_STRING @"7.0.0-dev" diff --git a/src/php/composer.json b/src/php/composer.json index 9c298c0e851..75fab483f14 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "Apache-2.0", - "version": "1.18.0", + "version": "1.19.0", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 1ddf90a667a..c85ee4d315b 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.18.0dev" +#define PHP_GRPC_VERSION "1.19.0dev" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 7a9f173947a..dd9d436c3fe 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.18.0.dev0""" +__version__ = """1.19.0.dev0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 2e91818d2ca..8e2f4d30bbc 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.19.0.dev0' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 16356ea4020..5f3a894a2ae 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.19.0.dev0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 85fa762f7e8..4c2d434066e 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.19.0.dev0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index e62ab169a2f..6b88b2dfc50 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.19.0.dev0' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index e009843b94f..2e58eb3b26c 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.19.0.dev0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 7b4c1695faa..d4c5d94ecbe 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.19.0.dev0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 2fcd1ad617f..e1645ab1b86 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.19.0.dev0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index a4ed052d85e..3b7f62d9f55 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.18.0.dev' + VERSION = '1.19.0.dev' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 389fb70684b..2ad685a7eb3 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.18.0.dev' + VERSION = '1.19.0.dev' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 29b2127960a..e5d9daef38f 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.19.0.dev0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 1ab3a394b96..b0415fd4f64 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.18.0-dev +PROJECT_NUMBER = 1.19.0-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 5f488d51940..6c31a467680 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.18.0-dev +PROJECT_NUMBER = 1.19.0-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 077cc271e55ddb881054ab69feaaabc6e0ef6d81 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 3 Jan 2019 15:54:21 -0800 Subject: [PATCH 426/534] Proposed Cronet fixes --- .../transport/cronet/transport/cronet_transport.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 349d8681d55..278ef5636e3 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -335,6 +335,9 @@ static void add_to_storage(struct stream_obj* s, /* add new op at the beginning of the linked list. The memory is freed in remove_from_storage */ op_and_state* new_op = grpc_core::New(s, *op); + // Pontential fix to crash on GPR_ASSERT(!curr->done) + // TODO (mxyan): check if this is indeed necessary. + new_op->done = false; gpr_mu_lock(&s->mu); storage->head = new_op; storage->num_pending_ops++; @@ -391,7 +394,7 @@ static void execute_from_storage(stream_obj* s) { gpr_mu_lock(&s->mu); for (struct op_and_state* curr = s->storage.head; curr != nullptr;) { CRONET_LOG(GPR_DEBUG, "calling op at %p. done = %d", curr, curr->done); - GPR_ASSERT(curr->done == 0); + GPR_ASSERT(!curr->done); enum e_op_result result = execute_stream_op(curr); CRONET_LOG(GPR_DEBUG, "execute_stream_op[%p] returns %s", curr, op_result_string(result)); @@ -400,13 +403,12 @@ static void execute_from_storage(stream_obj* s) { struct op_and_state* next = curr->next; remove_from_storage(s, curr); curr = next; - } - /* continue processing the same op if ACTION_TAKEN_WITHOUT_CALLBACK */ - if (result == NO_ACTION_POSSIBLE) { + } else if (result == NO_ACTION_POSSIBLE) { curr = curr->next; } else if (result == ACTION_TAKEN_WITH_CALLBACK) { + /* wait for the callback */ break; - } + } /* continue processing the same op if ACTION_TAKEN_WITHOUT_CALLBACK */ } gpr_mu_unlock(&s->mu); } From 04dfa7d7b2343fd63a2f40aea28608b5a4938a29 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 3 Jan 2019 16:02:29 -0800 Subject: [PATCH 427/534] clang-format --- src/core/ext/transport/cronet/transport/cronet_transport.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 278ef5636e3..ade88da4cb9 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -336,7 +336,7 @@ static void add_to_storage(struct stream_obj* s, in remove_from_storage */ op_and_state* new_op = grpc_core::New(s, *op); // Pontential fix to crash on GPR_ASSERT(!curr->done) - // TODO (mxyan): check if this is indeed necessary. + // TODO (mxyan): check if this is indeed necessary. new_op->done = false; gpr_mu_lock(&s->mu); storage->head = new_op; From 03431b4f696387e34d6c438069a42ce56e269f04 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 3 Jan 2019 16:18:01 -0800 Subject: [PATCH 428/534] Remove filters from subchannel args --- .../ext/filters/client_channel/subchannel.cc | 13 ------------- .../ext/filters/client_channel/subchannel.h | 5 ----- .../filters/client_channel/subchannel_index.cc | 17 ----------------- src/core/lib/surface/channel_init.h | 5 +++++ src/cpp/common/channel_filter.h | 5 +++++ 5 files changed, 10 insertions(+), 35 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 9077aa97539..3abacf68aeb 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -101,9 +101,6 @@ struct grpc_subchannel { keep the subchannel open */ gpr_atm ref_pair; - /** non-transport related channel filters */ - const grpc_channel_filter** filters; - size_t num_filters; /** channel arguments */ grpc_channel_args* args; @@ -384,7 +381,6 @@ static void subchannel_destroy(void* arg, grpc_error* error) { c->channelz_subchannel->MarkSubchannelDestroyed(); c->channelz_subchannel.reset(); } - gpr_free((void*)c->filters); c->health_check_service_name.reset(); grpc_channel_args_destroy(c->args); grpc_connectivity_state_destroy(&c->state_tracker); @@ -567,15 +563,6 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, gpr_atm_no_barrier_store(&c->ref_pair, 1 << INTERNAL_REF_BITS); c->connector = connector; grpc_connector_ref(c->connector); - c->num_filters = args->filter_count; - if (c->num_filters > 0) { - c->filters = static_cast( - gpr_malloc(sizeof(grpc_channel_filter*) * c->num_filters)); - memcpy((void*)c->filters, args->filters, - sizeof(grpc_channel_filter*) * c->num_filters); - } else { - c->filters = nullptr; - } c->pollset_set = grpc_pollset_set_create(); grpc_resolved_address* addr = static_cast(gpr_malloc(sizeof(*addr))); diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 14f87f2c68e..d0c0a672fa1 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -189,11 +189,6 @@ grpc_call_stack* grpc_subchannel_call_get_call_stack( struct grpc_subchannel_args { /* When updating this struct, also update subchannel_index.c */ - /** Channel filters for this channel - wrapped factories will likely - want to mutate this */ - const grpc_channel_filter** filters; - /** The number of filters in the above array */ - size_t filter_count; /** Channel arguments to be supplied to the newly created channel */ const grpc_channel_args* args; }; diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc index aa8441f17b0..0ae7898c5a4 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ b/src/core/ext/filters/client_channel/subchannel_index.cc @@ -49,15 +49,6 @@ static grpc_subchannel_key* create_key( grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)) { grpc_subchannel_key* k = static_cast(gpr_malloc(sizeof(*k))); - k->args.filter_count = args->filter_count; - if (k->args.filter_count > 0) { - k->args.filters = static_cast( - gpr_malloc(sizeof(*k->args.filters) * k->args.filter_count)); - memcpy(reinterpret_cast(k->args.filters), - args->filters, sizeof(*k->args.filters) * k->args.filter_count); - } else { - k->args.filters = nullptr; - } k->args.args = copy_channel_args(args->args); return k; } @@ -75,18 +66,10 @@ int grpc_subchannel_key_compare(const grpc_subchannel_key* a, const grpc_subchannel_key* b) { // To pretend the keys are different, return a non-zero value. if (GPR_UNLIKELY(g_force_creation)) return 1; - int c = GPR_ICMP(a->args.filter_count, b->args.filter_count); - if (c != 0) return c; - if (a->args.filter_count > 0) { - c = memcmp(a->args.filters, b->args.filters, - a->args.filter_count * sizeof(*a->args.filters)); - if (c != 0) return c; - } return grpc_channel_args_compare(a->args.args, b->args.args); } void grpc_subchannel_key_destroy(grpc_subchannel_key* k) { - gpr_free(reinterpret_cast(k->args.filters)); grpc_channel_args_destroy(const_cast(k->args.args)); gpr_free(k); } diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index f01852473ba..d17a721606d 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -45,6 +45,11 @@ void grpc_channel_init_init(void); /// registration order (in the case of a tie). /// Stages are registered against one of the pre-determined channel stack /// types. +/// If the channel stack type is GRPC_CLIENT_SUBCHANNEL, the caller should +/// ensure that subchannels with different filter lists will always have +/// different channel args. This requires setting a channel arg in case the +/// registration function relies on some condition other than channel args to +/// decide whether to add a filter or not. void grpc_channel_init_register_stage(grpc_channel_stack_type type, int priority, grpc_channel_init_stage stage_fn, diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h index 5e569c97e68..1a3295fc80f 100644 --- a/src/cpp/common/channel_filter.h +++ b/src/cpp/common/channel_filter.h @@ -366,6 +366,11 @@ void ChannelFilterPluginShutdown(); /// The \a include_filter argument specifies a function that will be called /// to determine at run-time whether or not to add the filter. If the /// value is nullptr, the filter will be added unconditionally. +/// If the channel stack type is GRPC_CLIENT_SUBCHANNEL, the caller should +/// ensure that subchannels with different filter lists will always have +/// different channel args. This requires setting a channel arg in case the +/// registration function relies on some condition other than channel args to +/// decide whether to add a filter or not. template void RegisterChannelFilter( const char* name, grpc_channel_stack_type stack_type, int priority, From 4224384d398ee3ddd01c0b95f93f33bdd75e8fb2 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 3 Jan 2019 15:47:00 -0800 Subject: [PATCH 429/534] Modifying semantics for GetSendMessage and GetSerializedSendMessage. Also adding ModifySendMessage --- include/grpcpp/impl/codegen/call_op_set.h | 31 +++++--- include/grpcpp/impl/codegen/interceptor.h | 2 + .../grpcpp/impl/codegen/interceptor_common.h | 33 +++++++-- .../client_interceptors_end2end_test.cc | 8 +-- .../server_interceptors_end2end_test.cc | 71 +++++++++++++++---- 5 files changed, 115 insertions(+), 30 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 310bea93ca7..b9cf0b1db04 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -317,7 +317,10 @@ class CallOpSendMessage { protected: void AddOp(grpc_op* ops, size_t* nops) { - if (!send_buf_.Valid() || hijacked_) return; + if ((msg_ == nullptr && !send_buf_.Valid()) || hijacked_) return; + if (msg_ != nullptr) { + GPR_CODEGEN_ASSERT(serializer_(msg_).ok()); + } grpc_op* op = &ops[(*nops)++]; op->op = GRPC_OP_SEND_MESSAGE; op->flags = write_options_.flags(); @@ -330,17 +333,17 @@ class CallOpSendMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - if (!send_buf_.Valid()) return; + if (msg_ == nullptr && !send_buf_.Valid()) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE); - interceptor_methods->SetSendMessage(&send_buf_, msg_); + interceptor_methods->SetSendMessage(&send_buf_, &msg_, serializer_); } void SetFinishInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { // The contents of the SendMessage value that was previously set // has had its references stolen by core's operations - interceptor_methods->SetSendMessage(nullptr, nullptr); + interceptor_methods->SetSendMessage(nullptr, nullptr, nullptr); } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { @@ -352,6 +355,7 @@ class CallOpSendMessage { bool hijacked_ = false; ByteBuffer send_buf_; WriteOptions write_options_; + std::function serializer_; }; template @@ -362,12 +366,21 @@ Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { // The void in the template parameter below should not be needed // (since it should be implicit) but is needed due to an observed // difference in behavior between clang and gcc for certain internal users - Status result = SerializationTraits::Serialize( - message, send_buf_.bbuf_ptr(), &own_buf); - if (!own_buf) { - send_buf_.Duplicate(); + serializer_ = [this](const void* message) { + bool own_buf; + send_buf_.Clear(); + Status result = SerializationTraits::Serialize( + *static_cast(message), send_buf_.bbuf_ptr(), &own_buf); + if (!own_buf) { + send_buf_.Duplicate(); + } + return result; + }; + // Serialize immediately only if we do not have access to the message pointer + if (msg_ == nullptr) { + return serializer_(&message); } - return result; + return Status::OK; } template diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 5a9a3a44e6e..edf3ab49f16 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -117,6 +117,8 @@ class InterceptorBatchMethods { /// only supported for sync and callback APIs at the present moment. virtual const void* GetSendMessage() = 0; + virtual void ModifySendMessage(const void* message) = 0; + /// Returns a modifiable multimap of the initial metadata to be sent. Valid /// for PRE_SEND_INITIAL_METADATA interceptions. A value of nullptr indicates /// that this field is not valid. diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 4b7eaefee1b..6fa6210dc36 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -79,9 +79,24 @@ class InterceptorBatchMethodsImpl hooks_[static_cast(type)] = true; } - ByteBuffer* GetSerializedSendMessage() override { return send_message_; } + ByteBuffer* GetSerializedSendMessage() override { + GPR_CODEGEN_ASSERT(orig_send_message_ != nullptr); + if (*orig_send_message_ != nullptr) { + GPR_CODEGEN_ASSERT(serializer_(*orig_send_message_).ok()); + *orig_send_message_ = nullptr; + } + return send_message_; + } + + const void* GetSendMessage() override { + GPR_CODEGEN_ASSERT(orig_send_message_ != nullptr); + return *orig_send_message_; + } - const void* GetSendMessage() override { return orig_send_message_; } + void ModifySendMessage(const void* message) override { + GPR_CODEGEN_ASSERT(orig_send_message_ != nullptr); + *orig_send_message_ = message; + } std::multimap* GetSendInitialMetadata() override { return send_initial_metadata_; @@ -117,9 +132,11 @@ class InterceptorBatchMethodsImpl return recv_trailing_metadata_->map(); } - void SetSendMessage(ByteBuffer* buf, const void* msg) { + void SetSendMessage(ByteBuffer* buf, const void** msg, + std::function serializer) { send_message_ = buf; orig_send_message_ = msg; + serializer_ = serializer; } void SetSendInitialMetadata( @@ -339,7 +356,8 @@ class InterceptorBatchMethodsImpl std::function callback_; ByteBuffer* send_message_ = nullptr; - const void* orig_send_message_ = nullptr; + const void** orig_send_message_ = nullptr; + std::function serializer_; std::multimap* send_initial_metadata_; @@ -400,6 +418,13 @@ class CancelInterceptorBatchMethods return nullptr; } + void ModifySendMessage(const void* message) override { + GPR_CODEGEN_ASSERT( + false && + "It is illegal to call ModifySendMessage on a method which " + "has a Cancel notification"); + } + std::multimap* GetSendInitialMetadata() override { GPR_CODEGEN_ASSERT(false && "It is illegal to call GetSendInitialMetadata on a " diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 3db709e956e..ea72c1eda88 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -287,16 +287,16 @@ class LoggingInterceptor : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; + EXPECT_EQ(static_cast(methods->GetSendMessage()) + ->message() + .find("Hello"), + 0u); auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); EXPECT_TRUE(req.message().find("Hello") == 0u); - EXPECT_EQ(static_cast(methods->GetSendMessage()) - ->message() - .find("Hello"), - 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 09e855b0d01..82f142ba913 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -142,29 +142,68 @@ class LoggingInterceptorFactory } }; -// Test if GetSendMessage works as expected -class GetSendMessageTester : public experimental::Interceptor { +// Test if SendMessage function family works as expected for sync/callback apis +class SyncSendMessageTester : public experimental::Interceptor { public: - GetSendMessageTester(experimental::ServerRpcInfo* info) {} + SyncSendMessageTester(experimental::ServerRpcInfo* info) {} void Intercept(experimental::InterceptorBatchMethods* methods) override { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { - EXPECT_EQ(static_cast(methods->GetSendMessage()) - ->message() - .find("Hello"), - 0u); + string old_msg = + static_cast(methods->GetSendMessage())->message(); + EXPECT_EQ(old_msg.find("Hello"), 0u); + new_msg_.set_message("World" + old_msg); + methods->ModifySendMessage(&new_msg_); } methods->Proceed(); } + + private: + EchoRequest new_msg_; }; -class GetSendMessageTesterFactory +class SyncSendMessageTesterFactory : public experimental::ServerInterceptorFactoryInterface { public: virtual experimental::Interceptor* CreateServerInterceptor( experimental::ServerRpcInfo* info) override { - return new GetSendMessageTester(info); + return new SyncSendMessageTester(info); + } +}; + +// Test if SendMessage function family works as expected for sync/callback apis +class SyncSendMessageVerifier : public experimental::Interceptor { + public: + SyncSendMessageVerifier(experimental::ServerRpcInfo* info) {} + + void Intercept(experimental::InterceptorBatchMethods* methods) override { + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + // Make sure that the changes made in SyncSendMessageTester persisted + string old_msg = + static_cast(methods->GetSendMessage())->message(); + EXPECT_EQ(old_msg.find("World"), 0u); + + // Remove the "World" part of the string that we added earlier + new_msg_.set_message(old_msg.erase(0, 5)); + methods->ModifySendMessage(&new_msg_); + + // LoggingInterceptor verifies that changes got reverted + } + methods->Proceed(); + } + + private: + EchoRequest new_msg_; +}; + +class SyncSendMessageVerifierFactory + : public experimental::ServerInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateServerInterceptor( + experimental::ServerRpcInfo* info) override { + return new SyncSendMessageVerifier(info); } }; @@ -201,10 +240,13 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { creators; creators.push_back( std::unique_ptr( - new LoggingInterceptorFactory())); + new SyncSendMessageTesterFactory())); creators.push_back( std::unique_ptr( - new GetSendMessageTesterFactory())); + new SyncSendMessageVerifierFactory())); + creators.push_back( + std::unique_ptr( + new LoggingInterceptorFactory())); // Add 20 dummy interceptor factories and null interceptor factories for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( @@ -244,10 +286,13 @@ class ServerInterceptorsEnd2endSyncStreamingTest : public ::testing::Test { creators; creators.push_back( std::unique_ptr( - new LoggingInterceptorFactory())); + new SyncSendMessageTesterFactory())); creators.push_back( std::unique_ptr( - new GetSendMessageTesterFactory())); + new SyncSendMessageVerifierFactory())); + creators.push_back( + std::unique_ptr( + new LoggingInterceptorFactory())); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); From df49204b975b898392655a4af5a0597d7b2ec850 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 3 Jan 2019 18:10:21 -0800 Subject: [PATCH 430/534] Remove unused variable --- include/grpcpp/impl/codegen/call_op_set.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index b9cf0b1db04..88c744a3fcf 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -361,7 +361,6 @@ class CallOpSendMessage { template Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { write_options_ = options; - bool own_buf; // TODO(vjpai): Remove the void below when possible // The void in the template parameter below should not be needed // (since it should be implicit) but is needed due to an observed From 7eeda22d9ed2f9936ec5a2ad61076274dfb5282b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 3 Jan 2019 18:23:15 -0800 Subject: [PATCH 431/534] s/two/three --- include/grpcpp/impl/codegen/interceptor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 0ad257bcd6d..519c65c7178 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -46,7 +46,7 @@ namespace experimental { /// operation has been requested and it is available. POST_RECV means that a /// result is available but has not yet been passed back to the application. enum class InterceptionHookPoints { - /// The first two in this list are for clients and servers + /// The first three in this list are for clients and servers PRE_SEND_INITIAL_METADATA, PRE_SEND_MESSAGE, POST_SEND_MESSAGE, From 2b4781ca526b0823fbea263a5c7b07fdf8abe41d Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 3 Jan 2019 18:32:10 -0800 Subject: [PATCH 432/534] Use Status() instead of Status::OK to avoid issues with codegen_test_minimal --- include/grpcpp/impl/codegen/call_op_set.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 88c744a3fcf..e8a4d389f17 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -379,7 +379,7 @@ Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { if (msg_ == nullptr) { return serializer_(&message); } - return Status::OK; + return Status(); } template From c4ed5b33c4de7d239f9ee26e128e4ee26e677465 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Fri, 4 Jan 2019 09:21:17 +0000 Subject: [PATCH 433/534] Pin bundler in ruby interop build --- tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh index 67f66090ae9..e71ad91499a 100755 --- a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh @@ -30,4 +30,4 @@ cd /var/local/git/grpc rvm --default use ruby-2.5 # build Ruby interop client and server -(cd src/ruby && gem update bundler && bundle && rake compile) +(cd src/ruby && gem install bundler -v 1.17.3 && bundle && rake compile) From 4cbdf08e61b2f168a42a8984b58126aebdb9097e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 4 Jan 2019 10:33:18 +0100 Subject: [PATCH 434/534] debug out of disk space in run_interop_matrix_tests.py --- tools/internal_ci/linux/grpc_interop_matrix.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/internal_ci/linux/grpc_interop_matrix.sh b/tools/internal_ci/linux/grpc_interop_matrix.sh index a5220ea087f..5f1f69db952 100755 --- a/tools/internal_ci/linux/grpc_interop_matrix.sh +++ b/tools/internal_ci/linux/grpc_interop_matrix.sh @@ -22,4 +22,15 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc -tools/interop_matrix/run_interop_matrix_tests.py $RUN_TESTS_FLAGS +# TODO(jtattermusch): Diagnose out of disk space problems. Remove once not needed. +df -h + +tools/interop_matrix/run_interop_matrix_tests.py $RUN_TESTS_FLAGS || FAILED="true" + +# TODO(jtattermusch): Diagnose out of disk space problems. Remove once not needed. +df -h + +if [ "$FAILED" != "" ] +then + exit 1 +fi From b0663e7e1ebb164982fc3ca95c453c4b4dad5964 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 4 Jan 2019 12:31:34 +0100 Subject: [PATCH 435/534] interop_matrix: reliable cleanup of interop docker images --- .../run_interop_matrix_tests.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index 6cf2a9b0365..d47b0ee0f7b 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -232,10 +232,13 @@ def _run_tests_for_lang(lang, runtime, images, xml_report_tree): images is a list of (, ) tuple. """ + skip_tests = False if not _pull_images_for_lang(lang, images): jobset.message( - 'FAILED', 'Image download failed. Exiting.', do_newline=True) - return 1 + 'FAILED', + 'Image download failed. Skipping tests for language "%s"' % lang, + do_newline=True) + skip_tests = True total_num_failures = 0 for release, image in images: @@ -246,17 +249,22 @@ def _run_tests_for_lang(lang, runtime, images, xml_report_tree): if not job_spec_list: jobset.message( 'FAILED', 'No test cases were found.', do_newline=True) - return 1 + total_num_failures += 1 + continue num_failures, resultset = jobset.run( job_spec_list, newline_on_success=True, add_env={'docker_image': image}, - maxjobs=args.jobs) + maxjobs=args.jobs, + skip_jobs=skip_tests) if args.bq_result_table and resultset: upload_test_results.upload_interop_results_to_bq( resultset, args.bq_result_table) - if num_failures: + if skip_tests: + jobset.message('FAILED', 'Tests were skipped', do_newline=True) + total_num_failures += 1 + elif num_failures: jobset.message('FAILED', 'Some tests failed', do_newline=True) total_num_failures += num_failures else: @@ -266,6 +274,8 @@ def _run_tests_for_lang(lang, runtime, images, xml_report_tree): 'grpc_interop_matrix', suite_name, str(uuid.uuid4())) + # cleanup all downloaded docker images + for _, image in images: if not args.keep: _cleanup_docker_image(image) From b4a926961abc9e29016b2ba30093f3925de10514 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 4 Jan 2019 09:40:18 -0800 Subject: [PATCH 436/534] Fix static analizer errors --- src/objective-c/GRPCClient/GRPCCallOptions.m | 11 ++++++++--- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index d3440ee6c07..e59a812bd85 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -160,7 +160,10 @@ static BOOL areObjectsEqual(id obj1, id obj2) { _timeout = timeout < 0 ? 0 : timeout; _oauth2AccessToken = [oauth2AccessToken copy]; _authTokenProvider = authTokenProvider; - _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; + _initialMetadata = + initialMetadata == nil + ? nil + : [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; _userAgentPrefix = [userAgentPrefix copy]; _responseSizeLimit = responseSizeLimit; _compressionAlgorithm = compressionAlgorithm; @@ -171,7 +174,9 @@ static BOOL areObjectsEqual(id obj1, id obj2) { _connectInitialBackoff = connectInitialBackoff < 0 ? 0 : connectInitialBackoff; _connectMaxBackoff = connectMaxBackoff < 0 ? 0 : connectMaxBackoff; _additionalChannelArgs = - [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; + additionalChannelArgs == nil + ? nil + : [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; _PEMRootCertificates = [PEMRootCertificates copy]; _PEMPrivateKey = [PEMPrivateKey copy]; _PEMCertificateChain = [PEMCertificateChain copy]; @@ -458,7 +463,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { - (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout { if (connectMinTimeout < 0) { - connectMinTimeout = 0; + _connectMinTimeout = 0; } else { _connectMinTimeout = connectMinTimeout; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index d3a99ca8263..e00ee69e63a 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -88,7 +88,8 @@ NS_ASSUME_NONNULL_BEGIN /** * Return a channel with a particular configuration. The channel may be a cached channel. */ -- (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; +- (nullable GRPCPooledChannel *)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions; /** * Disconnect all channels in this pool. From a5ed3d245e448c1e0e0e28b93e5821aaa7a3e439 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 4 Jan 2019 11:17:35 -0800 Subject: [PATCH 437/534] Avoid unsigned signed comparison issues --- test/cpp/end2end/client_interceptors_end2end_test.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index ab387aa9144..fc75fdb290b 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -291,7 +291,7 @@ class BidiStreamingRpcHijackingInterceptor : public experimental::Interceptor { EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); - EXPECT_EQ(req.message().find("Hello"), 0); + EXPECT_EQ(req.message().find("Hello"), 0u); msg = req.message(); } if (methods->QueryInterceptionHookPoint( @@ -316,7 +316,7 @@ class BidiStreamingRpcHijackingInterceptor : public experimental::Interceptor { EXPECT_EQ(static_cast(methods->GetRecvMessage()) ->message() .find("Hello"), - 0); + 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { @@ -370,7 +370,7 @@ class LoggingInterceptor : public experimental::Interceptor { EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); - EXPECT_TRUE(req.message().find("Hello") == 0); + EXPECT_TRUE(req.message().find("Hello") == 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { @@ -386,7 +386,7 @@ class LoggingInterceptor : public experimental::Interceptor { experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { EchoResponse* resp = static_cast(methods->GetRecvMessage()); - EXPECT_TRUE(resp->message().find("Hello") == 0); + EXPECT_TRUE(resp->message().find("Hello") == 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_STATUS)) { From 9b9ef640278fd5d0c9a64c1b0c7182277bc35f53 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 4 Jan 2019 11:29:57 -0800 Subject: [PATCH 438/534] Add more information on the usage of FailHijackedRecvMessage --- include/grpcpp/impl/codegen/interceptor.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index a1cb80013da..cf92ce46b43 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -157,7 +157,9 @@ class InterceptorBatchMethods { /// list. virtual std::unique_ptr GetInterceptedChannel() = 0; - // On a hijacked RPC, an interceptor can decide to fail a RECV MESSAGE op. + /// On a hijacked RPC, an interceptor can decide to fail a PRE_RECV_MESSAGE + /// op. This would be a signal to the reader that there will be no more + /// messages, or the stream has failed or been cancelled. virtual void FailHijackedRecvMessage() = 0; }; From d79d2f1ca763d758b2d83a39a27c3e7e698e94a9 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 4 Jan 2019 13:59:19 -0800 Subject: [PATCH 439/534] Do not reload grpc in unit tests This can break subsequently run tests, including any which have already stored references to gRPC enums (such as grpc.StatusCode.OK). The subsequent tests will compare now be comparing the old enums to the reloaded enums, and they will not match. This causes errors in _metadata_code_details_test and a hang in _metadata_flags_test, when run in sequence locally after _logging_test. It's unclear why this has been working on Kokoro, but it is reproducible locally and is behavior that should be avoided. --- .../grpcio_tests/tests/unit/_logging_test.py | 104 +++++++++++------- 1 file changed, 62 insertions(+), 42 deletions(-) diff --git a/src/python/grpcio_tests/tests/unit/_logging_test.py b/src/python/grpcio_tests/tests/unit/_logging_test.py index 631b9de9db5..8ff127f5062 100644 --- a/src/python/grpcio_tests/tests/unit/_logging_test.py +++ b/src/python/grpcio_tests/tests/unit/_logging_test.py @@ -14,66 +14,86 @@ """Test of gRPC Python's interaction with the python logging module""" import unittest -import six -from six.moves import reload_module import logging import grpc -import functools +import subprocess import sys +INTERPRETER = sys.executable -def patch_stderr(f): - @functools.wraps(f) - def _impl(*args, **kwargs): - old_stderr = sys.stderr - sys.stderr = six.StringIO() - try: - f(*args, **kwargs) - finally: - sys.stderr = old_stderr +class LoggingTest(unittest.TestCase): - return _impl + def test_logger_not_occupied(self): + script = """if True: + import logging + import grpc -def isolated_logging(f): + if len(logging.getLogger().handlers) != 0: + raise Exception('expected 0 logging handlers') - @functools.wraps(f) - def _impl(*args, **kwargs): - reload_module(logging) - reload_module(grpc) - try: - f(*args, **kwargs) - finally: - reload_module(logging) + """ + self._verifyScriptSucceeds(script) - return _impl + def test_handler_found(self): + script = """if True: + import logging + import grpc + """ + out, err = self._verifyScriptSucceeds(script) + self.assertEqual(0, len(err), 'unexpected output to stderr') -class LoggingTest(unittest.TestCase): + def test_can_configure_logger(self): + script = """if True: + import logging + import six - @isolated_logging - def test_logger_not_occupied(self): - self.assertEqual(0, len(logging.getLogger().handlers)) + import grpc - @patch_stderr - @isolated_logging - def test_handler_found(self): - self.assertEqual(0, len(sys.stderr.getvalue())) - @isolated_logging - def test_can_configure_logger(self): - intended_stream = six.StringIO() - logging.basicConfig(stream=intended_stream) - self.assertEqual(1, len(logging.getLogger().handlers)) - self.assertIs(logging.getLogger().handlers[0].stream, intended_stream) + intended_stream = six.StringIO() + logging.basicConfig(stream=intended_stream) + + if len(logging.getLogger().handlers) != 1: + raise Exception('expected 1 logging handler') + + if logging.getLogger().handlers[0].stream is not intended_stream: + raise Exception('wrong handler stream') + + """ + self._verifyScriptSucceeds(script) - @isolated_logging def test_grpc_logger(self): - self.assertIn("grpc", logging.Logger.manager.loggerDict) - root_logger = logging.getLogger("grpc") - self.assertEqual(1, len(root_logger.handlers)) - self.assertIsInstance(root_logger.handlers[0], logging.NullHandler) + script = """if True: + import logging + + import grpc + + if "grpc" not in logging.Logger.manager.loggerDict: + raise Exception('grpc logger not found') + + root_logger = logging.getLogger("grpc") + if len(root_logger.handlers) != 1: + raise Exception('expected 1 root logger handler') + if not isinstance(root_logger.handlers[0], logging.NullHandler): + raise Exception('expected logging.NullHandler') + + """ + self._verifyScriptSucceeds(script) + + def _verifyScriptSucceeds(self, script): + process = subprocess.Popen( + [INTERPRETER, '-c', script], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, err = process.communicate() + self.assertEqual( + 0, process.returncode, + 'process failed with exit code %d (stdout: %s, stderr: %s)' % + (process.returncode, out, err)) + return out, err if __name__ == '__main__': From 4b2086eecdb6fb97c1fa791c58f23c22acea74be Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 4 Jan 2019 14:12:11 -0800 Subject: [PATCH 440/534] restore cython flag value to default after test --- src/python/grpcio_tests/tests/unit/_cython/_fork_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py b/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py index aeb02458a7e..5a5dedd5f26 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py @@ -27,6 +27,7 @@ def _get_number_active_threads(): class ForkPosixTester(unittest.TestCase): def setUp(self): + self._saved_fork_support_flag = cygrpc._GRPC_ENABLE_FORK_SUPPORT cygrpc._GRPC_ENABLE_FORK_SUPPORT = True def testForkManagedThread(self): @@ -50,6 +51,9 @@ class ForkPosixTester(unittest.TestCase): thread.join() self.assertEqual(0, _get_number_active_threads()) + def tearDown(self): + cygrpc._GRPC_ENABLE_FORK_SUPPORT = self._saved_fork_support_flag + @unittest.skipUnless(os.name == 'nt', 'Windows-specific tests') class ForkWindowsTester(unittest.TestCase): From 0d6e10e795e9c627368afebf7d877bc392cd78dd Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Mon, 7 Jan 2019 10:15:07 -0500 Subject: [PATCH 441/534] clang-format all the files. Whenever we run clang-format, gen_build_yaml.py and ServerServiceDefinitionExtensions.cs get modified by the script. Let's commit those changes so that these file remain unmodified after running the formatting script. --- .../Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs | 2 +- test/cpp/qps/gen_build_yaml.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs b/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs index 8987544f7f4..56ead8a6a15 100644 --- a/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs +++ b/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs @@ -76,4 +76,4 @@ namespace Grpc.Core.Interceptors return serverServiceDefinition; } } -} \ No newline at end of file +} diff --git a/test/cpp/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py index fb2caf5486a..8ca0dc6a620 100755 --- a/test/cpp/qps/gen_build_yaml.py +++ b/test/cpp/qps/gen_build_yaml.py @@ -131,4 +131,4 @@ def generate_yaml(): } -print(yaml.dump(generate_yaml())) \ No newline at end of file +print(yaml.dump(generate_yaml())) From 747608df379e0a06ccc5cea469455d80591ea430 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 17:16:04 +0100 Subject: [PATCH 442/534] add go1.11 interop image templates --- .../grpc_interop_go1.11/Dockerfile.template | 23 +++++++++++++++++++ .../build_interop.sh.template | 3 +++ 2 files changed, 26 insertions(+) create mode 100644 templates/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile.template create mode 100644 templates/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh.template diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile.template new file mode 100644 index 00000000000..4921d93f499 --- /dev/null +++ b/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile.template @@ -0,0 +1,23 @@ +%YAML 1.2 +--- | + # Copyright 2018 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. + + FROM golang:1.11 + + <%include file="../../go_path.include"/> + <%include file="../../python_deps.include"/> + # Define the default command. + CMD ["bash"] + diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh.template new file mode 100644 index 00000000000..a08798b1d6b --- /dev/null +++ b/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh.template @@ -0,0 +1,3 @@ +%YAML 1.2 +--- | + <%include file="../../go_build_interop.sh.include"/> From bdee6308312376d28e762e49b3d7834c1e925d06 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 17:16:39 +0100 Subject: [PATCH 443/534] regenerate dockerimages --- .../grpc_interop_go1.11/Dockerfile | 36 +++++++++++++++++++ .../grpc_interop_go1.11/build_interop.sh | 33 +++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile create mode 100644 tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh diff --git a/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile new file mode 100644 index 00000000000..0892bc34599 --- /dev/null +++ b/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile @@ -0,0 +1,36 @@ +# Copyright 2018 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. + +FROM golang:1.11 + +# Using login shell removes Go from path, so we add it. +RUN ln -s /usr/local/go/bin/go /usr/local/bin + +#==================== +# Python dependencies + +# Install dependencies + +RUN apt-get update && apt-get install -y \ + python-all-dev \ + python3-all-dev \ + python-pip + +# Install Python packages from PyPI +RUN pip install --upgrade pip==10.0.1 +RUN pip install virtualenv +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0 + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh new file mode 100644 index 00000000000..b11ace3a4e7 --- /dev/null +++ b/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# Copyright 2015 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. +# +# Builds Go interop server and client in a base image. +set -e + +# Clone just the grpc-go source code without any dependencies. +# We are cloning from a local git repo that contains the right revision +# to test instead of using "go get" to download from Github directly. +git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc + +# Get all gRPC Go dependencies +(cd src/google.golang.org/grpc && make deps && make testdeps) + +# copy service account keys if available +cp -r /var/local/jenkins/service_account $HOME || true + +# Build the interop client and server +(cd src/google.golang.org/grpc/interop/client && go install) +(cd src/google.golang.org/grpc/interop/server && go install) + From a13e77e14db90fd2b0a87ca151b4db0786f34ff6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 7 Jan 2019 11:47:33 -0500 Subject: [PATCH 444/534] interop_matrix: support skipping runtimes --- tools/interop_matrix/client_matrix.py | 83 +++++++++++++++---- tools/interop_matrix/create_matrix_images.py | 2 +- .../run_interop_matrix_tests.py | 15 ++-- 3 files changed, 76 insertions(+), 24 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index c0b08a59b26..3546d59c313 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -35,6 +35,18 @@ def get_release_tag_name(release_info): return release_info.keys()[0] +def get_runtimes_for_lang_release(lang, release): + """Get list of valid runtimes for given release of lang.""" + runtimes_to_skip = [] + # see if any the lang release has "skip_runtime" annotation. + for release_info in LANG_RELEASE_MATRIX[lang]: + if get_release_tag_name(release_info) == release: + if release_info[release] is not None: + runtimes_to_skip = release_info[release].get('skip_runtime', []) + break + return [runtime for runtime in LANG_RUNTIME_MATRIX[lang] if runtime not in runtimes_to_skip] + + def should_build_docker_interop_image_from_release_tag(lang): if lang in ['go', 'java', 'node']: return False @@ -44,7 +56,7 @@ def should_build_docker_interop_image_from_release_tag(lang): # Dictionary of runtimes per language LANG_RUNTIME_MATRIX = { 'cxx': ['cxx'], # This is actually debian8. - 'go': ['go1.7', 'go1.8'], + 'go': ['go1.7', 'go1.8', 'go1.11'], 'java': ['java_oracle8'], 'python': ['python'], 'node': ['node'], @@ -110,52 +122,89 @@ LANG_RELEASE_MATRIX = { ], 'go': [ { - 'v1.0.5': None + 'v1.0.5': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.2.1': None + 'v1.2.1': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.3.0': None + 'v1.3.0': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.4.2': None + 'v1.4.2': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.5.2': None + 'v1.5.2': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.6.0': None + 'v1.6.0': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.7.4': None + 'v1.7.4': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.8.2': None + 'v1.8.2': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.9.2': None + 'v1.9.2': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.10.1': None + 'v1.10.1': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.11.3': None + 'v1.11.3': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.12.2': None + 'v1.12.2': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.13.0': None + 'v1.13.0': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.14.0': None + 'v1.14.0': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.15.0': None + 'v1.15.0': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.16.0': None + 'v1.16.0': { + 'skip_runtime': ['go1.11'] + } + }, + { + 'v1.17.0': { + 'skip_runtime': ['go1.7', 'go1.8'] + } }, ], 'java': [ diff --git a/tools/interop_matrix/create_matrix_images.py b/tools/interop_matrix/create_matrix_images.py index c2568efba0f..cf61d462482 100755 --- a/tools/interop_matrix/create_matrix_images.py +++ b/tools/interop_matrix/create_matrix_images.py @@ -217,7 +217,7 @@ def build_all_images_for_release(lang, release): }.get(lang, 'GRPC_ROOT') env[var] = stack_base - for runtime in client_matrix.LANG_RUNTIME_MATRIX[lang]: + for runtime in client_matrix.get_runtimes_for_lang_release(lang, release): job = build_image_jobspec(runtime, env, release, stack_base) docker_images.append(job.tag) build_jobs.append(job) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index 6cf2a9b0365..693996031e3 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -113,13 +113,16 @@ def _get_test_images_for_lang(lang, release_arg, image_path_prefix): return {} releases = [release_arg] - # Images tuples keyed by runtime. + # Image tuples keyed by runtime. images = {} - for runtime in client_matrix.LANG_RUNTIME_MATRIX[lang]: - image_path = '%s/grpc_interop_%s' % (image_path_prefix, runtime) - images[runtime] = [ - (tag, '%s:%s' % (image_path, tag)) for tag in releases - ] + for tag in releases: + for runtime in client_matrix.get_runtimes_for_lang_release(lang, tag): + image_name = '%s/grpc_interop_%s:%s' % (image_path_prefix, runtime, tag) + image_tuple = (tag, image_name) + + if not images.has_key(runtime): + images[runtime] = [] + images[runtime].append(image_tuple) return images From 7d1491d64c9b6279233c780d290c514a7040c1c7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 7 Jan 2019 09:23:35 -0800 Subject: [PATCH 445/534] Address reviewer comments --- include/grpcpp/impl/codegen/call_op_set.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index e8a4d389f17..ced0b2ff3e6 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -321,6 +321,7 @@ class CallOpSendMessage { if (msg_ != nullptr) { GPR_CODEGEN_ASSERT(serializer_(msg_).ok()); } + serializer_ = nullptr; grpc_op* op = &ops[(*nops)++]; op->op = GRPC_OP_SEND_MESSAGE; op->flags = write_options_.flags(); @@ -361,13 +362,13 @@ class CallOpSendMessage { template Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { write_options_ = options; - // TODO(vjpai): Remove the void below when possible - // The void in the template parameter below should not be needed - // (since it should be implicit) but is needed due to an observed - // difference in behavior between clang and gcc for certain internal users serializer_ = [this](const void* message) { bool own_buf; send_buf_.Clear(); + // TODO(vjpai): Remove the void below when possible + // The void in the template parameter below should not be needed + // (since it should be implicit) but is needed due to an observed + // difference in behavior between clang and gcc for certain internal users Status result = SerializationTraits::Serialize( *static_cast(message), send_buf_.bbuf_ptr(), &own_buf); if (!own_buf) { From 2dc63f3d02efd2cb0ccea45248dd305e442c70d9 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 7 Jan 2019 19:08:02 +0100 Subject: [PATCH 446/534] yapf code --- tools/interop_matrix/client_matrix.py | 5 ++++- tools/interop_matrix/run_interop_matrix_tests.py | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 3546d59c313..4964fd61674 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -44,7 +44,10 @@ def get_runtimes_for_lang_release(lang, release): if release_info[release] is not None: runtimes_to_skip = release_info[release].get('skip_runtime', []) break - return [runtime for runtime in LANG_RUNTIME_MATRIX[lang] if runtime not in runtimes_to_skip] + return [ + runtime for runtime in LANG_RUNTIME_MATRIX[lang] + if runtime not in runtimes_to_skip + ] def should_build_docker_interop_image_from_release_tag(lang): diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index 693996031e3..d75cab90c25 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -117,7 +117,8 @@ def _get_test_images_for_lang(lang, release_arg, image_path_prefix): images = {} for tag in releases: for runtime in client_matrix.get_runtimes_for_lang_release(lang, tag): - image_name = '%s/grpc_interop_%s:%s' % (image_path_prefix, runtime, tag) + image_name = '%s/grpc_interop_%s:%s' % (image_path_prefix, runtime, + tag) image_tuple = (tag, image_name) if not images.has_key(runtime): From 5e10a3b037bcd20ab17428ccb765ba9464eb3644 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 21 Dec 2018 13:39:21 -0800 Subject: [PATCH 447/534] Make gRPC ObjC thread safety right --- src/objective-c/GRPCClient/GRPCCall.m | 360 ++++++++++-------- src/objective-c/RxLibrary/GRXBufferedPipe.m | 21 +- .../RxLibrary/GRXConcurrentWriteable.h | 4 +- .../RxLibrary/GRXConcurrentWriteable.m | 76 +--- .../RxLibrary/GRXForwardingWriter.m | 48 ++- .../RxLibrary/GRXImmediateSingleWriter.m | 30 +- src/objective-c/RxLibrary/GRXWriter.h | 4 +- 7 files changed, 275 insertions(+), 268 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 83c6edc6e3f..5ea1755c589 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -448,24 +448,30 @@ const char *kCFStreamVarName = "grpc_cfstream"; return; } NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; - switch (callSafety) { - case GRPCCallSafetyDefault: - callFlags[hostAndPath] = @0; - break; - case GRPCCallSafetyIdempotentRequest: - callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; - break; - case GRPCCallSafetyCacheableRequest: - callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; - break; - default: - break; + @synchronized (callFlags) { + switch (callSafety) { + case GRPCCallSafetyDefault: + callFlags[hostAndPath] = @0; + break; + case GRPCCallSafetyIdempotentRequest: + callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; + break; + case GRPCCallSafetyCacheableRequest: + callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; + break; + default: + break; + } } } + (uint32_t)callFlagsForHost:(NSString *)host path:(NSString *)path { NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; - return [callFlags[hostAndPath] intValue]; + uint32_t flags = 0; + @synchronized (callFlags) { + flags = [callFlags[hostAndPath] intValue]; + } + return flags; } // Designated initializer @@ -506,7 +512,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = [callOptions copy]; // Serial queue to invoke the non-reentrant methods of the grpc_call object. - _callQueue = dispatch_queue_create("io.grpc.call", NULL); + _callQueue = dispatch_queue_create("io.grpc.call", DISPATCH_QUEUE_SERIAL); _requestWriter = requestWriter; @@ -523,53 +529,49 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)setResponseDispatchQueue:(dispatch_queue_t)queue { - if (_state != GRXWriterStateNotStarted) { - return; + @synchronized (self) { + if (_state != GRXWriterStateNotStarted) { + return; + } + _responseQueue = queue; } - _responseQueue = queue; } #pragma mark Finish - (void)finishWithError:(NSError *)errorOrNil { + GRXConcurrentWriteable *copiedResponseWriteable = nil; + @synchronized(self) { + if (_state == GRXWriterStateFinished) { + return; + } _state = GRXWriterStateFinished; - } + copiedResponseWriteable = _responseWriteable; - // If there were still request messages coming, stop them. - @synchronized(_requestWriter) { - _requestWriter.state = GRXWriterStateFinished; + // If the call isn't retained anywhere else, it can be deallocated now. + _retainSelf = nil; } if (errorOrNil) { - [_responseWriteable cancelWithError:errorOrNil]; + [copiedResponseWriteable cancelWithError:errorOrNil]; } else { - [_responseWriteable enqueueSuccessfulCompletion]; - } - - [GRPCConnectivityMonitor unregisterObserver:self]; - - // If the call isn't retained anywhere else, it can be deallocated now. - _retainSelf = nil; -} - -- (void)cancelCall { - // Can be called from any thread, any number of times. - @synchronized(self) { - [_wrappedCall cancel]; + [copiedResponseWriteable enqueueSuccessfulCompletion]; } + _requestWriter.state = GRXWriterStateFinished; } - (void)cancel { - @synchronized(self) { - [self cancelCall]; - self.isWaitingForToken = NO; + @synchronized (self) { + if (_state == GRXWriterStateFinished) { + return; + } + [self finishWithError:[NSError + errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]]; + [_wrappedCall cancel]; } - [self - maybeFinishWithError:[NSError - errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]]; } - (void)maybeFinishWithError:(NSError *)errorOrNil { @@ -609,21 +611,24 @@ const char *kCFStreamVarName = "grpc_cfstream"; // TODO(jcanizales): Rename to readResponseIfNotPaused. - (void)startNextRead { @synchronized(self) { - if (self.state == GRXWriterStatePaused) { + if (_state != GRXWriterStateStarted) { return; } } dispatch_async(_callQueue, ^{ __weak GRPCCall *weakSelf = self; - __weak GRXConcurrentWriteable *weakWriteable = self->_responseWriteable; [self startReadWithHandler:^(grpc_byte_buffer *message) { - __strong GRPCCall *strongSelf = weakSelf; - __strong GRXConcurrentWriteable *strongWriteable = weakWriteable; + NSLog(@"message received"); if (message == NULL) { // No more messages from the server return; } + __strong GRPCCall *strongSelf = weakSelf; + if (strongSelf == nil) { + grpc_byte_buffer_destroy(message); + return; + } NSData *data = [NSData grpc_dataWithByteBuffer:message]; grpc_byte_buffer_destroy(message); if (!data) { @@ -631,21 +636,25 @@ const char *kCFStreamVarName = "grpc_cfstream"; // 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 cancelCall]; - [strongSelf - maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeResourceExhausted - userInfo:@{ - NSLocalizedDescriptionKey : - @"Client does not have enough memory to " - @"hold the server response." - }]]; - return; + @synchronized (strongSelf) { + [strongSelf + finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeResourceExhausted + userInfo:@{ + NSLocalizedDescriptionKey : + @"Client does not have enough memory to " + @"hold the server response." + }]]; + [strongSelf->_wrappedCall cancel]; + } + } else { + @synchronized (strongSelf) { + [strongSelf->_responseWriteable enqueueValue:data + completionHandler:^{ + [strongSelf startNextRead]; + }]; + } } - [strongWriteable enqueueValue:data - completionHandler:^{ - [strongSelf startNextRead]; - }]; }]; }); } @@ -680,15 +689,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; } // TODO(jcanizales): Add error handlers for async failures - GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] - initWithMetadata:headers - flags:callSafetyFlags - handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA - if (!_unaryCall) { - [_wrappedCall startBatchWithOperations:@[ op ]]; - } else { - [_unaryOpBatch addObject:op]; - } + GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] initWithMetadata:headers + flags:callSafetyFlags + handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA + dispatch_async(_callQueue, ^{ + if (!self->_unaryCall) { + [self->_wrappedCall startBatchWithOperations:@[ op ]]; + } else { + [self->_unaryOpBatch addObject:op]; + } + }); } #pragma mark GRXWriteable implementation @@ -703,9 +713,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Resume the request writer. GRPCCall *strongSelf = weakSelf; if (strongSelf) { - @synchronized(strongSelf->_requestWriter) { - strongSelf->_requestWriter.state = GRXWriterStateStarted; - } + strongSelf->_requestWriter.state = GRXWriterStateStarted; } }; @@ -721,13 +729,17 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)writeValue:(id)value { - // TODO(jcanizales): Throw/assert if value isn't NSData. + NSAssert([value isKindOfClass:[NSData class]], @"value must be of type NSData"); + + @synchronized (self) { + if (_state == GRXWriterStateFinished) { + return; + } + } // Pause the input and only resume it when the C layer notifies us that writes // can proceed. - @synchronized(_requestWriter) { - _requestWriter.state = GRXWriterStatePaused; - } + _requestWriter.state = GRXWriterStatePaused; dispatch_async(_callQueue, ^{ // Write error is not processed here. It is handled by op batch of GRPC_OP_RECV_STATUS_ON_CLIENT @@ -752,6 +764,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self cancel]; } else { dispatch_async(_callQueue, ^{ + // EOS error is not processed here. It is handled by op batch of GRPC_OP_RECV_STATUS_ON_CLIENT [self finishRequestWithErrorHandler:nil]; }); @@ -766,17 +779,20 @@ const char *kCFStreamVarName = "grpc_cfstream"; // The second one (completionHandler), whenever the RPC finishes for any reason. - (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] ]]; + dispatch_async(_callQueue, ^{ + // TODO(jcanizales): Add error handlers for async failures + [self->_wrappedCall + startBatchWithOperations:@[ [[GRPCOpRecvMetadata alloc] initWithHandler:headersHandler] ]]; + [self->_wrappedCall + startBatchWithOperations:@[ [[GRPCOpRecvStatus alloc] initWithHandler:completionHandler] ]]; + }); } - (void)invokeCall { __weak GRPCCall *weakSelf = self; [self invokeCallWithHeadersHandler:^(NSDictionary *headers) { // Response headers received. + NSLog(@"response received"); __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { strongSelf.responseHeaders = headers; @@ -784,6 +800,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } completionHandler:^(NSError *error, NSDictionary *trailers) { + NSLog(@"completion received"); __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { strongSelf.responseTrailers = trailers; @@ -794,112 +811,113 @@ const char *kCFStreamVarName = "grpc_cfstream"; [userInfo addEntriesFromDictionary:error.userInfo]; } 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. - if (strongSelf.responseHeaders) { - userInfo[kGRPCHeadersKey] = strongSelf.responseHeaders; - } + // Since gRPC core does not guarantee the headers block being called before this block, + // responseHeaders might be nil. + userInfo[kGRPCHeadersKey] = strongSelf.responseHeaders; error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; } - [strongSelf maybeFinishWithError:error]; + [strongSelf finishWithError:error]; } }]; - // Now that the RPC has been initiated, request writes can start. - @synchronized(_requestWriter) { - [_requestWriter startWithWriteable:self]; - } } #pragma mark GRXWriter implementation +// Lock acquired inside startWithWriteable: - (void)startCallWithWriteable:(id)writeable { - _responseWriteable = - [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - - GRPCPooledChannel *channel = - [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; - GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:_path - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:_callOptions]; - - if (wrappedCall == nil) { - [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeUnavailable - userInfo:@{ - NSLocalizedDescriptionKey : - @"Failed to create call or channel." - }]]; - return; - } + @synchronized (self) { + if (_state == GRXWriterStateFinished) { + return; + } - @synchronized(self) { - _wrappedCall = wrappedCall; - } + _responseWriteable = + [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; + + GRPCPooledChannel *channel = + [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; + _wrappedCall = [channel wrappedCallWithPath:_path + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:_callOptions]; - [self sendHeaders]; - [self invokeCall]; + if (_wrappedCall == nil) { + [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; + return; + } - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; + [self sendHeaders]; + [self invokeCall]; + + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; + } } + + // Now that the RPC has been initiated, request writes can start. + [_requestWriter startWithWriteable:self]; } - (void)startWithWriteable:(id)writeable { + id tokenProvider = nil; @synchronized(self) { _state = GRXWriterStateStarted; - } - // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled). - // This makes RPCs in which the call isn't externally retained possible (as long as it is started - // before being autoreleased). - // Care is taken not to retain self strongly in any of the blocks used in this implementation, so - // that the life of the instance is determined by this retain cycle. - _retainSelf = self; + // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled). + // This makes RPCs in which the call isn't externally retained possible (as long as it is started + // before being autoreleased). + // Care is taken not to retain self strongly in any of the blocks used in this implementation, so + // that the life of the instance is determined by this retain cycle. + _retainSelf = self; + + if (_callOptions == nil) { + GRPCMutableCallOptions *callOptions = [[GRPCHost callOptionsForHost:_host] mutableCopy]; + if (_serverName.length != 0) { + callOptions.serverAuthority = _serverName; + } + if (_timeout > 0) { + callOptions.timeout = _timeout; + } + uint32_t callFlags = [GRPCCall callFlagsForHost:_host path:_path]; + if (callFlags != 0) { + if (callFlags == GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) { + _callSafety = GRPCCallSafetyIdempotentRequest; + } else if (callFlags == GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) { + _callSafety = GRPCCallSafetyCacheableRequest; + } + } - if (_callOptions == nil) { - GRPCMutableCallOptions *callOptions = [[GRPCHost callOptionsForHost:_host] mutableCopy]; - if (_serverName.length != 0) { - callOptions.serverAuthority = _serverName; - } - if (_timeout > 0) { - callOptions.timeout = _timeout; - } - uint32_t callFlags = [GRPCCall callFlagsForHost:_host path:_path]; - if (callFlags != 0) { - if (callFlags == GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) { - _callSafety = GRPCCallSafetyIdempotentRequest; - } else if (callFlags == GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) { - _callSafety = GRPCCallSafetyCacheableRequest; + id tokenProvider = self.tokenProvider; + if (tokenProvider != nil) { + callOptions.authTokenProvider = tokenProvider; } + _callOptions = callOptions; } - id tokenProvider = self.tokenProvider; - if (tokenProvider != nil) { - callOptions.authTokenProvider = tokenProvider; - } - _callOptions = callOptions; + NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, + @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); + + tokenProvider = _callOptions.authTokenProvider; } - NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, - @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); - if (_callOptions.authTokenProvider != nil) { - @synchronized(self) { - self.isWaitingForToken = YES; - } - [_callOptions.authTokenProvider getTokenWithHandler:^(NSString *token) { - @synchronized(self) { - if (self.isWaitingForToken) { - if (token) { - self->_fetchedOauth2AccessToken = [token copy]; + if (tokenProvider != nil) { + __weak typeof(self) weakSelf = self; + [tokenProvider getTokenWithHandler:^(NSString *token) { + __strong typeof(self) strongSelf = weakSelf; + if (strongSelf) { + @synchronized(strongSelf) { + if (strongSelf->_state == GRXWriterStateNotStarted) { + if (token) { + strongSelf->_fetchedOauth2AccessToken = [token copy]; + } } - [self startCallWithWriteable:writeable]; - self.isWaitingForToken = NO; } + [strongSelf startCallWithWriteable:writeable]; } }]; } else { @@ -938,16 +956,20 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)connectivityChanged:(NSNotification *)note { - // Cancel underlying call upon this notification + // Cancel underlying call upon this notification. + + // Retain because connectivity manager only keeps weak reference to GRPCCall. __strong GRPCCall *strongSelf = self; if (strongSelf) { - [self cancelCall]; - [self - maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeUnavailable - userInfo:@{ - NSLocalizedDescriptionKey : @"Connectivity lost." - }]]; + @synchronized (strongSelf) { + [_wrappedCall cancel]; + [strongSelf + finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : @"Connectivity lost." + }]]; + } } } diff --git a/src/objective-c/RxLibrary/GRXBufferedPipe.m b/src/objective-c/RxLibrary/GRXBufferedPipe.m index 546d46cba32..d0064a5cfaf 100644 --- a/src/objective-c/RxLibrary/GRXBufferedPipe.m +++ b/src/objective-c/RxLibrary/GRXBufferedPipe.m @@ -51,16 +51,22 @@ // We need a copy, so that it doesn't mutate before it's written at the other end of the pipe. value = [value copy]; } - __weak GRXBufferedPipe *weakSelf = self; dispatch_async(_writeQueue, ^(void) { - [weakSelf.writeable writeValue:value]; + @synchronized (self) { + if (self->_state == GRXWriterStateFinished) { + return; + } + [self.writeable writeValue:value]; + } }); } - (void)writesFinishedWithError:(NSError *)errorOrNil { - __weak GRXBufferedPipe *weakSelf = self; dispatch_async(_writeQueue, ^{ - [weakSelf finishWithError:errorOrNil]; + if (self->_state == GRXWriterStateFinished) { + return; + } + [self finishWithError:errorOrNil]; }); } @@ -100,14 +106,15 @@ } - (void)startWithWriteable:(id)writeable { - self.writeable = writeable; - _state = GRXWriterStateStarted; + @synchronized (self) { + self.writeable = writeable; + _state = GRXWriterStateStarted; + } dispatch_resume(_writeQueue); } - (void)finishWithError:(NSError *)errorOrNil { [self.writeable writesFinishedWithError:errorOrNil]; - self.state = GRXWriterStateFinished; } - (void)dealloc { diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h index abb831e6fb4..606f5dea954 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h @@ -23,9 +23,9 @@ /** * This is a thread-safe wrapper over a GRXWriteable instance. It lets one enqueue calls to a - * GRXWriteable instance for the main thread, guaranteeing that writesFinishedWithError: is the last + * GRXWriteable instance for the thread user provided, guaranteeing that writesFinishedWithError: is the last * message sent to it (no matter what messages are sent to the wrapper, in what order, nor from - * which thread). It also guarantees that, if cancelWithError: is called from the main thread (e.g. + * which thread). It also guarantees that, if cancelWithError: is called (e.g. * by the app cancelling the writes), no further messages are sent to the writeable except * writesFinishedWithError:. * diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index 81ccc3fbcea..229d592f484 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -41,6 +41,7 @@ if (self = [super init]) { _writeableQueue = queue; _writeable = writeable; + _alreadyFinished = NO; } return self; } @@ -51,78 +52,43 @@ - (void)enqueueValue:(id)value completionHandler:(void (^)(void))handler { dispatch_async(_writeableQueue, ^{ - // We're racing a possible cancellation performed by another thread. To turn all already- - // enqueued messages into noops, cancellation nillifies the writeable property. If we get it - // before it's nil, we won the race. - id writeable = self.writeable; - if (writeable) { - [writeable writeValue:value]; - handler(); + if (self->_alreadyFinished) { + return; } + + [self.writeable writeValue:value]; + handler(); }); } - (void)enqueueSuccessfulCompletion { - __weak typeof(self) weakSelf = self; dispatch_async(_writeableQueue, ^{ - typeof(self) strongSelf = weakSelf; - if (strongSelf) { - BOOL finished = NO; - @synchronized(strongSelf) { - if (!strongSelf->_alreadyFinished) { - strongSelf->_alreadyFinished = YES; - } else { - finished = YES; - } - } - if (!finished) { - // Cancellation is now impossible. None of the other three blocks can run concurrently with - // this one. - [strongSelf.writeable writesFinishedWithError:nil]; - // Skip any possible message to the wrapped writeable enqueued after this one. - strongSelf.writeable = nil; - } + if (self->_alreadyFinished) { + return; } + [self.writeable writesFinishedWithError:nil]; + // Skip any possible message to the wrapped writeable enqueued after this one. + self.writeable = nil; }); } - (void)cancelWithError:(NSError *)error { - NSAssert(error, @"For a successful completion, use enqueueSuccessfulCompletion."); - BOOL finished = NO; - @synchronized(self) { - if (!_alreadyFinished) { - _alreadyFinished = YES; - } else { - finished = YES; + NSAssert(error != nil, @"For a successful completion, use enqueueSuccessfulCompletion."); + dispatch_async(_writeableQueue, ^{ + if (self->_alreadyFinished) { + return; } - } - if (!finished) { - // Skip any of the still-enqueued messages to the wrapped writeable. We use the atomic setter to - // nillify writeable because we might be running concurrently with the blocks in - // _writeableQueue, and assignment with ARC isn't atomic. - id writeable = self.writeable; + [self.writeable writesFinishedWithError:error]; self.writeable = nil; - - dispatch_async(_writeableQueue, ^{ - [writeable writesFinishedWithError:error]; - }); - } + }); } - (void)cancelSilently { - BOOL finished = NO; - @synchronized(self) { - if (!_alreadyFinished) { - _alreadyFinished = YES; - } else { - finished = YES; + dispatch_async(_writeableQueue, ^{ + if (self->_alreadyFinished) { + return; } - } - if (!finished) { - // Skip any of the still-enqueued messages to the wrapped writeable. We use the atomic setter to - // nillify writeable because we might be running concurrently with the blocks in - // _writeableQueue, and assignment with ARC isn't atomic. self.writeable = nil; - } + }); } @end diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.m b/src/objective-c/RxLibrary/GRXForwardingWriter.m index 3e522ef24e0..376c196b4f3 100644 --- a/src/objective-c/RxLibrary/GRXForwardingWriter.m +++ b/src/objective-c/RxLibrary/GRXForwardingWriter.m @@ -54,23 +54,19 @@ [writeable writesFinishedWithError:errorOrNil]; } -// This is used to stop the input writer. It nillifies our reference to it -// to release it. -- (void)finishInput { - GRXWriter *writer = _writer; - _writer = nil; - writer.state = GRXWriterStateFinished; -} - #pragma mark GRXWriteable implementation - (void)writeValue:(id)value { - [_writeable writeValue:value]; + @synchronized (self) { + [_writeable writeValue:value]; + } } - (void)writesFinishedWithError:(NSError *)errorOrNil { - _writer = nil; - [self finishOutputWithError:errorOrNil]; + @synchronized (self) { + _writer = nil; + [self finishOutputWithError:errorOrNil]; + } } #pragma mark GRXWriter implementation @@ -80,22 +76,38 @@ } - (void)setState:(GRXWriterState)state { + GRXWriter *copiedWriter = nil; if (state == GRXWriterStateFinished) { - _writeable = nil; - [self finishInput]; + @synchronized (self) { + _writeable = nil; + copiedWriter = _writer; + _writer = nil; + } + copiedWriter.state = GRXWriterStateFinished; } else { - _writer.state = state; + @synchronized (self) { + copiedWriter = _writer; + } + copiedWriter.state = state; } } - (void)startWithWriteable:(id)writeable { - _writeable = writeable; - [_writer startWithWriteable:self]; + GRXWriter *copiedWriter = nil; + @synchronized (self) { + _writeable = writeable; + copiedWriter = _writer; + } + [copiedWriter startWithWriteable:self]; } - (void)finishWithError:(NSError *)errorOrNil { - [self finishOutputWithError:errorOrNil]; - [self finishInput]; + GRXWriter *copiedWriter = nil; + @synchronized (self) { + [self finishOutputWithError:errorOrNil]; + copiedWriter = _writer; + } + copiedWriter.state = GRXWriterStateFinished; } @end diff --git a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m index 3126ae4bd16..eadad6c3b65 100644 --- a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m +++ b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m @@ -20,7 +20,6 @@ @implementation GRXImmediateSingleWriter { id _value; - id _writeable; } @synthesize state = _state; @@ -38,17 +37,16 @@ } - (void)startWithWriteable:(id)writeable { - _state = GRXWriterStateStarted; - _writeable = writeable; - [writeable writeValue:_value]; - [self finish]; -} - -- (void)finish { - _state = GRXWriterStateFinished; - _value = nil; - id writeable = _writeable; - _writeable = nil; + id copiedValue = nil; + @synchronized (self) { + if (_state != GRXWriterStateNotStarted) { + return; + } + copiedValue = _value; + _value = nil; + _state = GRXWriterStateFinished; + } + [writeable writeValue:copiedValue]; [writeable writesFinishedWithError:nil]; } @@ -65,9 +63,11 @@ // the original \a map function returns a new Writer of another type. So we // need to override this function here. - (GRXWriter *)map:(id (^)(id))map { - // Since _value is available when creating the object, we can simply - // apply the map and store the output. - _value = map(_value); + @synchronized (self) { + // Since _value is available when creating the object, we can simply + // apply the map and store the output. + _value = map(_value); + } return self; } diff --git a/src/objective-c/RxLibrary/GRXWriter.h b/src/objective-c/RxLibrary/GRXWriter.h index 5d99583a928..ac1f7b9c4cf 100644 --- a/src/objective-c/RxLibrary/GRXWriter.h +++ b/src/objective-c/RxLibrary/GRXWriter.h @@ -80,9 +80,9 @@ typedef NS_ENUM(NSInteger, GRXWriterState) { * This property can be used to query the current state of the writer, which determines how it might * currently use its writeable. Some state transitions can be triggered by setting this property to * the corresponding value, and that's useful for advanced use cases like pausing an writer. For - * more details, see the documentation of the enum further down. + * more details, see the documentation of the enum further down. The property is thread safe. */ -@property(nonatomic) GRXWriterState state; +@property(atomic) GRXWriterState state; /** * Transition to the Started state, and start sending messages to the writeable (a reference to it From 03232ba46fba25465341b5e9632344f102f9df83 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 21 Dec 2018 16:21:18 -0800 Subject: [PATCH 448/534] Polish comments and correct concurrent writeable behavior --- src/objective-c/RxLibrary/GRXBufferedPipe.h | 3 +-- .../RxLibrary/GRXConcurrentWriteable.h | 13 +++++++------ .../RxLibrary/GRXConcurrentWriteable.m | 18 +++++++++++++----- .../RxLibrary/GRXForwardingWriter.h | 6 +----- .../RxLibrary/GRXImmediateSingleWriter.h | 2 ++ 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/objective-c/RxLibrary/GRXBufferedPipe.h b/src/objective-c/RxLibrary/GRXBufferedPipe.h index a871ea895aa..ae08cc315bb 100644 --- a/src/objective-c/RxLibrary/GRXBufferedPipe.h +++ b/src/objective-c/RxLibrary/GRXBufferedPipe.h @@ -36,8 +36,7 @@ * crash. If you want to react to flow control signals to prevent that, instead of using this class * you can implement an object that conforms to GRXWriter. * - * Thread-safety: - * The methods of an object of this class should not be called concurrently from different threads. + * Thread-safety: the methods of this class are thread-safe. */ @interface GRXBufferedPipe : GRXWriter diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h index 606f5dea954..55468b3c07a 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h @@ -43,21 +43,22 @@ - (instancetype)initWithWriteable:(id)writeable; /** - * Enqueues writeValue: to be sent to the writeable in the main thread. - * The passed handler is invoked from the main thread after writeValue: returns. + * Enqueues writeValue: to be sent to the writeable from the designated dispatch queue. + * The passed handler is invoked from designated dispatch queue after writeValue: returns. */ - (void)enqueueValue:(id)value completionHandler:(void (^)(void))handler; /** - * Enqueues writesFinishedWithError:nil to be sent to the writeable in the main thread. After that - * message is sent to the writeable, all other methods of this object are effectively noops. + * Enqueues writesFinishedWithError:nil to be sent to the writeable in the designated dispatch + * queue. After that message is sent to the writeable, all other methods of this object are + * effectively noops. */ - (void)enqueueSuccessfulCompletion; /** * If the writeable has not yet received a writesFinishedWithError: message, this will enqueue one - * to be sent to it in the main thread, and cancel all other pending messages to the writeable - * enqueued by this object (both past and future). + * to be sent to it in the designated dispatch queue, and cancel all other pending messages to the + * writeable enqueued by this object (both past and future). * The error argument cannot be nil. */ - (void)cancelWithError:(NSError *)error; diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index 229d592f484..d9d0e8c31e4 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -63,8 +63,10 @@ - (void)enqueueSuccessfulCompletion { dispatch_async(_writeableQueue, ^{ - if (self->_alreadyFinished) { - return; + @synchronized (self) { + if (self->_alreadyFinished) { + return; + } } [self.writeable writesFinishedWithError:nil]; // Skip any possible message to the wrapped writeable enqueued after this one. @@ -74,10 +76,14 @@ - (void)cancelWithError:(NSError *)error { NSAssert(error != nil, @"For a successful completion, use enqueueSuccessfulCompletion."); - dispatch_async(_writeableQueue, ^{ + @synchronized (self) { if (self->_alreadyFinished) { return; } + } + dispatch_async(_writeableQueue, ^{ + // If enqueueSuccessfulCompletion is already issued, self.writeable is nil and the following + // line is no-op. [self.writeable writesFinishedWithError:error]; self.writeable = nil; }); @@ -85,8 +91,10 @@ - (void)cancelSilently { dispatch_async(_writeableQueue, ^{ - if (self->_alreadyFinished) { - return; + @synchronized (self) { + if (self->_alreadyFinished) { + return; + } } self.writeable = nil; }); diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.h b/src/objective-c/RxLibrary/GRXForwardingWriter.h index 3814ff8831c..00366b64162 100644 --- a/src/objective-c/RxLibrary/GRXForwardingWriter.h +++ b/src/objective-c/RxLibrary/GRXForwardingWriter.h @@ -25,11 +25,7 @@ * input writer, and for classes that represent objects with input and * output sequences of values, like an RPC. * - * Thread-safety: - * All messages sent to this object need to be serialized. When it is started, the writer it wraps - * is started in the same thread. Manual state changes are propagated to the wrapped writer in the - * same thread too. Importantly, all messages the wrapped writer sends to its writeable need to be - * serialized with any message sent to this object. + * Thread-safety: the methods of this class are thread safe. */ @interface GRXForwardingWriter : GRXWriter - (instancetype)initWithWriter:(GRXWriter *)writer NS_DESIGNATED_INITIALIZER; diff --git a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h index 601abdc6b90..2fa38b3dcea 100644 --- a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h +++ b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h @@ -23,6 +23,8 @@ /** * Utility to construct GRXWriter instances from values that are immediately available when * required. + * + * Thread safety: the methods of this class are thread safe. */ @interface GRXImmediateSingleWriter : GRXImmediateWriter From 3cdc0db838626ab1d186a4980125bc3e6219c0e0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 2 Jan 2019 15:59:19 -0800 Subject: [PATCH 449/534] clang-format --- src/objective-c/GRPCClient/GRPCCall.m | 77 ++++++++++--------- src/objective-c/RxLibrary/GRXBufferedPipe.m | 4 +- .../RxLibrary/GRXConcurrentWriteable.h | 8 +- .../RxLibrary/GRXConcurrentWriteable.m | 6 +- .../RxLibrary/GRXForwardingWriter.m | 12 +-- .../RxLibrary/GRXImmediateSingleWriter.m | 4 +- 6 files changed, 56 insertions(+), 55 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 5ea1755c589..c18dfae6351 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -448,7 +448,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; return; } NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; - @synchronized (callFlags) { + @synchronized(callFlags) { switch (callSafety) { case GRPCCallSafetyDefault: callFlags[hostAndPath] = @0; @@ -468,7 +468,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; + (uint32_t)callFlagsForHost:(NSString *)host path:(NSString *)path { NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; uint32_t flags = 0; - @synchronized (callFlags) { + @synchronized(callFlags) { flags = [callFlags[hostAndPath] intValue]; } return flags; @@ -529,7 +529,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)setResponseDispatchQueue:(dispatch_queue_t)queue { - @synchronized (self) { + @synchronized(self) { if (_state != GRXWriterStateNotStarted) { return; } @@ -562,14 +562,14 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)cancel { - @synchronized (self) { + @synchronized(self) { if (_state == GRXWriterStateFinished) { return; } [self finishWithError:[NSError - errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]]; + errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]]; [_wrappedCall cancel]; } } @@ -636,19 +636,19 @@ const char *kCFStreamVarName = "grpc_cfstream"; // 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. - @synchronized (strongSelf) { + @synchronized(strongSelf) { [strongSelf - finishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeResourceExhausted - userInfo:@{ - NSLocalizedDescriptionKey : - @"Client does not have enough memory to " - @"hold the server response." - }]]; + finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeResourceExhausted + userInfo:@{ + NSLocalizedDescriptionKey : + @"Client does not have enough memory to " + @"hold the server response." + }]]; [strongSelf->_wrappedCall cancel]; } } else { - @synchronized (strongSelf) { + @synchronized(strongSelf) { [strongSelf->_responseWriteable enqueueValue:data completionHandler:^{ [strongSelf startNextRead]; @@ -689,9 +689,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; } // TODO(jcanizales): Add error handlers for async failures - GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] initWithMetadata:headers - flags:callSafetyFlags - handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA + GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] + initWithMetadata:headers + flags:callSafetyFlags + handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA dispatch_async(_callQueue, ^{ if (!self->_unaryCall) { [self->_wrappedCall startBatchWithOperations:@[ op ]]; @@ -731,7 +732,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeValue:(id)value { NSAssert([value isKindOfClass:[NSData class]], @"value must be of type NSData"); - @synchronized (self) { + @synchronized(self) { if (_state == GRXWriterStateFinished) { return; } @@ -782,9 +783,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_async(_callQueue, ^{ // TODO(jcanizales): Add error handlers for async failures [self->_wrappedCall - startBatchWithOperations:@[ [[GRPCOpRecvMetadata alloc] initWithHandler:headersHandler] ]]; + startBatchWithOperations:@[ [[GRPCOpRecvMetadata alloc] initWithHandler:headersHandler] ]]; [self->_wrappedCall - startBatchWithOperations:@[ [[GRPCOpRecvStatus alloc] initWithHandler:completionHandler] ]]; + startBatchWithOperations:@[ [[GRPCOpRecvStatus alloc] initWithHandler:completionHandler] ]]; }); } @@ -825,16 +826,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Lock acquired inside startWithWriteable: - (void)startCallWithWriteable:(id)writeable { - @synchronized (self) { + @synchronized(self) { if (_state == GRXWriterStateFinished) { return; } _responseWriteable = - [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; + [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; GRPCPooledChannel *channel = - [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; + [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; _wrappedCall = [channel wrappedCallWithPath:_path completionQueue:[GRPCCompletionQueue completionQueue] callOptions:_callOptions]; @@ -843,9 +844,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{ - NSLocalizedDescriptionKey : - @"Failed to create call or channel." - }]]; + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; return; } @@ -869,10 +870,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; _state = GRXWriterStateStarted; // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled). - // This makes RPCs in which the call isn't externally retained possible (as long as it is started - // before being autoreleased). - // Care is taken not to retain self strongly in any of the blocks used in this implementation, so - // that the life of the instance is determined by this retain cycle. + // This makes RPCs in which the call isn't externally retained possible (as long as it is + // started before being autoreleased). Care is taken not to retain self strongly in any of the + // blocks used in this implementation, so that the life of the instance is determined by this + // retain cycle. _retainSelf = self; if (_callOptions == nil) { @@ -961,14 +962,14 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Retain because connectivity manager only keeps weak reference to GRPCCall. __strong GRPCCall *strongSelf = self; if (strongSelf) { - @synchronized (strongSelf) { + @synchronized(strongSelf) { [_wrappedCall cancel]; [strongSelf - finishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeUnavailable - userInfo:@{ - NSLocalizedDescriptionKey : @"Connectivity lost." - }]]; + finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : @"Connectivity lost." + }]]; } } } diff --git a/src/objective-c/RxLibrary/GRXBufferedPipe.m b/src/objective-c/RxLibrary/GRXBufferedPipe.m index d0064a5cfaf..74e2f03da6c 100644 --- a/src/objective-c/RxLibrary/GRXBufferedPipe.m +++ b/src/objective-c/RxLibrary/GRXBufferedPipe.m @@ -52,7 +52,7 @@ value = [value copy]; } dispatch_async(_writeQueue, ^(void) { - @synchronized (self) { + @synchronized(self) { if (self->_state == GRXWriterStateFinished) { return; } @@ -106,7 +106,7 @@ } - (void)startWithWriteable:(id)writeable { - @synchronized (self) { + @synchronized(self) { self.writeable = writeable; _state = GRXWriterStateStarted; } diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h index 55468b3c07a..5beca9d41e3 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h @@ -23,10 +23,10 @@ /** * This is a thread-safe wrapper over a GRXWriteable instance. It lets one enqueue calls to a - * GRXWriteable instance for the thread user provided, guaranteeing that writesFinishedWithError: is the last - * message sent to it (no matter what messages are sent to the wrapper, in what order, nor from - * which thread). It also guarantees that, if cancelWithError: is called (e.g. - * by the app cancelling the writes), no further messages are sent to the writeable except + * GRXWriteable instance for the thread user provided, guaranteeing that writesFinishedWithError: is + * the last message sent to it (no matter what messages are sent to the wrapper, in what order, nor + * from which thread). It also guarantees that, if cancelWithError: is called (e.g. by the app + * cancelling the writes), no further messages are sent to the writeable except * writesFinishedWithError:. * * TODO(jcanizales): Let the user specify another queue for the writeable callbacks. diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index d9d0e8c31e4..e50cdf240d1 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -63,7 +63,7 @@ - (void)enqueueSuccessfulCompletion { dispatch_async(_writeableQueue, ^{ - @synchronized (self) { + @synchronized(self) { if (self->_alreadyFinished) { return; } @@ -76,7 +76,7 @@ - (void)cancelWithError:(NSError *)error { NSAssert(error != nil, @"For a successful completion, use enqueueSuccessfulCompletion."); - @synchronized (self) { + @synchronized(self) { if (self->_alreadyFinished) { return; } @@ -91,7 +91,7 @@ - (void)cancelSilently { dispatch_async(_writeableQueue, ^{ - @synchronized (self) { + @synchronized(self) { if (self->_alreadyFinished) { return; } diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.m b/src/objective-c/RxLibrary/GRXForwardingWriter.m index 376c196b4f3..f5ed603698d 100644 --- a/src/objective-c/RxLibrary/GRXForwardingWriter.m +++ b/src/objective-c/RxLibrary/GRXForwardingWriter.m @@ -57,13 +57,13 @@ #pragma mark GRXWriteable implementation - (void)writeValue:(id)value { - @synchronized (self) { + @synchronized(self) { [_writeable writeValue:value]; } } - (void)writesFinishedWithError:(NSError *)errorOrNil { - @synchronized (self) { + @synchronized(self) { _writer = nil; [self finishOutputWithError:errorOrNil]; } @@ -78,14 +78,14 @@ - (void)setState:(GRXWriterState)state { GRXWriter *copiedWriter = nil; if (state == GRXWriterStateFinished) { - @synchronized (self) { + @synchronized(self) { _writeable = nil; copiedWriter = _writer; _writer = nil; } copiedWriter.state = GRXWriterStateFinished; } else { - @synchronized (self) { + @synchronized(self) { copiedWriter = _writer; } copiedWriter.state = state; @@ -94,7 +94,7 @@ - (void)startWithWriteable:(id)writeable { GRXWriter *copiedWriter = nil; - @synchronized (self) { + @synchronized(self) { _writeable = writeable; copiedWriter = _writer; } @@ -103,7 +103,7 @@ - (void)finishWithError:(NSError *)errorOrNil { GRXWriter *copiedWriter = nil; - @synchronized (self) { + @synchronized(self) { [self finishOutputWithError:errorOrNil]; copiedWriter = _writer; } diff --git a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m index eadad6c3b65..079c11b94fb 100644 --- a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m +++ b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m @@ -38,7 +38,7 @@ - (void)startWithWriteable:(id)writeable { id copiedValue = nil; - @synchronized (self) { + @synchronized(self) { if (_state != GRXWriterStateNotStarted) { return; } @@ -63,7 +63,7 @@ // the original \a map function returns a new Writer of another type. So we // need to override this function here. - (GRXWriter *)map:(id (^)(id))map { - @synchronized (self) { + @synchronized(self) { // Since _value is available when creating the object, we can simply // apply the map and store the output. _value = map(_value); From 34d77aae5ec26063e2eb5dc4b47ba4dce90c7136 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 7 Jan 2019 14:12:03 -0800 Subject: [PATCH 450/534] Always nullify serializer to free memory --- include/grpcpp/impl/codegen/call_op_set.h | 2 +- include/grpcpp/impl/codegen/interceptor_common.h | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 2c34082ebb1..880c62344b8 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -324,8 +324,8 @@ class CallOpSendMessage { } if (msg_ != nullptr) { GPR_CODEGEN_ASSERT(serializer_(msg_).ok()); - serializer_ = nullptr; } + serializer_ = nullptr; grpc_op* op = &ops[(*nops)++]; op->op = GRPC_OP_SEND_MESSAGE; op->flags = write_options_.flags(); diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 33e46389b3d..09721343ffa 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -98,9 +98,7 @@ class InterceptorBatchMethodsImpl *orig_send_message_ = message; } - bool GetSendMessageStatus() override { - return !*fail_send_message_; - } + bool GetSendMessageStatus() override { return !*fail_send_message_; } std::multimap* GetSendInitialMetadata() override { return send_initial_metadata_; From d7650a841b8acac747b5a8d12502a46ec0e4a54c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 7 Jan 2019 16:51:08 -0800 Subject: [PATCH 451/534] Bug fix for GRXConcurrentWriter --- .../RxLibrary/GRXConcurrentWriteable.m | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index e50cdf240d1..7cc2101a55f 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -27,8 +27,15 @@ @implementation GRXConcurrentWriteable { dispatch_queue_t _writeableQueue; - // This ensures that writesFinishedWithError: is only sent once to the writeable. + + // This ivar ensures that writesFinishedWithError: is only sent once to the writeable. Protected + // by _writeableQueue. BOOL _alreadyFinished; + + // This ivar ensures that a cancelWithError: call prevents further values to be sent to + // self.writeable. It must support manipulation outside of _writeableQueue and thus needs to be + // protected by self lock. + BOOL _cancelled; } - (instancetype)init { @@ -42,6 +49,7 @@ _writeableQueue = queue; _writeable = writeable; _alreadyFinished = NO; + _cancelled = NO; } return self; } @@ -56,6 +64,12 @@ return; } + @synchronized (self) { + if (self->_cancelled) { + return; + } + } + [self.writeable writeValue:value]; handler(); }); @@ -63,13 +77,18 @@ - (void)enqueueSuccessfulCompletion { dispatch_async(_writeableQueue, ^{ - @synchronized(self) { - if (self->_alreadyFinished) { + if (self->_alreadyFinished) { + return; + } + @synchronized (self) { + if (self->_cancelled) { return; } } [self.writeable writesFinishedWithError:nil]; + // Skip any possible message to the wrapped writeable enqueued after this one. + self->_alreadyFinished = YES; self.writeable = nil; }); } @@ -77,14 +96,17 @@ - (void)cancelWithError:(NSError *)error { NSAssert(error != nil, @"For a successful completion, use enqueueSuccessfulCompletion."); @synchronized(self) { + self->_cancelled = YES; + } + dispatch_async(_writeableQueue, ^{ if (self->_alreadyFinished) { + // a cancel or a successful completion is already issued return; } - } - dispatch_async(_writeableQueue, ^{ - // If enqueueSuccessfulCompletion is already issued, self.writeable is nil and the following - // line is no-op. [self.writeable writesFinishedWithError:error]; + + // Skip any possible message to the wrapped writeable enqueued after this one. + self->_alreadyFinished = YES; self.writeable = nil; }); } From cf303c3ee7d4b4364650ca6fdecbaafdca117497 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 7 Jan 2019 16:51:23 -0800 Subject: [PATCH 452/534] Deadlock fix for GRPCCall --- src/objective-c/GRPCClient/GRPCCall.m | 47 ++++++++++----------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index c18dfae6351..714c7dbbc26 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -539,26 +539,24 @@ const char *kCFStreamVarName = "grpc_cfstream"; #pragma mark Finish +// This function should support being called within a @synchronized(self) block in another function +// Should not manipulate _requestWriter for deadlock prevention. - (void)finishWithError:(NSError *)errorOrNil { - GRXConcurrentWriteable *copiedResponseWriteable = nil; - @synchronized(self) { if (_state == GRXWriterStateFinished) { return; } _state = GRXWriterStateFinished; - copiedResponseWriteable = _responseWriteable; + + if (errorOrNil) { + [_responseWriteable cancelWithError:errorOrNil]; + } else { + [_responseWriteable enqueueSuccessfulCompletion]; + } // If the call isn't retained anywhere else, it can be deallocated now. _retainSelf = nil; } - - if (errorOrNil) { - [copiedResponseWriteable cancelWithError:errorOrNil]; - } else { - [copiedResponseWriteable enqueueSuccessfulCompletion]; - } - _requestWriter.state = GRXWriterStateFinished; } - (void)cancel { @@ -572,19 +570,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]]; [_wrappedCall cancel]; } -} - -- (void)maybeFinishWithError:(NSError *)errorOrNil { - BOOL toFinish = NO; - @synchronized(self) { - if (_finished == NO) { - _finished = YES; - toFinish = YES; - } - } - if (toFinish == YES) { - [self finishWithError:errorOrNil]; - } + _requestWriter.state = GRXWriterStateFinished; } - (void)dealloc { @@ -647,6 +633,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; }]]; [strongSelf->_wrappedCall cancel]; } + strongSelf->_requestWriter.state = GRXWriterStateFinished; } else { @synchronized(strongSelf) { [strongSelf->_responseWriteable enqueueValue:data @@ -818,6 +805,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; } [strongSelf finishWithError:error]; + strongSelf->_requestWriter.state = GRXWriterStateFinished; } }]; } @@ -841,12 +829,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; callOptions:_callOptions]; if (_wrappedCall == nil) { - [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeUnavailable - userInfo:@{ - NSLocalizedDescriptionKey : - @"Failed to create call or channel." - }]]; + [self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; return; } @@ -971,6 +959,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; NSLocalizedDescriptionKey : @"Connectivity lost." }]]; } + strongSelf->_requestWriter.state = GRXWriterStateFinished; } } From 8b55c6a8714e7c4422adc8e7e105588397b707ba Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 7 Jan 2019 16:54:37 -0800 Subject: [PATCH 453/534] clang-format --- src/objective-c/GRPCClient/GRPCCall.m | 6 +++--- src/objective-c/RxLibrary/GRXConcurrentWriteable.m | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 714c7dbbc26..20703f548e4 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -832,9 +832,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{ - NSLocalizedDescriptionKey : - @"Failed to create call or channel." - }]]; + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; return; } diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index 7cc2101a55f..d8491d2aed5 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -64,10 +64,10 @@ return; } - @synchronized (self) { - if (self->_cancelled) { - return; - } + @synchronized(self) { + if (self->_cancelled) { + return; + } } [self.writeable writeValue:value]; @@ -80,7 +80,7 @@ if (self->_alreadyFinished) { return; } - @synchronized (self) { + @synchronized(self) { if (self->_cancelled) { return; } From b35b449166e1c18c180701725b8ba97ab98994e0 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 7 Jan 2019 17:17:01 -0800 Subject: [PATCH 454/534] Update docs according to #17630 --- include/grpcpp/impl/codegen/call_op_set.h | 3 ++- include/grpcpp/impl/codegen/interceptor.h | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 880c62344b8..c0de5ed6025 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -400,8 +400,9 @@ Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { }; // Serialize immediately only if we do not have access to the message pointer if (msg_ == nullptr) { - return serializer_(&message); + Status result = serializer_(&message); serializer_ = nullptr; + return result; } return Status(); } diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index d749d8578ae..5dea796a3b7 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -112,12 +112,17 @@ class InterceptorBatchMethods { /// A return value of nullptr indicates that this ByteBuffer is not valid. virtual ByteBuffer* GetSerializedSendMessage() = 0; - /// Returns a non-modifiable pointer to the original non-serialized form of - /// the message. Valid for PRE_SEND_MESSAGE interceptions. A return value of + /// Returns a non-modifiable pointer to the non-serialized form of the message + /// to be sent. Valid for PRE_SEND_MESSAGE interceptions. A return value of /// nullptr indicates that this field is not valid. Also note that this is /// only supported for sync and callback APIs at the present moment. virtual const void* GetSendMessage() = 0; + /// Overwrites the message to be sent with \a message. \a message should be in + /// the non-serialized form expected by the method. Valid for PRE_SEND_MESSAGE + /// interceptions. Note that the interceptor is responsible for maintaining + /// the life of the message for the duration on the send operation, i.e., till + /// POST_SEND_MESSAGE. virtual void ModifySendMessage(const void* message) = 0; /// Checks whether the SEND MESSAGE op succeeded. Valid for POST_SEND_MESSAGE From 361acdbed1805dd9f313deb4bc92dbd5e8612a7b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 7 Jan 2019 17:33:16 -0800 Subject: [PATCH 455/534] Use the WriteOptions in Client Callback API --- include/grpcpp/impl/codegen/client_callback.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index c20e8458106..52bcea99706 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -340,13 +340,13 @@ class ClientCallbackReaderWriterImpl context_->initial_metadata_flags()); start_corked_ = false; } - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg).ok()); if (options.is_last_message()) { options.set_buffer_hint(); write_ops_.ClientSendClose(); } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); callbacks_outstanding_++; if (started_) { call_.PerformOps(&write_ops_); @@ -649,13 +649,13 @@ class ClientCallbackWriterImpl context_->initial_metadata_flags()); start_corked_ = false; } - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg).ok()); if (options.is_last_message()) { options.set_buffer_hint(); write_ops_.ClientSendClose(); } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); callbacks_outstanding_++; if (started_) { call_.PerformOps(&write_ops_); From 832e5f06c305b88d3ac662fd19f2c1985e664403 Mon Sep 17 00:00:00 2001 From: Christopher Warrington Date: Mon, 7 Jan 2019 17:30:46 -0800 Subject: [PATCH 456/534] Fix typos in comments --- include/grpc/impl/codegen/grpc_types.h | 2 +- src/ruby/ext/grpc/rb_channel.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 610548b5f36..5d577eb8557 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -163,7 +163,7 @@ typedef struct { /** Maximum time that a channel may exist. Int valued, milliseconds. * INT_MAX means unlimited. */ #define GRPC_ARG_MAX_CONNECTION_AGE_MS "grpc.max_connection_age_ms" -/** Grace period after the chennel reaches its max age. Int valued, +/** Grace period after the channel reaches its max age. Int valued, milliseconds. INT_MAX means unlimited. */ #define GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS "grpc.max_connection_age_grace_ms" /** Enable/disable support for per-message compression. Defaults to 1, unless diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index 6d4b2293a24..2e570b8e87c 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -153,7 +153,7 @@ static void grpc_rb_channel_free(void* p) { if (ch->bg_wrapped != NULL) { /* assumption made here: it's ok to directly gpr_mu_lock the global - * connection polling mutex becuse we're in a finalizer, + * connection polling mutex because we're in a finalizer, * and we can count on this thread to not be interrupted or * yield the gil. */ grpc_rb_channel_safe_destroy(ch->bg_wrapped); @@ -292,7 +292,7 @@ static void* get_state_without_gil(void* arg) { Indicates the current state of the channel, whose value is one of the constants defined in GRPC::Core::ConnectivityStates. - It also tries to connect if the chennel is idle in the second form. */ + It also tries to connect if the channel is idle in the second form. */ static VALUE grpc_rb_channel_get_connectivity_state(int argc, VALUE* argv, VALUE self) { VALUE try_to_connect_param = Qfalse; @@ -327,7 +327,7 @@ static void* wait_for_watch_state_op_complete_without_gvl(void* arg) { void* success = (void*)0; gpr_mu_lock(&global_connection_polling_mu); - // its unsafe to do a "watch" after "channel polling abort" because the cq has + // it's unsafe to do a "watch" after "channel polling abort" because the cq has // been shut down. if (abort_channel_polling || stack->bg_wrapped->channel_destroyed) { gpr_mu_unlock(&global_connection_polling_mu); From 11eff929e24cae59ed21c2f3a0bde22a6dbe0d91 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 7 Jan 2019 18:22:50 -0800 Subject: [PATCH 457/534] Avoid the thread jump in server callback APIs. Add a utility function in iomgr to check whether the caller thread is a worker for any background poller, and keep grpc combiner from offloading closures to the default executor if the current thread is a worker for any background poller. --- src/core/lib/iomgr/combiner.cc | 9 ++++++++- src/core/lib/iomgr/ev_epoll1_linux.cc | 3 +++ src/core/lib/iomgr/ev_epollex_linux.cc | 3 +++ src/core/lib/iomgr/ev_poll_posix.cc | 3 +++ src/core/lib/iomgr/ev_posix.cc | 4 ++++ src/core/lib/iomgr/ev_posix.h | 4 ++++ src/core/lib/iomgr/iomgr.cc | 4 ++++ src/core/lib/iomgr/iomgr.h | 3 +++ src/core/lib/iomgr/iomgr_custom.cc | 6 +++++- src/core/lib/iomgr/iomgr_internal.cc | 4 ++++ src/core/lib/iomgr/iomgr_internal.h | 4 ++++ src/core/lib/iomgr/iomgr_posix.cc | 7 ++++++- src/core/lib/iomgr/iomgr_posix_cfstream.cc | 7 ++++++- src/core/lib/iomgr/iomgr_windows.cc | 7 ++++++- test/cpp/microbenchmarks/bm_cq_multiple_threads.cc | 1 + 15 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/combiner.cc b/src/core/lib/iomgr/combiner.cc index 7c0062eb4ec..402f8904eae 100644 --- a/src/core/lib/iomgr/combiner.cc +++ b/src/core/lib/iomgr/combiner.cc @@ -29,6 +29,7 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/profiling/timers.h" grpc_core::DebugOnlyTraceFlag grpc_combiner_trace(false, "combiner"); @@ -228,8 +229,14 @@ bool grpc_combiner_continue_exec_ctx() { grpc_core::ExecCtx::Get()->IsReadyToFinish(), lock->time_to_execute_final_list)); + // offload only if all the following conditions are true: + // 1. the combiner is contended and has more than one closure to execute + // 2. the current execution context needs to finish as soon as possible + // 3. the DEFAULT executor is threaded + // 4. the current thread is not a worker for any background poller if (contended && grpc_core::ExecCtx::Get()->IsReadyToFinish() && - grpc_executor_is_threaded()) { + grpc_executor_is_threaded() && + !grpc_iomgr_is_any_background_poller_thread()) { GPR_TIMER_MARK("offload_from_finished_exec_ctx", 0); // this execution context wants to move on: schedule remaining work to be // picked up on the executor diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index 4b8c891e9b0..9eb4c089d86 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -1242,6 +1242,8 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag, * Event engine binding */ +static bool is_any_background_poller_thread(void) { return false; } + static void shutdown_background_closure(void) {} static void shutdown_engine(void) { @@ -1287,6 +1289,7 @@ static const grpc_event_engine_vtable vtable = { pollset_set_add_fd, pollset_set_del_fd, + is_any_background_poller_thread, shutdown_background_closure, shutdown_engine, }; diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index 7a4870db785..0a0891013af 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -1604,6 +1604,8 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag, * Event engine binding */ +static bool is_any_background_poller_thread(void) { return false; } + static void shutdown_background_closure(void) {} static void shutdown_engine(void) { @@ -1644,6 +1646,7 @@ static const grpc_event_engine_vtable vtable = { pollset_set_add_fd, pollset_set_del_fd, + is_any_background_poller_thread, shutdown_background_closure, shutdown_engine, }; diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index 67cbfbbd021..c479206410b 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -1782,6 +1782,8 @@ static void global_cv_fd_table_shutdown() { * event engine binding */ +static bool is_any_background_poller_thread(void) { return false; } + static void shutdown_background_closure(void) {} static void shutdown_engine(void) { @@ -1828,6 +1830,7 @@ static const grpc_event_engine_vtable vtable = { pollset_set_add_fd, pollset_set_del_fd, + is_any_background_poller_thread, shutdown_background_closure, shutdown_engine, }; diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 32d1b6c43ef..fb2e70eee49 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -399,6 +399,10 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) { g_event_engine->pollset_set_del_fd(pollset_set, fd); } +bool grpc_is_any_background_poller_thread(void) { + return g_event_engine->is_any_background_poller_thread(); +} + void grpc_shutdown_background_closure(void) { g_event_engine->shutdown_background_closure(); } diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h index 812c7a0f0f8..94ac9fdba6f 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -80,6 +80,7 @@ typedef struct grpc_event_engine_vtable { void (*pollset_set_add_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd); void (*pollset_set_del_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd); + bool (*is_any_background_poller_thread)(void); void (*shutdown_background_closure)(void); void (*shutdown_engine)(void); } grpc_event_engine_vtable; @@ -181,6 +182,9 @@ void grpc_pollset_add_fd(grpc_pollset* pollset, struct grpc_fd* fd); void grpc_pollset_set_add_fd(grpc_pollset_set* pollset_set, grpc_fd* fd); void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd); +/* Returns true if the caller is a worker thread for any background poller. */ +bool grpc_is_any_background_poller_thread(); + /* Shut down all the closures registered in the background poller. */ void grpc_shutdown_background_closure(); diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index eb29973514f..a4921468578 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -161,6 +161,10 @@ void grpc_iomgr_shutdown_background_closure() { grpc_iomgr_platform_shutdown_background_closure(); } +bool grpc_iomgr_is_any_background_poller_thread() { + return grpc_iomgr_platform_is_any_background_poller_thread(); +} + void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name) { obj->name = gpr_strdup(name); gpr_mu_lock(&g_mu); diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h index 8ea9289e068..6261aa550c3 100644 --- a/src/core/lib/iomgr/iomgr.h +++ b/src/core/lib/iomgr/iomgr.h @@ -39,6 +39,9 @@ void grpc_iomgr_shutdown(); * background poller. */ void grpc_iomgr_shutdown_background_closure(); +/** Returns true if the caller is a worker thread for any background poller. */ +bool grpc_iomgr_is_any_background_poller_thread(); + /* Exposed only for testing */ size_t grpc_iomgr_count_objects_for_testing(); diff --git a/src/core/lib/iomgr/iomgr_custom.cc b/src/core/lib/iomgr/iomgr_custom.cc index 4b112c9097f..e1cd8f73104 100644 --- a/src/core/lib/iomgr/iomgr_custom.cc +++ b/src/core/lib/iomgr/iomgr_custom.cc @@ -41,10 +41,14 @@ static void iomgr_platform_init(void) { static void iomgr_platform_flush(void) {} static void iomgr_platform_shutdown(void) { grpc_pollset_global_shutdown(); } static void iomgr_platform_shutdown_background_closure(void) {} +static bool iomgr_platform_is_any_background_poller_thread(void) { + return false; +} static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, - iomgr_platform_shutdown_background_closure}; + iomgr_platform_shutdown_background_closure, + iomgr_platform_is_any_background_poller_thread}; void grpc_custom_iomgr_init(grpc_socket_vtable* socket, grpc_custom_resolver_vtable* resolver, diff --git a/src/core/lib/iomgr/iomgr_internal.cc b/src/core/lib/iomgr/iomgr_internal.cc index b6c9211865d..e68b1cf5812 100644 --- a/src/core/lib/iomgr/iomgr_internal.cc +++ b/src/core/lib/iomgr/iomgr_internal.cc @@ -45,3 +45,7 @@ void grpc_iomgr_platform_shutdown() { iomgr_platform_vtable->shutdown(); } void grpc_iomgr_platform_shutdown_background_closure() { iomgr_platform_vtable->shutdown_background_closure(); } + +bool grpc_iomgr_platform_is_any_background_poller_thread() { + return iomgr_platform_vtable->is_any_background_poller_thread(); +} diff --git a/src/core/lib/iomgr/iomgr_internal.h b/src/core/lib/iomgr/iomgr_internal.h index bca7409907f..2250ad9a18c 100644 --- a/src/core/lib/iomgr/iomgr_internal.h +++ b/src/core/lib/iomgr/iomgr_internal.h @@ -36,6 +36,7 @@ typedef struct grpc_iomgr_platform_vtable { void (*flush)(void); void (*shutdown)(void); void (*shutdown_background_closure)(void); + bool (*is_any_background_poller_thread)(void); } grpc_iomgr_platform_vtable; void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name); @@ -56,6 +57,9 @@ void grpc_iomgr_platform_shutdown(void); /** shut down all the closures registered in the background poller */ void grpc_iomgr_platform_shutdown_background_closure(void); +/** return true is the caller is a worker thread for any background poller */ +bool grpc_iomgr_platform_is_any_background_poller_thread(void); + bool grpc_iomgr_abort_on_leaks(void); #endif /* GRPC_CORE_LIB_IOMGR_IOMGR_INTERNAL_H */ diff --git a/src/core/lib/iomgr/iomgr_posix.cc b/src/core/lib/iomgr/iomgr_posix.cc index 9386adf060d..278c8de6886 100644 --- a/src/core/lib/iomgr/iomgr_posix.cc +++ b/src/core/lib/iomgr/iomgr_posix.cc @@ -55,9 +55,14 @@ static void iomgr_platform_shutdown_background_closure(void) { grpc_shutdown_background_closure(); } +static bool iomgr_platform_is_any_background_poller_thread(void) { + return grpc_is_any_background_poller_thread(); +} + static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, - iomgr_platform_shutdown_background_closure}; + iomgr_platform_shutdown_background_closure, + iomgr_platform_is_any_background_poller_thread}; void grpc_set_default_iomgr_platform() { grpc_set_tcp_client_impl(&grpc_posix_tcp_client_vtable); diff --git a/src/core/lib/iomgr/iomgr_posix_cfstream.cc b/src/core/lib/iomgr/iomgr_posix_cfstream.cc index 552ef4309c8..462ac41fcde 100644 --- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc +++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc @@ -58,9 +58,14 @@ static void iomgr_platform_shutdown_background_closure(void) { grpc_shutdown_background_closure(); } +static bool iomgr_platform_is_any_background_poller_thread(void) { + return grpc_is_any_background_poller_thread(); +} + static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, - iomgr_platform_shutdown_background_closure}; + iomgr_platform_shutdown_background_closure, + iomgr_platform_is_any_background_poller_thread}; void grpc_set_default_iomgr_platform() { char* enable_cfstream = getenv(grpc_cfstream_env_var); diff --git a/src/core/lib/iomgr/iomgr_windows.cc b/src/core/lib/iomgr/iomgr_windows.cc index 24ef0dba7b4..0579e16aa76 100644 --- a/src/core/lib/iomgr/iomgr_windows.cc +++ b/src/core/lib/iomgr/iomgr_windows.cc @@ -73,9 +73,14 @@ static void iomgr_platform_shutdown(void) { static void iomgr_platform_shutdown_background_closure(void) {} +static bool iomgr_platform_is_any_background_poller_thread(void) { + return false; +} + static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, - iomgr_platform_shutdown_background_closure}; + iomgr_platform_shutdown_background_closure, + iomgr_platform_is_any_background_poller_thread}; void grpc_set_default_iomgr_platform() { grpc_set_tcp_client_impl(&grpc_windows_tcp_client_vtable); diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc index dca97c85b19..7aa197b5979 100644 --- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc +++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc @@ -94,6 +94,7 @@ static const grpc_event_engine_vtable* init_engine_vtable(bool) { g_vtable.pollset_destroy = pollset_destroy; g_vtable.pollset_work = pollset_work; g_vtable.pollset_kick = pollset_kick; + g_vtable.is_any_background_poller_thread = [] { return false; }; g_vtable.shutdown_background_closure = [] {}; g_vtable.shutdown_engine = [] {}; From 5a6c984d3ab6084a092173a6c19eb52c5aae8414 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 8 Jan 2019 16:06:38 +0100 Subject: [PATCH 458/534] clang format code --- src/ruby/ext/grpc/rb_channel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index 2e570b8e87c..5bde962f788 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -327,8 +327,8 @@ static void* wait_for_watch_state_op_complete_without_gvl(void* arg) { void* success = (void*)0; gpr_mu_lock(&global_connection_polling_mu); - // it's unsafe to do a "watch" after "channel polling abort" because the cq has - // been shut down. + // it's unsafe to do a "watch" after "channel polling abort" because the cq + // has been shut down. if (abort_channel_polling || stack->bg_wrapped->channel_destroyed) { gpr_mu_unlock(&global_connection_polling_mu); return (void*)0; From da4ab59b0d2e136ec82038cf5f0e3f2ec8fb19f5 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 8 Jan 2019 11:44:33 -0800 Subject: [PATCH 459/534] Remove state_watcher from subchannel --- src/core/ext/filters/client_channel/subchannel.cc | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 3abacf68aeb..dff213efc6b 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -64,18 +64,6 @@ #define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120 #define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2 -namespace { -struct state_watcher { - grpc_closure closure; - grpc_subchannel* subchannel; - grpc_connectivity_state connectivity_state; - grpc_connectivity_state last_connectivity_state; - grpc_core::OrphanablePtr health_check_client; - grpc_closure health_check_closure; - grpc_connectivity_state health_state; -}; -} // namespace - typedef struct external_state_watcher { grpc_subchannel* subchannel; grpc_pollset_set* pollset_set; From 0c4c2de427399fe260aeaa2140638825fa43f26b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 8 Jan 2019 11:45:02 -0800 Subject: [PATCH 460/534] Clean up code --- src/objective-c/GRPCClient/GRPCCall.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 20703f548e4..bc48f1aa1b3 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -467,11 +467,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; + (uint32_t)callFlagsForHost:(NSString *)host path:(NSString *)path { NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; - uint32_t flags = 0; @synchronized(callFlags) { - flags = [callFlags[hostAndPath] intValue]; + return [callFlags[hostAndPath] intValue]; } - return flags; } // Designated initializer From f52dd290e20ec57780255f90ed1f985ee7df63b8 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 8 Jan 2019 13:41:08 +0100 Subject: [PATCH 461/534] improve readme.md --- tools/interop_matrix/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index db84d9b454c..6676f5d470c 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -1,6 +1,6 @@ # Overview -This directory contains scripts that facilitate building and running gRPC tests for combinations of language/runtimes (known as matrix). +This directory contains scripts that facilitate building and running gRPC interoperability tests for combinations of language/runtimes (known as matrix). The setup builds gRPC docker images for each language/runtime and upload it to Google Container Registry (GCR). These images, encapsulating gRPC stack from specific releases/tag, are used to test version compatiblity between gRPC release versions. From 5aa166eb2d8f98d83b016581abc36321b821f29f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 8 Jan 2019 13:44:13 +0100 Subject: [PATCH 462/534] interop_matrix: refactor LANG_RELEASE_MATRIX --- tools/interop_matrix/client_matrix.py | 654 +++++------------- tools/interop_matrix/create_matrix_images.py | 16 +- .../run_interop_matrix_tests.py | 7 +- 3 files changed, 196 insertions(+), 481 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 4964fd61674..12051e70a0b 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -15,6 +15,8 @@ # Defines languages, runtimes and releases for backward compatibility testing +from collections import OrderedDict + def get_github_repo(lang): return { @@ -27,23 +29,16 @@ def get_github_repo(lang): def get_release_tags(lang): - return map(lambda r: get_release_tag_name(r), LANG_RELEASE_MATRIX[lang]) - - -def get_release_tag_name(release_info): - assert len(release_info.keys()) == 1 - return release_info.keys()[0] + """Returns list of known releases for given language.""" + return list(LANG_RELEASE_MATRIX[lang].keys()) def get_runtimes_for_lang_release(lang, release): """Get list of valid runtimes for given release of lang.""" runtimes_to_skip = [] - # see if any the lang release has "skip_runtime" annotation. - for release_info in LANG_RELEASE_MATRIX[lang]: - if get_release_tag_name(release_info) == release: - if release_info[release] is not None: - runtimes_to_skip = release_info[release].get('skip_runtime', []) - break + release_info = LANG_RELEASE_MATRIX[lang][release] + if release_info: + runtimes_to_skip = release_info.skip_runtime return [ runtime for runtime in LANG_RUNTIME_MATRIX[lang] if runtime not in runtimes_to_skip @@ -51,6 +46,9 @@ def get_runtimes_for_lang_release(lang, release): def should_build_docker_interop_image_from_release_tag(lang): + # All dockerfile definitions live in grpc/grpc repository. + # For language that have a separate repo, we need to use + # dockerfile definitions from head of grpc/grpc. if lang in ['go', 'java', 'node']: return False return True @@ -68,465 +66,183 @@ LANG_RUNTIME_MATRIX = { 'csharp': ['csharp', 'csharpcoreclr'], } + +class ReleaseInfo: + """Info about a single release of a language""" + + def __init__(self, patch=[], skip_runtime=[], testcases_file=None): + self.patch = patch + self.skip_runtime = skip_runtime + self.testcases_file = None + + # Dictionary of known releases for given language. LANG_RELEASE_MATRIX = { - 'cxx': [ - { - 'v1.0.1': None - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - { - 'v1.17.1': None - }, - ], - 'go': [ - { - 'v1.0.5': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.2.1': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.3.0': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.4.2': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.5.2': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.6.0': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.7.4': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.8.2': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.9.2': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.10.1': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.11.3': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.12.2': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.13.0': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.14.0': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.15.0': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.16.0': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.17.0': { - 'skip_runtime': ['go1.7', 'go1.8'] - } - }, - ], - 'java': [ - { - 'v1.0.3': None - }, - { - 'v1.1.2': None - }, - { - 'v1.2.0': None - }, - { - 'v1.3.1': None - }, - { - 'v1.4.0': None - }, - { - 'v1.5.0': None - }, - { - 'v1.6.1': None - }, - { - 'v1.7.0': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.0': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.1': None - }, - { - 'v1.14.0': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.1': None - }, - { - 'v1.17.1': None - }, - ], - 'python': [ - { - 'v1.0.x': None - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.1': None # first python 1.8 release is 1.8.1 - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - { - 'v1.17.1': None - }, - ], - 'node': [ - { - 'v1.0.1': None - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, + 'cxx': + OrderedDict([ + ('v1.0.1', ReleaseInfo()), + ('v1.1.4', ReleaseInfo()), + ('v1.2.5', ReleaseInfo()), + ('v1.3.9', ReleaseInfo()), + ('v1.4.2', ReleaseInfo()), + ('v1.6.6', ReleaseInfo()), + ('v1.7.2', ReleaseInfo()), + ('v1.8.0', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.1', ReleaseInfo()), + ('v1.11.1', ReleaseInfo()), + ('v1.12.0', ReleaseInfo()), + ('v1.13.0', ReleaseInfo()), + ('v1.14.1', ReleaseInfo()), + ('v1.15.0', ReleaseInfo()), + ('v1.16.0', ReleaseInfo()), + ('v1.17.1', ReleaseInfo()), + ]), + 'go': + OrderedDict([ + ('v1.0.5', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.2.1', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.3.0', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.4.2', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.5.2', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.6.0', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.7.4', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.8.2', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.9.2', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.10.1', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.11.3', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.12.2', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.13.0', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.14.0', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.15.0', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.16.0', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.17.0', ReleaseInfo(skip_runtime=['go1.7', 'go1.8'])), + ]), + 'java': + OrderedDict([ + ('v1.0.3', ReleaseInfo()), + ('v1.1.2', ReleaseInfo()), + ('v1.2.0', ReleaseInfo()), + ('v1.3.1', ReleaseInfo()), + ('v1.4.0', ReleaseInfo()), + ('v1.5.0', ReleaseInfo()), + ('v1.6.1', ReleaseInfo()), + ('v1.7.0', ReleaseInfo()), + ('v1.8.0', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.1', ReleaseInfo()), + ('v1.11.0', ReleaseInfo()), + ('v1.12.0', ReleaseInfo()), + ('v1.13.1', ReleaseInfo()), + ('v1.14.0', ReleaseInfo()), + ('v1.15.0', ReleaseInfo()), + ('v1.16.1', ReleaseInfo()), + ('v1.17.1', ReleaseInfo()), + ]), + 'python': + OrderedDict([ + ('v1.0.x', ReleaseInfo()), + ('v1.1.4', ReleaseInfo()), + ('v1.2.5', ReleaseInfo()), + ('v1.3.9', ReleaseInfo()), + ('v1.4.2', ReleaseInfo()), + ('v1.6.6', ReleaseInfo()), + ('v1.7.2', ReleaseInfo()), + ('v1.8.1', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.1', ReleaseInfo()), + ('v1.11.1', ReleaseInfo()), + ('v1.12.0', ReleaseInfo()), + ('v1.13.0', ReleaseInfo()), + ('v1.14.1', ReleaseInfo()), + ('v1.15.0', ReleaseInfo()), + ('v1.16.0', ReleaseInfo()), + ('v1.17.1', ReleaseInfo()), + ]), + 'node': + OrderedDict([ + ('v1.0.1', ReleaseInfo()), + ('v1.1.4', ReleaseInfo()), + ('v1.2.5', ReleaseInfo()), + ('v1.3.9', ReleaseInfo()), + ('v1.4.2', ReleaseInfo()), + ('v1.6.6', ReleaseInfo()), # TODO: https://github.com/grpc/grpc-node/issues/235. - #{ - # 'v1.7.2': None - #}, - { - 'v1.8.4': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.0': None - }, - { - 'v1.11.3': None - }, - { - 'v1.12.4': None - }, - ], - 'ruby': [ - { - 'v1.0.1': { - 'patch': [ - 'tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile', - 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', - ] - } - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - { - 'v1.17.1': None - }, - ], - 'php': [ - { - 'v1.0.1': None - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - { - 'v1.17.1': None - }, - ], - 'csharp': [ - { - 'v1.0.1': { - 'patch': [ - 'tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile', - 'tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile', - ] - } - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - { - 'v1.17.1': None - }, - ], + # ('v1.7.2', ReleaseInfo()), + ('v1.8.4', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.0', ReleaseInfo()), + ('v1.11.3', ReleaseInfo()), + ('v1.12.4', ReleaseInfo()), + ]), + 'ruby': + OrderedDict([ + ('v1.0.1', + ReleaseInfo(patch=[ + 'tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile', + 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', + ])), + ('v1.1.4', ReleaseInfo()), + ('v1.2.5', ReleaseInfo()), + ('v1.3.9', ReleaseInfo()), + ('v1.4.2', ReleaseInfo()), + ('v1.6.6', ReleaseInfo()), + ('v1.7.2', ReleaseInfo()), + ('v1.8.0', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.1', ReleaseInfo()), + ('v1.11.1', ReleaseInfo()), + ('v1.12.0', ReleaseInfo()), + ('v1.13.0', ReleaseInfo()), + ('v1.14.1', ReleaseInfo()), + ('v1.15.0', ReleaseInfo()), + ('v1.16.0', ReleaseInfo()), + ('v1.17.1', ReleaseInfo()), + ]), + 'php': + OrderedDict([ + ('v1.0.1', ReleaseInfo()), + ('v1.1.4', ReleaseInfo()), + ('v1.2.5', ReleaseInfo()), + ('v1.3.9', ReleaseInfo()), + ('v1.4.2', ReleaseInfo()), + ('v1.6.6', ReleaseInfo()), + ('v1.7.2', ReleaseInfo()), + ('v1.8.0', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.1', ReleaseInfo()), + ('v1.11.1', ReleaseInfo()), + ('v1.12.0', ReleaseInfo()), + ('v1.13.0', ReleaseInfo()), + ('v1.14.1', ReleaseInfo()), + ('v1.15.0', ReleaseInfo()), + ('v1.16.0', ReleaseInfo()), + ('v1.17.1', ReleaseInfo()), + ]), + 'csharp': + OrderedDict([ + ('v1.0.1', + ReleaseInfo(patch=[ + 'tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile', + 'tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile', + ])), + ('v1.1.4', ReleaseInfo()), + ('v1.2.5', ReleaseInfo()), + ('v1.3.9', ReleaseInfo()), + ('v1.4.2', ReleaseInfo()), + ('v1.6.6', ReleaseInfo()), + ('v1.7.2', ReleaseInfo()), + ('v1.8.0', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.1', ReleaseInfo()), + ('v1.11.1', ReleaseInfo()), + ('v1.12.0', ReleaseInfo()), + ('v1.13.0', ReleaseInfo()), + ('v1.14.1', ReleaseInfo()), + ('v1.15.0', ReleaseInfo()), + ('v1.16.0', ReleaseInfo()), + ('v1.17.1', ReleaseInfo()), + ]), } # This matrix lists the version of testcases to use for a release. As new @@ -535,6 +251,8 @@ LANG_RELEASE_MATRIX = { # particular version in some cases. If not specified, xxx__master file will be # used. For example, all java versions will run the commands in java__master. # The testcases files exist under the testcases directory. +# TODO(jtattermusch): make this data part of LANG_RELEASE_MATRIX, +# there is no reason for this to be a separate data structure. TESTCASES_VERSION_MATRIX = { 'node_v1.0.1': 'node__v1.0.1', 'node_v1.1.4': 'node__v1.1.4', diff --git a/tools/interop_matrix/create_matrix_images.py b/tools/interop_matrix/create_matrix_images.py index cf61d462482..31a0e1c7ba6 100755 --- a/tools/interop_matrix/create_matrix_images.py +++ b/tools/interop_matrix/create_matrix_images.py @@ -39,10 +39,9 @@ _LANGUAGES = client_matrix.LANG_RUNTIME_MATRIX.keys() # All gRPC release tags, flattened, deduped and sorted. _RELEASES = sorted( list( - set( - client_matrix.get_release_tag_name(info) - for lang in client_matrix.LANG_RELEASE_MATRIX.values() - for info in lang))) + set(release + for release_dict in client_matrix.LANG_RELEASE_MATRIX.values() + for release in release_dict.keys()))) # Destination directory inside docker image to keep extra info from build time. _BUILD_INFO = '/var/local/build_info' @@ -260,11 +259,10 @@ atexit.register(cleanup) def maybe_apply_patches_on_git_tag(stack_base, lang, release): files_to_patch = [] - for release_info in client_matrix.LANG_RELEASE_MATRIX[lang]: - if client_matrix.get_release_tag_name(release_info) == release: - if release_info[release] is not None: - files_to_patch = release_info[release].get('patch') - break + + release_info = client_matrix.LANG_RELEASE_MATRIX[lang][release] + if release_info: + files_to_patch = release_info.patch if not files_to_patch: return patch_file_relative_path = 'patches/%s_%s/git_repo.patch' % (lang, release) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index dabb4865237..c855de3b1e8 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -44,10 +44,9 @@ _LANGUAGES = client_matrix.LANG_RUNTIME_MATRIX.keys() # All gRPC release tags, flattened, deduped and sorted. _RELEASES = sorted( list( - set( - client_matrix.get_release_tag_name(info) - for lang in client_matrix.LANG_RELEASE_MATRIX.values() - for info in lang))) + set(release + for release_dict in client_matrix.LANG_RELEASE_MATRIX.values() + for release in release_dict.keys()))) argp = argparse.ArgumentParser(description='Run interop tests.') argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int) From 1287cd34eacbc5597bb6c2cdbf7f8d1e8a426509 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 8 Jan 2019 21:10:34 +0100 Subject: [PATCH 463/534] make tcp_server_posix_test pass on foundry --- test/core/iomgr/tcp_server_posix_test.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/core/iomgr/tcp_server_posix_test.cc b/test/core/iomgr/tcp_server_posix_test.cc index 2c66cdec77f..81e26b20cd8 100644 --- a/test/core/iomgr/tcp_server_posix_test.cc +++ b/test/core/iomgr/tcp_server_posix_test.cc @@ -439,6 +439,11 @@ int main(int argc, char** argv) { static_cast(gpr_zalloc(sizeof(*dst_addrs))); grpc::testing::TestEnvironment env(argc, argv); grpc_init(); + // wait a few seconds to make sure IPv6 link-local addresses can be bound + // if we are running under docker container that has just started. + // See https://github.com/moby/moby/issues/38491 + // See https://github.com/grpc/grpc/issues/15610 + gpr_sleep_until(grpc_timeout_seconds_to_deadline(4)); { grpc_core::ExecCtx exec_ctx; g_pollset = static_cast(gpr_zalloc(grpc_pollset_size())); From 7850704d644e41c03ee41a7b6a7aad24b75e4a1d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 8 Jan 2019 21:14:00 +0100 Subject: [PATCH 464/534] reenable tcp_server_posix_test on Foundry --- test/core/iomgr/BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index e920ceacf00..fa59f215887 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -237,7 +237,6 @@ grpc_cc_test( name = "tcp_server_posix_test", srcs = ["tcp_server_posix_test.cc"], language = "C++", - tags = ["manual"], # TODO(adelez): Remove once this works on Foundry. deps = [ "//:gpr", "//:grpc", From 21446eb35afb8a9a13ed65081f331cb056d383fb Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 8 Jan 2019 14:19:43 -0800 Subject: [PATCH 465/534] Fix build.yaml. --- CMakeLists.txt | 45 +------------- Makefile | 62 +++---------------- build.yaml | 13 +--- gRPC-Core.podspec | 2 + grpc.gyp | 11 +--- .../generated/sources_and_headers.json | 22 +------ 6 files changed, 18 insertions(+), 137 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc2cd1853b7..42904f2c277 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1756,6 +1756,7 @@ add_library(grpc_test_util test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc + test/core/util/forwarding_load_balancing_policy.cc test/core/util/fuzzer_util.cc test/core/util/grpc_profiler.cc test/core/util/histogram.cc @@ -2078,6 +2079,7 @@ add_library(grpc_test_util_unsecure test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc + test/core/util/forwarding_load_balancing_policy.cc test/core/util/fuzzer_util.cc test/core/util/grpc_profiler.cc test/core/util/histogram.cc @@ -2827,48 +2829,6 @@ target_link_libraries(test_tcp_server ) -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - -add_library(forwarding_load_balancing_policy - test/core/util/forwarding_load_balancing_policy.cc -) - -if(WIN32 AND MSVC) - set_target_properties(forwarding_load_balancing_policy PROPERTIES COMPILE_PDB_NAME "forwarding_load_balancing_policy" - COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" - ) - if (gRPC_INSTALL) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/forwarding_load_balancing_policy.pdb - DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL - ) - endif() -endif() - - -target_include_directories(forwarding_load_balancing_policy - PUBLIC $ $ - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${_gRPC_SSL_INCLUDE_DIR} - PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} - PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} - PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} - PRIVATE ${_gRPC_CARES_INCLUDE_DIR} - PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} - PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} - PRIVATE third_party/googletest/googletest/include - PRIVATE third_party/googletest/googletest - PRIVATE third_party/googletest/googlemock/include - PRIVATE third_party/googletest/googlemock - PRIVATE ${_gRPC_PROTO_GENS_DIR} -) -target_link_libraries(forwarding_load_balancing_policy - ${_gRPC_PROTOBUF_LIBRARIES} - ${_gRPC_ALLTARGETS_LIBRARIES} -) - - endif (gRPC_BUILD_TESTS) add_library(grpc++ @@ -12534,7 +12494,6 @@ target_link_libraries(client_lb_end2end_test grpc++ grpc gpr - forwarding_load_balancing_policy ${_gRPC_GFLAGS_LIBRARIES} ) diff --git a/Makefile b/Makefile index 8a53bff7d62..927c4c5e6f6 100644 --- a/Makefile +++ b/Makefile @@ -1425,9 +1425,9 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc ifeq ($(EMBED_OPENSSL),true) -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a else -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a endif @@ -4258,6 +4258,7 @@ LIBGRPC_TEST_UTIL_SRC = \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ + test/core/util/forwarding_load_balancing_policy.cc \ test/core/util/fuzzer_util.cc \ test/core/util/grpc_profiler.cc \ test/core/util/histogram.cc \ @@ -4567,6 +4568,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ + test/core/util/forwarding_load_balancing_policy.cc \ test/core/util/fuzzer_util.cc \ test/core/util/grpc_profiler.cc \ test/core/util/histogram.cc \ @@ -5259,55 +5261,6 @@ endif endif -LIBFORWARDING_LOAD_BALANCING_POLICY_SRC = \ - test/core/util/forwarding_load_balancing_policy.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBFORWARDING_LOAD_BALANCING_POLICY_SRC)))) - - -ifeq ($(NO_SECURE),true) - -# You can't build secure libraries if you don't have OpenSSL. - -$(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a: openssl_dep_error - - -else - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a -endif - - - - -endif - -endif - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS:.o=.dep) -endif -endif - - LIBGRPC++_SRC = \ src/cpp/client/insecure_credentials.cc \ src/cpp/client/secure_credentials.cc \ @@ -17575,16 +17528,16 @@ $(BINDIR)/$(CONFIG)/client_lb_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_lb_end2end_test: $(PROTOBUF_DEP) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a +$(BINDIR)/$(CONFIG)/client_lb_end2end_test: $(PROTOBUF_DEP) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_lb_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_lb_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_lb_end2end_test: $(CLIENT_LB_END2END_TEST_OBJS:.o=.dep) @@ -25356,7 +25309,6 @@ test/core/end2end/tests/call_creds.cc: $(OPENSSL_DEP) test/core/security/oauth2_utils.cc: $(OPENSSL_DEP) test/core/tsi/alts/crypt/gsec_test_util.cc: $(OPENSSL_DEP) test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc: $(OPENSSL_DEP) -test/core/util/forwarding_load_balancing_policy.cc: $(OPENSSL_DEP) test/core/util/reconnect_server.cc: $(OPENSSL_DEP) test/core/util/test_tcp_server.cc: $(OPENSSL_DEP) test/cpp/end2end/test_health_check_service_impl.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 84de1828177..0f6e6be4dfa 100644 --- a/build.yaml +++ b/build.yaml @@ -906,6 +906,7 @@ filegroups: - test/core/end2end/fixtures/proxy.h - test/core/iomgr/endpoint_tests.h - test/core/util/debugger_macros.h + - test/core/util/forwarding_load_balancing_policy.h - test/core/util/fuzzer_util.h - test/core/util/grpc_profiler.h - test/core/util/histogram.h @@ -928,6 +929,7 @@ filegroups: - test/core/end2end/fixtures/proxy.cc - test/core/iomgr/endpoint_tests.cc - test/core/util/debugger_macros.cc + - test/core/util/forwarding_load_balancing_policy.cc - test/core/util/fuzzer_util.cc - test/core/util/grpc_profiler.cc - test/core/util/histogram.cc @@ -1638,16 +1640,6 @@ libs: - grpc_test_util - grpc - gpr -- name: forwarding_load_balancing_policy - build: private - language: c++ - headers: - - test/core/util/forwarding_load_balancing_policy.h - src: - - test/core/util/forwarding_load_balancing_policy.cc - uses: - - grpc_base - - grpc_client_channel - name: grpc++ build: all language: c++ @@ -4480,7 +4472,6 @@ targets: - grpc++ - grpc - gpr - - forwarding_load_balancing_policy - name: codegen_test_full gtest: true build: test diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 7ddef6aa441..22521b06d43 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1212,6 +1212,7 @@ Pod::Spec.new do |s| 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', + 'test/core/util/forwarding_load_balancing_policy.cc', 'test/core/util/fuzzer_util.cc', 'test/core/util/grpc_profiler.cc', 'test/core/util/histogram.cc', @@ -1240,6 +1241,7 @@ Pod::Spec.new do |s| 'test/core/end2end/fixtures/proxy.h', 'test/core/iomgr/endpoint_tests.h', 'test/core/util/debugger_macros.h', + 'test/core/util/forwarding_load_balancing_policy.h', 'test/core/util/fuzzer_util.h', 'test/core/util/grpc_profiler.h', 'test/core/util/histogram.h', diff --git a/grpc.gyp b/grpc.gyp index 9aea11efa2e..450aa87e40f 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -611,6 +611,7 @@ 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', + 'test/core/util/forwarding_load_balancing_policy.cc', 'test/core/util/fuzzer_util.cc', 'test/core/util/grpc_profiler.cc', 'test/core/util/histogram.cc', @@ -853,6 +854,7 @@ 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', + 'test/core/util/forwarding_load_balancing_policy.cc', 'test/core/util/fuzzer_util.cc', 'test/core/util/grpc_profiler.cc', 'test/core/util/histogram.cc', @@ -1365,15 +1367,6 @@ 'test/core/util/test_tcp_server.cc', ], }, - { - 'target_name': 'forwarding_load_balancing_policy', - 'type': 'static_library', - 'dependencies': [ - ], - 'sources': [ - 'test/core/util/forwarding_load_balancing_policy.cc', - ], - }, { 'target_name': 'grpc++', 'type': 'static_library', diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 779f724226a..81fe8573c13 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3318,7 +3318,6 @@ }, { "deps": [ - "forwarding_load_balancing_policy", "gpr", "grpc", "grpc++", @@ -7054,24 +7053,6 @@ "third_party": false, "type": "lib" }, - { - "deps": [ - "grpc_base", - "grpc_client_channel" - ], - "headers": [ - "test/core/util/forwarding_load_balancing_policy.h" - ], - "is_filegroup": false, - "language": "c++", - "name": "forwarding_load_balancing_policy", - "src": [ - "test/core/util/forwarding_load_balancing_policy.cc", - "test/core/util/forwarding_load_balancing_policy.h" - ], - "third_party": false, - "type": "lib" - }, { "deps": [ "gpr", @@ -10478,6 +10459,7 @@ "test/core/end2end/fixtures/proxy.h", "test/core/iomgr/endpoint_tests.h", "test/core/util/debugger_macros.h", + "test/core/util/forwarding_load_balancing_policy.h", "test/core/util/fuzzer_util.h", "test/core/util/grpc_profiler.h", "test/core/util/histogram.h", @@ -10511,6 +10493,8 @@ "test/core/iomgr/endpoint_tests.h", "test/core/util/debugger_macros.cc", "test/core/util/debugger_macros.h", + "test/core/util/forwarding_load_balancing_policy.cc", + "test/core/util/forwarding_load_balancing_policy.h", "test/core/util/fuzzer_util.cc", "test/core/util/fuzzer_util.h", "test/core/util/grpc_profiler.cc", From 46a872864cfa3b3e81bbb650d6fd01e8a775c1b5 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 12 Oct 2018 11:56:29 -0700 Subject: [PATCH 466/534] Turn on c-ares as the default resolver --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 2 +- .../cpp/naming/resolver_component_tests_defs.include | 1 - .../client_channel/resolvers/dns_resolver_test.cc | 11 +++++++---- test/cpp/naming/resolver_component_tests_runner.py | 1 - 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index abacd0c960d..fba20000ef6 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -472,7 +472,7 @@ static grpc_address_resolver_vtable ares_resolver = { grpc_resolve_address_ares, blocking_resolve_address_ares}; static bool should_use_ares(const char* resolver_env) { - return resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0; + return resolver_env == nullptr || gpr_stricmp(resolver_env, "ares") == 0; } void grpc_resolver_dns_ares_init() { diff --git a/templates/test/cpp/naming/resolver_component_tests_defs.include b/templates/test/cpp/naming/resolver_component_tests_defs.include index b34845e01a3..d38316cbe68 100644 --- a/templates/test/cpp/naming/resolver_component_tests_defs.include +++ b/templates/test/cpp/naming/resolver_component_tests_defs.include @@ -55,7 +55,6 @@ if cur_resolver and cur_resolver != 'ares': 'needs to use GRPC_DNS_RESOLVER=ares.')) test_runner_log('Exit 1 without running tests.') sys.exit(1) -os.environ.update({'GRPC_DNS_RESOLVER': 'ares'}) os.environ.update({'GRPC_TRACE': 'cares_resolver'}) def wait_until_dns_server_is_up(args, diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index 571746abe86..6f153cc9bf6 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -22,6 +22,8 @@ #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/combiner.h" #include "test/core/util/test_config.h" @@ -72,12 +74,13 @@ int main(int argc, char** argv) { test_succeeds(dns, "dns:10.2.1.1:1234"); test_succeeds(dns, "dns:www.google.com"); test_succeeds(dns, "dns:///www.google.com"); - if (grpc_resolve_address == grpc_resolve_address_ares) { - test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888"); - } else { + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + if (resolver_env != nullptr && gpr_stricmp(resolver_env, "native") == 0) { test_fails(dns, "dns://8.8.8.8/8.8.8.8:8888"); + } else { + test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888"); } - + gpr_free(resolver_env); { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index 1873eec35bd..950a9d4897e 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -55,7 +55,6 @@ if cur_resolver and cur_resolver != 'ares': 'needs to use GRPC_DNS_RESOLVER=ares.')) test_runner_log('Exit 1 without running tests.') sys.exit(1) -os.environ.update({'GRPC_DNS_RESOLVER': 'ares'}) os.environ.update({'GRPC_TRACE': 'cares_resolver'}) def wait_until_dns_server_is_up(args, From 0ec937207431a8512e3820d2da808693e2a21a48 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Mon, 17 Dec 2018 13:32:57 -0800 Subject: [PATCH 467/534] Multiple test timeout 5x --- test/core/surface/concurrent_connectivity_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/surface/concurrent_connectivity_test.cc b/test/core/surface/concurrent_connectivity_test.cc index f606e89ac8d..b201568f482 100644 --- a/test/core/surface/concurrent_connectivity_test.cc +++ b/test/core/surface/concurrent_connectivity_test.cc @@ -44,7 +44,7 @@ #define NUM_OUTER_LOOPS 10 #define NUM_INNER_LOOPS 10 #define DELAY_MILLIS 10 -#define POLL_MILLIS 3000 +#define POLL_MILLIS 15000 #define NUM_OUTER_LOOPS_SHORT_TIMEOUTS 10 #define NUM_INNER_LOOPS_SHORT_TIMEOUTS 100 From 23677bd827f6e749b4a3e2bec73eea40dece565e Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 8 Jan 2019 17:41:23 -0800 Subject: [PATCH 468/534] Remove subchannel args --- .../client_channel/client_channel_factory.cc | 2 +- .../client_channel/client_channel_factory.h | 4 +- .../lb_policy/subchannel_list.h | 5 +-- .../ext/filters/client_channel/subchannel.cc | 11 +++-- .../ext/filters/client_channel/subchannel.h | 10 +---- .../client_channel/subchannel_index.cc | 15 +++---- .../filters/client_channel/subchannel_index.h | 3 +- .../chttp2/client/insecure/channel_create.cc | 10 ++--- .../client/secure/secure_channel_create.cc | 44 +++++++------------ test/cpp/microbenchmarks/bm_call_create.cc | 2 +- 10 files changed, 40 insertions(+), 66 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_factory.cc b/src/core/ext/filters/client_channel/client_channel_factory.cc index 172e9f03c73..130bbe04180 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.cc +++ b/src/core/ext/filters/client_channel/client_channel_factory.cc @@ -30,7 +30,7 @@ void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory) { } grpc_subchannel* grpc_client_channel_factory_create_subchannel( - grpc_client_channel_factory* factory, const grpc_subchannel_args* args) { + grpc_client_channel_factory* factory, const grpc_channel_args* args) { return factory->vtable->create_subchannel(factory, args); } diff --git a/src/core/ext/filters/client_channel/client_channel_factory.h b/src/core/ext/filters/client_channel/client_channel_factory.h index 601ec46b2a5..91dec12282f 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.h +++ b/src/core/ext/filters/client_channel/client_channel_factory.h @@ -49,7 +49,7 @@ struct grpc_client_channel_factory_vtable { void (*ref)(grpc_client_channel_factory* factory); void (*unref)(grpc_client_channel_factory* factory); grpc_subchannel* (*create_subchannel)(grpc_client_channel_factory* factory, - const grpc_subchannel_args* args); + const grpc_channel_args* args); grpc_channel* (*create_client_channel)(grpc_client_channel_factory* factory, const char* target, grpc_client_channel_type type, @@ -61,7 +61,7 @@ void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory); /** Create a new grpc_subchannel */ grpc_subchannel* grpc_client_channel_factory_create_subchannel( - grpc_client_channel_factory* factory, const grpc_subchannel_args* args); + grpc_client_channel_factory* factory, const grpc_channel_args* args); /** Create a new grpc_channel */ grpc_channel* grpc_client_channel_factory_create_channel( diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 6f31a643c1d..1d0ecbe3f64 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -509,12 +509,10 @@ SubchannelList::SubchannelList( GRPC_ARG_SERVER_ADDRESS_LIST, GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. - grpc_subchannel_args sc_args; for (size_t i = 0; i < addresses.size(); i++) { // If there were any balancer addresses, we would have chosen grpclb // policy, which does not use a SubchannelList. GPR_ASSERT(!addresses[i].IsBalancer()); - memset(&sc_args, 0, sizeof(grpc_subchannel_args)); InlinedVector args_to_add; args_to_add.emplace_back( grpc_create_subchannel_address_arg(&addresses[i].address())); @@ -527,9 +525,8 @@ SubchannelList::SubchannelList( &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add.data(), args_to_add.size()); gpr_free(args_to_add[0].value.string); - sc_args.args = new_args; grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel( - client_channel_factory, &sc_args); + client_channel_factory, new_args); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) { // Subchannel could not be created. diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index dff213efc6b..640a052e91e 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -537,7 +537,7 @@ struct HealthCheckParams { } // namespace grpc_core grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, - const grpc_subchannel_args* args) { + const grpc_channel_args* args) { grpc_subchannel_key* key = grpc_subchannel_key_create(args); grpc_subchannel* c = grpc_subchannel_index_find(key); if (c) { @@ -554,11 +554,10 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, c->pollset_set = grpc_pollset_set_create(); grpc_resolved_address* addr = static_cast(gpr_malloc(sizeof(*addr))); - grpc_get_subchannel_address_arg(args->args, addr); + grpc_get_subchannel_address_arg(args, addr); grpc_resolved_address* new_address = nullptr; grpc_channel_args* new_args = nullptr; - if (grpc_proxy_mappers_map_address(addr, args->args, &new_address, - &new_args)) { + if (grpc_proxy_mappers_map_address(addr, args, &new_address, &new_args)) { GPR_ASSERT(new_address != nullptr); gpr_free(addr); addr = new_address; @@ -567,7 +566,7 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, grpc_arg new_arg = grpc_create_subchannel_address_arg(addr); gpr_free(addr); c->args = grpc_channel_args_copy_and_add_and_remove( - new_args != nullptr ? new_args : args->args, keys_to_remove, + new_args != nullptr ? new_args : args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1); gpr_free(new_arg.value.string); if (new_args != nullptr) grpc_channel_args_destroy(new_args); @@ -580,7 +579,7 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, grpc_connectivity_state_init(&c->state_and_health_tracker, GRPC_CHANNEL_IDLE, "subchannel"); grpc_core::BackOff::Options backoff_options; - parse_args_for_backoff_values(args->args, &backoff_options, + parse_args_for_backoff_values(args, &backoff_options, &c->min_connect_timeout_ms); c->backoff.Init(backoff_options); gpr_mu_init(&c->mu); diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index d0c0a672fa1..8c994c64f50 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -38,7 +38,6 @@ address. Provides a target for load balancing. */ typedef struct grpc_subchannel grpc_subchannel; typedef struct grpc_subchannel_call grpc_subchannel_call; -typedef struct grpc_subchannel_args grpc_subchannel_args; typedef struct grpc_subchannel_key grpc_subchannel_key; #ifndef NDEBUG @@ -186,16 +185,9 @@ void grpc_subchannel_call_set_cleanup_closure( grpc_call_stack* grpc_subchannel_call_get_call_stack( grpc_subchannel_call* subchannel_call); -struct grpc_subchannel_args { - /* When updating this struct, also update subchannel_index.c */ - - /** Channel arguments to be supplied to the newly created channel */ - const grpc_channel_args* args; -}; - /** create a subchannel given a connector */ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, - const grpc_subchannel_args* args); + const grpc_channel_args* args); /// Sets \a addr from \a args. void grpc_get_subchannel_address_arg(const grpc_channel_args* args, diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc index 0ae7898c5a4..d0ceda8312c 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ b/src/core/ext/filters/client_channel/subchannel_index.cc @@ -39,38 +39,37 @@ static gpr_mu g_mu; static gpr_refcount g_refcount; struct grpc_subchannel_key { - grpc_subchannel_args args; + grpc_channel_args* args; }; static bool g_force_creation = false; static grpc_subchannel_key* create_key( - const grpc_subchannel_args* args, + const grpc_channel_args* args, grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)) { grpc_subchannel_key* k = static_cast(gpr_malloc(sizeof(*k))); - k->args.args = copy_channel_args(args->args); + k->args = copy_channel_args(args); return k; } -grpc_subchannel_key* grpc_subchannel_key_create( - const grpc_subchannel_args* args) { +grpc_subchannel_key* grpc_subchannel_key_create(const grpc_channel_args* args) { return create_key(args, grpc_channel_args_normalize); } static grpc_subchannel_key* subchannel_key_copy(grpc_subchannel_key* k) { - return create_key(&k->args, grpc_channel_args_copy); + return create_key(k->args, grpc_channel_args_copy); } int grpc_subchannel_key_compare(const grpc_subchannel_key* a, const grpc_subchannel_key* b) { // To pretend the keys are different, return a non-zero value. if (GPR_UNLIKELY(g_force_creation)) return 1; - return grpc_channel_args_compare(a->args.args, b->args.args); + return grpc_channel_args_compare(a->args, b->args); } void grpc_subchannel_key_destroy(grpc_subchannel_key* k) { - grpc_channel_args_destroy(const_cast(k->args.args)); + grpc_channel_args_destroy(k->args); gpr_free(k); } diff --git a/src/core/ext/filters/client_channel/subchannel_index.h b/src/core/ext/filters/client_channel/subchannel_index.h index c135613d26b..429634bd54c 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.h +++ b/src/core/ext/filters/client_channel/subchannel_index.h @@ -27,8 +27,7 @@ shared amongst channels */ /** Create a key that can be used to uniquely identify a subchannel */ -grpc_subchannel_key* grpc_subchannel_key_create( - const grpc_subchannel_args* args); +grpc_subchannel_key* grpc_subchannel_key_create(const grpc_channel_args* args); /** Destroy a subchannel key */ void grpc_subchannel_key_destroy(grpc_subchannel_key* key); diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc index e6c8c382607..a5bf1bf21d4 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -40,14 +40,12 @@ static void client_channel_factory_unref( grpc_client_channel_factory* cc_factory) {} static grpc_subchannel* client_channel_factory_create_subchannel( - grpc_client_channel_factory* cc_factory, const grpc_subchannel_args* args) { - grpc_subchannel_args final_sc_args; - memcpy(&final_sc_args, args, sizeof(*args)); - final_sc_args.args = grpc_default_authority_add_if_not_present(args->args); + grpc_client_channel_factory* cc_factory, const grpc_channel_args* args) { + grpc_channel_args* new_args = grpc_default_authority_add_if_not_present(args); grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_subchannel* s = grpc_subchannel_create(connector, &final_sc_args); + grpc_subchannel* s = grpc_subchannel_create(connector, new_args); grpc_connector_unref(connector); - grpc_channel_args_destroy(const_cast(final_sc_args.args)); + grpc_channel_args_destroy(new_args); return s; } diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc index 9612698e967..ddd538faa80 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc @@ -46,10 +46,10 @@ static void client_channel_factory_ref( static void client_channel_factory_unref( grpc_client_channel_factory* cc_factory) {} -static grpc_subchannel_args* get_secure_naming_subchannel_args( - const grpc_subchannel_args* args) { +static grpc_channel_args* get_secure_naming_channel_args( + const grpc_channel_args* args) { grpc_channel_credentials* channel_credentials = - grpc_channel_credentials_find_in_args(args->args); + grpc_channel_credentials_find_in_args(args); if (channel_credentials == nullptr) { gpr_log(GPR_ERROR, "Can't create subchannel: channel credentials missing for secure " @@ -57,7 +57,7 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( return nullptr; } // Make sure security connector does not already exist in args. - if (grpc_security_connector_find_in_args(args->args) != nullptr) { + if (grpc_security_connector_find_in_args(args) != nullptr) { gpr_log(GPR_ERROR, "Can't create subchannel: security connector already present in " "channel args."); @@ -65,19 +65,18 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( } // To which address are we connecting? By default, use the server URI. const grpc_arg* server_uri_arg = - grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI); + grpc_channel_args_find(args, GRPC_ARG_SERVER_URI); const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg); GPR_ASSERT(server_uri_str != nullptr); grpc_uri* server_uri = grpc_uri_parse(server_uri_str, true /* supress errors */); GPR_ASSERT(server_uri != nullptr); const grpc_core::TargetAuthorityTable* target_authority_table = - grpc_core::FindTargetAuthorityTableInArgs(args->args); + grpc_core::FindTargetAuthorityTableInArgs(args); grpc_core::UniquePtr authority; if (target_authority_table != nullptr) { // Find the authority for the target. - const char* target_uri_str = - grpc_get_subchannel_address_uri_arg(args->args); + const char* target_uri_str = grpc_get_subchannel_address_uri_arg(args); grpc_uri* target_uri = grpc_uri_parse(target_uri_str, false /* suppress errors */); GPR_ASSERT(target_uri != nullptr); @@ -100,15 +99,14 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( } grpc_arg args_to_add[2]; size_t num_args_to_add = 0; - if (grpc_channel_args_find(args->args, GRPC_ARG_DEFAULT_AUTHORITY) == - nullptr) { + if (grpc_channel_args_find(args, GRPC_ARG_DEFAULT_AUTHORITY) == nullptr) { // If the channel args don't already contain GRPC_ARG_DEFAULT_AUTHORITY, add // the arg, setting it to the value just obtained. args_to_add[num_args_to_add++] = grpc_channel_arg_string_create( const_cast(GRPC_ARG_DEFAULT_AUTHORITY), authority.get()); } grpc_channel_args* args_with_authority = - grpc_channel_args_copy_and_add(args->args, args_to_add, num_args_to_add); + grpc_channel_args_copy_and_add(args, args_to_add, num_args_to_add); grpc_uri_destroy(server_uri); // Create the security connector using the credentials and target name. grpc_channel_args* new_args_from_connector = nullptr; @@ -137,29 +135,21 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( grpc_channel_args_destroy(new_args_from_connector); } grpc_channel_args_destroy(args_with_authority); - grpc_subchannel_args* final_sc_args = - static_cast(gpr_malloc(sizeof(*final_sc_args))); - memcpy(final_sc_args, args, sizeof(*args)); - final_sc_args->args = new_args; - return final_sc_args; + return new_args; } static grpc_subchannel* client_channel_factory_create_subchannel( - grpc_client_channel_factory* cc_factory, const grpc_subchannel_args* args) { - grpc_subchannel_args* subchannel_args = - get_secure_naming_subchannel_args(args); - if (subchannel_args == nullptr) { - gpr_log( - GPR_ERROR, - "Failed to create subchannel arguments during subchannel creation."); + grpc_client_channel_factory* cc_factory, const grpc_channel_args* args) { + grpc_channel_args* new_args = get_secure_naming_channel_args(args); + if (new_args == nullptr) { + gpr_log(GPR_ERROR, + "Failed to create channel args during subchannel creation."); return nullptr; } grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_subchannel* s = grpc_subchannel_create(connector, subchannel_args); + grpc_subchannel* s = grpc_subchannel_create(connector, new_args); grpc_connector_unref(connector); - grpc_channel_args_destroy( - const_cast(subchannel_args->args)); - gpr_free(subchannel_args); + grpc_channel_args_destroy(new_args); return s; } diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 8d12606434b..125b1ce5c4e 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -326,7 +326,7 @@ class FakeClientChannelFactory : public grpc_client_channel_factory { static void NoRef(grpc_client_channel_factory* factory) {} static void NoUnref(grpc_client_channel_factory* factory) {} static grpc_subchannel* CreateSubchannel(grpc_client_channel_factory* factory, - const grpc_subchannel_args* args) { + const grpc_channel_args* args) { return nullptr; } static grpc_channel* CreateClientChannel(grpc_client_channel_factory* factory, From d4fa274bf2994276341e47920aa46e7a009b4d10 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 9 Jan 2019 09:38:47 -0800 Subject: [PATCH 469/534] address comments --- src/objective-c/GRPCClient/GRPCCall.m | 4 ---- src/objective-c/RxLibrary/GRXConcurrentWriteable.m | 6 ++---- src/objective-c/RxLibrary/GRXWriter.h | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index bc48f1aa1b3..c0d10cacc14 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -425,9 +425,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; // queue dispatch_queue_t _responseQueue; - // Whether the call is finished. If it is, should not call finishWithError again. - BOOL _finished; - // The OAuth2 token fetched from a token provider. NSString *_fetchedOauth2AccessToken; } @@ -750,7 +747,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self cancel]; } else { dispatch_async(_callQueue, ^{ - // EOS error is not processed here. It is handled by op batch of GRPC_OP_RECV_STATUS_ON_CLIENT [self finishRequestWithErrorHandler:nil]; }); diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index d8491d2aed5..115195463de 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -113,10 +113,8 @@ - (void)cancelSilently { dispatch_async(_writeableQueue, ^{ - @synchronized(self) { - if (self->_alreadyFinished) { - return; - } + if (self->_alreadyFinished) { + return; } self.writeable = nil; }); diff --git a/src/objective-c/RxLibrary/GRXWriter.h b/src/objective-c/RxLibrary/GRXWriter.h index ac1f7b9c4cf..df4c80c28dd 100644 --- a/src/objective-c/RxLibrary/GRXWriter.h +++ b/src/objective-c/RxLibrary/GRXWriter.h @@ -82,7 +82,7 @@ typedef NS_ENUM(NSInteger, GRXWriterState) { * the corresponding value, and that's useful for advanced use cases like pausing an writer. For * more details, see the documentation of the enum further down. The property is thread safe. */ -@property(atomic) GRXWriterState state; +@property GRXWriterState state; /** * Transition to the Started state, and start sending messages to the writeable (a reference to it From ca5c0a83664068dc0691166c0438e664a95a58ac Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 9 Jan 2019 09:43:14 -0800 Subject: [PATCH 470/534] Switch to absolute import --- src/python/grpcio/grpc/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 70d7618e056..8613bc501f1 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -24,7 +24,7 @@ from grpc._cython import cygrpc as _cygrpc logging.getLogger(__name__).addHandler(logging.NullHandler()) try: - from ._grpcio_metadata import __version__ + from grpc._grpcio_metadata import __version__ except ImportError: __version__ = "dev0" From 025cb9b1e712ad215b9180d9a74c2c71ce870ac2 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 9 Jan 2019 10:33:48 -0800 Subject: [PATCH 471/534] correctly name __dealloc__ method --- src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index d72648a35d0..ef74f61e043 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -149,6 +149,6 @@ cdef class Server: grpc_server_destroy(self.c_server) self.c_server = NULL - def __dealloc(self): + def __dealloc__(self): if self.c_server == NULL: grpc_shutdown() From b4818682be9be27398142996e8b02c23624b1184 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 19:41:22 +0100 Subject: [PATCH 472/534] fix #17625 --- tools/run_tests/dockerize/build_interop_image.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/run_tests/dockerize/build_interop_image.sh b/tools/run_tests/dockerize/build_interop_image.sh index 0f88787639a..025c532d976 100755 --- a/tools/run_tests/dockerize/build_interop_image.sh +++ b/tools/run_tests/dockerize/build_interop_image.sh @@ -90,9 +90,6 @@ else docker build -t "$BASE_IMAGE" --force-rm=true "tools/dockerfile/interoptest/$BASE_NAME" || exit $? fi -# Create a local branch so the child Docker script won't complain -git branch -f jenkins-docker - CONTAINER_NAME="build_${BASE_NAME}_$(uuidgen)" # Prepare image for interop tests, commit it on success. From eda9742bbdb4899c6661509981abab729a7044e8 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 9 Jan 2019 10:57:53 -0800 Subject: [PATCH 473/534] updated bazel and RBE instance versions --- third_party/toolchains/BUILD | 12 ++++++------ tools/remote_build/rbe_common.bazelrc | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index e213461acc9..2499d1c788c 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -20,17 +20,17 @@ package(default_visibility = ["//visibility:public"]) # Update every time when a new container is released. alias( name = "rbe_ubuntu1604", - actual = ":rbe_ubuntu1604_r342117", + actual = ":rbe_ubuntu1604_r346485", ) alias( name = "rbe_ubuntu1604_large", - actual = ":rbe_ubuntu1604_r342117_large", + actual = ":rbe_ubuntu1604_r346485_large", ) -# RBE Ubuntu16_04 r342117 +# RBE Ubuntu16_04 r346485 platform( - name = "rbe_ubuntu1604_r342117", + name = "rbe_ubuntu1604_r346485", constraint_values = [ "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", @@ -51,9 +51,9 @@ platform( """, ) -# RBE Ubuntu16_04 r342117 large +# RBE Ubuntu16_04 r346485 large platform( - name = "rbe_ubuntu1604_r342117_large", + name = "rbe_ubuntu1604_r346485_large", constraint_values = [ "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index aa3ddb050cd..8cf17a30860 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -18,7 +18,7 @@ startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 -build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain +build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.20.0/default:toolchain build --extra_toolchains=//third_party/toolchains:cc-toolchain-clang-x86_64-default # Use custom execution platforms defined in third_party/toolchains build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large @@ -61,9 +61,9 @@ build:msan --cxxopt=--stdlib=libc++ # setting LD_LIBRARY_PATH is necessary # to avoid "libc++.so.1: cannot open shared object file" build:msan --action_env=LD_LIBRARY_PATH=/usr/local/lib -build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain +build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.20.0/default:toolchain # override the config-agnostic crosstool_top -build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/msan:toolchain +build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.20.0/msan:toolchain # thread sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific @@ -79,7 +79,7 @@ build:ubsan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:ubsan --test_timeout=3600 # override the config-agnostic crosstool_top ---crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.1/bazel_0.16.1/ubsan:toolchain +--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.1/bazel_0.20.0/ubsan:toolchain # TODO(jtattermusch): remove this once Foundry adds the env to the docker image. # ubsan needs symbolizer to work properly, otherwise the suppression file doesn't work # and we get test failures. From 95dc9c1110d83c42dea668d6d8729b920caa400c Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 9 Jan 2019 11:21:29 -0800 Subject: [PATCH 474/534] updated repo for bazel --- bazel/grpc_deps.bzl | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 3eacd2b0475..ea66fa80999 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -93,17 +93,17 @@ def grpc_deps(): native.bind( name = "opencensus-trace", - actual = "@io_opencensus_cpp//opencensus/trace:trace" + actual = "@io_opencensus_cpp//opencensus/trace:trace", ) native.bind( name = "opencensus-stats", - actual = "@io_opencensus_cpp//opencensus/stats:stats" + actual = "@io_opencensus_cpp//opencensus/stats:stats", ) native.bind( name = "opencensus-stats-test", - actual = "@io_opencensus_cpp//opencensus/stats:test_utils" + actual = "@io_opencensus_cpp//opencensus/stats:test_utils", ) if "boringssl" not in native.existing_rules(): @@ -177,16 +177,16 @@ def grpc_deps(): if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): http_archive( name = "com_github_bazelbuild_bazeltoolchains", - strip_prefix = "bazel-toolchains-280edaa6f93623074513d2b426068de42e62ea4d", + strip_prefix = "bazel-toolchains-35bfb70728dedc936a370e551294f2fc9c02b7d5", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/280edaa6f93623074513d2b426068de42e62ea4d.tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/280edaa6f93623074513d2b426068de42e62ea4d.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/35bfb70728dedc936a370e551294f2fc9c02b7d5.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/35bfb70728dedc936a370e551294f2fc9c02b7d5.tar.gz", ], sha256 = "50c9df51f80cdf9ff8f2bc27620c155526b9ba67be95e8a686f32ff8898a06e2", ) if "io_opencensus_cpp" not in native.existing_rules(): - http_archive( + http_archive( name = "io_opencensus_cpp", strip_prefix = "opencensus-cpp-fdf0f308b1631bb4a942e32ba5d22536a6170274", url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz", @@ -199,7 +199,6 @@ def grpc_deps(): url = "https://github.com/google/upb/archive/9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3.tar.gz", ) - # TODO: move some dependencies from "grpc_deps" here? def grpc_test_only_deps(): """Internal, not intended for use by packages that are consuming grpc. From b2ac318566bcdcdd0a8306af5030e62025d6666a Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 9 Jan 2019 11:25:05 -0800 Subject: [PATCH 475/534] updated repo for bazel to latest version --- bazel/grpc_deps.bzl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index ea66fa80999..8eb60d13d4f 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -177,12 +177,12 @@ def grpc_deps(): if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): http_archive( name = "com_github_bazelbuild_bazeltoolchains", - strip_prefix = "bazel-toolchains-35bfb70728dedc936a370e551294f2fc9c02b7d5", + strip_prefix = "bazel-toolchains-37419a124bdb9af2fec5b99a973d359b6b899b61 ", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/35bfb70728dedc936a370e551294f2fc9c02b7d5.tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/35bfb70728dedc936a370e551294f2fc9c02b7d5.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61 .tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61 .tar.gz", ], - sha256 = "50c9df51f80cdf9ff8f2bc27620c155526b9ba67be95e8a686f32ff8898a06e2", + sha256 = "ee854b5de299138c1f4a2edb5573d22b21d975acfc7aa938f36d30b49ef97498", ) if "io_opencensus_cpp" not in native.existing_rules(): From 56268e092719860491de0d2b1da44d7a7d7fcb2c Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 9 Jan 2019 11:32:18 -0800 Subject: [PATCH 476/534] fixed typo on hash --- bazel/grpc_deps.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 8eb60d13d4f..450928828c2 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -177,10 +177,10 @@ def grpc_deps(): if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): http_archive( name = "com_github_bazelbuild_bazeltoolchains", - strip_prefix = "bazel-toolchains-37419a124bdb9af2fec5b99a973d359b6b899b61 ", + strip_prefix = "bazel-toolchains-37419a124bdb9af2fec5b99a973d359b6b899b61", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61 .tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61 .tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61.tar.gz", ], sha256 = "ee854b5de299138c1f4a2edb5573d22b21d975acfc7aa938f36d30b49ef97498", ) From 3dafee1e51813beff7b5947702772f1d22a06ed5 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 9 Jan 2019 11:55:57 -0800 Subject: [PATCH 477/534] bumped bazel version for internal CI --- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 4d7d4271d61..863b43a1728 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -23,7 +23,7 @@ cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321 # Download bazel temp_dir="$(mktemp -d)" -wget -q https://github.com/bazelbuild/bazel/releases/download/0.17.1/bazel-0.17.1-linux-x86_64 -O "${temp_dir}/bazel" +wget -q https://github.com/bazelbuild/bazel/releases/download/0.20.0/bazel-0.20.0-linux-x86_64 -O "${temp_dir}/bazel" chmod 755 "${temp_dir}/bazel" export PATH="${temp_dir}:${PATH}" # This should show ${temp_dir}/bazel From 9f85ead667121f5c74fe232e7908ab774131e1e2 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 9 Jan 2019 12:06:24 -0800 Subject: [PATCH 478/534] Add new proto in examples --- examples/BUILD | 5 +++++ examples/protos/keyvaluestore.proto | 33 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 examples/protos/keyvaluestore.proto diff --git a/examples/BUILD b/examples/BUILD index c4f25d0de9f..b6cb9d48d3c 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -38,6 +38,11 @@ grpc_proto_library( srcs = ["protos/route_guide.proto"], ) +grpc_proto_library( + name = "keyvaluestore", + srcs = ["protos/keyvaluestore.proto"], +) + cc_binary( name = "greeter_client", srcs = ["cpp/helloworld/greeter_client.cc"], diff --git a/examples/protos/keyvaluestore.proto b/examples/protos/keyvaluestore.proto new file mode 100644 index 00000000000..06b516a1501 --- /dev/null +++ b/examples/protos/keyvaluestore.proto @@ -0,0 +1,33 @@ +// 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. + +syntax = "proto3"; + +package keyvaluestore; + +// Key value store service definition. +service KeyValueStore { + // Provides a value for each key reques + rpc GetValues (stream Key) returns (stream Value) {} +} + +// The request message containing the key +message Key { + string key = 1; +} + +// The response message containing the greetings +message Value { + string value = 1; +} From 4f11b9650099212b9bb3c01b6b73e977a20c2c8e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 16:35:35 +0100 Subject: [PATCH 479/534] stop testing older releases with go1.7: 1.8 should be enough --- tools/interop_matrix/README.md | 4 ++-- tools/interop_matrix/client_matrix.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index 6676f5d470c..531bef82b8e 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -42,10 +42,10 @@ For more details on each step, refer to sections below. - The output for all the test cases is recorded in a junit style xml file (default to 'report.xml'). ## Instructions for running test cases against a GCR image manually -- Download docker image from GCR. For example: `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_go1.7:master`. +- Download docker image from GCR. For example: `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_go1.8:master`. - Run test cases by specifying `docker_image` variable inline with the test case script created above. For example: - - `docker_image=gcr.io/grpc-testing/grpc_interop_go1.7:master ./testcases/go__master` will run go__master test cases against `go1.7` with gRPC release `master` docker image in GCR. + - `docker_image=gcr.io/grpc-testing/grpc_interop_go1.8:master ./testcases/go__master` will run go__master test cases against `go1.8` with gRPC release `master` docker image in GCR. Note: - File path starting with `tools/` or `template/` are relative to the grpc repo root dir. File path starting with `./` are relative to current directory (`tools/interop_matrix`). diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 12051e70a0b..9a7c90acd32 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -57,7 +57,7 @@ def should_build_docker_interop_image_from_release_tag(lang): # Dictionary of runtimes per language LANG_RUNTIME_MATRIX = { 'cxx': ['cxx'], # This is actually debian8. - 'go': ['go1.7', 'go1.8', 'go1.11'], + 'go': ['go1.8', 'go1.11'], 'java': ['java_oracle8'], 'python': ['python'], 'node': ['node'], @@ -116,7 +116,7 @@ LANG_RELEASE_MATRIX = { ('v1.14.0', ReleaseInfo(skip_runtime=['go1.11'])), ('v1.15.0', ReleaseInfo(skip_runtime=['go1.11'])), ('v1.16.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.17.0', ReleaseInfo(skip_runtime=['go1.7', 'go1.8'])), + ('v1.17.0', ReleaseInfo(skip_runtime=['go1.8'])), ]), 'java': OrderedDict([ From bd5e15608d217e7a5efcaac73dc45f7d1be28a21 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 16:44:43 +0100 Subject: [PATCH 480/534] minor doc updates --- tools/interop_matrix/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index 531bef82b8e..5a8965757ee 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -11,8 +11,8 @@ We have continuous nightly test setup to test gRPC backward compatibility betwee - Build new client docker image(s). For example, for C and wrapper languages release `v1.9.9`, do - `tools/interop_matrix/create_matrix_images.py --git_checkout --release=v1.9.9 --upload_images --language cxx csharp python ruby php` - Verify that the new docker image was built successfully and uploaded to GCR. For example, - - `gcloud beta container images list --repository gcr.io/grpc-testing` shows image repos. - - `gcloud beta container images list-tags gcr.io/grpc-testing/grpc_interop_java_oracle8` should show an image entry with tag `v1.9.9`. + - `gcloud container images list --repository gcr.io/grpc-testing` lists available images. + - `gcloud container images list-tags gcr.io/grpc-testing/grpc_interop_java_oracle8` should show an image entry with tag `v1.9.9`. - Verify the just-created docker client image would pass backward compatibility test (it should). For example, - `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_java_oracle8:v1.9.9` followed by - `docker_image=gcr.io/grpc-testing/grpc_interop_java_oracle8:v1.9.9 tools/interop_matrix/testcases/java__master` From 2a997c66eada4015912230a482d3b898ec526800 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 16:51:51 +0100 Subject: [PATCH 481/534] allow creating images for non-yet-listed releases --- tools/interop_matrix/client_matrix.py | 2 +- tools/interop_matrix/create_matrix_images.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 9a7c90acd32..ec499a98b61 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -36,7 +36,7 @@ def get_release_tags(lang): def get_runtimes_for_lang_release(lang, release): """Get list of valid runtimes for given release of lang.""" runtimes_to_skip = [] - release_info = LANG_RELEASE_MATRIX[lang][release] + release_info = LANG_RELEASE_MATRIX[lang].get(release) if release_info: runtimes_to_skip = release_info.skip_runtime return [ diff --git a/tools/interop_matrix/create_matrix_images.py b/tools/interop_matrix/create_matrix_images.py index 31a0e1c7ba6..28dc4be0f4d 100755 --- a/tools/interop_matrix/create_matrix_images.py +++ b/tools/interop_matrix/create_matrix_images.py @@ -260,7 +260,7 @@ atexit.register(cleanup) def maybe_apply_patches_on_git_tag(stack_base, lang, release): files_to_patch = [] - release_info = client_matrix.LANG_RELEASE_MATRIX[lang][release] + release_info = client_matrix.LANG_RELEASE_MATRIX[lang].get(release) if release_info: files_to_patch = release_info.patch if not files_to_patch: From 0d1743b3cc2a24dc2a17fb8e87e2fc8795d44585 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 17:11:54 +0100 Subject: [PATCH 482/534] having GCR images with ":master" tag is an antipattern. --- tools/interop_matrix/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index 5a8965757ee..a2c3189bbd6 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -42,10 +42,10 @@ For more details on each step, refer to sections below. - The output for all the test cases is recorded in a junit style xml file (default to 'report.xml'). ## Instructions for running test cases against a GCR image manually -- Download docker image from GCR. For example: `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_go1.8:master`. +- Download docker image from GCR. For example: `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_go1.8:v1.16.0`. - Run test cases by specifying `docker_image` variable inline with the test case script created above. For example: - - `docker_image=gcr.io/grpc-testing/grpc_interop_go1.8:master ./testcases/go__master` will run go__master test cases against `go1.8` with gRPC release `master` docker image in GCR. + - `docker_image=gcr.io/grpc-testing/grpc_interop_go1.8:v1.16.0 ./testcases/go__master` will run go__master test cases against `go1.8` with gRPC release `v1.16.0` docker image in GCR. Note: - File path starting with `tools/` or `template/` are relative to the grpc repo root dir. File path starting with `./` are relative to current directory (`tools/interop_matrix`). From b2044fdd6f8a74cbd489affee7f195b82bb15aac Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 17:22:09 +0100 Subject: [PATCH 483/534] remove confusing remarks from interop_matrix README.md --- tools/interop_matrix/README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index a2c3189bbd6..ecd71be7f87 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -13,6 +13,7 @@ We have continuous nightly test setup to test gRPC backward compatibility betwee - Verify that the new docker image was built successfully and uploaded to GCR. For example, - `gcloud container images list --repository gcr.io/grpc-testing` lists available images. - `gcloud container images list-tags gcr.io/grpc-testing/grpc_interop_java_oracle8` should show an image entry with tag `v1.9.9`. + - images can also be viewed in https://pantheon.corp.google.com/gcr/images/grpc-testing?project=grpc-testing - Verify the just-created docker client image would pass backward compatibility test (it should). For example, - `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_java_oracle8:v1.9.9` followed by - `docker_image=gcr.io/grpc-testing/grpc_interop_java_oracle8:v1.9.9 tools/interop_matrix/testcases/java__master` @@ -20,13 +21,11 @@ We have continuous nightly test setup to test gRPC backward compatibility betwee - (Optional) clean up the tmp directory to where grpc source is cloned at `/export/hda3/tmp/grpc_matrix/`. For more details on each step, refer to sections below. -## Instructions for adding new language/runtimes* +## Instructions for adding new language/runtimes - Create new `Dockerfile.template`, `build_interop.sh.template` for the language/runtime under `template/tools/dockerfile/`. - Run `tools/buildgen/generate_projects.sh` to create corresponding files under `tools/dockerfile/`. - Add language/runtimes to `client_matrix.py` following existing language/runtimes examples. -- Run `tools/interop_matrix/create_matrix_images.py` which will build and upload images to GCR. Unless you are also building images for a gRPC release, make sure not to set `--release` (the default release 'master' is used for testing). - -*: Please delete your docker images at https://pantheon.corp.google.com/gcr/images/grpc-testing?project=grpc-testing afterwards. Permissions to access GrpcTesting project is required for this step. +- Run `tools/interop_matrix/create_matrix_images.py` which will build (and upload) images to GCR. ## Instructions for creating new test cases - Create test cases by running `LANG= [RELEASE=] ./create_testcases.sh`. For example, @@ -39,7 +38,7 @@ For more details on each step, refer to sections below. - `--release` specifies a git release tag. Defaults to `--release=all`. Make sure the GCR images with the tag have been created using `create_matrix_images.py` above. - `--language` specifies a language. Defaults to `--language=all`. For example, To test all languages for all gRPC releases across all runtimes, do `tools/interop_matrix/run_interop_matrix_test.py --release=all`. -- The output for all the test cases is recorded in a junit style xml file (default to 'report.xml'). +- The output for all the test cases is recorded in a junit style xml file (defaults to 'report.xml'). ## Instructions for running test cases against a GCR image manually - Download docker image from GCR. For example: `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_go1.8:v1.16.0`. From 905cd6a3151269fd2c3ad8577fbce5431d8f791b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 18:10:06 +0100 Subject: [PATCH 484/534] invert the strategy test runtimes are being selected per release --- tools/interop_matrix/client_matrix.py | 53 ++++++++++++++------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index ec499a98b61..655c7c7b6bf 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -35,14 +35,15 @@ def get_release_tags(lang): def get_runtimes_for_lang_release(lang, release): """Get list of valid runtimes for given release of lang.""" - runtimes_to_skip = [] + runtimes = list(LANG_RUNTIME_MATRIX[lang]) release_info = LANG_RELEASE_MATRIX[lang].get(release) - if release_info: - runtimes_to_skip = release_info.skip_runtime - return [ - runtime for runtime in LANG_RUNTIME_MATRIX[lang] - if runtime not in runtimes_to_skip - ] + if release_info and release_info.runtime_subset: + runtimes = list(release_info.runtime_subset) + + # check that all selected runtimes are valid for given language + for runtime in runtimes: + assert runtime in LANG_RUNTIME_MATRIX[lang] + return runtimes def should_build_docker_interop_image_from_release_tag(lang): @@ -70,9 +71,9 @@ LANG_RUNTIME_MATRIX = { class ReleaseInfo: """Info about a single release of a language""" - def __init__(self, patch=[], skip_runtime=[], testcases_file=None): + def __init__(self, patch=[], runtime_subset=[], testcases_file=None): self.patch = patch - self.skip_runtime = skip_runtime + self.runtime_subset = runtime_subset self.testcases_file = None @@ -100,23 +101,23 @@ LANG_RELEASE_MATRIX = { ]), 'go': OrderedDict([ - ('v1.0.5', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.2.1', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.3.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.4.2', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.5.2', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.6.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.7.4', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.8.2', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.9.2', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.10.1', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.11.3', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.12.2', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.13.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.14.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.15.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.16.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.17.0', ReleaseInfo(skip_runtime=['go1.8'])), + ('v1.0.5', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.2.1', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.3.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.4.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.5.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.6.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.7.4', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.8.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.9.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.10.1', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.11.3', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.12.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.13.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.14.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.15.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.16.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.17.0', ReleaseInfo(runtime_subset=['go1.11'])), ]), 'java': OrderedDict([ From 93e84947dfa3c3af2fdaaf5af0c6d6c93dd4e9fc Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 9 Jan 2019 14:58:50 -0800 Subject: [PATCH 485/534] Reviewer comments --- examples/protos/keyvaluestore.proto | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/protos/keyvaluestore.proto b/examples/protos/keyvaluestore.proto index 06b516a1501..9b5e53d8135 100644 --- a/examples/protos/keyvaluestore.proto +++ b/examples/protos/keyvaluestore.proto @@ -18,16 +18,16 @@ package keyvaluestore; // Key value store service definition. service KeyValueStore { - // Provides a value for each key reques - rpc GetValues (stream Key) returns (stream Value) {} + // Provides a value for each key request + rpc GetValues (stream Request) returns (stream Response) {} } // The request message containing the key -message Key { +message Request { string key = 1; } -// The response message containing the greetings -message Value { +// The response message containing the value associated with the key +message Response { string value = 1; } From 121e04bc1e44bb684d464be6788f1c0a065b1116 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 9 Jan 2019 15:22:05 -0800 Subject: [PATCH 486/534] address comments 2 --- src/objective-c/GRPCClient/GRPCCall.m | 1 - src/objective-c/RxLibrary/GRXForwardingWriter.m | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index c0d10cacc14..e8fae09a1f8 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -56,7 +56,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Make them read-write. @property(atomic, strong) NSDictionary *responseHeaders; @property(atomic, strong) NSDictionary *responseTrailers; -@property(atomic) BOOL isWaitingForToken; - (instancetype)initWithHost:(NSString *)host path:(NSString *)path diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.m b/src/objective-c/RxLibrary/GRXForwardingWriter.m index f5ed603698d..27ac0acdfff 100644 --- a/src/objective-c/RxLibrary/GRXForwardingWriter.m +++ b/src/objective-c/RxLibrary/GRXForwardingWriter.m @@ -72,7 +72,11 @@ #pragma mark GRXWriter implementation - (GRXWriterState)state { - return _writer ? _writer.state : GRXWriterStateFinished; + GRXWriter *copiedWriter; + @synchronized(self) { + copiedWriter = _writer; + } + return copiedWriter ? copiedWriter.state : GRXWriterStateFinished; } - (void)setState:(GRXWriterState)state { @@ -106,6 +110,7 @@ @synchronized(self) { [self finishOutputWithError:errorOrNil]; copiedWriter = _writer; + _writer = nil; } copiedWriter.state = GRXWriterStateFinished; } From de902e18b7db2cd93deff87a17d76ced99a2305a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 9 Jan 2019 16:03:29 -0800 Subject: [PATCH 487/534] Reviewer comments --- examples/protos/keyvaluestore.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/protos/keyvaluestore.proto b/examples/protos/keyvaluestore.proto index 9b5e53d8135..74ad57e0297 100644 --- a/examples/protos/keyvaluestore.proto +++ b/examples/protos/keyvaluestore.proto @@ -16,7 +16,7 @@ syntax = "proto3"; package keyvaluestore; -// Key value store service definition. +// A simple key-value storage service service KeyValueStore { // Provides a value for each key request rpc GetValues (stream Request) returns (stream Response) {} From 38f0fa394b1d75772a37aac2829a51a037d3271f Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 9 Jan 2019 17:01:07 -0800 Subject: [PATCH 488/534] Attempt to fix homebrew installation problem --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 632db5ae145..5b6b2569393 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -38,6 +38,8 @@ if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then fi set +ex # rvm script is very verbose and exits with errorcode +# Advice from https://github.com/Homebrew/homebrew-cask/issues/8629#issuecomment-68641176 +brew update && brew upgrade brew-cask && brew cleanup && brew cask cleanup source $HOME/.rvm/scripts/rvm set -e # rvm commands are very verbose time rvm install 2.5.0 From c059946a75cab05a38dfb0c93afdbc0ee824d3a3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 9 Jan 2019 18:26:22 -0800 Subject: [PATCH 489/534] Fix bug where remote host's trailing slash is not removed, causing name resolution failure --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index a323f0490c8..60a33eda824 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -236,6 +236,12 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; return nil; } + // remove trailing slash of hostname + NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:host]]; + if (hostURL.host && hostURL.port == nil) { + host = [hostURL.host stringByAppendingString:@":443"]; + } + GRPCPooledChannel *pooledChannel = nil; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; From 7a814e2597fbda08e06034717324d8e5b423b93a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Jan 2019 11:50:14 +0100 Subject: [PATCH 490/534] fix build with bazel 0.21 --- bazel/grpc_deps.bzl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 3eacd2b0475..ba0d72a266d 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -124,8 +124,8 @@ def grpc_deps(): if "com_google_protobuf" not in native.existing_rules(): http_archive( name = "com_google_protobuf", - strip_prefix = "protobuf-48cb18e5c419ddd23d9badcfe4e9df7bde1979b2", - url = "https://github.com/google/protobuf/archive/48cb18e5c419ddd23d9badcfe4e9df7bde1979b2.tar.gz", + strip_prefix = "protobuf-66dc42d891a4fc8e9190c524fd67961688a37bbe", + url = "https://github.com/google/protobuf/archive/66dc42d891a4fc8e9190c524fd67961688a37bbe.tar.gz", ) if "com_github_nanopb_nanopb" not in native.existing_rules(): From 8cd7178afb2cde1e9203c2edd4668f04210484b9 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 10 Jan 2019 09:26:44 -0800 Subject: [PATCH 491/534] Add dtors in LB policy subclasses. --- .../util/forwarding_load_balancing_policy.cc | 36 +++++++++++++++++++ .../util/forwarding_load_balancing_policy.h | 35 +++--------------- test/cpp/end2end/client_lb_end2end_test.cc | 2 ++ 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/test/core/util/forwarding_load_balancing_policy.cc b/test/core/util/forwarding_load_balancing_policy.cc index e2755bfed0c..0da566d2bac 100644 --- a/test/core/util/forwarding_load_balancing_policy.cc +++ b/test/core/util/forwarding_load_balancing_policy.cc @@ -18,8 +18,44 @@ #include "test/core/util/forwarding_load_balancing_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/pollset_set.h" + namespace grpc_core { TraceFlag grpc_trace_forwarding_lb(false, "forwarding_lb"); +ForwardingLoadBalancingPolicy::ForwardingLoadBalancingPolicy( + const Args& args, const std::string& delegate_policy_name) + : LoadBalancingPolicy(args) { + delegate_ = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + delegate_policy_name.c_str(), args); + grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), + interested_parties()); + // Give re-resolution closure to delegate. + GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, + OnDelegateRequestReresolutionLocked, this, + grpc_combiner_scheduler(combiner())); + Ref().release(); // held by callback. + delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); +} + +ForwardingLoadBalancingPolicy::~ForwardingLoadBalancingPolicy() {} + +void ForwardingLoadBalancingPolicy::OnDelegateRequestReresolutionLocked( + void* arg, grpc_error* error) { + ForwardingLoadBalancingPolicy* self = + static_cast(arg); + if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { + self->Unref(); + return; + } + self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); + self->delegate_->SetReresolutionClosureLocked( + &self->on_delegate_request_reresolution_); +} + } // namespace grpc_core diff --git a/test/core/util/forwarding_load_balancing_policy.h b/test/core/util/forwarding_load_balancing_policy.h index aeb89803c35..b387f2e606e 100644 --- a/test/core/util/forwarding_load_balancing_policy.h +++ b/test/core/util/forwarding_load_balancing_policy.h @@ -19,16 +19,12 @@ #include #include "src/core/ext/filters/client_channel/lb_policy.h" -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channelz.h" -#include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/error.h" -#include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/json/json.h" #include "src/core/lib/transport/connectivity_state.h" @@ -37,26 +33,13 @@ namespace grpc_core { -extern TraceFlag grpc_trace_forwarding_lb; - // A minimal forwarding class to avoid implementing a standalone test LB. class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { public: ForwardingLoadBalancingPolicy(const Args& args, - const std::string& delegate_policy_name) - : LoadBalancingPolicy(args) { - delegate_ = - LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - delegate_policy_name.c_str(), args); - grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), - interested_parties()); - // Give re-resolution closure to delegate. - GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, - OnDelegateRequestReresolutionLocked, this, - grpc_combiner_scheduler(combiner())); - Ref().release(); // held by callback. - delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); - } + const std::string& delegate_policy_name); + + ~ForwardingLoadBalancingPolicy() override; const char* name() const override { return delegate_->name(); } @@ -108,17 +91,7 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { void ShutdownLocked() override { delegate_.reset(); } static void OnDelegateRequestReresolutionLocked(void* arg, - grpc_error* error) { - ForwardingLoadBalancingPolicy* self = - static_cast(arg); - if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { - self->Unref(); - return; - } - self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); - self->delegate_->SetReresolutionClosureLocked( - &self->on_delegate_request_reresolution_); - } + grpc_error* error); OrphanablePtr delegate_; grpc_closure on_delegate_request_reresolution_; diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 2d474f71982..b14f85100ad 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -1255,6 +1255,8 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { delegate_lb_policy_name), test_(test) {} + ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; + bool PickLocked(PickState* pick, grpc_error** error) override { bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); // Note: This assumes that the delegate policy does not From 5eed6d9d58b96e4d14d2cb9423656c90f572b57c Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 10 Jan 2019 10:23:43 -0800 Subject: [PATCH 492/534] fixed version on toolchain --- third_party/toolchains/BUILD | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 2499d1c788c..a1bee7f1f68 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -74,14 +74,12 @@ platform( """, ) -# This target is auto-generated from release/cpp.tpl and should not be -# modified directly. toolchain( name = "cc-toolchain-clang-x86_64-default", exec_compatible_with = [ ], target_compatible_with = [ ], - toolchain = "@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:cc-compiler-k8", + toolchain = "@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.20.0/default:cc-compiler-k8", toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", ) From d6e2b336702fff194ec8d6208f2fe8e8b028672c Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 10 Jan 2019 10:31:16 -0800 Subject: [PATCH 493/534] Move InterceptRecvTrailingMetadataLoadBalancingPolicy to a separate file. This fixes a link error when building with make. --- CMakeLists.txt | 4 +- Makefile | 4 +- build.yaml | 4 +- gRPC-Core.podspec | 4 +- grpc.gyp | 4 +- .../util/forwarding_load_balancing_policy.cc | 61 ----- .../util/forwarding_load_balancing_policy.h | 102 -------- test/core/util/test_lb_policies.cc | 240 ++++++++++++++++++ test/core/util/test_lb_policies.h | 34 +++ test/cpp/end2end/client_lb_end2end_test.cc | 107 +------- .../generated/sources_and_headers.json | 6 +- 11 files changed, 297 insertions(+), 273 deletions(-) delete mode 100644 test/core/util/forwarding_load_balancing_policy.cc delete mode 100644 test/core/util/forwarding_load_balancing_policy.h create mode 100644 test/core/util/test_lb_policies.cc create mode 100644 test/core/util/test_lb_policies.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 42904f2c277..db9ed00b88e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1756,7 +1756,6 @@ add_library(grpc_test_util test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc - test/core/util/forwarding_load_balancing_policy.cc test/core/util/fuzzer_util.cc test/core/util/grpc_profiler.cc test/core/util/histogram.cc @@ -1771,6 +1770,7 @@ add_library(grpc_test_util test/core/util/subprocess_posix.cc test/core/util/subprocess_windows.cc test/core/util/test_config.cc + test/core/util/test_lb_policies.cc test/core/util/tracer_util.cc test/core/util/trickle_endpoint.cc test/core/util/cmdline.cc @@ -2079,7 +2079,6 @@ add_library(grpc_test_util_unsecure test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc - test/core/util/forwarding_load_balancing_policy.cc test/core/util/fuzzer_util.cc test/core/util/grpc_profiler.cc test/core/util/histogram.cc @@ -2094,6 +2093,7 @@ add_library(grpc_test_util_unsecure test/core/util/subprocess_posix.cc test/core/util/subprocess_windows.cc test/core/util/test_config.cc + test/core/util/test_lb_policies.cc test/core/util/tracer_util.cc test/core/util/trickle_endpoint.cc test/core/util/cmdline.cc diff --git a/Makefile b/Makefile index 927c4c5e6f6..0d1c83f3787 100644 --- a/Makefile +++ b/Makefile @@ -4258,7 +4258,6 @@ LIBGRPC_TEST_UTIL_SRC = \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ - test/core/util/forwarding_load_balancing_policy.cc \ test/core/util/fuzzer_util.cc \ test/core/util/grpc_profiler.cc \ test/core/util/histogram.cc \ @@ -4273,6 +4272,7 @@ LIBGRPC_TEST_UTIL_SRC = \ test/core/util/subprocess_posix.cc \ test/core/util/subprocess_windows.cc \ test/core/util/test_config.cc \ + test/core/util/test_lb_policies.cc \ test/core/util/tracer_util.cc \ test/core/util/trickle_endpoint.cc \ test/core/util/cmdline.cc \ @@ -4568,7 +4568,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ - test/core/util/forwarding_load_balancing_policy.cc \ test/core/util/fuzzer_util.cc \ test/core/util/grpc_profiler.cc \ test/core/util/histogram.cc \ @@ -4583,6 +4582,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ test/core/util/subprocess_posix.cc \ test/core/util/subprocess_windows.cc \ test/core/util/test_config.cc \ + test/core/util/test_lb_policies.cc \ test/core/util/tracer_util.cc \ test/core/util/trickle_endpoint.cc \ test/core/util/cmdline.cc \ diff --git a/build.yaml b/build.yaml index 0f6e6be4dfa..bb96a611266 100644 --- a/build.yaml +++ b/build.yaml @@ -906,7 +906,6 @@ filegroups: - test/core/end2end/fixtures/proxy.h - test/core/iomgr/endpoint_tests.h - test/core/util/debugger_macros.h - - test/core/util/forwarding_load_balancing_policy.h - test/core/util/fuzzer_util.h - test/core/util/grpc_profiler.h - test/core/util/histogram.h @@ -919,6 +918,7 @@ filegroups: - test/core/util/slice_splitter.h - test/core/util/subprocess.h - test/core/util/test_config.h + - test/core/util/test_lb_policies.h - test/core/util/tracer_util.h - test/core/util/trickle_endpoint.h src: @@ -929,7 +929,6 @@ filegroups: - test/core/end2end/fixtures/proxy.cc - test/core/iomgr/endpoint_tests.cc - test/core/util/debugger_macros.cc - - test/core/util/forwarding_load_balancing_policy.cc - test/core/util/fuzzer_util.cc - test/core/util/grpc_profiler.cc - test/core/util/histogram.cc @@ -944,6 +943,7 @@ filegroups: - test/core/util/subprocess_posix.cc - test/core/util/subprocess_windows.cc - test/core/util/test_config.cc + - test/core/util/test_lb_policies.cc - test/core/util/tracer_util.cc - test/core/util/trickle_endpoint.cc deps: diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 22521b06d43..a62595383a4 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1212,7 +1212,6 @@ Pod::Spec.new do |s| 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', - 'test/core/util/forwarding_load_balancing_policy.cc', 'test/core/util/fuzzer_util.cc', 'test/core/util/grpc_profiler.cc', 'test/core/util/histogram.cc', @@ -1227,6 +1226,7 @@ Pod::Spec.new do |s| 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', 'test/core/util/test_config.cc', + 'test/core/util/test_lb_policies.cc', 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -1241,7 +1241,6 @@ Pod::Spec.new do |s| 'test/core/end2end/fixtures/proxy.h', 'test/core/iomgr/endpoint_tests.h', 'test/core/util/debugger_macros.h', - 'test/core/util/forwarding_load_balancing_policy.h', 'test/core/util/fuzzer_util.h', 'test/core/util/grpc_profiler.h', 'test/core/util/histogram.h', @@ -1254,6 +1253,7 @@ Pod::Spec.new do |s| 'test/core/util/slice_splitter.h', 'test/core/util/subprocess.h', 'test/core/util/test_config.h', + 'test/core/util/test_lb_policies.h', 'test/core/util/tracer_util.h', 'test/core/util/trickle_endpoint.h', 'test/core/util/cmdline.h', diff --git a/grpc.gyp b/grpc.gyp index 450aa87e40f..d9002886280 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -611,7 +611,6 @@ 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', - 'test/core/util/forwarding_load_balancing_policy.cc', 'test/core/util/fuzzer_util.cc', 'test/core/util/grpc_profiler.cc', 'test/core/util/histogram.cc', @@ -626,6 +625,7 @@ 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', 'test/core/util/test_config.cc', + 'test/core/util/test_lb_policies.cc', 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -854,7 +854,6 @@ 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', - 'test/core/util/forwarding_load_balancing_policy.cc', 'test/core/util/fuzzer_util.cc', 'test/core/util/grpc_profiler.cc', 'test/core/util/histogram.cc', @@ -869,6 +868,7 @@ 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', 'test/core/util/test_config.cc', + 'test/core/util/test_lb_policies.cc', 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', diff --git a/test/core/util/forwarding_load_balancing_policy.cc b/test/core/util/forwarding_load_balancing_policy.cc deleted file mode 100644 index 0da566d2bac..00000000000 --- a/test/core/util/forwarding_load_balancing_policy.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * 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 "test/core/util/forwarding_load_balancing_policy.h" - -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" -#include "src/core/lib/debug/trace.h" -#include "src/core/lib/iomgr/combiner.h" -#include "src/core/lib/iomgr/pollset_set.h" - -namespace grpc_core { - -TraceFlag grpc_trace_forwarding_lb(false, "forwarding_lb"); - -ForwardingLoadBalancingPolicy::ForwardingLoadBalancingPolicy( - const Args& args, const std::string& delegate_policy_name) - : LoadBalancingPolicy(args) { - delegate_ = - LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - delegate_policy_name.c_str(), args); - grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), - interested_parties()); - // Give re-resolution closure to delegate. - GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, - OnDelegateRequestReresolutionLocked, this, - grpc_combiner_scheduler(combiner())); - Ref().release(); // held by callback. - delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); -} - -ForwardingLoadBalancingPolicy::~ForwardingLoadBalancingPolicy() {} - -void ForwardingLoadBalancingPolicy::OnDelegateRequestReresolutionLocked( - void* arg, grpc_error* error) { - ForwardingLoadBalancingPolicy* self = - static_cast(arg); - if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { - self->Unref(); - return; - } - self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); - self->delegate_->SetReresolutionClosureLocked( - &self->on_delegate_request_reresolution_); -} - -} // namespace grpc_core diff --git a/test/core/util/forwarding_load_balancing_policy.h b/test/core/util/forwarding_load_balancing_policy.h deleted file mode 100644 index b387f2e606e..00000000000 --- a/test/core/util/forwarding_load_balancing_policy.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * 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 - -#include "src/core/ext/filters/client_channel/lb_policy.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/channelz.h" -#include "src/core/lib/gprpp/orphanable.h" -#include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/error.h" -#include "src/core/lib/json/json.h" -#include "src/core/lib/transport/connectivity_state.h" - -#ifndef GRPC_TEST_CORE_UTIL_FORWARDING_LOAD_BALANCING_POLICY_H -#define GRPC_TEST_CORE_UTIL_FORWARDING_LOAD_BALANCING_POLICY_H - -namespace grpc_core { - -// A minimal forwarding class to avoid implementing a standalone test LB. -class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { - public: - ForwardingLoadBalancingPolicy(const Args& args, - const std::string& delegate_policy_name); - - ~ForwardingLoadBalancingPolicy() override; - - const char* name() const override { return delegate_->name(); } - - void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override { - delegate_->UpdateLocked(args, lb_config); - } - - bool PickLocked(PickState* pick, grpc_error** error) override { - return delegate_->PickLocked(pick, error); - } - - void CancelPickLocked(PickState* pick, grpc_error* error) override { - delegate_->CancelPickLocked(pick, error); - } - - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override { - delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, error); - } - - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override { - delegate_->NotifyOnStateChangeLocked(state, closure); - } - - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override { - return delegate_->CheckConnectivityLocked(connectivity_error); - } - - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { - delegate_->HandOffPendingPicksLocked(new_policy); - } - - void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } - - void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } - - void FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) override { - delegate_->FillChildRefsForChannelz(child_subchannels, child_channels); - } - - private: - void ShutdownLocked() override { delegate_.reset(); } - - static void OnDelegateRequestReresolutionLocked(void* arg, - grpc_error* error); - - OrphanablePtr delegate_; - grpc_closure on_delegate_request_reresolution_; -}; - -} // namespace grpc_core - -#endif // GRPC_TEST_CORE_UTIL_FORWARDING_LOAD_BALANCING_POLICY_H diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc new file mode 100644 index 00000000000..6b428af8e71 --- /dev/null +++ b/test/core/util/test_lb_policies.cc @@ -0,0 +1,240 @@ +/* + * + * 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 "test/core/util/test_lb_policies.h" + +#include + +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channelz.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/transport/connectivity_state.h" + +namespace grpc_core { + +TraceFlag grpc_trace_forwarding_lb(false, "forwarding_lb"); + +namespace { + +// +// ForwardingLoadBalancingPolicy +// + +// A minimal forwarding class to avoid implementing a standalone test LB. +class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { + public: + ForwardingLoadBalancingPolicy(const Args& args, + const std::string& delegate_policy_name) + : LoadBalancingPolicy(args) { + delegate_ = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + delegate_policy_name.c_str(), args); + grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), + interested_parties()); + // Give re-resolution closure to delegate. + GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, + OnDelegateRequestReresolutionLocked, this, + grpc_combiner_scheduler(combiner())); + Ref().release(); // held by callback. + delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); + } + + ~ForwardingLoadBalancingPolicy() override = default; + + void UpdateLocked(const grpc_channel_args& args, + grpc_json* lb_config) override { + delegate_->UpdateLocked(args, lb_config); + } + + bool PickLocked(PickState* pick, grpc_error** error) override { + return delegate_->PickLocked(pick, error); + } + + void CancelPickLocked(PickState* pick, grpc_error* error) override { + delegate_->CancelPickLocked(pick, error); + } + + void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) override { + delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, + initial_metadata_flags_eq, error); + } + + void NotifyOnStateChangeLocked(grpc_connectivity_state* state, + grpc_closure* closure) override { + delegate_->NotifyOnStateChangeLocked(state, closure); + } + + grpc_connectivity_state CheckConnectivityLocked( + grpc_error** connectivity_error) override { + return delegate_->CheckConnectivityLocked(connectivity_error); + } + + void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { + delegate_->HandOffPendingPicksLocked(new_policy); + } + + void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } + + void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } + + void FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) override { + delegate_->FillChildRefsForChannelz(child_subchannels, child_channels); + } + + private: + void ShutdownLocked() override { + delegate_.reset(); + TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_CANCELLED); + } + + static void OnDelegateRequestReresolutionLocked(void* arg, + grpc_error* error) { + ForwardingLoadBalancingPolicy* self = + static_cast(arg); + if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { + self->Unref(); + return; + } + self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); + self->delegate_->SetReresolutionClosureLocked( + &self->on_delegate_request_reresolution_); + } + + OrphanablePtr delegate_; + grpc_closure on_delegate_request_reresolution_; +}; + +// +// InterceptRecvTrailingMetadataLoadBalancingPolicy +// + +constexpr char kInterceptRecvTrailingMetadataLbPolicyName[] = + "intercept_trailing_metadata_lb"; + +class InterceptRecvTrailingMetadataLoadBalancingPolicy + : public ForwardingLoadBalancingPolicy { + public: + InterceptRecvTrailingMetadataLoadBalancingPolicy( + const Args& args, InterceptRecvTrailingMetadataCallback cb, + void* user_data) + : ForwardingLoadBalancingPolicy(args, + /*delegate_lb_policy_name=*/"pick_first"), + cb_(cb), user_data_(user_data) {} + + ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; + + const char* name() const override { + return kInterceptRecvTrailingMetadataLbPolicyName; + } + + bool PickLocked(PickState* pick, grpc_error** error) override { + bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); + // Note: This assumes that the delegate policy does not + // intercepting recv_trailing_metadata. If we ever need to use + // this with a delegate policy that does, then we'll need to + // handle async pick returns separately. + New(pick, cb_, user_data_); // deletes itself + return ret; + } + + private: + class TrailingMetadataHandler { + public: + TrailingMetadataHandler(PickState* pick, + InterceptRecvTrailingMetadataCallback cb, + void* user_data) + : cb_(cb), user_data_(user_data) { + GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, + RecordRecvTrailingMetadata, this, + grpc_schedule_on_exec_ctx); + pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; + pick->original_recv_trailing_metadata_ready = + &original_recv_trailing_metadata_ready_; + pick->recv_trailing_metadata = &recv_trailing_metadata_; + } + + private: + static void RecordRecvTrailingMetadata(void* arg, grpc_error* err) { + TrailingMetadataHandler* self = + static_cast(arg); + GPR_ASSERT(self->recv_trailing_metadata_ != nullptr); + self->cb_(self->user_data_); + GRPC_CLOSURE_SCHED(self->original_recv_trailing_metadata_ready_, + GRPC_ERROR_REF(err)); + Delete(self); + } + + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; + grpc_closure recv_trailing_metadata_ready_; + grpc_closure* original_recv_trailing_metadata_ready_ = nullptr; + grpc_metadata_batch* recv_trailing_metadata_ = nullptr; + }; + + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; +}; + +class InterceptTrailingFactory : public LoadBalancingPolicyFactory { + public: + explicit InterceptTrailingFactory( + InterceptRecvTrailingMetadataCallback cb, void* user_data) + : cb_(cb), user_data_(user_data) {} + + grpc_core::OrphanablePtr + CreateLoadBalancingPolicy( + const grpc_core::LoadBalancingPolicy::Args& args) const override { + return grpc_core::OrphanablePtr( + grpc_core::New( + args, cb_, user_data_)); + } + + const char* name() const override { + return kInterceptRecvTrailingMetadataLbPolicyName; + } + + private: + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; +}; + +} // namespace + +void RegisterInterceptRecvTrailingMetadataLoadBalancingPolicy( + InterceptRecvTrailingMetadataCallback cb, void* user_data) { + grpc_core::LoadBalancingPolicyRegistry::Builder:: + RegisterLoadBalancingPolicyFactory( + grpc_core::UniquePtr( + grpc_core::New(cb, user_data))); +} + +} // namespace grpc_core diff --git a/test/core/util/test_lb_policies.h b/test/core/util/test_lb_policies.h new file mode 100644 index 00000000000..6d2693a0d59 --- /dev/null +++ b/test/core/util/test_lb_policies.h @@ -0,0 +1,34 @@ +/* + * + * 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. + * + */ + +#ifndef GRPC_TEST_CORE_UTIL_TEST_LB_POLICIES_H +#define GRPC_TEST_CORE_UTIL_TEST_LB_POLICIES_H + +namespace grpc_core { + +typedef void (*InterceptRecvTrailingMetadataCallback)(void*); + +// Registers an LB policy called "intercept_trailing_metadata_lb" that +// invokes cb with argument user_data when trailing metadata is received +// for each call. +void RegisterInterceptRecvTrailingMetadataLoadBalancingPolicy( + InterceptRecvTrailingMetadataCallback cb, void* user_data); + +} // namespace grpc_core + +#endif // GRPC_TEST_CORE_UTIL_TEST_LB_POLICIES_H diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index b14f85100ad..4a6307a22ca 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -60,8 +60,8 @@ #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" -#include "test/core/util/forwarding_load_balancing_policy.h" #include "test/core/util/test_config.h" +#include "test/core/util/test_lb_policies.h" #include "test/cpp/end2end/test_service_impl.h" #include @@ -1237,112 +1237,25 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { protected: void SetUp() override { ClientLbEnd2endTest::SetUp(); - grpc_core::LoadBalancingPolicyRegistry::Builder:: - RegisterLoadBalancingPolicyFactory( - grpc_core::UniquePtr( - grpc_core::New(this))); + grpc_core::RegisterInterceptRecvTrailingMetadataLoadBalancingPolicy( + ReportTrailerIntercepted, this); } void TearDown() override { ClientLbEnd2endTest::TearDown(); } - class InterceptRecvTrailingMetadataLoadBalancingPolicy - : public grpc_core::ForwardingLoadBalancingPolicy { - public: - InterceptRecvTrailingMetadataLoadBalancingPolicy( - const Args& args, const std::string& delegate_lb_policy_name, - ClientLbInterceptTrailingMetadataTest* test) - : grpc_core::ForwardingLoadBalancingPolicy(args, - delegate_lb_policy_name), - test_(test) {} - - ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; - - bool PickLocked(PickState* pick, grpc_error** error) override { - bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); - // Note: This assumes that the delegate policy does not - // intercepting recv_trailing_metadata. If we ever need to use - // this with a delegate policy that does, then we'll need to - // handle async pick returns separately. - new TrailingMetadataHandler(pick, test_); // deletes itself - return ret; - } - - private: - class TrailingMetadataHandler { - public: - TrailingMetadataHandler(PickState* pick, - ClientLbInterceptTrailingMetadataTest* test) - : test_(test) { - GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, - RecordRecvTrailingMetadata, this, - grpc_schedule_on_exec_ctx); - pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; - pick->original_recv_trailing_metadata_ready = - &original_recv_trailing_metadata_ready_; - pick->recv_trailing_metadata = &recv_trailing_metadata_; - } - - private: - static void RecordRecvTrailingMetadata(void* arg, grpc_error* err) { - TrailingMetadataHandler* self = - static_cast(arg); - GPR_ASSERT(self->recv_trailing_metadata_ != nullptr); - // a simple check to make sure the trailing metadata is valid - GPR_ASSERT( - grpc_get_status_code_from_metadata( - self->recv_trailing_metadata_->idx.named.grpc_status->md) == - grpc_status_code::GRPC_STATUS_OK); - self->test_->ReportTrailerIntercepted(); - GRPC_CLOSURE_SCHED(self->original_recv_trailing_metadata_ready_, - GRPC_ERROR_REF(err)); - delete self; - } - - ClientLbInterceptTrailingMetadataTest* test_; - grpc_closure recv_trailing_metadata_ready_; - grpc_closure* original_recv_trailing_metadata_ready_ = nullptr; - grpc_metadata_batch* recv_trailing_metadata_ = nullptr; - }; - - ClientLbInterceptTrailingMetadataTest* test_; - }; - - // A factory for a test LB policy that intercepts trailing metadata. - // The LB policy is implemented as a wrapper around a delegate LB policy. - class InterceptTrailingFactory - : public grpc_core::LoadBalancingPolicyFactory { - public: - explicit InterceptTrailingFactory( - ClientLbInterceptTrailingMetadataTest* test) - : test_(test) {} - - grpc_core::OrphanablePtr - CreateLoadBalancingPolicy( - const grpc_core::LoadBalancingPolicy::Args& args) const override { - return grpc_core::OrphanablePtr( - grpc_core::New( - args, /*delegate_lb_policy_name=*/ "pick_first", test_)); - } - - const char* name() const override { - return "intercept_trailing_metadata_lb"; - } - - private: - ClientLbInterceptTrailingMetadataTest* test_; - }; - - void ReportTrailerIntercepted() { - std::unique_lock lock(mu_); - trailers_intercepted_++; - } - int trailers_intercepted() { std::unique_lock lock(mu_); return trailers_intercepted_; } private: + static void ReportTrailerIntercepted(void* arg) { + ClientLbInterceptTrailingMetadataTest* self = + static_cast(arg); + std::unique_lock lock(self->mu_); + self->trailers_intercepted_++; + } + std::mutex mu_; int trailers_intercepted_ = 0; }; diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 81fe8573c13..a0e0a8ae769 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10459,7 +10459,6 @@ "test/core/end2end/fixtures/proxy.h", "test/core/iomgr/endpoint_tests.h", "test/core/util/debugger_macros.h", - "test/core/util/forwarding_load_balancing_policy.h", "test/core/util/fuzzer_util.h", "test/core/util/grpc_profiler.h", "test/core/util/histogram.h", @@ -10472,6 +10471,7 @@ "test/core/util/slice_splitter.h", "test/core/util/subprocess.h", "test/core/util/test_config.h", + "test/core/util/test_lb_policies.h", "test/core/util/tracer_util.h", "test/core/util/trickle_endpoint.h" ], @@ -10493,8 +10493,6 @@ "test/core/iomgr/endpoint_tests.h", "test/core/util/debugger_macros.cc", "test/core/util/debugger_macros.h", - "test/core/util/forwarding_load_balancing_policy.cc", - "test/core/util/forwarding_load_balancing_policy.h", "test/core/util/fuzzer_util.cc", "test/core/util/fuzzer_util.h", "test/core/util/grpc_profiler.cc", @@ -10521,6 +10519,8 @@ "test/core/util/subprocess_windows.cc", "test/core/util/test_config.cc", "test/core/util/test_config.h", + "test/core/util/test_lb_policies.cc", + "test/core/util/test_lb_policies.h", "test/core/util/tracer_util.cc", "test/core/util/tracer_util.h", "test/core/util/trickle_endpoint.cc", From d655509e3d965b7b050e1238af5fe7f05c80005b Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 10 Jan 2019 10:52:29 -0800 Subject: [PATCH 494/534] Fix sanity and build. --- test/core/util/BUILD | 6 +++--- test/core/util/test_lb_policies.cc | 14 +++++++------- test/cpp/end2end/BUILD | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 8d50dd2bbac..b931a9d683c 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -156,10 +156,10 @@ sh_library( ) grpc_cc_library( - name = "forwarding_load_balancing_policy", + name = "test_lb_policies", testonly = 1, - srcs = ["forwarding_load_balancing_policy.cc"], - hdrs = ["forwarding_load_balancing_policy.h"], + srcs = ["test_lb_policies.cc"], + hdrs = ["test_lb_policies.h"], deps = [ "//:grpc", ], diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 6b428af8e71..5f042867dd9 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -25,8 +25,8 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channelz.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/combiner.h" @@ -51,9 +51,8 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { ForwardingLoadBalancingPolicy(const Args& args, const std::string& delegate_policy_name) : LoadBalancingPolicy(args) { - delegate_ = - LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - delegate_policy_name.c_str(), args); + delegate_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + delegate_policy_name.c_str(), args); grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), interested_parties()); // Give re-resolution closure to delegate. @@ -148,7 +147,8 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy void* user_data) : ForwardingLoadBalancingPolicy(args, /*delegate_lb_policy_name=*/"pick_first"), - cb_(cb), user_data_(user_data) {} + cb_(cb), + user_data_(user_data) {} ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; @@ -206,8 +206,8 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy class InterceptTrailingFactory : public LoadBalancingPolicyFactory { public: - explicit InterceptTrailingFactory( - InterceptRecvTrailingMetadataCallback cb, void* user_data) + explicit InterceptTrailingFactory(InterceptRecvTrailingMetadataCallback cb, + void* user_data) : cb_(cb), user_data_(user_data) {} grpc_core::OrphanablePtr diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index ae204f580b3..47cb6ba14c3 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -387,8 +387,8 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:forwarding_load_balancing_policy", "//test/core/util:grpc_test_util", + "//test/core/util:test_lb_policies", "//test/cpp/util:test_util", ], ) From 62052d7a12f8dfb12dc7d8c0e933fbb7625c1de1 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 10 Jan 2019 11:22:58 -0800 Subject: [PATCH 495/534] Fix bug in cancellation. --- src/core/ext/filters/client_channel/client_channel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index cc34178d619..35c3efab6aa 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -870,7 +870,7 @@ static void pending_batches_fail(grpc_call_element* elem, grpc_error* error, pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { - if (batch->recv_trailing_metadata) { + if (batch->recv_trailing_metadata && calld->have_request) { maybe_inject_recv_trailing_metadata_ready_for_lb( *calld->request->pick(), batch); } From 7a5a9544ef9afb8456e5241741ceb387153bfb38 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 9 Jan 2019 14:56:42 -0800 Subject: [PATCH 496/534] Add a naive client server implementation --- examples/BUILD | 14 +++ .../cpp/keyvaluestore/caching_interceptor.cc | 0 examples/cpp/keyvaluestore/client.cc | 85 ++++++++++++++++ examples/cpp/keyvaluestore/server.cc | 99 +++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 examples/cpp/keyvaluestore/caching_interceptor.cc create mode 100644 examples/cpp/keyvaluestore/client.cc create mode 100644 examples/cpp/keyvaluestore/server.cc diff --git a/examples/BUILD b/examples/BUILD index b6cb9d48d3c..4fee663bd9e 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -98,3 +98,17 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) + +cc_binary( + name = "keyvaluestore_client", + srcs = ["cpp/keyvaluestore/client.cc"], + defines = ["BAZEL_BUILD"], + deps = [":keyvaluestore", "//:grpc++"], +) + +cc_binary( + name = "keyvaluestore_server", + srcs = ["cpp/keyvaluestore/server.cc"], + defines = ["BAZEL_BUILD"], + deps = [":keyvaluestore", "//:grpc++"], +) \ No newline at end of file diff --git a/examples/cpp/keyvaluestore/caching_interceptor.cc b/examples/cpp/keyvaluestore/caching_interceptor.cc new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/cpp/keyvaluestore/client.cc b/examples/cpp/keyvaluestore/client.cc new file mode 100644 index 00000000000..9f5fa37cb1e --- /dev/null +++ b/examples/cpp/keyvaluestore/client.cc @@ -0,0 +1,85 @@ +/* + * + * 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 +#include +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using keyvaluestore::Request; +using keyvaluestore::Response; +using keyvaluestore::KeyValueStore; + +class KeyValueStoreClient { + public: + KeyValueStoreClient(std::shared_ptr channel) + : stub_(KeyValueStore::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + void GetValues(const std::vector& keys) { + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + auto stream = stub_->GetValues(&context); + for (const auto& key:keys) { + // Data we are sending to the server. + Request request; + request.set_key(key); + stream->Write(request); + + Response response; + stream->Read(&response); + std::cout << key << " : " << response.value() << "\n"; + } + stream->WritesDone(); + Status status = stream->Finish(); + if(!status.ok()) { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + std::cout << "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureChannelCredentials()). + KeyValueStoreClient client(grpc::CreateChannel( + "localhost:50051", grpc::InsecureChannelCredentials())); + std::vector keys = {"key1", "key2", "key3", "key4", "key5"}; + client.GetValues(keys); + + return 0; +} diff --git a/examples/cpp/keyvaluestore/server.cc b/examples/cpp/keyvaluestore/server.cc new file mode 100644 index 00000000000..75d30eb1f88 --- /dev/null +++ b/examples/cpp/keyvaluestore/server.cc @@ -0,0 +1,99 @@ +/* + * + * 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 +#include +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::ServerReaderWriter; +using grpc::Status; +using keyvaluestore::Request; +using keyvaluestore::Response; +using keyvaluestore::KeyValueStore; + +struct kv_pair { + const char* key; + const char* value; +}; + +static const kv_pair kvs_map[] = { + {"key1", "value1"}, + {"key2", "value2"}, + {"key3", "value3"}, + {"key4", "value4"}, + {"key5", "value5"}, +}; + +const char * get_value_from_map(const char* key) { + for(size_t i = 0; i < sizeof(kvs_map) / sizeof(kv_pair); ++i) { + if(strcmp(key, kvs_map[i].key) == 0) { + return kvs_map[i].value; + } + } + return nullptr; +} + +// Logic and data behind the server's behavior. +class KeyValueStoreServiceImpl final : public KeyValueStore::Service { + Status GetValues(ServerContext* context, ServerReaderWriter *stream) override { + Request request; + while(stream->Read(&request)) { + Response response; + response.set_value(get_value_from_map(request.key().c_str())); + stream->Write(response); + } + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + KeyValueStoreServiceImpl service; + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} From f1e9306c702ee83f4808597212824301d3a909a5 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 13:22:37 -0800 Subject: [PATCH 497/534] return empty string instead of nullptr --- examples/cpp/keyvaluestore/server.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cpp/keyvaluestore/server.cc b/examples/cpp/keyvaluestore/server.cc index 75d30eb1f88..8dc8752edab 100644 --- a/examples/cpp/keyvaluestore/server.cc +++ b/examples/cpp/keyvaluestore/server.cc @@ -57,7 +57,7 @@ const char * get_value_from_map(const char* key) { return kvs_map[i].value; } } - return nullptr; + return ""; } // Logic and data behind the server's behavior. From c01e866a88beee6143f19fa243b85d5792c36cae Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 13:25:57 -0800 Subject: [PATCH 498/534] better documentation --- examples/cpp/keyvaluestore/client.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/cpp/keyvaluestore/client.cc b/examples/cpp/keyvaluestore/client.cc index 9f5fa37cb1e..cdf353fafd1 100644 --- a/examples/cpp/keyvaluestore/client.cc +++ b/examples/cpp/keyvaluestore/client.cc @@ -41,19 +41,19 @@ class KeyValueStoreClient { KeyValueStoreClient(std::shared_ptr channel) : stub_(KeyValueStore::NewStub(channel)) {} - // Assembles the client's payload, sends it and presents the response back - // from the server. + // Requests each key in the vector and displays the value as a pair void GetValues(const std::vector& keys) { // Context for the client. It could be used to convey extra information to // the server and/or tweak certain RPC behaviors. ClientContext context; auto stream = stub_->GetValues(&context); for (const auto& key:keys) { - // Data we are sending to the server. + // Key we are sending to the server. Request request; request.set_key(key); stream->Write(request); + // Get the value for the sent key Response response; stream->Read(&response); std::cout << key << " : " << response.value() << "\n"; From aa5950936923437b45dbe75f5d981033ec00a2f9 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 14:13:43 -0800 Subject: [PATCH 499/534] Reviewer comments --- examples/cpp/keyvaluestore/caching_interceptor.cc | 0 examples/cpp/keyvaluestore/client.cc | 3 ++- examples/cpp/keyvaluestore/server.cc | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) delete mode 100644 examples/cpp/keyvaluestore/caching_interceptor.cc diff --git a/examples/cpp/keyvaluestore/caching_interceptor.cc b/examples/cpp/keyvaluestore/caching_interceptor.cc deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/examples/cpp/keyvaluestore/client.cc b/examples/cpp/keyvaluestore/client.cc index cdf353fafd1..e956a165734 100644 --- a/examples/cpp/keyvaluestore/client.cc +++ b/examples/cpp/keyvaluestore/client.cc @@ -41,7 +41,8 @@ class KeyValueStoreClient { KeyValueStoreClient(std::shared_ptr channel) : stub_(KeyValueStore::NewStub(channel)) {} - // Requests each key in the vector and displays the value as a pair + // Requests each key in the vector and displays the key and its corresponding + // value as a pair void GetValues(const std::vector& keys) { // Context for the client. It could be used to convey extra information to // the server and/or tweak certain RPC behaviors. diff --git a/examples/cpp/keyvaluestore/server.cc b/examples/cpp/keyvaluestore/server.cc index 8dc8752edab..515a1ba4c9b 100644 --- a/examples/cpp/keyvaluestore/server.cc +++ b/examples/cpp/keyvaluestore/server.cc @@ -81,7 +81,7 @@ void RunServer() { // Listen on the given address without any authentication mechanism. builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); // Register "service" as the instance through which we'll communicate with - // clients. In this case it corresponds to an *synchronous* service. + // clients. In this case, it corresponds to an *synchronous* service. builder.RegisterService(&service); // Finally assemble the server. std::unique_ptr server(builder.BuildAndStart()); From b72bb30126b8baf8b8140266bad2009e6d3c4ded Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 14:18:24 -0800 Subject: [PATCH 500/534] Clang format --- examples/cpp/keyvaluestore/client.cc | 8 ++++---- examples/cpp/keyvaluestore/server.cc | 20 +++++++++----------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/examples/cpp/keyvaluestore/client.cc b/examples/cpp/keyvaluestore/client.cc index e956a165734..17e407c273b 100644 --- a/examples/cpp/keyvaluestore/client.cc +++ b/examples/cpp/keyvaluestore/client.cc @@ -32,9 +32,9 @@ using grpc::Channel; using grpc::ClientContext; using grpc::Status; +using keyvaluestore::KeyValueStore; using keyvaluestore::Request; using keyvaluestore::Response; -using keyvaluestore::KeyValueStore; class KeyValueStoreClient { public: @@ -48,7 +48,7 @@ class KeyValueStoreClient { // the server and/or tweak certain RPC behaviors. ClientContext context; auto stream = stub_->GetValues(&context); - for (const auto& key:keys) { + for (const auto& key : keys) { // Key we are sending to the server. Request request; request.set_key(key); @@ -61,7 +61,7 @@ class KeyValueStoreClient { } stream->WritesDone(); Status status = stream->Finish(); - if(!status.ok()) { + if (!status.ok()) { std::cout << status.error_code() << ": " << status.error_message() << std::endl; std::cout << "RPC failed"; @@ -79,7 +79,7 @@ int main(int argc, char** argv) { // (use of InsecureChannelCredentials()). KeyValueStoreClient client(grpc::CreateChannel( "localhost:50051", grpc::InsecureChannelCredentials())); - std::vector keys = {"key1", "key2", "key3", "key4", "key5"}; + std::vector keys = {"key1", "key2", "key3", "key4", "key5"}; client.GetValues(keys); return 0; diff --git a/examples/cpp/keyvaluestore/server.cc b/examples/cpp/keyvaluestore/server.cc index 515a1ba4c9b..e75da9c62d1 100644 --- a/examples/cpp/keyvaluestore/server.cc +++ b/examples/cpp/keyvaluestore/server.cc @@ -34,9 +34,9 @@ using grpc::ServerBuilder; using grpc::ServerContext; using grpc::ServerReaderWriter; using grpc::Status; +using keyvaluestore::KeyValueStore; using keyvaluestore::Request; using keyvaluestore::Response; -using keyvaluestore::KeyValueStore; struct kv_pair { const char* key; @@ -44,16 +44,13 @@ struct kv_pair { }; static const kv_pair kvs_map[] = { - {"key1", "value1"}, - {"key2", "value2"}, - {"key3", "value3"}, - {"key4", "value4"}, - {"key5", "value5"}, + {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}, + {"key4", "value4"}, {"key5", "value5"}, }; -const char * get_value_from_map(const char* key) { - for(size_t i = 0; i < sizeof(kvs_map) / sizeof(kv_pair); ++i) { - if(strcmp(key, kvs_map[i].key) == 0) { +const char* get_value_from_map(const char* key) { + for (size_t i = 0; i < sizeof(kvs_map) / sizeof(kv_pair); ++i) { + if (strcmp(key, kvs_map[i].key) == 0) { return kvs_map[i].value; } } @@ -62,9 +59,10 @@ const char * get_value_from_map(const char* key) { // Logic and data behind the server's behavior. class KeyValueStoreServiceImpl final : public KeyValueStore::Service { - Status GetValues(ServerContext* context, ServerReaderWriter *stream) override { + Status GetValues(ServerContext* context, + ServerReaderWriter* stream) override { Request request; - while(stream->Read(&request)) { + while (stream->Read(&request)) { Response response; response.set_value(get_value_from_map(request.key().c_str())); stream->Write(response); From 6e94552a306e9cfcff834e39bc833bcb8055e6fe Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 17:00:49 -0800 Subject: [PATCH 501/534] Add a caching interceptor to the keyvaluestore example --- examples/BUILD | 3 +- .../cpp/keyvaluestore/caching_interceptor.h | 128 ++++++++++++++++++ examples/cpp/keyvaluestore/client.cc | 19 ++- 3 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 examples/cpp/keyvaluestore/caching_interceptor.h diff --git a/examples/BUILD b/examples/BUILD index 4fee663bd9e..0a1ca94a649 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -101,7 +101,8 @@ cc_binary( cc_binary( name = "keyvaluestore_client", - srcs = ["cpp/keyvaluestore/client.cc"], + srcs = ["cpp/keyvaluestore/caching_interceptor.h", + "cpp/keyvaluestore/client.cc"], defines = ["BAZEL_BUILD"], deps = [":keyvaluestore", "//:grpc++"], ) diff --git a/examples/cpp/keyvaluestore/caching_interceptor.h b/examples/cpp/keyvaluestore/caching_interceptor.h new file mode 100644 index 00000000000..393212b83bb --- /dev/null +++ b/examples/cpp/keyvaluestore/caching_interceptor.h @@ -0,0 +1,128 @@ +/* + * + * 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 + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +// This is a naive implementation of a cache. A new cache is for each call. For +// each new key request, the key is first searched in the map and if found. Only +// if the key is not found in the cache do we make a request. +class CachingInterceptor : public grpc::experimental::Interceptor { + public: + CachingInterceptor(grpc::experimental::ClientRpcInfo* info) {} + + void Intercept( + ::grpc::experimental::InterceptorBatchMethods* methods) override { + bool hijack = false; + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints:: + PRE_SEND_INITIAL_METADATA)) { + // Hijack all calls + hijack = true; + // Create a stream on which this interceptor can make requests + stub_ = keyvaluestore::KeyValueStore::NewStub( + methods->GetInterceptedChannel()); + stream_ = stub_->GetValues(&context_); + } + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + // We know that clients perform a Read and a Write in a loop, so we don't + // need to maintain a list of the responses. + std::string requested_key; + const keyvaluestore::Request* req_msg = + static_cast(methods->GetSendMessage()); + if (req_msg != nullptr) { + requested_key = req_msg->key(); + } else { + // The non-serialized form would not be available in certain scenarios, + // so add a fallback + keyvaluestore::Request req_msg; + auto* buffer = methods->GetSerializedSendMessage(); + auto copied_buffer = *buffer; + GPR_ASSERT( + grpc::SerializationTraits::Deserialize( + &copied_buffer, &req_msg) + .ok()); + requested_key = req_msg.key(); + } + + // Check if the key is present in the map + auto search = cached_map_.find(requested_key); + if (search != cached_map_.end()) { + std::cout << "Key " << requested_key << "found in map"; + response_ = search->second; + } else { + std::cout << "Key " << requested_key << "not found in cache"; + // Key was not found in the cache, so make a request + keyvaluestore::Request req; + req.set_key(requested_key); + stream_->Write(req); + keyvaluestore::Response resp; + stream_->Read(&resp); + response_ = resp.value(); + // Insert the pair in the cache for future requests + cached_map_.insert({requested_key, response_}); + } + } + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { + stream_->WritesDone(); + } + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { + keyvaluestore::Response* resp = + static_cast(methods->GetRecvMessage()); + resp->set_value(response_); + } + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { + auto* status = methods->GetRecvStatus(); + *status = grpc::Status::OK; + } + if (hijack) { + methods->Hijack(); + } else { + methods->Proceed(); + } + } + + private: + grpc::ClientContext context_; + std::unique_ptr stub_; + std::unique_ptr< + grpc::ClientReaderWriter> + stream_; + std::map cached_map_; + std::string response_; +}; + +class CachingInterceptorFactory + : public grpc::experimental::ClientInterceptorFactoryInterface { + public: + grpc::experimental::Interceptor* CreateClientInterceptor( + grpc::experimental::ClientRpcInfo* info) override { + return new CachingInterceptor(info); + } +}; \ No newline at end of file diff --git a/examples/cpp/keyvaluestore/client.cc b/examples/cpp/keyvaluestore/client.cc index 17e407c273b..57c451cadf3 100644 --- a/examples/cpp/keyvaluestore/client.cc +++ b/examples/cpp/keyvaluestore/client.cc @@ -23,6 +23,8 @@ #include +#include "caching_interceptor.h" + #ifdef BAZEL_BUILD #include "examples/protos/keyvaluestore.grpc.pb.h" #else @@ -77,9 +79,20 @@ int main(int argc, char** argv) { // are created. This channel models a connection to an endpoint (in this case, // localhost at port 50051). We indicate that the channel isn't authenticated // (use of InsecureChannelCredentials()). - KeyValueStoreClient client(grpc::CreateChannel( - "localhost:50051", grpc::InsecureChannelCredentials())); - std::vector keys = {"key1", "key2", "key3", "key4", "key5"}; + // In this example, we are using a cache which has been added in as an + // interceptor. + grpc::ChannelArguments args; + std::vector< + std::unique_ptr> + interceptor_creators; + interceptor_creators.push_back(std::unique_ptr( + new CachingInterceptorFactory())); + auto channel = grpc::experimental::CreateCustomChannelWithInterceptors( + "localhost:50051", grpc::InsecureChannelCredentials(), args, + std::move(interceptor_creators)); + KeyValueStoreClient client(channel); + std::vector keys = {"key1", "key2", "key3", "key4", + "key5", "key1", "key2", "key4"}; client.GetValues(keys); return 0; From 817fb588af4174fe5095a316e60a481f3be220df Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 17:06:41 -0800 Subject: [PATCH 502/534] Adding a new line at the end of the file --- examples/cpp/keyvaluestore/caching_interceptor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cpp/keyvaluestore/caching_interceptor.h b/examples/cpp/keyvaluestore/caching_interceptor.h index 393212b83bb..a5d130da8dd 100644 --- a/examples/cpp/keyvaluestore/caching_interceptor.h +++ b/examples/cpp/keyvaluestore/caching_interceptor.h @@ -125,4 +125,4 @@ class CachingInterceptorFactory grpc::experimental::ClientRpcInfo* info) override { return new CachingInterceptor(info); } -}; \ No newline at end of file +}; From f36a6e9aeff37b7d14c29e817b9b573359aa5cf5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 10 Jan 2019 18:04:36 -0800 Subject: [PATCH 503/534] Eliminate compiler warning --- src/compiler/objective_c_generator.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc index af5398ec683..e806f46d814 100644 --- a/src/compiler/objective_c_generator.cc +++ b/src/compiler/objective_c_generator.cc @@ -353,20 +353,23 @@ void PrintMethodImplementations(Printer* printer, printer.Print(vars, "@implementation $service_class$\n\n" + "#pragma clang diagnostic push\n" + "#pragma clang diagnostic ignored " + "\"-Wobjc-designated-initializers\"\n\n" "// Designated initializer\n" "- (instancetype)initWithHost:(NSString *)host " "callOptions:(GRPCCallOptions *_Nullable)callOptions {\n" - " self = [super initWithHost:host\n" + " return [super initWithHost:host\n" " packageName:@\"$package$\"\n" " serviceName:@\"$service_name$\"\n" " callOptions:callOptions];\n" - " return self;\n" "}\n\n" "- (instancetype)initWithHost:(NSString *)host {\n" " return [super initWithHost:host\n" " packageName:@\"$package$\"\n" " serviceName:@\"$service_name$\"];\n" - "}\n\n"); + "}\n\n" + "#pragma clang diagnostic pop\n\n"); printer.Print( "// Override superclass initializer to disallow different" @@ -375,6 +378,12 @@ void PrintMethodImplementations(Printer* printer, " packageName:(NSString *)packageName\n" " serviceName:(NSString *)serviceName {\n" " return [self initWithHost:host];\n" + "}\n\n" + "- (instancetype)initWithHost:(NSString *)host\n" + " packageName:(NSString *)packageName\n" + " serviceName:(NSString *)serviceName\n" + " callOptions:(GRPCCallOptions *)callOptions {\n" + " return [self initWithHost:host callOptions:callOptions];\n" "}\n\n"); printer.Print( From b12dd1be055d81a68d535cc052aac804734453df Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Thu, 10 Jan 2019 22:12:03 -0800 Subject: [PATCH 504/534] Fix GrpcCodegen initialization Initializing GrpcCodegen as a global static variable is problematic because it is possible for it to get destructed before the last instance of `GrpcLibraryCodegen` gets destructed and leaves the program dealing with a dangling pointer (imagine a scenario where another thread is using gRPC resources and the main thread tries to join it in an object's destructor after main ends and CoreCodegen is destructed.) In fact, Google style guide explicitly forbids non-trivially-destructible global variables of static storage duration for this and other reasons and the solution in this commit is among the recommended workarounds referenced in https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables --- include/grpcpp/impl/grpc_library.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/grpcpp/impl/grpc_library.h b/include/grpcpp/impl/grpc_library.h index d1f3ff1297b..3711c098790 100644 --- a/include/grpcpp/impl/grpc_library.h +++ b/include/grpcpp/impl/grpc_library.h @@ -35,18 +35,17 @@ class GrpcLibrary final : public GrpcLibraryInterface { void shutdown() override { grpc_shutdown(); } }; -static GrpcLibrary g_gli; -static CoreCodegen g_core_codegen; - /// Instantiating this class ensures the proper initialization of gRPC. class GrpcLibraryInitializer final { public: GrpcLibraryInitializer() { if (grpc::g_glip == nullptr) { - grpc::g_glip = &g_gli; + static auto* const g_gli = new GrpcLibrary(); + grpc::g_glip = g_gli; } if (grpc::g_core_codegen_interface == nullptr) { - grpc::g_core_codegen_interface = &g_core_codegen; + static auto* const g_core_codegen = new CoreCodegen(); + grpc::g_core_codegen_interface = g_core_codegen; } } From 371b987bf41af61488f19e57fc0d2a1c612d35c8 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 11 Jan 2019 09:54:16 -0800 Subject: [PATCH 505/534] Revert turning c-ares on by default --- .../client_channel/resolver/dns/c_ares/dns_resolver_ares.cc | 2 +- templates/test/cpp/naming/resolver_component_tests_defs.include | 1 + test/core/client_channel/resolvers/dns_resolver_test.cc | 2 +- test/cpp/naming/resolver_component_tests_runner.py | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index fba20000ef6..abacd0c960d 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -472,7 +472,7 @@ static grpc_address_resolver_vtable ares_resolver = { grpc_resolve_address_ares, blocking_resolve_address_ares}; static bool should_use_ares(const char* resolver_env) { - return resolver_env == nullptr || gpr_stricmp(resolver_env, "ares") == 0; + return resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0; } void grpc_resolver_dns_ares_init() { diff --git a/templates/test/cpp/naming/resolver_component_tests_defs.include b/templates/test/cpp/naming/resolver_component_tests_defs.include index d38316cbe68..b34845e01a3 100644 --- a/templates/test/cpp/naming/resolver_component_tests_defs.include +++ b/templates/test/cpp/naming/resolver_component_tests_defs.include @@ -55,6 +55,7 @@ if cur_resolver and cur_resolver != 'ares': 'needs to use GRPC_DNS_RESOLVER=ares.')) test_runner_log('Exit 1 without running tests.') sys.exit(1) +os.environ.update({'GRPC_DNS_RESOLVER': 'ares'}) os.environ.update({'GRPC_TRACE': 'cares_resolver'}) def wait_until_dns_server_is_up(args, diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index 6f153cc9bf6..f426eab9592 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -75,7 +75,7 @@ int main(int argc, char** argv) { test_succeeds(dns, "dns:www.google.com"); test_succeeds(dns, "dns:///www.google.com"); char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver_env != nullptr && gpr_stricmp(resolver_env, "native") == 0) { + if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) { test_fails(dns, "dns://8.8.8.8/8.8.8.8:8888"); } else { test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888"); diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index 950a9d4897e..1873eec35bd 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -55,6 +55,7 @@ if cur_resolver and cur_resolver != 'ares': 'needs to use GRPC_DNS_RESOLVER=ares.')) test_runner_log('Exit 1 without running tests.') sys.exit(1) +os.environ.update({'GRPC_DNS_RESOLVER': 'ares'}) os.environ.update({'GRPC_TRACE': 'cares_resolver'}) def wait_until_dns_server_is_up(args, From 95965f71d3e99f6baa4a237e0a7046d51cd0441f Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 11 Jan 2019 10:40:20 -0800 Subject: [PATCH 506/534] Remove network_status_tracker Remove network_status_tracker and its unit test as it does nothing. We can add tests for network status change in another commit. --- BUILD | 6 +- CMakeLists.txt | 8 - Makefile | 8 - build.yaml | 2 - config.m4 | 1 - config.w32 | 1 - gRPC-C++.podspec | 2 - gRPC-Core.podspec | 4 - grpc.gemspec | 2 - grpc.gyp | 6 - package.xml | 2 - src/core/lib/iomgr/iomgr.cc | 3 - src/core/lib/iomgr/network_status_tracker.cc | 36 - src/core/lib/iomgr/network_status_tracker.h | 32 - src/core/lib/iomgr/tcp_custom.cc | 4 - src/core/lib/iomgr/tcp_posix.cc | 13 +- src/core/lib/iomgr/tcp_uv.cc | 1 - src/core/lib/iomgr/tcp_windows.cc | 4 - .../CoreCronetEnd2EndTests.mm | 4 - src/python/grpcio/grpc_core_dependencies.py | 1 - test/core/end2end/end2end_nosec_tests.cc | 8 - test/core/end2end/end2end_tests.cc | 8 - test/core/end2end/gen_build_yaml.py | 1 - test/core/end2end/generate_tests.bzl | 1 - .../end2end/tests/network_status_change.cc | 237 ----- tools/doxygen/Doxyfile.c++.internal | 1 - tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 5 - tools/run_tests/generated/tests.json | 883 +----------------- 29 files changed, 53 insertions(+), 1233 deletions(-) delete mode 100644 src/core/lib/iomgr/network_status_tracker.cc delete mode 100644 src/core/lib/iomgr/network_status_tracker.h delete mode 100644 test/core/end2end/tests/network_status_change.cc diff --git a/BUILD b/BUILD index 453c64ab08c..5f53bbc6f0b 100644 --- a/BUILD +++ b/BUILD @@ -724,6 +724,8 @@ grpc_cc_library( "src/core/lib/iomgr/gethostname_fallback.cc", "src/core/lib/iomgr/gethostname_host_name_max.cc", "src/core/lib/iomgr/gethostname_sysconf.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_posix.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc", "src/core/lib/iomgr/internal_errqueue.cc", "src/core/lib/iomgr/iocp_windows.cc", "src/core/lib/iomgr/iomgr.cc", @@ -732,11 +734,8 @@ grpc_cc_library( "src/core/lib/iomgr/iomgr_posix.cc", "src/core/lib/iomgr/iomgr_windows.cc", "src/core/lib/iomgr/is_epollexclusive_available.cc", - "src/core/lib/iomgr/grpc_if_nametoindex_posix.cc", - "src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc", "src/core/lib/iomgr/load_file.cc", "src/core/lib/iomgr/lockfree_event.cc", - "src/core/lib/iomgr/network_status_tracker.cc", "src/core/lib/iomgr/polling_entity.cc", "src/core/lib/iomgr/pollset.cc", "src/core/lib/iomgr/pollset_custom.cc", @@ -886,7 +885,6 @@ grpc_cc_library( "src/core/lib/iomgr/load_file.h", "src/core/lib/iomgr/lockfree_event.h", "src/core/lib/iomgr/nameser.h", - "src/core/lib/iomgr/network_status_tracker.h", "src/core/lib/iomgr/polling_entity.h", "src/core/lib/iomgr/pollset.h", "src/core/lib/iomgr/pollset_custom.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 38f8ad915ff..13d5aca6584 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1008,7 +1008,6 @@ add_library(grpc src/core/lib/iomgr/is_epollexclusive_available.cc src/core/lib/iomgr/load_file.cc src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/network_status_tracker.cc src/core/lib/iomgr/polling_entity.cc src/core/lib/iomgr/pollset.cc src/core/lib/iomgr/pollset_custom.cc @@ -1432,7 +1431,6 @@ add_library(grpc_cronet src/core/lib/iomgr/is_epollexclusive_available.cc src/core/lib/iomgr/load_file.cc src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/network_status_tracker.cc src/core/lib/iomgr/polling_entity.cc src/core/lib/iomgr/pollset.cc src/core/lib/iomgr/pollset_custom.cc @@ -1840,7 +1838,6 @@ add_library(grpc_test_util src/core/lib/iomgr/is_epollexclusive_available.cc src/core/lib/iomgr/load_file.cc src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/network_status_tracker.cc src/core/lib/iomgr/polling_entity.cc src/core/lib/iomgr/pollset.cc src/core/lib/iomgr/pollset_custom.cc @@ -2164,7 +2161,6 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/is_epollexclusive_available.cc src/core/lib/iomgr/load_file.cc src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/network_status_tracker.cc src/core/lib/iomgr/polling_entity.cc src/core/lib/iomgr/pollset.cc src/core/lib/iomgr/pollset_custom.cc @@ -2465,7 +2461,6 @@ add_library(grpc_unsecure src/core/lib/iomgr/is_epollexclusive_available.cc src/core/lib/iomgr/load_file.cc src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/network_status_tracker.cc src/core/lib/iomgr/polling_entity.cc src/core/lib/iomgr/pollset.cc src/core/lib/iomgr/pollset_custom.cc @@ -3352,7 +3347,6 @@ add_library(grpc++_cronet src/core/lib/iomgr/is_epollexclusive_available.cc src/core/lib/iomgr/load_file.cc src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/network_status_tracker.cc src/core/lib/iomgr/polling_entity.cc src/core/lib/iomgr/pollset.cc src/core/lib/iomgr/pollset_custom.cc @@ -5609,7 +5603,6 @@ add_library(end2end_tests test/core/end2end/tests/max_connection_idle.cc test/core/end2end/tests/max_message_length.cc test/core/end2end/tests/negative_deadline.cc - test/core/end2end/tests/network_status_change.cc test/core/end2end/tests/no_error_on_hotpath.cc test/core/end2end/tests/no_logging.cc test/core/end2end/tests/no_op.cc @@ -5733,7 +5726,6 @@ add_library(end2end_nosec_tests test/core/end2end/tests/max_connection_idle.cc test/core/end2end/tests/max_message_length.cc test/core/end2end/tests/negative_deadline.cc - test/core/end2end/tests/network_status_change.cc test/core/end2end/tests/no_error_on_hotpath.cc test/core/end2end/tests/no_logging.cc test/core/end2end/tests/no_op.cc diff --git a/Makefile b/Makefile index 504ef409630..00186d891c6 100644 --- a/Makefile +++ b/Makefile @@ -3525,7 +3525,6 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ @@ -3943,7 +3942,6 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ @@ -4344,7 +4342,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ @@ -4655,7 +4652,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ @@ -4930,7 +4926,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ @@ -5794,7 +5789,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ @@ -10379,7 +10373,6 @@ LIBEND2END_TESTS_SRC = \ test/core/end2end/tests/max_connection_idle.cc \ test/core/end2end/tests/max_message_length.cc \ test/core/end2end/tests/negative_deadline.cc \ - test/core/end2end/tests/network_status_change.cc \ test/core/end2end/tests/no_error_on_hotpath.cc \ test/core/end2end/tests/no_logging.cc \ test/core/end2end/tests/no_op.cc \ @@ -10496,7 +10489,6 @@ LIBEND2END_NOSEC_TESTS_SRC = \ test/core/end2end/tests/max_connection_idle.cc \ test/core/end2end/tests/max_message_length.cc \ test/core/end2end/tests/negative_deadline.cc \ - test/core/end2end/tests/network_status_change.cc \ test/core/end2end/tests/no_error_on_hotpath.cc \ test/core/end2end/tests/no_logging.cc \ test/core/end2end/tests/no_op.cc \ diff --git a/build.yaml b/build.yaml index 28375c82589..c7b4d751731 100644 --- a/build.yaml +++ b/build.yaml @@ -289,7 +289,6 @@ filegroups: - src/core/lib/iomgr/is_epollexclusive_available.cc - src/core/lib/iomgr/load_file.cc - src/core/lib/iomgr/lockfree_event.cc - - src/core/lib/iomgr/network_status_tracker.cc - src/core/lib/iomgr/polling_entity.cc - src/core/lib/iomgr/pollset.cc - src/core/lib/iomgr/pollset_custom.cc @@ -465,7 +464,6 @@ filegroups: - src/core/lib/iomgr/load_file.h - src/core/lib/iomgr/lockfree_event.h - src/core/lib/iomgr/nameser.h - - src/core/lib/iomgr/network_status_tracker.h - src/core/lib/iomgr/polling_entity.h - src/core/lib/iomgr/pollset.h - src/core/lib/iomgr/pollset_custom.h diff --git a/config.m4 b/config.m4 index 3c3c0210d87..ccb218a1200 100644 --- a/config.m4 +++ b/config.m4 @@ -141,7 +141,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ diff --git a/config.w32 b/config.w32 index f87859ad09f..fd48ec6f485 100644 --- a/config.w32 +++ b/config.w32 @@ -116,7 +116,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\is_epollexclusive_available.cc " + "src\\core\\lib\\iomgr\\load_file.cc " + "src\\core\\lib\\iomgr\\lockfree_event.cc " + - "src\\core\\lib\\iomgr\\network_status_tracker.cc " + "src\\core\\lib\\iomgr\\polling_entity.cc " + "src\\core\\lib\\iomgr\\pollset.cc " + "src\\core\\lib\\iomgr\\pollset_custom.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 4e0a471fb44..bf124304487 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -434,7 +434,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/load_file.h', 'src/core/lib/iomgr/lockfree_event.h', 'src/core/lib/iomgr/nameser.h', - 'src/core/lib/iomgr/network_status_tracker.h', 'src/core/lib/iomgr/polling_entity.h', 'src/core/lib/iomgr/pollset.h', 'src/core/lib/iomgr/pollset_custom.h', @@ -628,7 +627,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/load_file.h', 'src/core/lib/iomgr/lockfree_event.h', 'src/core/lib/iomgr/nameser.h', - 'src/core/lib/iomgr/network_status_tracker.h', 'src/core/lib/iomgr/polling_entity.h', 'src/core/lib/iomgr/pollset.h', 'src/core/lib/iomgr/pollset_custom.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 4e4c8662411..60f34ebd6a2 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -428,7 +428,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/load_file.h', 'src/core/lib/iomgr/lockfree_event.h', 'src/core/lib/iomgr/nameser.h', - 'src/core/lib/iomgr/network_status_tracker.h', 'src/core/lib/iomgr/polling_entity.h', 'src/core/lib/iomgr/pollset.h', 'src/core/lib/iomgr/pollset_custom.h', @@ -585,7 +584,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/is_epollexclusive_available.cc', 'src/core/lib/iomgr/load_file.cc', 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', 'src/core/lib/iomgr/polling_entity.cc', 'src/core/lib/iomgr/pollset.cc', 'src/core/lib/iomgr/pollset_custom.cc', @@ -1054,7 +1052,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/load_file.h', 'src/core/lib/iomgr/lockfree_event.h', 'src/core/lib/iomgr/nameser.h', - 'src/core/lib/iomgr/network_status_tracker.h', 'src/core/lib/iomgr/polling_entity.h', 'src/core/lib/iomgr/pollset.h', 'src/core/lib/iomgr/pollset_custom.h', @@ -1300,7 +1297,6 @@ Pod::Spec.new do |s| 'test/core/end2end/tests/max_connection_idle.cc', 'test/core/end2end/tests/max_message_length.cc', 'test/core/end2end/tests/negative_deadline.cc', - 'test/core/end2end/tests/network_status_change.cc', 'test/core/end2end/tests/no_error_on_hotpath.cc', 'test/core/end2end/tests/no_logging.cc', 'test/core/end2end/tests/no_op.cc', diff --git a/grpc.gemspec b/grpc.gemspec index 42b1db35b4d..60c5bc480b6 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -364,7 +364,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/load_file.h ) s.files += %w( src/core/lib/iomgr/lockfree_event.h ) s.files += %w( src/core/lib/iomgr/nameser.h ) - s.files += %w( src/core/lib/iomgr/network_status_tracker.h ) s.files += %w( src/core/lib/iomgr/polling_entity.h ) s.files += %w( src/core/lib/iomgr/pollset.h ) s.files += %w( src/core/lib/iomgr/pollset_custom.h ) @@ -521,7 +520,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/is_epollexclusive_available.cc ) s.files += %w( src/core/lib/iomgr/load_file.cc ) s.files += %w( src/core/lib/iomgr/lockfree_event.cc ) - s.files += %w( src/core/lib/iomgr/network_status_tracker.cc ) s.files += %w( src/core/lib/iomgr/polling_entity.cc ) s.files += %w( src/core/lib/iomgr/pollset.cc ) s.files += %w( src/core/lib/iomgr/pollset_custom.cc ) diff --git a/grpc.gyp b/grpc.gyp index 13b9c1bc78b..1f5b6384975 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -323,7 +323,6 @@ 'src/core/lib/iomgr/is_epollexclusive_available.cc', 'src/core/lib/iomgr/load_file.cc', 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', 'src/core/lib/iomgr/polling_entity.cc', 'src/core/lib/iomgr/pollset.cc', 'src/core/lib/iomgr/pollset_custom.cc', @@ -687,7 +686,6 @@ 'src/core/lib/iomgr/is_epollexclusive_available.cc', 'src/core/lib/iomgr/load_file.cc', 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', 'src/core/lib/iomgr/polling_entity.cc', 'src/core/lib/iomgr/pollset.cc', 'src/core/lib/iomgr/pollset_custom.cc', @@ -931,7 +929,6 @@ 'src/core/lib/iomgr/is_epollexclusive_available.cc', 'src/core/lib/iomgr/load_file.cc', 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', 'src/core/lib/iomgr/polling_entity.cc', 'src/core/lib/iomgr/pollset.cc', 'src/core/lib/iomgr/pollset_custom.cc', @@ -1152,7 +1149,6 @@ 'src/core/lib/iomgr/is_epollexclusive_available.cc', 'src/core/lib/iomgr/load_file.cc', 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', 'src/core/lib/iomgr/polling_entity.cc', 'src/core/lib/iomgr/pollset.cc', 'src/core/lib/iomgr/pollset_custom.cc', @@ -2721,7 +2717,6 @@ 'test/core/end2end/tests/max_connection_idle.cc', 'test/core/end2end/tests/max_message_length.cc', 'test/core/end2end/tests/negative_deadline.cc', - 'test/core/end2end/tests/network_status_change.cc', 'test/core/end2end/tests/no_error_on_hotpath.cc', 'test/core/end2end/tests/no_logging.cc', 'test/core/end2end/tests/no_op.cc', @@ -2811,7 +2806,6 @@ 'test/core/end2end/tests/max_connection_idle.cc', 'test/core/end2end/tests/max_message_length.cc', 'test/core/end2end/tests/negative_deadline.cc', - 'test/core/end2end/tests/network_status_change.cc', 'test/core/end2end/tests/no_error_on_hotpath.cc', 'test/core/end2end/tests/no_logging.cc', 'test/core/end2end/tests/no_op.cc', diff --git a/package.xml b/package.xml index de5c56f4511..81a4aabdf5a 100644 --- a/package.xml +++ b/package.xml @@ -369,7 +369,6 @@ - @@ -526,7 +525,6 @@ - diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index a4921468578..dcc69332e0b 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -38,7 +38,6 @@ #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/internal_errqueue.h" #include "src/core/lib/iomgr/iomgr_internal.h" -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/timer_manager.h" @@ -57,7 +56,6 @@ void grpc_iomgr_init() { grpc_timer_list_init(); g_root_object.next = g_root_object.prev = &g_root_object; g_root_object.name = (char*)"root"; - grpc_network_status_init(); grpc_iomgr_platform_init(); grpc_core::grpc_errqueue_init(); } @@ -152,7 +150,6 @@ void grpc_iomgr_shutdown() { gpr_mu_unlock(&g_mu); grpc_iomgr_platform_shutdown(); - grpc_network_status_shutdown(); gpr_mu_destroy(&g_mu); gpr_cv_destroy(&g_rcv); } diff --git a/src/core/lib/iomgr/network_status_tracker.cc b/src/core/lib/iomgr/network_status_tracker.cc deleted file mode 100644 index d4b7f4a57d1..00000000000 --- a/src/core/lib/iomgr/network_status_tracker.cc +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * Copyright 2015 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 - -#include "src/core/lib/iomgr/endpoint.h" -#include "src/core/lib/iomgr/network_status_tracker.h" - -void grpc_network_status_shutdown(void) {} - -void grpc_network_status_init(void) { - // TODO(makarandd): Install callback with OS to monitor network status. -} - -void grpc_destroy_network_status_monitor() {} - -void grpc_network_status_register_endpoint(grpc_endpoint* ep) { (void)ep; } - -void grpc_network_status_unregister_endpoint(grpc_endpoint* ep) { (void)ep; } - -void grpc_network_status_shutdown_all_endpoints() {} diff --git a/src/core/lib/iomgr/network_status_tracker.h b/src/core/lib/iomgr/network_status_tracker.h deleted file mode 100644 index 198877f60f8..00000000000 --- a/src/core/lib/iomgr/network_status_tracker.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H -#define GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H -#include - -#include "src/core/lib/iomgr/endpoint.h" - -void grpc_network_status_init(void); -void grpc_network_status_shutdown(void); - -void grpc_network_status_register_endpoint(grpc_endpoint* ep); -void grpc_network_status_unregister_endpoint(grpc_endpoint* ep); -void grpc_network_status_shutdown_all_endpoints(); - -#endif /* GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H */ diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc index f7a5f36cdcd..1e5696e1279 100644 --- a/src/core/lib/iomgr/tcp_custom.cc +++ b/src/core/lib/iomgr/tcp_custom.cc @@ -31,7 +31,6 @@ #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/iomgr_custom.h" -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/iomgr/tcp_custom.h" @@ -309,7 +308,6 @@ static void custom_close_callback(grpc_custom_socket* socket) { } static void endpoint_destroy(grpc_endpoint* ep) { - grpc_network_status_unregister_endpoint(ep); custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep; grpc_custom_socket_vtable->close(tcp->socket, custom_close_callback); } @@ -361,8 +359,6 @@ grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket, tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string); grpc_resource_user_slice_allocator_init( &tcp->slice_allocator, tcp->resource_user, tcp_read_allocation_done, tcp); - /* Tell network status tracking code about the new endpoint */ - grpc_network_status_register_endpoint(&tcp->base); return &tcp->base; } diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index c268c18664a..d0642c015ff 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -22,7 +22,6 @@ #ifdef GRPC_POSIX_SOCKET_TCP -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/tcp_posix.h" #include @@ -127,9 +126,8 @@ struct grpc_tcp { bool socket_ts_enabled; /* True if timestamping options are set on the socket */ bool ts_capable; /* Cache whether we can set timestamping options */ - gpr_atm - stop_error_notification; /* Set to 1 if we do not want to be notified on - errors anymore */ + gpr_atm stop_error_notification; /* Set to 1 if we do not want to be notified + on errors anymore */ }; struct backup_poller { @@ -388,7 +386,6 @@ static void tcp_ref(grpc_tcp* tcp) { gpr_ref(&tcp->refcount); } #endif static void tcp_destroy(grpc_endpoint* ep) { - grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = reinterpret_cast(ep); grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { @@ -701,7 +698,8 @@ static void process_errors(grpc_tcp* tcp) { union { char rbuf[1024 /*CMSG_SPACE(sizeof(scm_timestamping)) + - CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in))*/]; + CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in))*/ + ]; struct cmsghdr align; } aligned_buf; memset(&aligned_buf, 0, sizeof(aligned_buf)); @@ -1131,8 +1129,6 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string); grpc_resource_user_slice_allocator_init( &tcp->slice_allocator, tcp->resource_user, tcp_read_allocation_done, tcp); - /* Tell network status tracker about new endpoint */ - grpc_network_status_register_endpoint(&tcp->base); grpc_resource_quota_unref_internal(resource_quota); gpr_mu_init(&tcp->tb_mu); tcp->tb_head = nullptr; @@ -1159,7 +1155,6 @@ int grpc_tcp_fd(grpc_endpoint* ep) { void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, grpc_closure* done) { - grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = reinterpret_cast(ep); GPR_ASSERT(ep->vtable == &vtable); tcp->release_fd = fd; diff --git a/src/core/lib/iomgr/tcp_uv.cc b/src/core/lib/iomgr/tcp_uv.cc index 8d0e4a5e79e..e53ff472fef 100644 --- a/src/core/lib/iomgr/tcp_uv.cc +++ b/src/core/lib/iomgr/tcp_uv.cc @@ -33,7 +33,6 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/iomgr_custom.h" -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/resolve_address_custom.h" #include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/iomgr/tcp_custom.h" diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 86ee1010cf7..43817c5a024 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -24,7 +24,6 @@ #include -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/sockaddr_windows.h" #include @@ -470,7 +469,6 @@ static void win_shutdown(grpc_endpoint* ep, grpc_error* why) { } static void win_destroy(grpc_endpoint* ep) { - grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = (grpc_tcp*)ep; grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); TCP_UNREF(tcp, "destroy"); @@ -526,8 +524,6 @@ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, tcp->peer_string = gpr_strdup(peer_string); grpc_slice_buffer_init(&tcp->last_read_buffer); tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string); - /* Tell network status tracking code about the new endpoint */ - grpc_network_status_register_endpoint(&tcp->base); grpc_resource_quota_unref_internal(resource_quota); return &tcp->base; diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm index fe85e915d4d..2fac1be3d0e 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm @@ -318,10 +318,6 @@ static char *roots_filename; [self testIndividualCase:(char *)"negative_deadline"]; } -- (void)testNetworkStatusChange { - [self testIndividualCase:(char *)"network_status_change"]; -} - - (void)testNoOp { [self testIndividualCase:(char *)"no_op"]; } diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 06de23903cb..f5e43ca657e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -115,7 +115,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/is_epollexclusive_available.cc', 'src/core/lib/iomgr/load_file.cc', 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', 'src/core/lib/iomgr/polling_entity.cc', 'src/core/lib/iomgr/pollset.cc', 'src/core/lib/iomgr/pollset_custom.cc', diff --git a/test/core/end2end/end2end_nosec_tests.cc b/test/core/end2end/end2end_nosec_tests.cc index c6a4005fb3e..614d1f98e2b 100644 --- a/test/core/end2end/end2end_nosec_tests.cc +++ b/test/core/end2end/end2end_nosec_tests.cc @@ -98,8 +98,6 @@ extern void max_message_length(grpc_end2end_test_config config); extern void max_message_length_pre_init(void); extern void negative_deadline(grpc_end2end_test_config config); extern void negative_deadline_pre_init(void); -extern void network_status_change(grpc_end2end_test_config config); -extern void network_status_change_pre_init(void); extern void no_error_on_hotpath(grpc_end2end_test_config config); extern void no_error_on_hotpath_pre_init(void); extern void no_logging(grpc_end2end_test_config config); @@ -223,7 +221,6 @@ void grpc_end2end_tests_pre_init(void) { max_connection_idle_pre_init(); max_message_length_pre_init(); negative_deadline_pre_init(); - network_status_change_pre_init(); no_error_on_hotpath_pre_init(); no_logging_pre_init(); no_op_pre_init(); @@ -309,7 +306,6 @@ void grpc_end2end_tests(int argc, char **argv, max_connection_idle(config); max_message_length(config); negative_deadline(config); - network_status_change(config); no_error_on_hotpath(config); no_logging(config); no_op(config); @@ -492,10 +488,6 @@ void grpc_end2end_tests(int argc, char **argv, negative_deadline(config); continue; } - if (0 == strcmp("network_status_change", argv[i])) { - network_status_change(config); - continue; - } if (0 == strcmp("no_error_on_hotpath", argv[i])) { no_error_on_hotpath(config); continue; diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc index 7748a39cb59..9d3d231b3c5 100644 --- a/test/core/end2end/end2end_tests.cc +++ b/test/core/end2end/end2end_tests.cc @@ -100,8 +100,6 @@ extern void max_message_length(grpc_end2end_test_config config); extern void max_message_length_pre_init(void); extern void negative_deadline(grpc_end2end_test_config config); extern void negative_deadline_pre_init(void); -extern void network_status_change(grpc_end2end_test_config config); -extern void network_status_change_pre_init(void); extern void no_error_on_hotpath(grpc_end2end_test_config config); extern void no_error_on_hotpath_pre_init(void); extern void no_logging(grpc_end2end_test_config config); @@ -226,7 +224,6 @@ void grpc_end2end_tests_pre_init(void) { max_connection_idle_pre_init(); max_message_length_pre_init(); negative_deadline_pre_init(); - network_status_change_pre_init(); no_error_on_hotpath_pre_init(); no_logging_pre_init(); no_op_pre_init(); @@ -313,7 +310,6 @@ void grpc_end2end_tests(int argc, char **argv, max_connection_idle(config); max_message_length(config); negative_deadline(config); - network_status_change(config); no_error_on_hotpath(config); no_logging(config); no_op(config); @@ -500,10 +496,6 @@ void grpc_end2end_tests(int argc, char **argv, negative_deadline(config); continue; } - if (0 == strcmp("network_status_change", argv[i])) { - network_status_change(config); - continue; - } if (0 == strcmp("no_error_on_hotpath", argv[i])) { no_error_on_hotpath(config); continue; diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 28a7a4e25d6..0ff1b7ee796 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -146,7 +146,6 @@ END2END_TESTS = { proxyable=False, exclude_iomgrs=['uv'], cpu_cost=LOWCPU), 'max_message_length': default_test_options._replace(cpu_cost=LOWCPU), 'negative_deadline': default_test_options, - 'network_status_change': default_test_options._replace(cpu_cost=LOWCPU), 'no_error_on_hotpath': default_test_options._replace(proxyable=False), 'no_logging': default_test_options._replace(traceable=False), 'no_op': default_test_options, diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 853619fcdaf..ec32aa5102c 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -234,7 +234,6 @@ END2END_TESTS = { "max_connection_idle": _test_options(needs_fullstack = True, proxyable = False), "max_message_length": _test_options(), "negative_deadline": _test_options(), - "network_status_change": _test_options(), "no_error_on_hotpath": _test_options(proxyable = False), "no_logging": _test_options(traceable = False), "no_op": _test_options(), diff --git a/test/core/end2end/tests/network_status_change.cc b/test/core/end2end/tests/network_status_change.cc deleted file mode 100644 index 98a95582046..00000000000 --- a/test/core/end2end/tests/network_status_change.cc +++ /dev/null @@ -1,237 +0,0 @@ -/* - * - * Copyright 2015 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 "test/core/end2end/end2end_tests.h" - -#include -#include - -#include -#include -#include -#include -#include "test/core/end2end/cq_verifier.h" - -/* this is a private API but exposed here for testing*/ -extern void grpc_network_status_shutdown_all_endpoints(); - -static void* tag(intptr_t t) { return (void*)t; } - -static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, - const char* test_name, - grpc_channel_args* client_args, - grpc_channel_args* server_args) { - grpc_end2end_test_fixture f; - gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); - f = config.create_fixture(client_args, server_args); - config.init_server(&f, server_args); - config.init_client(&f, client_args); - return f; -} - -static gpr_timespec n_seconds_from_now(int n) { - return grpc_timeout_seconds_to_deadline(n); -} - -static gpr_timespec five_seconds_from_now(void) { - return n_seconds_from_now(500); -} - -static void drain_cq(grpc_completion_queue* cq) { - grpc_event ev; - do { - ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); - } while (ev.type != GRPC_QUEUE_SHUTDOWN); -} - -static void shutdown_server(grpc_end2end_test_fixture* f) { - if (!f->server) return; - grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), - grpc_timeout_seconds_to_deadline(5), - nullptr) - .type == GRPC_OP_COMPLETE); - grpc_server_destroy(f->server); - f->server = nullptr; -} - -static void shutdown_client(grpc_end2end_test_fixture* f) { - if (!f->client) return; - grpc_channel_destroy(f->client); - f->client = nullptr; -} - -static void end_test(grpc_end2end_test_fixture* f) { - shutdown_server(f); - shutdown_client(f); - - grpc_completion_queue_shutdown(f->cq); - drain_cq(f->cq); - grpc_completion_queue_destroy(f->cq); - grpc_completion_queue_destroy(f->shutdown_cq); -} - -/* Client sends a request with payload, server reads then returns status. */ -static void test_invoke_network_status_change(grpc_end2end_test_config config) { - grpc_call* c; - grpc_call* s; - 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_end2end_test_fixture f = - begin_test(config, "test_invoke_request_with_payload", nullptr, nullptr); - cq_verifier* cqv = cq_verifier_create(f.cq); - grpc_op ops[6]; - grpc_op* op; - grpc_metadata_array initial_metadata_recv; - grpc_metadata_array trailing_metadata_recv; - grpc_metadata_array request_metadata_recv; - grpc_byte_buffer* request_payload_recv = nullptr; - grpc_call_details call_details; - grpc_status_code status; - grpc_call_error error; - grpc_slice details; - int was_cancelled = 2; - - gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), nullptr, - deadline, nullptr); - GPR_ASSERT(c); - - grpc_metadata_array_init(&initial_metadata_recv); - grpc_metadata_array_init(&trailing_metadata_recv); - grpc_metadata_array_init(&request_metadata_recv); - grpc_call_details_init(&call_details); - - memset(ops, 0, sizeof(ops)); - op = ops; - op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = 0; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_SEND_MESSAGE; - op->data.send_message.send_message = request_payload; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_INITIAL_METADATA; - op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; - op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; - op->data.recv_status_on_client.status = &status; - op->data.recv_status_on_client.status_details = &details; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(c, ops, static_cast(op - ops), tag(1), - nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( - f.server, &s, &call_details, - &request_metadata_recv, f.cq, f.cq, tag(101))); - CQ_EXPECT_COMPLETION(cqv, tag(101), 1); - cq_verify(cqv); - - op = ops; - op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = 0; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message.recv_message = &request_payload_recv; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(102), - nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - CQ_EXPECT_COMPLETION(cqv, tag(102), 1); - cq_verify(cqv); - - // Simulate the network loss event - grpc_network_status_shutdown_all_endpoints(); - - op = ops; - op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; - op->data.recv_close_on_server.cancelled = &was_cancelled; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; - op->data.send_status_from_server.trailing_metadata_count = 0; - op->data.send_status_from_server.status = GRPC_STATUS_OK; - grpc_slice status_details = grpc_slice_from_static_string("xyz"); - op->data.send_status_from_server.status_details = &status_details; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(103), - nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - CQ_EXPECT_COMPLETION(cqv, tag(103), 1); - CQ_EXPECT_COMPLETION(cqv, tag(1), 1); - cq_verify(cqv); - - // TODO(makdharma) Update this when the shutdown_all_endpoints is implemented. - // Expected behavior of a RPC when network is lost. - // GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); - GPR_ASSERT(status == GRPC_STATUS_OK); - - GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - - grpc_slice_unref(details); - grpc_metadata_array_destroy(&initial_metadata_recv); - grpc_metadata_array_destroy(&trailing_metadata_recv); - grpc_metadata_array_destroy(&request_metadata_recv); - grpc_call_details_destroy(&call_details); - - grpc_call_unref(c); - grpc_call_unref(s); - - cq_verifier_destroy(cqv); - - grpc_byte_buffer_destroy(request_payload); - grpc_byte_buffer_destroy(request_payload_recv); - - end_test(&f); - config.tear_down_data(&f); -} - -void network_status_change(grpc_end2end_test_config config) { - if (config.feature_mask & - FEATURE_MASK_DOES_NOT_SUPPORT_NETWORK_STATUS_CHANGE) { - return; - } - test_invoke_network_status_change(config); -} - -void network_status_change_pre_init(void) {} diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index a76a261d071..363df22aa15 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1111,7 +1111,6 @@ src/core/lib/iomgr/is_epollexclusive_available.h \ src/core/lib/iomgr/load_file.h \ src/core/lib/iomgr/lockfree_event.h \ src/core/lib/iomgr/nameser.h \ -src/core/lib/iomgr/network_status_tracker.h \ src/core/lib/iomgr/polling_entity.h \ src/core/lib/iomgr/pollset.h \ src/core/lib/iomgr/pollset_custom.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 38d17b6f21f..bb350550e94 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1238,8 +1238,6 @@ src/core/lib/iomgr/load_file.h \ src/core/lib/iomgr/lockfree_event.cc \ src/core/lib/iomgr/lockfree_event.h \ src/core/lib/iomgr/nameser.h \ -src/core/lib/iomgr/network_status_tracker.cc \ -src/core/lib/iomgr/network_status_tracker.h \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/polling_entity.h \ src/core/lib/iomgr/pollset.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 1478ac2cd5e..197de64dbe1 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8809,7 +8809,6 @@ "test/core/end2end/tests/max_connection_idle.cc", "test/core/end2end/tests/max_message_length.cc", "test/core/end2end/tests/negative_deadline.cc", - "test/core/end2end/tests/network_status_change.cc", "test/core/end2end/tests/no_error_on_hotpath.cc", "test/core/end2end/tests/no_logging.cc", "test/core/end2end/tests/no_op.cc", @@ -8908,7 +8907,6 @@ "test/core/end2end/tests/max_connection_idle.cc", "test/core/end2end/tests/max_message_length.cc", "test/core/end2end/tests/negative_deadline.cc", - "test/core/end2end/tests/network_status_change.cc", "test/core/end2end/tests/no_error_on_hotpath.cc", "test/core/end2end/tests/no_logging.cc", "test/core/end2end/tests/no_op.cc", @@ -9416,7 +9414,6 @@ "src/core/lib/iomgr/is_epollexclusive_available.cc", "src/core/lib/iomgr/load_file.cc", "src/core/lib/iomgr/lockfree_event.cc", - "src/core/lib/iomgr/network_status_tracker.cc", "src/core/lib/iomgr/polling_entity.cc", "src/core/lib/iomgr/pollset.cc", "src/core/lib/iomgr/pollset_custom.cc", @@ -9593,7 +9590,6 @@ "src/core/lib/iomgr/load_file.h", "src/core/lib/iomgr/lockfree_event.h", "src/core/lib/iomgr/nameser.h", - "src/core/lib/iomgr/network_status_tracker.h", "src/core/lib/iomgr/polling_entity.h", "src/core/lib/iomgr/pollset.h", "src/core/lib/iomgr/pollset_custom.h", @@ -9747,7 +9743,6 @@ "src/core/lib/iomgr/load_file.h", "src/core/lib/iomgr/lockfree_event.h", "src/core/lib/iomgr/nameser.h", - "src/core/lib/iomgr/network_status_tracker.h", "src/core/lib/iomgr/polling_entity.h", "src/core/lib/iomgr/pollset.h", "src/core/lib/iomgr/pollset_custom.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index f2d0cab5ede..6c667f10c48 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -8183,29 +8183,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_census_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -9958,29 +9935,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_compress_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -11675,28 +11629,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_fakesec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -13266,29 +13198,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_fd_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -14627,29 +14536,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_full_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -16258,25 +16144,6 @@ "linux" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_full+pipe_test", - "platforms": [ - "linux" - ] - }, { "args": [ "no_error_on_hotpath" @@ -17842,29 +17709,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -19594,29 +19438,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_full+workarounds_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -21400,30 +21221,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_http_proxy_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -23191,29 +22988,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_local_ipv4_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -24918,14 +24692,14 @@ }, { "args": [ - "network_status_change" + "no_error_on_hotpath" ], "ci_platforms": [ "linux", "mac", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "exclude_iomgrs": [ "uv" @@ -24941,7 +24715,7 @@ }, { "args": [ - "no_error_on_hotpath" + "no_logging" ], "ci_platforms": [ "linux", @@ -24964,7 +24738,7 @@ }, { "args": [ - "no_logging" + "no_op" ], "ci_platforms": [ "linux", @@ -24987,7 +24761,7 @@ }, { "args": [ - "no_op" + "payload" ], "ci_platforms": [ "linux", @@ -25010,14 +24784,14 @@ }, { "args": [ - "payload" + "ping" ], "ci_platforms": [ "linux", "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "exclude_iomgrs": [ "uv" @@ -25033,7 +24807,7 @@ }, { "args": [ - "ping" + "ping_pong_streaming" ], "ci_platforms": [ "linux", @@ -25056,14 +24830,14 @@ }, { "args": [ - "ping_pong_streaming" + "registered_call" ], "ci_platforms": [ "linux", "mac", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "exclude_iomgrs": [ "uv" @@ -25079,14 +24853,14 @@ }, { "args": [ - "registered_call" + "request_with_flags" ], "ci_platforms": [ "linux", "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "exclude_iomgrs": [ "uv" @@ -25102,7 +24876,7 @@ }, { "args": [ - "request_with_flags" + "request_with_payload" ], "ci_platforms": [ "linux", @@ -25125,14 +24899,14 @@ }, { "args": [ - "request_with_payload" + "resource_quota_server" ], "ci_platforms": [ "linux", "mac", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "exclude_iomgrs": [ "uv" @@ -25148,14 +24922,14 @@ }, { "args": [ - "resource_quota_server" + "retry" ], "ci_platforms": [ "linux", "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "exclude_iomgrs": [ "uv" @@ -25171,7 +24945,7 @@ }, { "args": [ - "retry" + "retry_cancellation" ], "ci_platforms": [ "linux", @@ -25194,7 +24968,7 @@ }, { "args": [ - "retry_cancellation" + "retry_disabled" ], "ci_platforms": [ "linux", @@ -25217,7 +24991,7 @@ }, { "args": [ - "retry_disabled" + "retry_exceeds_buffer_size_in_initial_batch" ], "ci_platforms": [ "linux", @@ -25240,30 +25014,7 @@ }, { "args": [ - "retry_exceeds_buffer_size_in_initial_batch" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_local_ipv6_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "retry_exceeds_buffer_size_in_subsequent_batch" + "retry_exceeds_buffer_size_in_subsequent_batch" ], "ci_platforms": [ "linux", @@ -26641,29 +26392,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_local_uds_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -28447,30 +28175,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_oauth2_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -30127,30 +29831,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_proxy_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_logging" @@ -31327,30 +31007,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -32575,30 +32231,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair+trace_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -33857,32 +33489,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "msan" - ], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair_1byte_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -35264,29 +34870,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -36902,30 +36485,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_ssl_proxy_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_logging" @@ -38165,29 +37724,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_uds_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -39662,7 +39198,7 @@ }, { "args": [ - "network_status_change" + "no_error_on_hotpath" ], "ci_platforms": [ "windows", @@ -39670,7 +39206,7 @@ "mac", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "exclude_iomgrs": [], "flaky": false, @@ -39685,53 +39221,30 @@ }, { "args": [ - "no_error_on_hotpath" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "no_logging" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "no_op" + "no_logging" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "inproc_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_op" ], "ci_platforms": [ "windows", @@ -40883,29 +40396,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_census_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -42635,29 +42125,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_compress_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -44222,29 +43689,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_fd_nosec_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -45560,29 +45004,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_full_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -47172,25 +46593,6 @@ "linux" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_full+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, { "args": [ "no_error_on_hotpath" @@ -48733,29 +48135,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -50462,29 +49841,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_full+workarounds_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -52244,30 +51600,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_http_proxy_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -53924,30 +53256,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_proxy_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_logging" @@ -55100,30 +54408,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -56324,30 +55608,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -57580,32 +56840,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "msan" - ], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair_1byte_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -58914,29 +58148,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_uds_nosec_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" From 4d391b64e12bb14fc894f5699884c1b029e9078c Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 11 Jan 2019 13:35:02 -0800 Subject: [PATCH 507/534] avoid AttributeError when object init fails --- src/python/grpcio/grpc/_channel.py | 2 +- src/python/grpcio/grpc/_server.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 8051fb306cd..3685969c7fe 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -1063,5 +1063,5 @@ class Channel(grpc.Channel): cygrpc.fork_unregister_channel(self) # This prevent the failed-at-initializing object removal from failing. # Though the __init__ failed, the removal will still trigger __del__. - if _moot is not None and hasattr(self, "_connectivity_state"): + if _moot is not None and hasattr(self, '_connectivity_state'): _moot(self._connectivity_state) diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index eb750ef1a82..c3ff1fa6bd3 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -860,9 +860,10 @@ class _Server(grpc.Server): return _stop(self._state, grace) def __del__(self): - # We can not grab a lock in __del__(), so set a flag to signal the - # serving daemon thread (if it exists) to initiate shutdown. - self._state.server_deallocated = True + if hasattr(self, '_state'): + # We can not grab a lock in __del__(), so set a flag to signal the + # serving daemon thread (if it exists) to initiate shutdown. + self._state.server_deallocated = True def create_server(thread_pool, generic_rpc_handlers, interceptors, options, From 67b8d4d33bd7f4850eb1d21ab2f2d41ef00d0777 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 14 Jan 2019 10:25:43 -0800 Subject: [PATCH 508/534] update default settings for RBE --- third_party/toolchains/BUILD | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index a1bee7f1f68..5c95f02a65f 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -48,6 +48,18 @@ platform( name: "gceMachineType" # Small machines for majority of tests. value: "n1-highmem-2" } + properties: { + name: "dockerSiblingContainers" + value: "false" + } + properties: { + name: "dockerDropCapabilities" + value: "SYS_PTRACE" + } + properties: { + name: "dockerNetwork" + value: "off" + } """, ) @@ -71,6 +83,18 @@ platform( name: "gceMachineType" # Large machines for some resource demanding tests (TSAN). value: "n1-standard-8" } + properties: { + name: "dockerSiblingContainers" + value: "false" + } + properties: { + name: "dockerDropCapabilities" + value: "SYS_PTRACE" + } + properties: { + name: "dockerNetwork" + value: "off" + } """, ) From 919f9f76b30bd77bdd0be7635ecafb01e7d48cd7 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 14 Jan 2019 11:50:18 -0800 Subject: [PATCH 509/534] attempt to disable PTREACE for ASAN --- tools/remote_build/rbe_common.bazelrc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index 8cf17a30860..c4928fb83a7 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -1,3 +1,4 @@ +#@IgnoreInspection BashAddShebang # Copyright 2018 The gRPC Authors # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,6 +50,12 @@ build:asan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:asan --test_timeout=3600 build:asan --test_tag_filters=-qps_json_driver +build:asan --host_platform_remote_properties_override=''' + properties: { + name: "dockerDropCapabilities" + value: "" + } +''' # memory sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific From f47e2057765d8a857647f20d8f23dd6816c2909e Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 14 Jan 2019 15:07:07 -0800 Subject: [PATCH 510/534] removed ptrace --- third_party/toolchains/BUILD | 8 -------- 1 file changed, 8 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 5c95f02a65f..04fd795b566 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -52,10 +52,6 @@ platform( name: "dockerSiblingContainers" value: "false" } - properties: { - name: "dockerDropCapabilities" - value: "SYS_PTRACE" - } properties: { name: "dockerNetwork" value: "off" @@ -87,10 +83,6 @@ platform( name: "dockerSiblingContainers" value: "false" } - properties: { - name: "dockerDropCapabilities" - value: "SYS_PTRACE" - } properties: { name: "dockerNetwork" value: "off" From 8ce2783b4bc6d4507232362430554c6462790ce6 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Tue, 15 Jan 2019 11:30:32 -0500 Subject: [PATCH 511/534] Correct a format string Use a format string macro from inttypes.h when printfing thread IDs on non-Windows, non-Linux platforms. This silences a -Wformat trigger when cross-compiling for macOS. --- src/core/lib/gpr/log_posix.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/gpr/log_posix.cc b/src/core/lib/gpr/log_posix.cc index 0acb2255724..b6edc14ab6b 100644 --- a/src/core/lib/gpr/log_posix.cc +++ b/src/core/lib/gpr/log_posix.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -83,7 +84,7 @@ void gpr_default_log(gpr_log_func_args* args) { } char* prefix; - gpr_asprintf(&prefix, "%s%s.%09d %7tu %s:%d]", + gpr_asprintf(&prefix, "%s%s.%09d %7" PRIdPTR " %s:%d]", gpr_log_severity_string(args->severity), time_buffer, (int)(now.tv_nsec), gettid(), display_file, args->line); From 08f94b16238503d252b33b1208b2b2873dca712a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 15 Jan 2019 08:32:18 -0800 Subject: [PATCH 512/534] Clean up test. --- test/cpp/end2end/client_lb_end2end_test.cc | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 4a6307a22ca..d52f16d8f20 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -35,26 +35,17 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy.h" -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/channelz.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/debug_location.h" -#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/core/lib/transport/connectivity_state.h" -#include "src/core/lib/transport/static_metadata.h" -#include "src/core/lib/transport/status_metadata.h" #include "src/cpp/client/secure_credentials.h" #include "src/cpp/server/secure_server_credentials.h" @@ -1260,23 +1251,20 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { int trailers_intercepted_ = 0; }; -TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesDisabled) { +TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetries) { const int kNumServers = 1; + const int kNumRpcs = 10; StartServers(kNumServers); auto channel = BuildChannel("intercept_trailing_metadata_lb"); auto stub = BuildStub(channel); - std::vector ports; - for (size_t i = 0; i < servers_.size(); ++i) { - ports.emplace_back(servers_[i]->port_); - } - SetNextResolution(ports); - for (size_t i = 0; i < servers_.size(); ++i) { + SetNextResolution(GetServersPorts()); + for (size_t i = 0; i < kNumRpcs; ++i) { CheckRpcSendOk(stub, DEBUG_LOCATION); } // Check LB policy name for the channel. EXPECT_EQ("intercept_trailing_metadata_lb", channel->GetLoadBalancingPolicyName()); - EXPECT_EQ(kNumServers, trailers_intercepted()); + EXPECT_EQ(kNumRpcs, trailers_intercepted()); } } // namespace From b3c0b91db18d81ddff973f2f640619819d47672d Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 15 Jan 2019 10:47:35 -0800 Subject: [PATCH 513/534] Remove force_creation param from subchannel index --- .../client_channel/subchannel_index.cc | 8 ------ .../filters/client_channel/subchannel_index.h | 9 ------- test/cpp/end2end/client_lb_end2end_test.cc | 26 +++---------------- 3 files changed, 3 insertions(+), 40 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc index d0ceda8312c..1c839ddd6a3 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ b/src/core/ext/filters/client_channel/subchannel_index.cc @@ -42,8 +42,6 @@ struct grpc_subchannel_key { grpc_channel_args* args; }; -static bool g_force_creation = false; - static grpc_subchannel_key* create_key( const grpc_channel_args* args, grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)) { @@ -63,8 +61,6 @@ static grpc_subchannel_key* subchannel_key_copy(grpc_subchannel_key* k) { int grpc_subchannel_key_compare(const grpc_subchannel_key* a, const grpc_subchannel_key* b) { - // To pretend the keys are different, return a non-zero value. - if (GPR_UNLIKELY(g_force_creation)) return 1; return grpc_channel_args_compare(a->args, b->args); } @@ -224,7 +220,3 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key, grpc_avl_unref(index, nullptr); } } - -void grpc_subchannel_index_test_only_set_force_creation(bool force_creation) { - g_force_creation = force_creation; -} diff --git a/src/core/ext/filters/client_channel/subchannel_index.h b/src/core/ext/filters/client_channel/subchannel_index.h index 429634bd54c..1aeb51e6535 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.h +++ b/src/core/ext/filters/client_channel/subchannel_index.h @@ -63,13 +63,4 @@ void grpc_subchannel_index_ref(void); to zero, unref the subchannel index and destroy its mutex. */ void grpc_subchannel_index_unref(void); -/** \em TEST ONLY. - * If \a force_creation is true, all keys are regarded different, resulting in - * new subchannels always being created. Otherwise, the keys will be compared as - * usual. - * - * Tests using this function \em MUST run tests with and without \a - * force_creation set. */ -void grpc_subchannel_index_test_only_set_force_creation(bool force_creation); - #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H */ diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 929c2bb5899..9783f51ab7d 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -38,7 +38,6 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/debug_location.h" @@ -662,30 +661,14 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } -class ClientLbEnd2endWithParamTest - : public ClientLbEnd2endTest, - public ::testing::WithParamInterface { - protected: - void SetUp() override { - grpc_subchannel_index_test_only_set_force_creation(GetParam()); - ClientLbEnd2endTest::SetUp(); - } - - void TearDown() override { - ClientLbEnd2endTest::TearDown(); - grpc_subchannel_index_test_only_set_force_creation(false); - } -}; - -TEST_P(ClientLbEnd2endWithParamTest, PickFirstManyUpdates) { - gpr_log(GPR_INFO, "subchannel force creation: %d", GetParam()); - // Start servers and send one RPC per server. +TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { + const int kNumUpdates = 1000; const int kNumServers = 3; StartServers(kNumServers); auto channel = BuildChannel("pick_first"); auto stub = BuildStub(channel); std::vector ports = GetServersPorts(); - for (size_t i = 0; i < 1000; ++i) { + for (size_t i = 0; i < kNumUpdates; ++i) { std::shuffle(ports.begin(), ports.end(), std::mt19937(std::random_device()())); SetNextResolution(ports); @@ -697,9 +680,6 @@ TEST_P(ClientLbEnd2endWithParamTest, PickFirstManyUpdates) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } -INSTANTIATE_TEST_CASE_P(SubchannelForceCreation, ClientLbEnd2endWithParamTest, - ::testing::Bool()); - TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) { // Prepare the ports for up servers and down servers. const int kNumServers = 3; From bf273ff00f6b955ecd1f2e9f64f0c2907d358840 Mon Sep 17 00:00:00 2001 From: "Penn (Dapeng) Zhang" Date: Tue, 15 Jan 2019 11:01:03 -0800 Subject: [PATCH 514/534] Add grpc-java 1.18.0 to interop matrix release note: no --- tools/interop_matrix/client_matrix.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 655c7c7b6bf..318e1da00f0 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -139,6 +139,7 @@ LANG_RELEASE_MATRIX = { ('v1.15.0', ReleaseInfo()), ('v1.16.1', ReleaseInfo()), ('v1.17.1', ReleaseInfo()), + ('v1.18.0', ReleaseInfo()), ]), 'python': OrderedDict([ From f821b384d9df63ba18f31ffa5953829854327bad Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 15 Jan 2019 13:26:28 -0800 Subject: [PATCH 515/534] The error description should be the error string --- src/core/lib/iomgr/error.cc | 2 +- src/core/lib/iomgr/resolve_address_posix.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index 6ae077fd548..59236b20c59 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -765,7 +765,7 @@ grpc_error* grpc_os_error(const char* file, int line, int err, grpc_error_set_str( grpc_error_set_int( grpc_error_create(file, line, - grpc_slice_from_static_string("OS Error"), + grpc_slice_from_static_string(strerror(err)), nullptr, 0), GRPC_ERROR_INT_ERRNO, err), GRPC_ERROR_STR_OS_ERROR, diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc index c285d7eca66..2a03244ff7d 100644 --- a/src/core/lib/iomgr/resolve_address_posix.cc +++ b/src/core/lib/iomgr/resolve_address_posix.cc @@ -105,7 +105,7 @@ static grpc_error* posix_blocking_resolve_address( grpc_error_set_str( grpc_error_set_str( grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("OS Error"), + GRPC_ERROR_CREATE_FROM_STATIC_STRING(gai_strerror(s)), GRPC_ERROR_INT_ERRNO, s), GRPC_ERROR_STR_OS_ERROR, grpc_slice_from_static_string(gai_strerror(s))), From bbe2587c39d60709358842f49aa46f91cc577ef7 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 15 Jan 2019 13:59:59 -0800 Subject: [PATCH 516/534] Enable per-channel subchannel pool --- BUILD | 8 +- CMakeLists.txt | 24 ++- Makefile | 24 ++- build.yaml | 8 +- config.m4 | 4 +- config.w32 | 4 +- gRPC-C++.podspec | 4 +- gRPC-Core.podspec | 12 +- grpc.gemspec | 8 +- grpc.gyp | 16 +- include/grpc/impl/codegen/grpc_types.h | 3 + package.xml | 8 +- .../client_channel/client_channel_plugin.cc | 6 +- .../client_channel/global_subchannel_pool.cc | 177 ++++++++++++++++++ .../client_channel/global_subchannel_pool.h | 68 +++++++ .../ext/filters/client_channel/lb_policy.cc | 2 + .../ext/filters/client_channel/lb_policy.h | 11 ++ .../client_channel/lb_policy/grpclb/grpclb.cc | 4 +- .../lb_policy/pick_first/pick_first.cc | 3 - .../lb_policy/round_robin/round_robin.cc | 3 - .../lb_policy/subchannel_list.h | 5 +- .../client_channel/lb_policy/xds/xds.cc | 4 +- .../client_channel/local_subchannel_pool.cc | 96 ++++++++++ .../client_channel/local_subchannel_pool.h | 56 ++++++ .../filters/client_channel/request_routing.cc | 16 +- .../filters/client_channel/request_routing.h | 6 +- .../ext/filters/client_channel/subchannel.cc | 44 +++-- .../ext/filters/client_channel/subchannel.h | 6 +- .../subchannel_pool_interface.cc | 97 ++++++++++ .../subchannel_pool_interface.h | 94 ++++++++++ src/python/grpcio/grpc_core_dependencies.py | 4 +- test/cpp/end2end/client_lb_end2end_test.cc | 63 +++++++ test/cpp/end2end/grpclb_end2end_test.cc | 3 +- tools/doxygen/Doxyfile.core.internal | 8 +- .../generated/sources_and_headers.json | 12 +- 35 files changed, 832 insertions(+), 79 deletions(-) create mode 100644 src/core/ext/filters/client_channel/global_subchannel_pool.cc create mode 100644 src/core/ext/filters/client_channel/global_subchannel_pool.h create mode 100644 src/core/ext/filters/client_channel/local_subchannel_pool.cc create mode 100644 src/core/ext/filters/client_channel/local_subchannel_pool.h create mode 100644 src/core/ext/filters/client_channel/subchannel_pool_interface.cc create mode 100644 src/core/ext/filters/client_channel/subchannel_pool_interface.h diff --git a/BUILD b/BUILD index 5f53bbc6f0b..03dc449cb02 100644 --- a/BUILD +++ b/BUILD @@ -1049,11 +1049,13 @@ grpc_cc_library( "src/core/ext/filters/client_channel/client_channel_factory.cc", "src/core/ext/filters/client_channel/client_channel_plugin.cc", "src/core/ext/filters/client_channel/connector.cc", + "src/core/ext/filters/client_channel/global_subchannel_pool.cc", "src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_proxy.cc", "src/core/ext/filters/client_channel/lb_policy.cc", "src/core/ext/filters/client_channel/lb_policy_registry.cc", + "src/core/ext/filters/client_channel/local_subchannel_pool.cc", "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/proxy_mapper.cc", "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", @@ -1064,7 +1066,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/retry_throttle.cc", "src/core/ext/filters/client_channel/server_address.cc", "src/core/ext/filters/client_channel/subchannel.cc", - "src/core/ext/filters/client_channel/subchannel_index.cc", + "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", ], hdrs = [ "src/core/ext/filters/client_channel/backup_poller.h", @@ -1072,12 +1074,14 @@ grpc_cc_library( "src/core/ext/filters/client_channel/client_channel_channelz.h", "src/core/ext/filters/client_channel/client_channel_factory.h", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.h", "src/core/ext/filters/client_channel/lb_policy_factory.h", "src/core/ext/filters/client_channel/lb_policy_registry.h", + "src/core/ext/filters/client_channel/local_subchannel_pool.h", "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", @@ -1089,7 +1093,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.h", - "src/core/ext/filters/client_channel/subchannel_index.h", + "src/core/ext/filters/client_channel/subchannel_pool_interface.h", ], language = "c++", deps = [ diff --git a/CMakeLists.txt b/CMakeLists.txt index 13d5aca6584..bb1caaaf565 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1212,11 +1212,13 @@ add_library(grpc src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -1227,7 +1229,7 @@ add_library(grpc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c src/core/tsi/fake_transport_security.cc @@ -1566,11 +1568,13 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -1581,7 +1585,7 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -1941,11 +1945,13 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -1956,7 +1962,7 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -2264,11 +2270,13 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -2279,7 +2287,7 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -2599,11 +2607,13 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -2614,7 +2624,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -3455,11 +3465,13 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -3470,7 +3482,7 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc diff --git a/Makefile b/Makefile index 00186d891c6..1a64c9e9683 100644 --- a/Makefile +++ b/Makefile @@ -3729,11 +3729,13 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -3744,7 +3746,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/fake_transport_security.cc \ @@ -4077,11 +4079,13 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -4092,7 +4096,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -4445,11 +4449,13 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -4460,7 +4466,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -4755,11 +4761,13 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -4770,7 +4778,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -5064,11 +5072,13 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -5079,7 +5089,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -5897,11 +5907,13 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -5912,7 +5924,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc \ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc \ diff --git a/build.yaml b/build.yaml index c7b4d751731..8f310e0e59d 100644 --- a/build.yaml +++ b/build.yaml @@ -576,12 +576,14 @@ filegroups: - src/core/ext/filters/client_channel/client_channel_channelz.h - src/core/ext/filters/client_channel/client_channel_factory.h - src/core/ext/filters/client_channel/connector.h + - src/core/ext/filters/client_channel/global_subchannel_pool.h - src/core/ext/filters/client_channel/health/health_check_client.h - src/core/ext/filters/client_channel/http_connect_handshaker.h - src/core/ext/filters/client_channel/http_proxy.h - src/core/ext/filters/client_channel/lb_policy.h - src/core/ext/filters/client_channel/lb_policy_factory.h - src/core/ext/filters/client_channel/lb_policy_registry.h + - src/core/ext/filters/client_channel/local_subchannel_pool.h - src/core/ext/filters/client_channel/parse_address.h - src/core/ext/filters/client_channel/proxy_mapper.h - src/core/ext/filters/client_channel/proxy_mapper_registry.h @@ -593,7 +595,7 @@ filegroups: - src/core/ext/filters/client_channel/retry_throttle.h - src/core/ext/filters/client_channel/server_address.h - src/core/ext/filters/client_channel/subchannel.h - - src/core/ext/filters/client_channel/subchannel_index.h + - src/core/ext/filters/client_channel/subchannel_pool_interface.h src: - src/core/ext/filters/client_channel/backup_poller.cc - src/core/ext/filters/client_channel/channel_connectivity.cc @@ -602,11 +604,13 @@ filegroups: - src/core/ext/filters/client_channel/client_channel_factory.cc - src/core/ext/filters/client_channel/client_channel_plugin.cc - src/core/ext/filters/client_channel/connector.cc + - src/core/ext/filters/client_channel/global_subchannel_pool.cc - src/core/ext/filters/client_channel/health/health_check_client.cc - src/core/ext/filters/client_channel/http_connect_handshaker.cc - src/core/ext/filters/client_channel/http_proxy.cc - src/core/ext/filters/client_channel/lb_policy.cc - src/core/ext/filters/client_channel/lb_policy_registry.cc + - src/core/ext/filters/client_channel/local_subchannel_pool.cc - src/core/ext/filters/client_channel/parse_address.cc - src/core/ext/filters/client_channel/proxy_mapper.cc - src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -617,7 +621,7 @@ filegroups: - src/core/ext/filters/client_channel/retry_throttle.cc - src/core/ext/filters/client_channel/server_address.cc - src/core/ext/filters/client_channel/subchannel.cc - - src/core/ext/filters/client_channel/subchannel_index.cc + - src/core/ext/filters/client_channel/subchannel_pool_interface.cc plugin: grpc_client_channel uses: - grpc_base diff --git a/config.m4 b/config.m4 index ccb218a1200..46597e6f0e3 100644 --- a/config.m4 +++ b/config.m4 @@ -345,11 +345,13 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -360,7 +362,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/fake_transport_security.cc \ diff --git a/config.w32 b/config.w32 index fd48ec6f485..00b92e88a05 100644 --- a/config.w32 +++ b/config.w32 @@ -320,11 +320,13 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\client_channel_factory.cc " + "src\\core\\ext\\filters\\client_channel\\client_channel_plugin.cc " + "src\\core\\ext\\filters\\client_channel\\connector.cc " + + "src\\core\\ext\\filters\\client_channel\\global_subchannel_pool.cc " + "src\\core\\ext\\filters\\client_channel\\health\\health_check_client.cc " + "src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " + "src\\core\\ext\\filters\\client_channel\\http_proxy.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " + + "src\\core\\ext\\filters\\client_channel\\local_subchannel_pool.cc " + "src\\core\\ext\\filters\\client_channel\\parse_address.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " + @@ -335,7 +337,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " + "src\\core\\ext\\filters\\client_channel\\server_address.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel.cc " + - "src\\core\\ext\\filters\\client_channel\\subchannel_index.cc " + + "src\\core\\ext\\filters\\client_channel\\subchannel_pool_interface.cc " + "src\\core\\ext\\filters\\deadline\\deadline_filter.cc " + "src\\core\\ext\\filters\\client_channel\\health\\health.pb.c " + "src\\core\\tsi\\fake_transport_security.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index bf124304487..481892b63c7 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -346,12 +346,14 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.h', 'src/core/ext/filters/client_channel/client_channel_factory.h', 'src/core/ext/filters/client_channel/connector.h', + 'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', 'src/core/ext/filters/client_channel/lb_policy_factory.h', 'src/core/ext/filters/client_channel/lb_policy_registry.h', + 'src/core/ext/filters/client_channel/local_subchannel_pool.h', 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', @@ -363,7 +365,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', - 'src/core/ext/filters/client_channel/subchannel_index.h', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 60f34ebd6a2..5bb6a514bb9 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -340,12 +340,14 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.h', 'src/core/ext/filters/client_channel/client_channel_factory.h', 'src/core/ext/filters/client_channel/connector.h', + 'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', 'src/core/ext/filters/client_channel/lb_policy_factory.h', 'src/core/ext/filters/client_channel/lb_policy_registry.h', + 'src/core/ext/filters/client_channel/local_subchannel_pool.h', 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', @@ -357,7 +359,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', - 'src/core/ext/filters/client_channel/subchannel_index.h', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', @@ -785,11 +787,13 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/local_subchannel_pool.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', @@ -800,7 +804,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', @@ -964,12 +968,14 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.h', 'src/core/ext/filters/client_channel/client_channel_factory.h', 'src/core/ext/filters/client_channel/connector.h', + 'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', 'src/core/ext/filters/client_channel/lb_policy_factory.h', 'src/core/ext/filters/client_channel/lb_policy_registry.h', + 'src/core/ext/filters/client_channel/local_subchannel_pool.h', 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', @@ -981,7 +987,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', - 'src/core/ext/filters/client_channel/subchannel_index.h', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', diff --git a/grpc.gemspec b/grpc.gemspec index 60c5bc480b6..5e5eb65ed2f 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -276,12 +276,14 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/client_channel_channelz.h ) s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.h ) s.files += %w( src/core/ext/filters/client_channel/connector.h ) + s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.h ) s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.h ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.h ) + s.files += %w( src/core/ext/filters/client_channel/local_subchannel_pool.h ) s.files += %w( src/core/ext/filters/client_channel/parse_address.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h ) @@ -293,7 +295,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h ) s.files += %w( src/core/ext/filters/client_channel/server_address.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel.h ) - s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h ) + s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.h ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.h ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.h ) s.files += %w( src/core/tsi/fake_transport_security.h ) @@ -724,11 +726,13 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.cc ) s.files += %w( src/core/ext/filters/client_channel/client_channel_plugin.cc ) s.files += %w( src/core/ext/filters/client_channel/connector.cc ) + s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.cc ) s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.cc ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.cc ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.cc ) + s.files += %w( src/core/ext/filters/client_channel/local_subchannel_pool.cc ) s.files += %w( src/core/ext/filters/client_channel/parse_address.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.cc ) @@ -739,7 +743,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc ) s.files += %w( src/core/ext/filters/client_channel/server_address.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel.cc ) - s.files += %w( src/core/ext/filters/client_channel/subchannel_index.cc ) + s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.cc ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.c ) s.files += %w( src/core/tsi/fake_transport_security.cc ) diff --git a/grpc.gyp b/grpc.gyp index 1f5b6384975..060af57efff 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -527,11 +527,13 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/local_subchannel_pool.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', @@ -542,7 +544,7 @@ 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', @@ -789,11 +791,13 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/local_subchannel_pool.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', @@ -804,7 +808,7 @@ 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', @@ -1032,11 +1036,13 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/local_subchannel_pool.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', @@ -1047,7 +1053,7 @@ 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', @@ -1287,11 +1293,13 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/local_subchannel_pool.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', @@ -1302,7 +1310,7 @@ 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 5d577eb8557..f9929186d58 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -355,6 +355,9 @@ typedef struct { * is 10000. Setting this to "0" will disable c-ares query timeouts * entirely. */ #define GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS "grpc.dns_ares_query_timeout" +/** If set, uses a local subchannel pool within the channel. Otherwise, uses the + * global subchannel pool. */ +#define GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL "grpc.use_local_subchannel_pool" /** gRPC Objective-C channel pooling domain string. */ #define GRPC_ARG_CHANNEL_POOL_DOMAIN "grpc.channel_pooling_domain" /** gRPC Objective-C channel pooling id. */ diff --git a/package.xml b/package.xml index 81a4aabdf5a..523f78f1db6 100644 --- a/package.xml +++ b/package.xml @@ -281,12 +281,14 @@ + + @@ -298,7 +300,7 @@ - + @@ -729,11 +731,13 @@ + + @@ -744,7 +748,7 @@ - + diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc index e0784b7e5c1..2031ab449f5 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -26,13 +26,13 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/client_channel_channelz.h" +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/http_proxy.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/surface/channel_init.h" static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { @@ -54,7 +54,7 @@ void grpc_client_channel_init(void) { grpc_core::internal::ServerRetryThrottleMap::Init(); grpc_proxy_mapper_registry_init(); grpc_register_http_proxy_mapper(); - grpc_subchannel_index_init(); + grpc_core::GlobalSubchannelPool::Init(); grpc_channel_init_register_stage( GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, append_filter, (void*)&grpc_client_channel_filter); @@ -62,7 +62,7 @@ void grpc_client_channel_init(void) { } void grpc_client_channel_shutdown(void) { - grpc_subchannel_index_shutdown(); + grpc_core::GlobalSubchannelPool::Shutdown(); grpc_channel_init_shutdown(); grpc_proxy_mapper_registry_shutdown(); grpc_core::internal::ServerRetryThrottleMap::Shutdown(); diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.cc b/src/core/ext/filters/client_channel/global_subchannel_pool.cc new file mode 100644 index 00000000000..a41d993fe66 --- /dev/null +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.cc @@ -0,0 +1,177 @@ +// +// +// 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 + +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" + +#include "src/core/ext/filters/client_channel/subchannel.h" + +namespace grpc_core { + +GlobalSubchannelPool::GlobalSubchannelPool() { + subchannel_map_ = grpc_avl_create(&subchannel_avl_vtable_); + gpr_mu_init(&mu_); +} + +GlobalSubchannelPool::~GlobalSubchannelPool() { + gpr_mu_destroy(&mu_); + grpc_avl_unref(subchannel_map_, nullptr); +} + +void GlobalSubchannelPool::Init() { + instance_ = New>( + MakeRefCounted()); +} + +void GlobalSubchannelPool::Shutdown() { + // To ensure Init() was called before. + GPR_ASSERT(instance_ != nullptr); + // To ensure Shutdown() was not called before. + GPR_ASSERT(*instance_ != nullptr); + instance_->reset(); + Delete(instance_); +} + +RefCountedPtr GlobalSubchannelPool::instance() { + GPR_ASSERT(instance_ != nullptr); + GPR_ASSERT(*instance_ != nullptr); + return *instance_; +} + +grpc_subchannel* GlobalSubchannelPool::RegisterSubchannel( + SubchannelKey* key, grpc_subchannel* constructed) { + grpc_subchannel* c = nullptr; + // Compare and swap (CAS) loop: + while (c == nullptr) { + // Ref the shared map to have a local copy. + gpr_mu_lock(&mu_); + grpc_avl old_map = grpc_avl_ref(subchannel_map_, nullptr); + gpr_mu_unlock(&mu_); + // Check to see if a subchannel already exists. + c = static_cast(grpc_avl_get(old_map, key, nullptr)); + if (c != nullptr) { + // The subchannel already exists. Reuse it. + c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "subchannel_register+reuse"); + GRPC_SUBCHANNEL_UNREF(constructed, "subchannel_register+found_existing"); + // Exit the CAS loop without modifying the shared map. + } else { + // There hasn't been such subchannel. Add one. + // Note that we should ref the old map first because grpc_avl_add() will + // unref it while we still need to access it later. + grpc_avl new_map = grpc_avl_add( + grpc_avl_ref(old_map, nullptr), New(*key), + GRPC_SUBCHANNEL_WEAK_REF(constructed, "subchannel_register+new"), + nullptr); + // Try to publish the change to the shared map. It may happen (but + // unlikely) that some other thread has changed the shared map, so compare + // to make sure it's unchanged before swapping. Retry if it's changed. + gpr_mu_lock(&mu_); + if (old_map.root == subchannel_map_.root) { + GPR_SWAP(grpc_avl, new_map, subchannel_map_); + c = constructed; + } + gpr_mu_unlock(&mu_); + grpc_avl_unref(new_map, nullptr); + } + grpc_avl_unref(old_map, nullptr); + } + return c; +} + +void GlobalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) { + bool done = false; + // Compare and swap (CAS) loop: + while (!done) { + // Ref the shared map to have a local copy. + gpr_mu_lock(&mu_); + grpc_avl old_map = grpc_avl_ref(subchannel_map_, nullptr); + gpr_mu_unlock(&mu_); + // Remove the subchannel. + // Note that we should ref the old map first because grpc_avl_remove() will + // unref it while we still need to access it later. + grpc_avl new_map = + grpc_avl_remove(grpc_avl_ref(old_map, nullptr), key, nullptr); + // Try to publish the change to the shared map. It may happen (but + // unlikely) that some other thread has changed the shared map, so compare + // to make sure it's unchanged before swapping. Retry if it's changed. + gpr_mu_lock(&mu_); + if (old_map.root == subchannel_map_.root) { + GPR_SWAP(grpc_avl, new_map, subchannel_map_); + done = true; + } + gpr_mu_unlock(&mu_); + grpc_avl_unref(new_map, nullptr); + grpc_avl_unref(old_map, nullptr); + } +} + +grpc_subchannel* GlobalSubchannelPool::FindSubchannel(SubchannelKey* key) { + // Lock, and take a reference to the subchannel map. + // We don't need to do the search under a lock as AVL's are immutable. + gpr_mu_lock(&mu_); + grpc_avl index = grpc_avl_ref(subchannel_map_, nullptr); + gpr_mu_unlock(&mu_); + grpc_subchannel* c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF( + static_cast(grpc_avl_get(index, key, nullptr)), + "found_from_pool"); + grpc_avl_unref(index, nullptr); + return c; +} + +RefCountedPtr* GlobalSubchannelPool::instance_ = nullptr; + +namespace { + +void sck_avl_destroy(void* p, void* user_data) { + SubchannelKey* key = static_cast(p); + Delete(key); +} + +void* sck_avl_copy(void* p, void* unused) { + const SubchannelKey* key = static_cast(p); + auto* new_key = New(*key); + return static_cast(new_key); +} + +long sck_avl_compare(void* a, void* b, void* unused) { + const SubchannelKey* key_a = static_cast(a); + const SubchannelKey* key_b = static_cast(b); + return key_a->Cmp(*key_b); +} + +void scv_avl_destroy(void* p, void* user_data) { + GRPC_SUBCHANNEL_WEAK_UNREF((grpc_subchannel*)p, "global_subchannel_pool"); +} + +void* scv_avl_copy(void* p, void* unused) { + GRPC_SUBCHANNEL_WEAK_REF((grpc_subchannel*)p, "global_subchannel_pool"); + return p; +} + +} // namespace + +const grpc_avl_vtable GlobalSubchannelPool::subchannel_avl_vtable_ = { + sck_avl_destroy, // destroy_key + sck_avl_copy, // copy_key + sck_avl_compare, // compare_keys + scv_avl_destroy, // destroy_value + scv_avl_copy // copy_value +}; + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.h b/src/core/ext/filters/client_channel/global_subchannel_pool.h new file mode 100644 index 00000000000..0deb3769360 --- /dev/null +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.h @@ -0,0 +1,68 @@ +/* + * + * 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. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_GLOBAL_SUBCHANNEL_POOL_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_GLOBAL_SUBCHANNEL_POOL_H + +#include + +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" + +namespace grpc_core { + +// The global subchannel pool. It shares subchannels among channels. There +// should be only one instance of this class. Init() should be called once at +// the filter initialization time; Shutdown() should be called once at the +// filter shutdown time. +// TODO(juanlishen): Enable subchannel retention. +class GlobalSubchannelPool final : public SubchannelPoolInterface { + public: + // The ctor and dtor are not intended to use directly. + GlobalSubchannelPool(); + ~GlobalSubchannelPool() override; + + // Should be called exactly once at filter initialization time. + static void Init(); + // Should be called exactly once at filter shutdown time. + static void Shutdown(); + + // Gets the singleton instance. + static RefCountedPtr instance(); + + // Implements interface methods. + grpc_subchannel* RegisterSubchannel(SubchannelKey* key, + grpc_subchannel* constructed) override; + void UnregisterSubchannel(SubchannelKey* key) override; + grpc_subchannel* FindSubchannel(SubchannelKey* key) override; + + private: + // The singleton instance. (It's a pointer to RefCountedPtr so that this + // non-local static object can be trivially destructible.) + static RefCountedPtr* instance_; + + // The vtable for subchannel operations in an AVL tree. + static const grpc_avl_vtable subchannel_avl_vtable_; + // A map from subchannel key to subchannel. + grpc_avl subchannel_map_; + // To protect subchannel_map_. + gpr_mu mu_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_GLOBAL_SUBCHANNEL_POOL_H */ diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index b4e803689e9..31b0399d874 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -19,6 +19,7 @@ #include #include "src/core/ext/filters/client_channel/lb_policy.h" + #include "src/core/lib/iomgr/combiner.h" grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount( @@ -30,6 +31,7 @@ LoadBalancingPolicy::LoadBalancingPolicy(const Args& args) : InternallyRefCounted(&grpc_trace_lb_policy_refcount), combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")), client_channel_factory_(args.client_channel_factory), + subchannel_pool_(*args.subchannel_pool), interested_parties_(grpc_pollset_set_create()), request_reresolution_(nullptr) {} diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 293d8e960cf..b9d97e092af 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -24,6 +24,7 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/subchannel.h" +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -53,6 +54,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_combiner* combiner = nullptr; /// Used to create channels and subchannels. grpc_client_channel_factory* client_channel_factory = nullptr; + /// Subchannel pool. + RefCountedPtr* subchannel_pool; /// Channel args from the resolver. /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. @@ -171,6 +174,12 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_pollset_set* interested_parties() const { return interested_parties_; } + /// Returns a pointer to the subchannel pool of type + /// RefCountedPtr. + RefCountedPtr* subchannel_pool() { + return &subchannel_pool_; + } + GRPC_ABSTRACT_BASE_CLASS protected: @@ -204,6 +213,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_combiner* combiner_; /// Client channel factory, used to create channels and subchannels. grpc_client_channel_factory* client_channel_factory_; + /// Subchannel pool. + RefCountedPtr subchannel_pool_; /// Owned pointer to interested parties in load balancing decisions. grpc_pollset_set* interested_parties_; /// Callback to force a re-resolution. diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index ba40febd534..40bf9c65644 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -85,7 +85,6 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" @@ -988,7 +987,6 @@ GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args) 1000)) { // Initialization. gpr_mu_init(&lb_channel_mu_); - grpc_subchannel_index_ref(); GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); @@ -1032,7 +1030,6 @@ GrpcLb::~GrpcLb() { if (serverlist_ != nullptr) { grpc_grpclb_destroy_serverlist(serverlist_); } - grpc_subchannel_index_unref(); } void GrpcLb::ShutdownLocked() { @@ -1699,6 +1696,7 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { lb_policy_args.combiner = combiner(); lb_policy_args.client_channel_factory = client_channel_factory(); lb_policy_args.args = args; + lb_policy_args.subchannel_pool = subchannel_pool(); CreateRoundRobinPolicyLocked(lb_policy_args); } grpc_channel_args_destroy(args); diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index d6ff74ec7f7..75eacb2e17e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -26,7 +26,6 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/iomgr/combiner.h" @@ -164,7 +163,6 @@ PickFirst::PickFirst(const Args& args) : LoadBalancingPolicy(args) { gpr_log(GPR_INFO, "Pick First %p created.", this); } UpdateLocked(*args.args, args.lb_config); - grpc_subchannel_index_ref(); } PickFirst::~PickFirst() { @@ -176,7 +174,6 @@ PickFirst::~PickFirst() { GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); GPR_ASSERT(pending_picks_ == nullptr); grpc_connectivity_state_destroy(&state_tracker_); - grpc_subchannel_index_unref(); } void PickFirst::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 3bcb33ef11c..5143c6d8380 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -33,7 +33,6 @@ #include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/mutex_lock.h" @@ -221,7 +220,6 @@ RoundRobin::RoundRobin(const Args& args) : LoadBalancingPolicy(args) { gpr_log(GPR_INFO, "[RR %p] Created with %" PRIuPTR " subchannels", this, subchannel_list_->num_subchannels()); } - grpc_subchannel_index_ref(); } RoundRobin::~RoundRobin() { @@ -233,7 +231,6 @@ RoundRobin::~RoundRobin() { GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); GPR_ASSERT(pending_picks_ == nullptr); grpc_connectivity_state_destroy(&state_tracker_); - grpc_subchannel_index_unref(); } void RoundRobin::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 1d0ecbe3f64..55f5d6da85a 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -514,6 +514,9 @@ SubchannelList::SubchannelList( // policy, which does not use a SubchannelList. GPR_ASSERT(!addresses[i].IsBalancer()); InlinedVector args_to_add; + args_to_add.emplace_back(SubchannelPoolInterface::CreateChannelArg( + policy_->subchannel_pool()->get())); + const size_t subchannel_address_arg_index = args_to_add.size(); args_to_add.emplace_back( grpc_create_subchannel_address_arg(&addresses[i].address())); if (addresses[i].args() != nullptr) { @@ -524,7 +527,7 @@ SubchannelList::SubchannelList( grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add.data(), args_to_add.size()); - gpr_free(args_to_add[0].value.string); + gpr_free(args_to_add[subchannel_address_arg_index].value.string); grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel( client_channel_factory, new_args); grpc_channel_args_destroy(new_args); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 8787f5bcc24..63bd8be011b 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -80,7 +80,6 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" @@ -905,7 +904,6 @@ XdsLb::XdsLb(const LoadBalancingPolicy::Args& args) .set_max_backoff(GRPC_XDS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { // Initialization. gpr_mu_init(&lb_channel_mu_); - grpc_subchannel_index_ref(); GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &XdsLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); @@ -949,7 +947,6 @@ XdsLb::~XdsLb() { if (serverlist_ != nullptr) { xds_grpclb_destroy_serverlist(serverlist_); } - grpc_subchannel_index_unref(); } void XdsLb::ShutdownLocked() { @@ -1526,6 +1523,7 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); lb_policy_args.client_channel_factory = client_channel_factory(); + lb_policy_args.subchannel_pool = subchannel_pool(); lb_policy_args.args = args; CreateChildPolicyLocked(lb_policy_args); if (grpc_lb_xds_trace.enabled()) { diff --git a/src/core/ext/filters/client_channel/local_subchannel_pool.cc b/src/core/ext/filters/client_channel/local_subchannel_pool.cc new file mode 100644 index 00000000000..145fa4e0374 --- /dev/null +++ b/src/core/ext/filters/client_channel/local_subchannel_pool.cc @@ -0,0 +1,96 @@ +// +// +// 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 + +#include "src/core/ext/filters/client_channel/local_subchannel_pool.h" + +#include "src/core/ext/filters/client_channel/subchannel.h" + +namespace grpc_core { + +LocalSubchannelPool::LocalSubchannelPool() { + subchannel_map_ = grpc_avl_create(&subchannel_avl_vtable_); +} + +LocalSubchannelPool::~LocalSubchannelPool() { + grpc_avl_unref(subchannel_map_, nullptr); +} + +grpc_subchannel* LocalSubchannelPool::RegisterSubchannel( + SubchannelKey* key, grpc_subchannel* constructed) { + // Check to see if a subchannel already exists. + grpc_subchannel* c = static_cast( + grpc_avl_get(subchannel_map_, key, nullptr)); + if (c != nullptr) { + // The subchannel already exists. Reuse it. + c = GRPC_SUBCHANNEL_REF(c, "subchannel_register+reuse"); + GRPC_SUBCHANNEL_UNREF(constructed, "subchannel_register+found_existing"); + } else { + // There hasn't been such subchannel. Add one. + subchannel_map_ = grpc_avl_add(subchannel_map_, New(*key), + constructed, nullptr); + c = constructed; + } + return c; +} + +void LocalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) { + subchannel_map_ = grpc_avl_remove(subchannel_map_, key, nullptr); +} + +grpc_subchannel* LocalSubchannelPool::FindSubchannel(SubchannelKey* key) { + grpc_subchannel* c = static_cast( + grpc_avl_get(subchannel_map_, key, nullptr)); + return c == nullptr ? c : GRPC_SUBCHANNEL_REF(c, "found_from_pool"); +} + +namespace { + +void sck_avl_destroy(void* p, void* user_data) { + SubchannelKey* key = static_cast(p); + Delete(key); +} + +void* sck_avl_copy(void* p, void* unused) { + const SubchannelKey* key = static_cast(p); + auto new_key = New(*key); + return static_cast(new_key); +} + +long sck_avl_compare(void* a, void* b, void* unused) { + const SubchannelKey* key_a = static_cast(a); + const SubchannelKey* key_b = static_cast(b); + return key_a->Cmp(*key_b); +} + +void scv_avl_destroy(void* p, void* user_data) {} + +void* scv_avl_copy(void* p, void* unused) { return p; } + +} // namespace + +const grpc_avl_vtable LocalSubchannelPool::subchannel_avl_vtable_ = { + sck_avl_destroy, // destroy_key + sck_avl_copy, // copy_key + sck_avl_compare, // compare_keys + scv_avl_destroy, // destroy_value + scv_avl_copy // copy_value +}; + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/local_subchannel_pool.h b/src/core/ext/filters/client_channel/local_subchannel_pool.h new file mode 100644 index 00000000000..9929cdb3627 --- /dev/null +++ b/src/core/ext/filters/client_channel/local_subchannel_pool.h @@ -0,0 +1,56 @@ +/* + * + * 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. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LOCAL_SUBCHANNEL_POOL_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LOCAL_SUBCHANNEL_POOL_H + +#include + +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" + +namespace grpc_core { + +// The local subchannel pool that is owned by a single channel. It doesn't +// support subchannel sharing with other channels by nature. Nor does it support +// subchannel retention when a subchannel is not used. The only real purpose of +// using this subchannel pool is to allow subchannel reuse within the channel +// when an incoming resolver update contains some addresses for which the +// channel has already created subchannels. +// Thread-unsafe. +class LocalSubchannelPool final : public SubchannelPoolInterface { + public: + LocalSubchannelPool(); + ~LocalSubchannelPool() override; + + // Implements interface methods. + // Thread-unsafe. Intended to be invoked within the client_channel combiner. + grpc_subchannel* RegisterSubchannel(SubchannelKey* key, + grpc_subchannel* constructed) override; + void UnregisterSubchannel(SubchannelKey* key) override; + grpc_subchannel* FindSubchannel(SubchannelKey* key) override; + + private: + // The vtable for subchannel operations in an AVL tree. + static const grpc_avl_vtable subchannel_avl_vtable_; + // A map from subchannel key to subchannel. + grpc_avl subchannel_map_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LOCAL_SUBCHANNEL_POOL_H */ diff --git a/src/core/ext/filters/client_channel/request_routing.cc b/src/core/ext/filters/client_channel/request_routing.cc index f9a7e164e75..5e52456859e 100644 --- a/src/core/ext/filters/client_channel/request_routing.cc +++ b/src/core/ext/filters/client_channel/request_routing.cc @@ -32,8 +32,10 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/local_subchannel_pool.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" @@ -517,6 +519,14 @@ RequestRouter::RequestRouter( tracer_(tracer), process_resolver_result_(process_resolver_result), process_resolver_result_user_data_(process_resolver_result_user_data) { + // Get subchannel pool. + const grpc_arg* arg = + grpc_channel_args_find(args, GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL); + if (grpc_channel_arg_get_bool(arg, false)) { + subchannel_pool_ = MakeRefCounted(); + } else { + subchannel_pool_ = GlobalSubchannelPool::instance(); + } GRPC_CLOSURE_INIT(&on_resolver_result_changed_, &RequestRouter::OnResolverResultChangedLocked, this, grpc_combiner_scheduler(combiner)); @@ -666,6 +676,7 @@ void RequestRouter::CreateNewLbPolicyLocked( LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner_; lb_policy_args.client_channel_factory = client_channel_factory_; + lb_policy_args.subchannel_pool = &subchannel_pool_; lb_policy_args.args = resolver_result_; lb_policy_args.lb_config = lb_config; OrphanablePtr new_lb_policy = @@ -751,9 +762,8 @@ void RequestRouter::ConcatenateAndAddChannelTraceLocked( char* flat; size_t flat_len = 0; flat = gpr_strvec_flatten(&v, &flat_len); - channelz_node_->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_new(flat, flat_len, gpr_free)); + channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info, + grpc_slice_new(flat, flat_len, gpr_free)); gpr_strvec_destroy(&v); } } diff --git a/src/core/ext/filters/client_channel/request_routing.h b/src/core/ext/filters/client_channel/request_routing.h index 0c671229c8e..0027163869e 100644 --- a/src/core/ext/filters/client_channel/request_routing.h +++ b/src/core/ext/filters/client_channel/request_routing.h @@ -25,6 +25,7 @@ #include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/lb_policy.h" #include "src/core/ext/filters/client_channel/resolver.h" +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/debug/trace.h" @@ -126,7 +127,7 @@ class RequestRouter { LoadBalancingPolicy* lb_policy() const { return lb_policy_.get(); } private: - using TraceStringVector = grpc_core::InlinedVector; + using TraceStringVector = InlinedVector; class ReresolutionRequestHandler; class LbConnectivityWatcher; @@ -169,6 +170,9 @@ class RequestRouter { OrphanablePtr lb_policy_; bool exit_idle_when_lb_policy_arrives_ = false; + // Subchannel pool to pass to LB policy. + RefCountedPtr subchannel_pool_; + grpc_connectivity_state_tracker state_tracker_; }; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 640a052e91e..0c75ee046d9 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -33,7 +33,7 @@ #include "src/core/ext/filters/client_channel/health/health_check_client.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" @@ -80,6 +80,9 @@ class ConnectedSubchannelStateWatcher; } // namespace grpc_core struct grpc_subchannel { + /** The subchannel pool this subchannel is in */ + grpc_core::RefCountedPtr subchannel_pool; + grpc_connector* connector; /** refcount @@ -92,7 +95,7 @@ struct grpc_subchannel { /** channel arguments */ grpc_channel_args* args; - grpc_subchannel_key* key; + grpc_core::SubchannelKey* key; /** set during connection */ grpc_connect_out_args connecting_result; @@ -375,7 +378,7 @@ static void subchannel_destroy(void* arg, grpc_error* error) { grpc_connectivity_state_destroy(&c->state_and_health_tracker); grpc_connector_unref(c->connector); grpc_pollset_set_destroy(c->pollset_set); - grpc_subchannel_key_destroy(c->key); + grpc_core::Delete(c->key); gpr_mu_destroy(&c->mu); gpr_free(c); } @@ -428,7 +431,12 @@ grpc_subchannel* grpc_subchannel_ref_from_weak_ref( } static void disconnect(grpc_subchannel* c) { - grpc_subchannel_index_unregister(c->key, c); + // The subchannel_pool is only used once here in this subchannel, so the + // access can be outside of the lock. + if (c->subchannel_pool != nullptr) { + c->subchannel_pool->UnregisterSubchannel(c->key); + c->subchannel_pool.reset(); + } gpr_mu_lock(&c->mu); GPR_ASSERT(!c->disconnected); c->disconnected = true; @@ -538,13 +546,17 @@ struct HealthCheckParams { grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, const grpc_channel_args* args) { - grpc_subchannel_key* key = grpc_subchannel_key_create(args); - grpc_subchannel* c = grpc_subchannel_index_find(key); - if (c) { - grpc_subchannel_key_destroy(key); + grpc_core::SubchannelKey* key = + grpc_core::New(args); + grpc_core::SubchannelPoolInterface* subchannel_pool = + grpc_core::SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs( + args); + GPR_ASSERT(subchannel_pool != nullptr); + grpc_subchannel* c = subchannel_pool->FindSubchannel(key); + if (c != nullptr) { + grpc_core::Delete(key); return c; } - GRPC_STATS_INC_CLIENT_SUBCHANNELS_CREATED(); c = static_cast(gpr_zalloc(sizeof(*c))); c->key = key; @@ -616,8 +628,13 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Subchannel created")); } - - return grpc_subchannel_index_register(key, c); + // Try to register the subchannel before setting the subchannel pool. + // Otherwise, in case of a registration race, unreffing c in + // RegisterSubchannel() will cause c to be tried to be unregistered, while its + // key maps to a different subchannel. + grpc_subchannel* registered = subchannel_pool->RegisterSubchannel(key, c); + if (registered == c) c->subchannel_pool = subchannel_pool->Ref(); + return registered; } grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( @@ -983,11 +1000,6 @@ grpc_subchannel_get_connected_subchannel(grpc_subchannel* c) { return copy; } -const grpc_subchannel_key* grpc_subchannel_get_key( - const grpc_subchannel* subchannel) { - return subchannel->key; -} - void* grpc_connected_subchannel_call_get_parent_data( grpc_subchannel_call* subchannel_call) { grpc_channel_stack* chanstk = subchannel_call->connection->channel_stack(); diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 8c994c64f50..fac515eee5c 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -23,6 +23,7 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/connector.h" +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/gpr/arena.h" #include "src/core/lib/gprpp/ref_counted.h" @@ -38,7 +39,6 @@ address. Provides a target for load balancing. */ typedef struct grpc_subchannel grpc_subchannel; typedef struct grpc_subchannel_call grpc_subchannel_call; -typedef struct grpc_subchannel_key grpc_subchannel_key; #ifndef NDEBUG #define GRPC_SUBCHANNEL_REF(p, r) \ @@ -162,10 +162,6 @@ void grpc_subchannel_notify_on_state_change( grpc_core::RefCountedPtr grpc_subchannel_get_connected_subchannel(grpc_subchannel* c); -/** return the subchannel index key for \a subchannel */ -const grpc_subchannel_key* grpc_subchannel_get_key( - const grpc_subchannel* subchannel); - // Resets the connection backoff of the subchannel. // TODO(roth): Move connection backoff out of subchannels and up into LB // policy code (probably by adding a SubchannelGroup between diff --git a/src/core/ext/filters/client_channel/subchannel_pool_interface.cc b/src/core/ext/filters/client_channel/subchannel_pool_interface.cc new file mode 100644 index 00000000000..bb35f228b70 --- /dev/null +++ b/src/core/ext/filters/client_channel/subchannel_pool_interface.cc @@ -0,0 +1,97 @@ +// +// +// 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 + +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" + +#include "src/core/lib/gpr/useful.h" + +// The subchannel pool to reuse subchannels. +#define GRPC_ARG_SUBCHANNEL_POOL "grpc.subchannel_pool" +// The subchannel key ID that is only used in test to make each key unique. +#define GRPC_ARG_SUBCHANNEL_KEY_TEST_ONLY_ID "grpc.subchannel_key_test_only_id" + +namespace grpc_core { + +TraceFlag grpc_subchannel_pool_trace(false, "subchannel_pool"); + +SubchannelKey::SubchannelKey(const grpc_channel_args* args) { + Init(args, grpc_channel_args_normalize); +} + +SubchannelKey::~SubchannelKey() { + grpc_channel_args_destroy(const_cast(args_)); +} + +SubchannelKey::SubchannelKey(const SubchannelKey& other) { + Init(other.args_, grpc_channel_args_copy); +} + +SubchannelKey& SubchannelKey::operator=(const SubchannelKey& other) { + grpc_channel_args_destroy(const_cast(args_)); + Init(other.args_, grpc_channel_args_copy); + return *this; +} + +int SubchannelKey::Cmp(const SubchannelKey& other) const { + return grpc_channel_args_compare(args_, other.args_); +} + +void SubchannelKey::Init( + const grpc_channel_args* args, + grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)) { + args_ = copy_channel_args(args); +} + +namespace { + +void* arg_copy(void* p) { + auto* subchannel_pool = static_cast(p); + subchannel_pool->Ref().release(); + return p; +} + +void arg_destroy(void* p) { + auto* subchannel_pool = static_cast(p); + subchannel_pool->Unref(); +} + +int arg_cmp(void* a, void* b) { return GPR_ICMP(a, b); } + +const grpc_arg_pointer_vtable subchannel_pool_arg_vtable = { + arg_copy, arg_destroy, arg_cmp}; + +} // namespace + +grpc_arg SubchannelPoolInterface::CreateChannelArg( + SubchannelPoolInterface* subchannel_pool) { + return grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_SUBCHANNEL_POOL), subchannel_pool, + &subchannel_pool_arg_vtable); +} + +SubchannelPoolInterface* +SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs( + const grpc_channel_args* args) { + const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_POOL); + if (arg == nullptr || arg->type != GRPC_ARG_POINTER) return nullptr; + return static_cast(arg->value.pointer.p); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/subchannel_pool_interface.h b/src/core/ext/filters/client_channel/subchannel_pool_interface.h new file mode 100644 index 00000000000..21597bf4276 --- /dev/null +++ b/src/core/ext/filters/client_channel/subchannel_pool_interface.h @@ -0,0 +1,94 @@ +/* + * + * 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. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_POOL_INTERFACE_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_POOL_INTERFACE_H + +#include + +#include "src/core/lib/avl/avl.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/abstract.h" +#include "src/core/lib/gprpp/ref_counted.h" + +struct grpc_subchannel; + +namespace grpc_core { + +extern TraceFlag grpc_subchannel_pool_trace; + +// A key that can uniquely identify a subchannel. +class SubchannelKey { + public: + explicit SubchannelKey(const grpc_channel_args* args); + ~SubchannelKey(); + + // Copyable. + SubchannelKey(const SubchannelKey& other); + SubchannelKey& operator=(const SubchannelKey& other); + // Not movable. + SubchannelKey(SubchannelKey&&) = delete; + SubchannelKey& operator=(SubchannelKey&&) = delete; + + int Cmp(const SubchannelKey& other) const; + + private: + // Initializes the subchannel key with the given \a args and the function to + // copy channel args. + void Init( + const grpc_channel_args* args, + grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)); + + const grpc_channel_args* args_; +}; + +// Interface for subchannel pool. +// TODO(juanlishen): This refcounting mechanism may lead to memory leak. +// To solve that, we should force polling to flush any pending callbacks, then +// shut down safely. See https://github.com/grpc/grpc/issues/12560. +class SubchannelPoolInterface : public RefCounted { + public: + SubchannelPoolInterface() : RefCounted(&grpc_subchannel_pool_trace) {} + virtual ~SubchannelPoolInterface() {} + + // Registers a subchannel against a key. Returns the subchannel registered + // with \a key, which may be different from \a constructed because we reuse + // (instead of update) any existing subchannel already registered with \a key. + virtual grpc_subchannel* RegisterSubchannel( + SubchannelKey* key, grpc_subchannel* constructed) GRPC_ABSTRACT; + + // Removes the registered subchannel found by \a key. + virtual void UnregisterSubchannel(SubchannelKey* key) GRPC_ABSTRACT; + + // Finds the subchannel registered for the given subchannel key. Returns NULL + // if no such channel exists. Thread-safe. + virtual grpc_subchannel* FindSubchannel(SubchannelKey* key) GRPC_ABSTRACT; + + // Creates a channel arg from \a subchannel pool. + static grpc_arg CreateChannelArg(SubchannelPoolInterface* subchannel_pool); + + // Gets the subchannel pool from the channel args. + static SubchannelPoolInterface* GetSubchannelPoolFromChannelArgs( + const grpc_channel_args* args); + + GRPC_ABSTRACT_BASE_CLASS +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_POOL_INTERFACE_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index f5e43ca657e..0272aae690d 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -319,11 +319,13 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/local_subchannel_pool.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', @@ -334,7 +336,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 9783f51ab7d..aa8a6a96c4b 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,7 @@ #include #include +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" @@ -96,6 +98,7 @@ class MyTestServiceImpl : public TestServiceImpl { std::unique_lock lock(mu_); ++request_count_; } + AddClient(context->peer()); return TestServiceImpl::Echo(context, request, response); } @@ -109,9 +112,21 @@ class MyTestServiceImpl : public TestServiceImpl { request_count_ = 0; } + std::set clients() { + std::unique_lock lock(clients_mu_); + return clients_; + } + private: + void AddClient(const grpc::string& client) { + std::unique_lock lock(clients_mu_); + clients_.insert(client); + } + std::mutex mu_; int request_count_; + std::mutex clients_mu_; + std::set clients_; }; class ClientLbEnd2endTest : public ::testing::Test { @@ -661,6 +676,54 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } +TEST_F(ClientLbEnd2endTest, PickFirstGlobalSubchannelPool) { + // Start one server. + const int kNumServers = 1; + StartServers(kNumServers); + std::vector ports = GetServersPorts(); + // Create two channels that (by default) use the global subchannel pool. + auto channel1 = BuildChannel("pick_first"); + auto stub1 = BuildStub(channel1); + SetNextResolution(ports); + auto channel2 = BuildChannel("pick_first"); + auto stub2 = BuildStub(channel2); + SetNextResolution(ports); + WaitForServer(stub1, 0, DEBUG_LOCATION); + // Send one RPC on each channel. + CheckRpcSendOk(stub1, DEBUG_LOCATION); + CheckRpcSendOk(stub2, DEBUG_LOCATION); + // The server receives two requests. + EXPECT_EQ(2, servers_[0]->service_.request_count()); + // The two requests are from the same client port, because the two channels + // share subchannels via the global subchannel pool. + EXPECT_EQ(1UL, servers_[0]->service_.clients().size()); +} + +TEST_F(ClientLbEnd2endTest, PickFirstLocalSubchannelPool) { + // Start one server. + const int kNumServers = 1; + StartServers(kNumServers); + std::vector ports = GetServersPorts(); + // Create two channels that use local subchannel pool. + ChannelArguments args; + args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1); + auto channel1 = BuildChannel("pick_first", args); + auto stub1 = BuildStub(channel1); + SetNextResolution(ports); + auto channel2 = BuildChannel("pick_first", args); + auto stub2 = BuildStub(channel2); + SetNextResolution(ports); + WaitForServer(stub1, 0, DEBUG_LOCATION); + // Send one RPC on each channel. + CheckRpcSendOk(stub1, DEBUG_LOCATION); + CheckRpcSendOk(stub2, DEBUG_LOCATION); + // The server receives two requests. + EXPECT_EQ(2, servers_[0]->service_.request_count()); + // The two requests are from two client ports, because the two channels didn't + // share subchannels with each other. + EXPECT_EQ(2UL, servers_[0]->service_.clients().size()); +} + TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { const int kNumUpdates = 1000; const int kNumServers = 3; diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index f739ed032bb..b589cd4044a 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -40,9 +40,8 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/cpp/server/secure_server_credentials.h" - #include "src/cpp/client/secure_credentials.h" +#include "src/cpp/server/secure_server_credentials.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index bb350550e94..51b9eda22b6 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -886,6 +886,8 @@ src/core/ext/filters/client_channel/client_channel_factory.h \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/connector.h \ +src/core/ext/filters/client_channel/global_subchannel_pool.cc \ +src/core/ext/filters/client_channel/global_subchannel_pool.h \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/ext/filters/client_channel/health/health.pb.h \ src/core/ext/filters/client_channel/health/health_check_client.cc \ @@ -926,6 +928,8 @@ src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h \ src/core/ext/filters/client_channel/lb_policy_factory.h \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/lb_policy_registry.h \ +src/core/ext/filters/client_channel/local_subchannel_pool.cc \ +src/core/ext/filters/client_channel/local_subchannel_pool.h \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/parse_address.h \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -964,8 +968,8 @@ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/server_address.h \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel.h \ -src/core/ext/filters/client_channel/subchannel_index.cc \ -src/core/ext/filters/client_channel/subchannel_index.h \ +src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ +src/core/ext/filters/client_channel/subchannel_pool_interface.h \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/deadline/deadline_filter.h \ src/core/ext/filters/http/client/http_client_filter.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 197de64dbe1..8ab9c57142e 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9883,12 +9883,14 @@ "src/core/ext/filters/client_channel/client_channel_channelz.h", "src/core/ext/filters/client_channel/client_channel_factory.h", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.h", "src/core/ext/filters/client_channel/lb_policy_factory.h", "src/core/ext/filters/client_channel/lb_policy_registry.h", + "src/core/ext/filters/client_channel/local_subchannel_pool.h", "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", @@ -9900,7 +9902,7 @@ "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.h", - "src/core/ext/filters/client_channel/subchannel_index.h" + "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], "is_filegroup": true, "language": "c", @@ -9918,6 +9920,8 @@ "src/core/ext/filters/client_channel/client_channel_plugin.cc", "src/core/ext/filters/client_channel/connector.cc", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/global_subchannel_pool.cc", + "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", @@ -9929,6 +9933,8 @@ "src/core/ext/filters/client_channel/lb_policy_factory.h", "src/core/ext/filters/client_channel/lb_policy_registry.cc", "src/core/ext/filters/client_channel/lb_policy_registry.h", + "src/core/ext/filters/client_channel/local_subchannel_pool.cc", + "src/core/ext/filters/client_channel/local_subchannel_pool.h", "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.cc", @@ -9950,8 +9956,8 @@ "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel.h", - "src/core/ext/filters/client_channel/subchannel_index.cc", - "src/core/ext/filters/client_channel/subchannel_index.h" + "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", + "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], "third_party": false, "type": "filegroup" From c55ff1b96eecc75fe238bbc5ae535047d850a140 Mon Sep 17 00:00:00 2001 From: Yuxuan Li Date: Tue, 15 Jan 2019 17:33:37 -0800 Subject: [PATCH 517/534] Add v1.18.0 releases of grpc-go --- tools/interop_matrix/client_matrix.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 318e1da00f0..cd542b0f4c5 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -118,6 +118,7 @@ LANG_RELEASE_MATRIX = { ('v1.15.0', ReleaseInfo(runtime_subset=['go1.8'])), ('v1.16.0', ReleaseInfo(runtime_subset=['go1.8'])), ('v1.17.0', ReleaseInfo(runtime_subset=['go1.11'])), + ('v1.18.0', ReleaseInfo(runtime_subset=['go1.11'])), ]), 'java': OrderedDict([ From 9c51ff9b331a07938525c49c3146a7ebbe1d0e57 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Jan 2019 22:32:06 +0100 Subject: [PATCH 518/534] Make C# ServerCallContext implementation agnostic --- .../TestServerCallContext.cs | 21 +--- .../Grpc.Core/Internal/CallSafeHandle.cs | 1 + .../Internal/IServerResponseStream.cs | 38 +++++++ .../Internal/ServerCallContextExtraData.cs | 97 +++++++++++++++++ .../Grpc.Core/Internal/ServerCallHandler.cs | 10 +- .../Internal/ServerResponseStream.cs | 2 +- src/csharp/Grpc.Core/ServerCallContext.cs | 101 +++++++----------- 7 files changed, 182 insertions(+), 88 deletions(-) create mode 100644 src/csharp/Grpc.Core/Internal/IServerResponseStream.cs create mode 100644 src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs diff --git a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs index 5418417d7ed..d72e98e75a2 100644 --- a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs +++ b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs @@ -37,22 +37,11 @@ namespace Grpc.Core.Testing Func writeHeadersFunc, Func writeOptionsGetter, Action writeOptionsSetter) { return new ServerCallContext(null, method, host, deadline, requestHeaders, cancellationToken, - writeHeadersFunc, new WriteOptionsHolder(writeOptionsGetter, writeOptionsSetter), - () => peer, () => authContext, () => contextPropagationToken); - } - - private class WriteOptionsHolder : IHasWriteOptions - { - Func writeOptionsGetter; - Action writeOptionsSetter; - - public WriteOptionsHolder(Func writeOptionsGetter, Action writeOptionsSetter) - { - this.writeOptionsGetter = writeOptionsGetter; - this.writeOptionsSetter = writeOptionsSetter; - } - - public WriteOptions WriteOptions { get => writeOptionsGetter(); set => writeOptionsSetter(value); } + (ctx, extraData, headers) => writeHeadersFunc(headers), + (ctx, extraData) => writeOptionsGetter(), + (ctx, extraData, options) => writeOptionsSetter(options), + (ctx, extraData) => peer, (ctx, callHandle) => authContext, + (ctx, callHandle, options) => contextPropagationToken); } } } diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index a3ef3e61ee1..7154ddae30b 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -18,6 +18,7 @@ using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; +using System.Threading; using Grpc.Core; using Grpc.Core.Utils; using Grpc.Core.Profiling; diff --git a/src/csharp/Grpc.Core/Internal/IServerResponseStream.cs b/src/csharp/Grpc.Core/Internal/IServerResponseStream.cs new file mode 100644 index 00000000000..874aae703a2 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/IServerResponseStream.cs @@ -0,0 +1,38 @@ +#region Copyright notice and license +// Copyright 2019 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. +#endregion + +using System; +using System.Threading.Tasks; +using Grpc.Core.Internal; + +namespace Grpc.Core.Internal +{ + /// + /// Exposes non-generic members of ServerReponseStream. + /// + internal interface IServerResponseStream + { + /// + /// Asynchronously sends response headers for the current call to the client. See ServerCallContext.WriteResponseHeadersAsync for exact semantics. + /// + Task WriteResponseHeadersAsync(Metadata responseHeaders); + + /// + /// Gets or sets the write options. + /// + WriteOptions WriteOptions { get; set; } + } +} diff --git a/src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs b/src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs new file mode 100644 index 00000000000..97b95e66df9 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs @@ -0,0 +1,97 @@ +#region Copyright notice and license + +// Copyright 2019 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. + +#endregion + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Grpc.Core.Internal +{ + /// + /// Additional state for ServerCallContext. + /// Storing the extra state outside of ServerCallContext allows it to be implementation-agnostic. + /// + internal class ServerCallContextExtraData + { + readonly CallSafeHandle callHandle; + readonly IServerResponseStream serverResponseStream; + readonly Lazy cachedAuthContext; + + public ServerCallContextExtraData(CallSafeHandle callHandle, IServerResponseStream serverResponseStream) + { + this.callHandle = callHandle; + this.serverResponseStream = serverResponseStream; + // TODO(jtattermusch): avoid unnecessary allocation of factory function and the lazy object. + this.cachedAuthContext = new Lazy(GetAuthContextEager); + } + + public ServerCallContext NewServerCallContext(ServerRpcNew newRpc, CancellationToken cancellationToken) + { + DateTime realtimeDeadline = newRpc.Deadline.ToClockType(ClockType.Realtime).ToDateTime(); + + return new ServerCallContext(this, newRpc.Method, newRpc.Host, realtimeDeadline, + newRpc.RequestMetadata, cancellationToken, + ServerCallContext_WriteHeadersFunc, ServerCallContext_WriteOptionsGetter, ServerCallContext_WriteOptionsSetter, + ServerCallContext_PeerGetter, ServerCallContext_AuthContextGetter, ServerCallContext_ContextPropagationTokenFactory); + } + + private AuthContext GetAuthContextEager() + { + using (var authContextNative = callHandle.GetAuthContext()) + { + return authContextNative.ToAuthContext(); + } + } + + // Implementors of ServerCallContext's members are pre-allocated to avoid unneccessary delegate allocations. + readonly static Func ServerCallContext_WriteHeadersFunc = (ctx, extraData, headers) => + { + return ((ServerCallContextExtraData)extraData).serverResponseStream.WriteResponseHeadersAsync(headers); + }; + + readonly static Func ServerCallContext_WriteOptionsGetter = (ctx, extraData) => + { + + return ((ServerCallContextExtraData)extraData).serverResponseStream.WriteOptions; + }; + + readonly static Action ServerCallContext_WriteOptionsSetter = (ctx, extraData, options) => + { + ((ServerCallContextExtraData)extraData).serverResponseStream.WriteOptions = options; + }; + + readonly static Func ServerCallContext_PeerGetter = (ctx, extraData) => + { + // Getting the peer lazily is fine as the native call is guaranteed + // not to be disposed before user-supplied server side handler returns. + // Most users won't need to read this field anyway. + return ((ServerCallContextExtraData)extraData).callHandle.GetPeer(); + }; + + readonly static Func ServerCallContext_AuthContextGetter = (ctx, extraData) => + { + return ((ServerCallContextExtraData)extraData).cachedAuthContext.Value; + }; + + readonly static Func ServerCallContext_ContextPropagationTokenFactory = (ctx, extraData, options) => + { + var callHandle = ((ServerCallContextExtraData)extraData).callHandle; + return new ContextPropagationToken(callHandle, ctx.Deadline, ctx.CancellationToken, options); + }; + } +} diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs index ec732e8c7f4..ae586f7d1c4 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs @@ -71,7 +71,7 @@ namespace Grpc.Core.Internal var response = await handler(request, context).ConfigureAwait(false); status = context.Status; responseWithFlags = new AsyncCallServer.ResponseWithFlags(response, HandlerUtils.GetWriteFlags(context.WriteOptions)); - } + } catch (Exception e) { if (!(e is RpcException)) @@ -345,14 +345,12 @@ namespace Grpc.Core.Internal return writeOptions != null ? writeOptions.Flags : default(WriteFlags); } - public static ServerCallContext NewContext(ServerRpcNew newRpc, ServerResponseStream serverResponseStream, CancellationToken cancellationToken) - where TRequest : class - where TResponse : class + public static ServerCallContext NewContext(ServerRpcNew newRpc, IServerResponseStream serverResponseStream, CancellationToken cancellationToken) { DateTime realtimeDeadline = newRpc.Deadline.ToClockType(ClockType.Realtime).ToDateTime(); - return new ServerCallContext(newRpc.Call, newRpc.Method, newRpc.Host, realtimeDeadline, - newRpc.RequestMetadata, cancellationToken, serverResponseStream.WriteResponseHeadersAsync, serverResponseStream); + var contextExtraData = new ServerCallContextExtraData(newRpc.Call, serverResponseStream); + return contextExtraData.NewServerCallContext(newRpc, cancellationToken); } } } diff --git a/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs b/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs index 352b98829c7..079849e4c61 100644 --- a/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs +++ b/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs @@ -23,7 +23,7 @@ namespace Grpc.Core.Internal /// /// Writes responses asynchronously to an underlying AsyncCallServer object. /// - internal class ServerResponseStream : IServerStreamWriter, IHasWriteOptions + internal class ServerResponseStream : IServerStreamWriter, IServerResponseStream where TRequest : class where TResponse : class { diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs index 74a7deabea0..05c20ca75f8 100644 --- a/src/csharp/Grpc.Core/ServerCallContext.cs +++ b/src/csharp/Grpc.Core/ServerCallContext.cs @@ -21,6 +21,7 @@ using System.Threading; using System.Threading.Tasks; using Grpc.Core.Internal; +using Grpc.Core.Utils; namespace Grpc.Core { @@ -29,45 +30,49 @@ namespace Grpc.Core /// public class ServerCallContext { - private readonly CallSafeHandle callHandle; + private readonly object extraData; private readonly string method; private readonly string host; private readonly DateTime deadline; private readonly Metadata requestHeaders; private readonly CancellationToken cancellationToken; private readonly Metadata responseTrailers = new Metadata(); - private readonly Func writeHeadersFunc; - private readonly IHasWriteOptions writeOptionsHolder; - private readonly Lazy authContext; - private readonly Func testingOnlyPeerGetter; - private readonly Func testingOnlyAuthContextGetter; - private readonly Func testingOnlyContextPropagationTokenFactory; + private readonly Func writeHeadersFunc; + private readonly Func writeOptionsGetter; + private readonly Action writeOptionsSetter; - private Status status = Status.DefaultSuccess; + private readonly Func peerGetter; + private readonly Func authContextGetter; + private readonly Func contextPropagationTokenFactory; - internal ServerCallContext(CallSafeHandle callHandle, string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, - Func writeHeadersFunc, IHasWriteOptions writeOptionsHolder) - : this(callHandle, method, host, deadline, requestHeaders, cancellationToken, writeHeadersFunc, writeOptionsHolder, null, null, null) - { - } + private Status status = Status.DefaultSuccess; - // Additional constructor params should be used for testing only - internal ServerCallContext(CallSafeHandle callHandle, string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, - Func writeHeadersFunc, IHasWriteOptions writeOptionsHolder, - Func testingOnlyPeerGetter, Func testingOnlyAuthContextGetter, Func testingOnlyContextPropagationTokenFactory) + /// + /// Creates a new instance of ServerCallContext. + /// To allow reuse of ServerCallContext API by different gRPC implementations, the implementation of some members is provided externally. + /// To provide state, this ServerCallContext instance and extraData will be passed to the member implementations. + /// + internal ServerCallContext(object extraData, + string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, + Func writeHeadersFunc, + Func writeOptionsGetter, + Action writeOptionsSetter, + Func peerGetter, + Func authContextGetter, + Func contextPropagationTokenFactory) { - this.callHandle = callHandle; + this.extraData = extraData; this.method = method; this.host = host; this.deadline = deadline; this.requestHeaders = requestHeaders; this.cancellationToken = cancellationToken; - this.writeHeadersFunc = writeHeadersFunc; - this.writeOptionsHolder = writeOptionsHolder; - this.authContext = new Lazy(GetAuthContextEager); - this.testingOnlyPeerGetter = testingOnlyPeerGetter; - this.testingOnlyAuthContextGetter = testingOnlyAuthContextGetter; - this.testingOnlyContextPropagationTokenFactory = testingOnlyContextPropagationTokenFactory; + this.writeHeadersFunc = GrpcPreconditions.CheckNotNull(writeHeadersFunc); + this.writeOptionsGetter = GrpcPreconditions.CheckNotNull(writeOptionsGetter); + this.writeOptionsSetter = GrpcPreconditions.CheckNotNull(writeOptionsSetter); + this.peerGetter = GrpcPreconditions.CheckNotNull(peerGetter); + this.authContextGetter = GrpcPreconditions.CheckNotNull(authContextGetter); + this.contextPropagationTokenFactory = GrpcPreconditions.CheckNotNull(contextPropagationTokenFactory); } /// @@ -79,7 +84,7 @@ namespace Grpc.Core /// The task that finished once response headers have been written. public Task WriteResponseHeadersAsync(Metadata responseHeaders) { - return writeHeadersFunc(responseHeaders); + return writeHeadersFunc(this, extraData, responseHeaders); } /// @@ -87,13 +92,9 @@ namespace Grpc.Core /// public ContextPropagationToken CreatePropagationToken(ContextPropagationOptions options = null) { - if (testingOnlyContextPropagationTokenFactory != null) - { - return testingOnlyContextPropagationTokenFactory(); - } - return new ContextPropagationToken(callHandle, deadline, cancellationToken, options); + return contextPropagationTokenFactory(this, extraData, options); } - + /// Name of method called in this RPC. public string Method { @@ -117,14 +118,7 @@ namespace Grpc.Core { get { - if (testingOnlyPeerGetter != null) - { - return testingOnlyPeerGetter(); - } - // Getting the peer lazily is fine as the native call is guaranteed - // not to be disposed before user-supplied server side handler returns. - // Most users won't need to read this field anyway. - return this.callHandle.GetPeer(); + return peerGetter(this, extraData); } } @@ -187,12 +181,12 @@ namespace Grpc.Core { get { - return writeOptionsHolder.WriteOptions; + return writeOptionsGetter(this, extraData); } set { - writeOptionsHolder.WriteOptions = value; + writeOptionsSetter(this, extraData, value); } } @@ -204,31 +198,8 @@ namespace Grpc.Core { get { - if (testingOnlyAuthContextGetter != null) - { - return testingOnlyAuthContextGetter(); - } - return authContext.Value; + return authContextGetter(this, extraData); } } - - private AuthContext GetAuthContextEager() - { - using (var authContextNative = callHandle.GetAuthContext()) - { - return authContextNative.ToAuthContext(); - } - } - } - - /// - /// Allows sharing write options between ServerCallContext and other objects. - /// - internal interface IHasWriteOptions - { - /// - /// Gets or sets the write options. - /// - WriteOptions WriteOptions { get; set; } } } From e8cd36924e4b2eb9d04a8d580579327976d99244 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 16 Jan 2019 10:19:14 -0800 Subject: [PATCH 519/534] Add test for retry code path. --- src/core/lib/transport/service_config.h | 1 + test/cpp/end2end/client_lb_end2end_test.cc | 34 +++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h index 2c0dd758453..0d78016ab05 100644 --- a/src/core/lib/transport/service_config.h +++ b/src/core/lib/transport/service_config.h @@ -240,6 +240,7 @@ RefCountedPtr ServiceConfig::MethodConfigTableLookup( value = table.Get(wildcard_path); grpc_slice_unref_internal(wildcard_path); gpr_free(path_str); + if (value == nullptr) return nullptr; } return RefCountedPtr(*value); } diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index d52f16d8f20..b4c1d8594cd 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -1251,7 +1251,7 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { int trailers_intercepted_ = 0; }; -TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetries) { +TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesDisabled) { const int kNumServers = 1; const int kNumRpcs = 10; StartServers(kNumServers); @@ -1267,6 +1267,38 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetries) { EXPECT_EQ(kNumRpcs, trailers_intercepted()); } +TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesEnabled) { + const int kNumServers = 1; + const int kNumRpcs = 10; + StartServers(kNumServers); + ChannelArguments args; + args.SetServiceConfigJSON( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"grpc.testing.EchoTestService\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + auto channel = BuildChannel("intercept_trailing_metadata_lb", args); + auto stub = BuildStub(channel); + SetNextResolution(GetServersPorts()); + for (size_t i = 0; i < kNumRpcs; ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + // Check LB policy name for the channel. + EXPECT_EQ("intercept_trailing_metadata_lb", + channel->GetLoadBalancingPolicyName()); + EXPECT_EQ(kNumRpcs, trailers_intercepted()); +} + } // namespace } // namespace testing } // namespace grpc From 60e4ec2caf8beb496f96e75067366704a84f1693 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 16 Jan 2019 13:22:10 -0800 Subject: [PATCH 520/534] Clean up debug messages --- src/objective-c/GRPCClient/GRPCCall.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e8fae09a1f8..16c01d01ce7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -599,7 +599,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_async(_callQueue, ^{ __weak GRPCCall *weakSelf = self; [self startReadWithHandler:^(grpc_byte_buffer *message) { - NSLog(@"message received"); if (message == NULL) { // No more messages from the server return; @@ -773,7 +772,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; __weak GRPCCall *weakSelf = self; [self invokeCallWithHeadersHandler:^(NSDictionary *headers) { // Response headers received. - NSLog(@"response received"); __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { strongSelf.responseHeaders = headers; @@ -781,7 +779,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } completionHandler:^(NSError *error, NSDictionary *trailers) { - NSLog(@"completion received"); __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { strongSelf.responseTrailers = trailers; From 7dd938d5f4b74b080f47a2cfa349486503292985 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 16 Jan 2019 14:27:10 -0800 Subject: [PATCH 521/534] Reviewer comments --- examples/cpp/keyvaluestore/caching_interceptor.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/cpp/keyvaluestore/caching_interceptor.h b/examples/cpp/keyvaluestore/caching_interceptor.h index a5d130da8dd..8ecdafaf159 100644 --- a/examples/cpp/keyvaluestore/caching_interceptor.h +++ b/examples/cpp/keyvaluestore/caching_interceptor.h @@ -27,7 +27,7 @@ #endif // This is a naive implementation of a cache. A new cache is for each call. For -// each new key request, the key is first searched in the map and if found. Only +// each new key request, the key is first searched in the map and if found, the interceptor feeds in the value. Only // if the key is not found in the cache do we make a request. class CachingInterceptor : public grpc::experimental::Interceptor { public: @@ -102,8 +102,10 @@ class CachingInterceptor : public grpc::experimental::Interceptor { *status = grpc::Status::OK; } if (hijack) { + // Hijack is called only once when PRE_SEND_INITIAL_METADATA is present in the hook points methods->Hijack(); } else { + // Proceed is an indicator that the interceptor is done intercepting the batch. methods->Proceed(); } } From 92c4dffc174491d056207699fb93731d942cd7cf Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 16 Jan 2019 15:10:48 -0800 Subject: [PATCH 522/534] Remove uneeded lock --- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 40bf9c65644..31b454098e1 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1208,7 +1208,6 @@ void GrpcLb::FillChildRefsForChannelz( channelz::ChildRefsList* child_channels) { // delegate to the RoundRobin to fill the children subchannels. rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); - MutexLock lock(&lb_channel_mu_); if (lb_channel_ != nullptr) { grpc_core::channelz::ChannelNode* channel_node = grpc_channel_get_channelz_node(lb_channel_); From 6e3fee6f2aeeccca2b6e63b7be2a72c0db51bd84 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 16 Jan 2019 15:27:21 -0800 Subject: [PATCH 523/534] Add additional nullptr check --- .../ext/filters/client_channel/lb_policy/grpclb/grpclb.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 31b454098e1..78de8b35659 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1207,7 +1207,9 @@ void GrpcLb::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { // delegate to the RoundRobin to fill the children subchannels. - rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + if (rr_policy_ != nullptr) { + rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + } if (lb_channel_ != nullptr) { grpc_core::channelz::ChannelNode* channel_node = grpc_channel_get_channelz_node(lb_channel_); From d80731d3e8098fc9068bc4a7f15128db42935d53 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 17 Jan 2019 09:54:26 +0100 Subject: [PATCH 524/534] revert unnecessary using --- src/csharp/Grpc.Core/Internal/CallSafeHandle.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index 7154ddae30b..a3ef3e61ee1 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -18,7 +18,6 @@ using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; -using System.Threading; using Grpc.Core; using Grpc.Core.Utils; using Grpc.Core.Profiling; From e358f567b0edc26ead1db3bd6c5e4d033bf69a7d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 17 Jan 2019 14:16:41 +0100 Subject: [PATCH 525/534] make ServerCallContext an abstract base class --- .../TestServerCallContext.cs | 73 ++++++++- .../Internal/DefaultServerCallContext.cs | 111 ++++++++++++++ .../Internal/ServerCallContextExtraData.cs | 97 ------------ .../Grpc.Core/Internal/ServerCallHandler.cs | 4 +- src/csharp/Grpc.Core/ServerCallContext.cs | 143 +++++------------- 5 files changed, 220 insertions(+), 208 deletions(-) create mode 100644 src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs delete mode 100644 src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs diff --git a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs index d72e98e75a2..7a4fb15b4f9 100644 --- a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs +++ b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs @@ -36,12 +36,73 @@ namespace Grpc.Core.Testing string peer, AuthContext authContext, ContextPropagationToken contextPropagationToken, Func writeHeadersFunc, Func writeOptionsGetter, Action writeOptionsSetter) { - return new ServerCallContext(null, method, host, deadline, requestHeaders, cancellationToken, - (ctx, extraData, headers) => writeHeadersFunc(headers), - (ctx, extraData) => writeOptionsGetter(), - (ctx, extraData, options) => writeOptionsSetter(options), - (ctx, extraData) => peer, (ctx, callHandle) => authContext, - (ctx, callHandle, options) => contextPropagationToken); + return new TestingServerCallContext(method, host, deadline, requestHeaders, cancellationToken, peer, + authContext, contextPropagationToken, writeHeadersFunc, writeOptionsGetter, writeOptionsSetter); + } + + private class TestingServerCallContext : ServerCallContext + { + private readonly string method; + private readonly string host; + private readonly DateTime deadline; + private readonly Metadata requestHeaders; + private readonly CancellationToken cancellationToken; + private readonly Metadata responseTrailers = new Metadata(); + private Status status; + private readonly string peer; + private readonly AuthContext authContext; + private readonly ContextPropagationToken contextPropagationToken; + private readonly Func writeHeadersFunc; + private readonly Func writeOptionsGetter; + private readonly Action writeOptionsSetter; + + public TestingServerCallContext(string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, + string peer, AuthContext authContext, ContextPropagationToken contextPropagationToken, + Func writeHeadersFunc, Func writeOptionsGetter, Action writeOptionsSetter) + { + this.method = method; + this.host = host; + this.deadline = deadline; + this.requestHeaders = requestHeaders; + this.cancellationToken = cancellationToken; + this.responseTrailers = new Metadata(); + this.status = Status.DefaultSuccess; + this.peer = peer; + this.authContext = authContext; + this.contextPropagationToken = contextPropagationToken; + this.writeHeadersFunc = writeHeadersFunc; + this.writeOptionsGetter = writeOptionsGetter; + this.writeOptionsSetter = writeOptionsSetter; + } + + protected override string MethodInternal => method; + + protected override string HostInternal => host; + + protected override string PeerInternal => peer; + + protected override DateTime DeadlineInternal => deadline; + + protected override Metadata RequestHeadersInternal => requestHeaders; + + protected override CancellationToken CancellationTokenInternal => cancellationToken; + + protected override Metadata ResponseTrailersInternal => responseTrailers; + + protected override Status StatusInternal { get => status; set => status = value; } + protected override WriteOptions WriteOptionsInternal { get => writeOptionsGetter(); set => writeOptionsSetter(value); } + + protected override AuthContext AuthContextInternal => authContext; + + protected override ContextPropagationToken CreatePropagationTokenInternal(ContextPropagationOptions options) + { + return contextPropagationToken; + } + + protected override Task WriteResponseHeadersInternalAsync(Metadata responseHeaders) + { + return writeHeadersFunc(responseHeaders); + } } } } diff --git a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs new file mode 100644 index 00000000000..1e484bdcf2d --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs @@ -0,0 +1,111 @@ +#region Copyright notice and license + +// Copyright 2019 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. + +#endregion + +using System; +using System.Threading; +using System.Threading.Tasks; + +using Grpc.Core.Internal; +using Grpc.Core.Utils; + +namespace Grpc.Core +{ + /// + /// Default implementation of ServerCallContext. + /// + internal class DefaultServerCallContext : ServerCallContext + { + private readonly CallSafeHandle callHandle; + private readonly string method; + private readonly string host; + private readonly DateTime deadline; + private readonly Metadata requestHeaders; + private readonly CancellationToken cancellationToken; + private readonly Metadata responseTrailers; + private Status status; + private readonly IServerResponseStream serverResponseStream; + private readonly Lazy authContext; + + /// + /// Creates a new instance of ServerCallContext. + /// To allow reuse of ServerCallContext API by different gRPC implementations, the implementation of some members is provided externally. + /// To provide state, this ServerCallContext instance and extraData will be passed to the member implementations. + /// + internal DefaultServerCallContext(CallSafeHandle callHandle, string method, string host, DateTime deadline, + Metadata requestHeaders, CancellationToken cancellationToken, IServerResponseStream serverResponseStream) + { + this.callHandle = callHandle; + this.method = method; + this.host = host; + this.deadline = deadline; + this.requestHeaders = requestHeaders; + this.cancellationToken = cancellationToken; + this.responseTrailers = new Metadata(); + this.status = Status.DefaultSuccess; + this.serverResponseStream = serverResponseStream; + // TODO(jtattermusch): avoid unnecessary allocation of factory function and the lazy object + this.authContext = new Lazy(GetAuthContextEager); + } + + protected override ContextPropagationToken CreatePropagationTokenInternal(ContextPropagationOptions options) + { + return new ContextPropagationToken(callHandle, deadline, cancellationToken, options); + } + + protected override Task WriteResponseHeadersInternalAsync(Metadata responseHeaders) + { + return serverResponseStream.WriteResponseHeadersAsync(responseHeaders); + } + + protected override string MethodInternal => method; + + protected override string HostInternal => host; + + protected override string PeerInternal => callHandle.GetPeer(); + + protected override DateTime DeadlineInternal => deadline; + + protected override Metadata RequestHeadersInternal => requestHeaders; + + protected override CancellationToken CancellationTokenInternal => cancellationToken; + + protected override Metadata ResponseTrailersInternal => responseTrailers; + + protected override Status StatusInternal + { + get => status; + set => status = value; + } + + protected override WriteOptions WriteOptionsInternal + { + get => serverResponseStream.WriteOptions; + set => serverResponseStream.WriteOptions = value; + } + + protected override AuthContext AuthContextInternal => authContext.Value; + + private AuthContext GetAuthContextEager() + { + using (var authContextNative = callHandle.GetAuthContext()) + { + return authContextNative.ToAuthContext(); + } + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs b/src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs deleted file mode 100644 index 97b95e66df9..00000000000 --- a/src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs +++ /dev/null @@ -1,97 +0,0 @@ -#region Copyright notice and license - -// Copyright 2019 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. - -#endregion - -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Grpc.Core.Internal -{ - /// - /// Additional state for ServerCallContext. - /// Storing the extra state outside of ServerCallContext allows it to be implementation-agnostic. - /// - internal class ServerCallContextExtraData - { - readonly CallSafeHandle callHandle; - readonly IServerResponseStream serverResponseStream; - readonly Lazy cachedAuthContext; - - public ServerCallContextExtraData(CallSafeHandle callHandle, IServerResponseStream serverResponseStream) - { - this.callHandle = callHandle; - this.serverResponseStream = serverResponseStream; - // TODO(jtattermusch): avoid unnecessary allocation of factory function and the lazy object. - this.cachedAuthContext = new Lazy(GetAuthContextEager); - } - - public ServerCallContext NewServerCallContext(ServerRpcNew newRpc, CancellationToken cancellationToken) - { - DateTime realtimeDeadline = newRpc.Deadline.ToClockType(ClockType.Realtime).ToDateTime(); - - return new ServerCallContext(this, newRpc.Method, newRpc.Host, realtimeDeadline, - newRpc.RequestMetadata, cancellationToken, - ServerCallContext_WriteHeadersFunc, ServerCallContext_WriteOptionsGetter, ServerCallContext_WriteOptionsSetter, - ServerCallContext_PeerGetter, ServerCallContext_AuthContextGetter, ServerCallContext_ContextPropagationTokenFactory); - } - - private AuthContext GetAuthContextEager() - { - using (var authContextNative = callHandle.GetAuthContext()) - { - return authContextNative.ToAuthContext(); - } - } - - // Implementors of ServerCallContext's members are pre-allocated to avoid unneccessary delegate allocations. - readonly static Func ServerCallContext_WriteHeadersFunc = (ctx, extraData, headers) => - { - return ((ServerCallContextExtraData)extraData).serverResponseStream.WriteResponseHeadersAsync(headers); - }; - - readonly static Func ServerCallContext_WriteOptionsGetter = (ctx, extraData) => - { - - return ((ServerCallContextExtraData)extraData).serverResponseStream.WriteOptions; - }; - - readonly static Action ServerCallContext_WriteOptionsSetter = (ctx, extraData, options) => - { - ((ServerCallContextExtraData)extraData).serverResponseStream.WriteOptions = options; - }; - - readonly static Func ServerCallContext_PeerGetter = (ctx, extraData) => - { - // Getting the peer lazily is fine as the native call is guaranteed - // not to be disposed before user-supplied server side handler returns. - // Most users won't need to read this field anyway. - return ((ServerCallContextExtraData)extraData).callHandle.GetPeer(); - }; - - readonly static Func ServerCallContext_AuthContextGetter = (ctx, extraData) => - { - return ((ServerCallContextExtraData)extraData).cachedAuthContext.Value; - }; - - readonly static Func ServerCallContext_ContextPropagationTokenFactory = (ctx, extraData, options) => - { - var callHandle = ((ServerCallContextExtraData)extraData).callHandle; - return new ContextPropagationToken(callHandle, ctx.Deadline, ctx.CancellationToken, options); - }; - } -} diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs index ae586f7d1c4..c3859f1de27 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs @@ -348,9 +348,7 @@ namespace Grpc.Core.Internal public static ServerCallContext NewContext(ServerRpcNew newRpc, IServerResponseStream serverResponseStream, CancellationToken cancellationToken) { DateTime realtimeDeadline = newRpc.Deadline.ToClockType(ClockType.Realtime).ToDateTime(); - - var contextExtraData = new ServerCallContextExtraData(newRpc.Call, serverResponseStream); - return contextExtraData.NewServerCallContext(newRpc, cancellationToken); + return new DefaultServerCallContext(newRpc.Call, newRpc.Method, newRpc.Host, realtimeDeadline, newRpc.RequestMetadata, cancellationToken, serverResponseStream); } } } diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs index 05c20ca75f8..4a2fdf32c71 100644 --- a/src/csharp/Grpc.Core/ServerCallContext.cs +++ b/src/csharp/Grpc.Core/ServerCallContext.cs @@ -28,51 +28,13 @@ namespace Grpc.Core /// /// Context for a server-side call. /// - public class ServerCallContext + public abstract class ServerCallContext { - private readonly object extraData; - private readonly string method; - private readonly string host; - private readonly DateTime deadline; - private readonly Metadata requestHeaders; - private readonly CancellationToken cancellationToken; - private readonly Metadata responseTrailers = new Metadata(); - private readonly Func writeHeadersFunc; - private readonly Func writeOptionsGetter; - private readonly Action writeOptionsSetter; - - private readonly Func peerGetter; - private readonly Func authContextGetter; - private readonly Func contextPropagationTokenFactory; - - private Status status = Status.DefaultSuccess; - /// /// Creates a new instance of ServerCallContext. - /// To allow reuse of ServerCallContext API by different gRPC implementations, the implementation of some members is provided externally. - /// To provide state, this ServerCallContext instance and extraData will be passed to the member implementations. /// - internal ServerCallContext(object extraData, - string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, - Func writeHeadersFunc, - Func writeOptionsGetter, - Action writeOptionsSetter, - Func peerGetter, - Func authContextGetter, - Func contextPropagationTokenFactory) + protected ServerCallContext() { - this.extraData = extraData; - this.method = method; - this.host = host; - this.deadline = deadline; - this.requestHeaders = requestHeaders; - this.cancellationToken = cancellationToken; - this.writeHeadersFunc = GrpcPreconditions.CheckNotNull(writeHeadersFunc); - this.writeOptionsGetter = GrpcPreconditions.CheckNotNull(writeOptionsGetter); - this.writeOptionsSetter = GrpcPreconditions.CheckNotNull(writeOptionsSetter); - this.peerGetter = GrpcPreconditions.CheckNotNull(peerGetter); - this.authContextGetter = GrpcPreconditions.CheckNotNull(authContextGetter); - this.contextPropagationTokenFactory = GrpcPreconditions.CheckNotNull(contextPropagationTokenFactory); } /// @@ -84,7 +46,7 @@ namespace Grpc.Core /// The task that finished once response headers have been written. public Task WriteResponseHeadersAsync(Metadata responseHeaders) { - return writeHeadersFunc(this, extraData, responseHeaders); + return WriteResponseHeadersInternalAsync(responseHeaders); } /// @@ -92,83 +54,41 @@ namespace Grpc.Core /// public ContextPropagationToken CreatePropagationToken(ContextPropagationOptions options = null) { - return contextPropagationTokenFactory(this, extraData, options); + return CreatePropagationTokenInternal(options); } /// Name of method called in this RPC. - public string Method - { - get - { - return this.method; - } - } + public string Method => MethodInternal; /// Name of host called in this RPC. - public string Host - { - get - { - return this.host; - } - } + public string Host => HostInternal; /// Address of the remote endpoint in URI format. - public string Peer - { - get - { - return peerGetter(this, extraData); - } - } + public string Peer => PeerInternal; /// Deadline for this RPC. - public DateTime Deadline - { - get - { - return this.deadline; - } - } + public DateTime Deadline => DeadlineInternal; /// Initial metadata sent by client. - public Metadata RequestHeaders - { - get - { - return this.requestHeaders; - } - } + public Metadata RequestHeaders => RequestHeadersInternal; /// Cancellation token signals when call is cancelled. - public CancellationToken CancellationToken - { - get - { - return this.cancellationToken; - } - } + public CancellationToken CancellationToken => CancellationTokenInternal; /// Trailers to send back to client after RPC finishes. - public Metadata ResponseTrailers - { - get - { - return this.responseTrailers; - } - } + public Metadata ResponseTrailers => ResponseTrailersInternal; /// Status to send back to client after RPC finishes. public Status Status { get { - return this.status; + return StatusInternal; } set { - status = value; + StatusInternal = value; } } @@ -181,12 +101,12 @@ namespace Grpc.Core { get { - return writeOptionsGetter(this, extraData); + return WriteOptionsInternal; } set { - writeOptionsSetter(this, extraData, value); + WriteOptionsInternal = value; } } @@ -194,12 +114,31 @@ namespace Grpc.Core /// Gets the AuthContext associated with this call. /// Note: Access to AuthContext is an experimental API that can change without any prior notice. /// - public AuthContext AuthContext - { - get - { - return authContextGetter(this, extraData); - } - } + public AuthContext AuthContext => AuthContextInternal; + + /// Provides implementation of a non-virtual public member. + protected abstract Task WriteResponseHeadersInternalAsync(Metadata responseHeaders); + /// Provides implementation of a non-virtual public member. + protected abstract ContextPropagationToken CreatePropagationTokenInternal(ContextPropagationOptions options); + /// Provides implementation of a non-virtual public member. + protected abstract string MethodInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract string HostInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract string PeerInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract DateTime DeadlineInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract Metadata RequestHeadersInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract CancellationToken CancellationTokenInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract Metadata ResponseTrailersInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract Status StatusInternal { get; set; } + /// Provides implementation of a non-virtual public member. + protected abstract WriteOptions WriteOptionsInternal { get; set; } + /// Provides implementation of a non-virtual public member. + protected abstract AuthContext AuthContextInternal { get; } } } From 7d6341b627b883d400074bbdd0a70735f5290e84 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 17 Jan 2019 14:51:02 +0100 Subject: [PATCH 526/534] remove unnecessary using --- src/csharp/Grpc.Core.Testing/TestServerCallContext.cs | 1 - src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs | 1 - src/csharp/Grpc.Core/ServerCallContext.cs | 3 --- 3 files changed, 5 deletions(-) diff --git a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs index 7a4fb15b4f9..ff4fb66c6c9 100644 --- a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs +++ b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs @@ -19,7 +19,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Grpc.Core; namespace Grpc.Core.Testing { diff --git a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs index 1e484bdcf2d..b6a29af2edb 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs @@ -21,7 +21,6 @@ using System.Threading; using System.Threading.Tasks; using Grpc.Core.Internal; -using Grpc.Core.Utils; namespace Grpc.Core { diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs index 4a2fdf32c71..17aa1fe0661 100644 --- a/src/csharp/Grpc.Core/ServerCallContext.cs +++ b/src/csharp/Grpc.Core/ServerCallContext.cs @@ -20,9 +20,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Grpc.Core.Internal; -using Grpc.Core.Utils; - namespace Grpc.Core { /// From e3f1f3c8568314bd777f78883fa56520e0b7aee2 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 17 Jan 2019 09:39:23 -0800 Subject: [PATCH 527/534] Atomically store uuid of lb channel --- .../client_channel/lb_policy/grpclb/grpclb.cc | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 78de8b35659..6d46baa08fe 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -296,9 +296,8 @@ class GrpcLb : public LoadBalancingPolicy { // The channel for communicating with the LB server. grpc_channel* lb_channel_ = nullptr; - // Mutex to protect the channel to the LB server. This is used when - // processing a channelz request. - gpr_mu lb_channel_mu_; + // Uuid of the lb channel. Used for channelz. + gpr_atm lb_channel_uuid_ = 0; grpc_connectivity_state lb_channel_connectivity_; grpc_closure lb_channel_on_connectivity_changed_; // Are we already watching the LB channel's connectivity? @@ -986,7 +985,6 @@ GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args) .set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { // Initialization. - gpr_mu_init(&lb_channel_mu_); GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); @@ -1023,7 +1021,6 @@ GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args) GrpcLb::~GrpcLb() { GPR_ASSERT(pending_picks_ == nullptr); - gpr_mu_destroy(&lb_channel_mu_); gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); grpc_connectivity_state_destroy(&state_tracker_); @@ -1049,10 +1046,9 @@ void GrpcLb::ShutdownLocked() { // OnBalancerChannelConnectivityChangedLocked(), and we need to be // alive when that callback is invoked. if (lb_channel_ != nullptr) { - gpr_mu_lock(&lb_channel_mu_); grpc_channel_destroy(lb_channel_); lb_channel_ = nullptr; - gpr_mu_unlock(&lb_channel_mu_); + gpr_atm_no_barrier_store(&lb_channel_uuid_, 0); } grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), "grpclb_shutdown"); @@ -1210,12 +1206,8 @@ void GrpcLb::FillChildRefsForChannelz( if (rr_policy_ != nullptr) { rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); } - if (lb_channel_ != nullptr) { - grpc_core::channelz::ChannelNode* channel_node = - grpc_channel_get_channelz_node(lb_channel_); - if (channel_node != nullptr) { - child_channels->push_back(channel_node->uuid()); - } + if (lb_channel_uuid_ != 0) { + child_channels->push_back(lb_channel_uuid_); } } @@ -1275,12 +1267,15 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { if (lb_channel_ == nullptr) { char* uri_str; gpr_asprintf(&uri_str, "fake:///%s", server_name_); - gpr_mu_lock(&lb_channel_mu_); lb_channel_ = grpc_client_channel_factory_create_channel( client_channel_factory(), uri_str, GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args); - gpr_mu_unlock(&lb_channel_mu_); GPR_ASSERT(lb_channel_ != nullptr); + grpc_core::channelz::ChannelNode* channel_node = + grpc_channel_get_channelz_node(lb_channel_); + if (channel_node != nullptr) { + gpr_atm_no_barrier_store(&lb_channel_uuid_, channel_node->uuid()); + } gpr_free(uri_str); } // Propagate updates to the LB channel (pick_first) through the fake From 79b9707db4469aa48af694689e73157b7cd16864 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 17 Jan 2019 09:51:07 -0800 Subject: [PATCH 528/534] reviewer feedback --- .../ext/filters/client_channel/lb_policy/grpclb/grpclb.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 6d46baa08fe..51b61ecb92c 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1206,8 +1206,9 @@ void GrpcLb::FillChildRefsForChannelz( if (rr_policy_ != nullptr) { rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); } - if (lb_channel_uuid_ != 0) { - child_channels->push_back(lb_channel_uuid_); + gpr_atm uuid = gpr_atm_no_barrier_load(&lb_channel_uuid_); + if (uuid != 0) { + child_channels->push_back(uuid); } } From dde966f8c62f664b637d195983562b75860e4626 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 17 Jan 2019 12:03:14 -0800 Subject: [PATCH 529/534] Reviewer comments --- examples/cpp/keyvaluestore/caching_interceptor.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/cpp/keyvaluestore/caching_interceptor.h b/examples/cpp/keyvaluestore/caching_interceptor.h index 8ecdafaf159..5a31afe0f01 100644 --- a/examples/cpp/keyvaluestore/caching_interceptor.h +++ b/examples/cpp/keyvaluestore/caching_interceptor.h @@ -27,8 +27,9 @@ #endif // This is a naive implementation of a cache. A new cache is for each call. For -// each new key request, the key is first searched in the map and if found, the interceptor feeds in the value. Only -// if the key is not found in the cache do we make a request. +// each new key request, the key is first searched in the map and if found, the +// interceptor fills in the return value without making a request to the server. +// Only if the key is not found in the cache do we make a request. class CachingInterceptor : public grpc::experimental::Interceptor { public: CachingInterceptor(grpc::experimental::ClientRpcInfo* info) {} @@ -101,11 +102,14 @@ class CachingInterceptor : public grpc::experimental::Interceptor { auto* status = methods->GetRecvStatus(); *status = grpc::Status::OK; } + // One of Hijack or Proceed always needs to be called to make progress. if (hijack) { - // Hijack is called only once when PRE_SEND_INITIAL_METADATA is present in the hook points + // Hijack is called only once when PRE_SEND_INITIAL_METADATA is present in + // the hook points methods->Hijack(); } else { - // Proceed is an indicator that the interceptor is done intercepting the batch. + // Proceed is an indicator that the interceptor is done intercepting the + // batch. methods->Proceed(); } } From 189313d1ddf1358fc23e3924a2cf4785916a61b8 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Thu, 17 Jan 2019 01:31:11 +0000 Subject: [PATCH 530/534] Get the ruby interop client buildable for 1.18.0 back compatiblity matrix --- tools/interop_matrix/client_matrix.py | 4 ++++ .../interop_matrix/patches/ruby_v1.18.0/git_repo.patch | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 tools/interop_matrix/patches/ruby_v1.18.0/git_repo.patch diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index cd542b0f4c5..9b533867836 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -201,6 +201,10 @@ LANG_RELEASE_MATRIX = { ('v1.15.0', ReleaseInfo()), ('v1.16.0', ReleaseInfo()), ('v1.17.1', ReleaseInfo()), + ('v1.18.0', + ReleaseInfo(patch=[ + 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', + ])), ]), 'php': OrderedDict([ diff --git a/tools/interop_matrix/patches/ruby_v1.18.0/git_repo.patch b/tools/interop_matrix/patches/ruby_v1.18.0/git_repo.patch new file mode 100644 index 00000000000..dfa3cfc031a --- /dev/null +++ b/tools/interop_matrix/patches/ruby_v1.18.0/git_repo.patch @@ -0,0 +1,10 @@ +diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh +index 67f66090ae..e71ad91499 100755 +--- a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh ++++ b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh +@@ -30,4 +30,4 @@ cd /var/local/git/grpc + rvm --default use ruby-2.5 + + # build Ruby interop client and server +-(cd src/ruby && gem update bundler && bundle && rake compile) ++(cd src/ruby && gem install bundler -v 1.17.3 && bundle && rake compile) From 3bd12ee2a8ec39cc186bd11abb7f0afa23633072 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Thu, 17 Jan 2019 16:15:44 -0700 Subject: [PATCH 531/534] grpc: init compression_algorithm_ in ClientContext ctor `compression_algorithm_` could be a random value because not initialized in ctor. --- src/cpp/client/client_context.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc index c9ea3e5f83b..efb59c71a8c 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -57,6 +57,7 @@ ClientContext::ClientContext() deadline_(gpr_inf_future(GPR_CLOCK_REALTIME)), census_context_(nullptr), propagate_from_call_(nullptr), + compression_algorithm_(GRPC_COMPRESS_NONE), initial_metadata_corked_(false) { g_client_callbacks->DefaultConstructor(this); } From 5fc904a5e52e3e310eab4ae5425039dc4ae9718f Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 17 Jan 2019 11:56:56 -0800 Subject: [PATCH 532/534] Attempt to fix brew-update/rvm installation issue on mac --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 5b6b2569393..7b9b02b6318 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -40,6 +40,7 @@ fi set +ex # rvm script is very verbose and exits with errorcode # Advice from https://github.com/Homebrew/homebrew-cask/issues/8629#issuecomment-68641176 brew update && brew upgrade brew-cask && brew cleanup && brew cask cleanup +rvm --debug requirements ruby-2.5.0 source $HOME/.rvm/scripts/rvm set -e # rvm commands are very verbose time rvm install 2.5.0 From bf48d410a748cbb3a0e385121ebf49583ac52053 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 18 Jan 2019 09:33:35 +0100 Subject: [PATCH 533/534] change suffix for protected ServerCallContext members to *Core --- .../TestServerCallContext.cs | 24 ++++----- .../Internal/DefaultServerCallContext.cs | 24 ++++----- src/csharp/Grpc.Core/ServerCallContext.cs | 52 +++++++++---------- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs index ff4fb66c6c9..e6297e61226 100644 --- a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs +++ b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs @@ -74,31 +74,31 @@ namespace Grpc.Core.Testing this.writeOptionsSetter = writeOptionsSetter; } - protected override string MethodInternal => method; + protected override string MethodCore => method; - protected override string HostInternal => host; + protected override string HostCore => host; - protected override string PeerInternal => peer; + protected override string PeerCore => peer; - protected override DateTime DeadlineInternal => deadline; + protected override DateTime DeadlineCore => deadline; - protected override Metadata RequestHeadersInternal => requestHeaders; + protected override Metadata RequestHeadersCore => requestHeaders; - protected override CancellationToken CancellationTokenInternal => cancellationToken; + protected override CancellationToken CancellationTokenCore => cancellationToken; - protected override Metadata ResponseTrailersInternal => responseTrailers; + protected override Metadata ResponseTrailersCore => responseTrailers; - protected override Status StatusInternal { get => status; set => status = value; } - protected override WriteOptions WriteOptionsInternal { get => writeOptionsGetter(); set => writeOptionsSetter(value); } + protected override Status StatusCore { get => status; set => status = value; } + protected override WriteOptions WriteOptionsCore { get => writeOptionsGetter(); set => writeOptionsSetter(value); } - protected override AuthContext AuthContextInternal => authContext; + protected override AuthContext AuthContextCore => authContext; - protected override ContextPropagationToken CreatePropagationTokenInternal(ContextPropagationOptions options) + protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) { return contextPropagationToken; } - protected override Task WriteResponseHeadersInternalAsync(Metadata responseHeaders) + protected override Task WriteResponseHeadersAsyncCore(Metadata responseHeaders) { return writeHeadersFunc(responseHeaders); } diff --git a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs index b6a29af2edb..8220e599f92 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs @@ -61,43 +61,43 @@ namespace Grpc.Core this.authContext = new Lazy(GetAuthContextEager); } - protected override ContextPropagationToken CreatePropagationTokenInternal(ContextPropagationOptions options) + protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) { return new ContextPropagationToken(callHandle, deadline, cancellationToken, options); } - protected override Task WriteResponseHeadersInternalAsync(Metadata responseHeaders) + protected override Task WriteResponseHeadersAsyncCore(Metadata responseHeaders) { return serverResponseStream.WriteResponseHeadersAsync(responseHeaders); } - protected override string MethodInternal => method; + protected override string MethodCore => method; - protected override string HostInternal => host; + protected override string HostCore => host; - protected override string PeerInternal => callHandle.GetPeer(); + protected override string PeerCore => callHandle.GetPeer(); - protected override DateTime DeadlineInternal => deadline; + protected override DateTime DeadlineCore => deadline; - protected override Metadata RequestHeadersInternal => requestHeaders; + protected override Metadata RequestHeadersCore => requestHeaders; - protected override CancellationToken CancellationTokenInternal => cancellationToken; + protected override CancellationToken CancellationTokenCore => cancellationToken; - protected override Metadata ResponseTrailersInternal => responseTrailers; + protected override Metadata ResponseTrailersCore => responseTrailers; - protected override Status StatusInternal + protected override Status StatusCore { get => status; set => status = value; } - protected override WriteOptions WriteOptionsInternal + protected override WriteOptions WriteOptionsCore { get => serverResponseStream.WriteOptions; set => serverResponseStream.WriteOptions = value; } - protected override AuthContext AuthContextInternal => authContext.Value; + protected override AuthContext AuthContextCore => authContext.Value; private AuthContext GetAuthContextEager() { diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs index 17aa1fe0661..90b6e9419f0 100644 --- a/src/csharp/Grpc.Core/ServerCallContext.cs +++ b/src/csharp/Grpc.Core/ServerCallContext.cs @@ -43,7 +43,7 @@ namespace Grpc.Core /// The task that finished once response headers have been written. public Task WriteResponseHeadersAsync(Metadata responseHeaders) { - return WriteResponseHeadersInternalAsync(responseHeaders); + return WriteResponseHeadersAsyncCore(responseHeaders); } /// @@ -51,41 +51,41 @@ namespace Grpc.Core /// public ContextPropagationToken CreatePropagationToken(ContextPropagationOptions options = null) { - return CreatePropagationTokenInternal(options); + return CreatePropagationTokenCore(options); } /// Name of method called in this RPC. - public string Method => MethodInternal; + public string Method => MethodCore; /// Name of host called in this RPC. - public string Host => HostInternal; + public string Host => HostCore; /// Address of the remote endpoint in URI format. - public string Peer => PeerInternal; + public string Peer => PeerCore; /// Deadline for this RPC. - public DateTime Deadline => DeadlineInternal; + public DateTime Deadline => DeadlineCore; /// Initial metadata sent by client. - public Metadata RequestHeaders => RequestHeadersInternal; + public Metadata RequestHeaders => RequestHeadersCore; /// Cancellation token signals when call is cancelled. - public CancellationToken CancellationToken => CancellationTokenInternal; + public CancellationToken CancellationToken => CancellationTokenCore; /// Trailers to send back to client after RPC finishes. - public Metadata ResponseTrailers => ResponseTrailersInternal; + public Metadata ResponseTrailers => ResponseTrailersCore; /// Status to send back to client after RPC finishes. public Status Status { get { - return StatusInternal; + return StatusCore; } set { - StatusInternal = value; + StatusCore = value; } } @@ -98,12 +98,12 @@ namespace Grpc.Core { get { - return WriteOptionsInternal; + return WriteOptionsCore; } set { - WriteOptionsInternal = value; + WriteOptionsCore = value; } } @@ -111,31 +111,31 @@ namespace Grpc.Core /// Gets the AuthContext associated with this call. /// Note: Access to AuthContext is an experimental API that can change without any prior notice. /// - public AuthContext AuthContext => AuthContextInternal; + public AuthContext AuthContext => AuthContextCore; /// Provides implementation of a non-virtual public member. - protected abstract Task WriteResponseHeadersInternalAsync(Metadata responseHeaders); + protected abstract Task WriteResponseHeadersAsyncCore(Metadata responseHeaders); /// Provides implementation of a non-virtual public member. - protected abstract ContextPropagationToken CreatePropagationTokenInternal(ContextPropagationOptions options); + protected abstract ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options); /// Provides implementation of a non-virtual public member. - protected abstract string MethodInternal { get; } + protected abstract string MethodCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract string HostInternal { get; } + protected abstract string HostCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract string PeerInternal { get; } + protected abstract string PeerCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract DateTime DeadlineInternal { get; } + protected abstract DateTime DeadlineCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract Metadata RequestHeadersInternal { get; } + protected abstract Metadata RequestHeadersCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract CancellationToken CancellationTokenInternal { get; } + protected abstract CancellationToken CancellationTokenCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract Metadata ResponseTrailersInternal { get; } + protected abstract Metadata ResponseTrailersCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract Status StatusInternal { get; set; } + protected abstract Status StatusCore { get; set; } /// Provides implementation of a non-virtual public member. - protected abstract WriteOptions WriteOptionsInternal { get; set; } + protected abstract WriteOptions WriteOptionsCore { get; set; } /// Provides implementation of a non-virtual public member. - protected abstract AuthContext AuthContextInternal { get; } + protected abstract AuthContext AuthContextCore { get; } } } From d67009124fd258d7f42aef0ca87b1c0dddf3e018 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 17 Jan 2019 17:10:18 +0100 Subject: [PATCH 534/534] commenting on PRs is no longer used --- .../prepare_build_linux_perf_rc | 7 ---- .../helper_scripts/prepare_build_macos_rc | 6 --- .../pull_request/grpc_ios_binary_size.cfg | 1 - tools/run_tests/python_utils/comment_on_pr.py | 37 ------------------- 4 files changed, 51 deletions(-) delete mode 100644 tools/run_tests/python_utils/comment_on_pr.py diff --git a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc index ec1ec1179d3..ff5593e031a 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc @@ -21,15 +21,8 @@ ulimit -c unlimited # Performance PR testing needs GH API key and PR metadata to comment results if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then - set +x sudo apt-get install -y jq export ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) - - gsutil cp gs://grpc-testing-secrets/github_credentials/oauth_token.txt ~/ - # TODO(matt-kwong): rename this to GITHUB_OAUTH_TOKEN after Jenkins deprecation - export JENKINS_OAUTH_TOKEN=$(cat ~/oauth_token.txt) - export ghprbPullId=$KOKORO_GITHUB_PULL_REQUEST_NUMBER - set -x fi sudo pip install tabulate diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 7b9b02b6318..23619ecbb8b 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -25,16 +25,10 @@ export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db3 # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then - set +x brew update brew install jq || brew upgrade jq ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$ghprbTargetBranch" - - # TODO(matt-kwong): rename this to GITHUB_OAUTH_TOKEN after Jenkins deprecation - export JENKINS_OAUTH_TOKEN=$(cat ${KOKORO_GFILE_DIR}/oauth_token.txt) - export ghprbPullId=$KOKORO_GITHUB_PULL_REQUEST_NUMBER - set -x fi set +ex # rvm script is very verbose and exits with errorcode diff --git a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg index 1c4f7b23109..dc35ce81ffd 100644 --- a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg @@ -17,7 +17,6 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/macos/grpc_ios_binary_size.sh" timeout_mins: 60 -gfile_resources: "/bigstore/grpc-testing-secrets/github_credentials/oauth_token.txt" before_action { fetch_keystore { keystore_resource { diff --git a/tools/run_tests/python_utils/comment_on_pr.py b/tools/run_tests/python_utils/comment_on_pr.py deleted file mode 100644 index 399c996d4db..00000000000 --- a/tools/run_tests/python_utils/comment_on_pr.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2017 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 os -import json -import urllib2 - - -def comment_on_pr(text): - if 'JENKINS_OAUTH_TOKEN' not in os.environ: - print 'Missing JENKINS_OAUTH_TOKEN env var: not commenting' - return - if 'ghprbPullId' not in os.environ: - print 'Missing ghprbPullId env var: not commenting' - return - req = urllib2.Request( - url='https://api.github.com/repos/grpc/grpc/issues/%s/comments' % - os.environ['ghprbPullId'], - data=json.dumps({ - 'body': text - }), - headers={ - 'Authorization': 'token %s' % os.environ['JENKINS_OAUTH_TOKEN'], - 'Content-Type': 'application/json', - }) - print urllib2.urlopen(req).read()