diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index b6bc3f4bc7f..d5429bf302d 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -229,6 +229,52 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +// Test that responses can be dispatched even if we do not run main run-loop +- (void)testAsyncDispatchWithV2API { + XCTAssertNotNil([[self class] host]); + + GPBEmpty *request = [GPBEmpty message]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + + __block BOOL messageReceived = NO; + __block BOOL done = NO; + NSCondition *cond = [[NSCondition alloc] init]; + GRPCUnaryProtoCall *call = [_service + emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + if (message) { + id expectedResponse = [GPBEmpty message]; + XCTAssertEqualObjects(message, expectedResponse); + [cond lock]; + messageReceived = YES; + [cond unlock]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + [cond lock]; + done = YES; + [cond signal]; + [cond unlock]; + }] + callOptions:options]; + + NSDate *deadline = [NSDate dateWithTimeIntervalSinceNow:TEST_TIMEOUT]; + [call start]; + + [cond lock]; + while (!done && [deadline timeIntervalSinceNow] > 0) { + [cond waitUntilDate:deadline]; + } + XCTAssertTrue(messageReceived); + XCTAssertTrue(done); + [cond unlock]; +} + - (void)testLargeUnaryRPC { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"];