diff --git a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m index a50bf4728f8..9589926d8b5 100644 --- a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m +++ b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m @@ -32,13 +32,13 @@ */ #import -#import #import +#import #import -#import -#import #import +#import +#import #import "test/core/end2end/cq_verifier.h" #import "test/core/util/port.h" @@ -49,19 +49,19 @@ #import "src/core/lib/support/env.h" #import "src/core/lib/support/string.h" #import "src/core/lib/support/tmpfile.h" -#import "test/core/util/test_config.h" #import "test/core/end2end/data/ssl_test_data.h" +#import "test/core/util/test_config.h" #import static void drain_cq(grpc_completion_queue *cq) { grpc_event ev; do { - ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5), NULL); + ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5), + NULL); } while (ev.type != GRPC_QUEUE_SHUTDOWN); } - @interface CronetUnitTests : XCTestCase @end @@ -71,8 +71,8 @@ static void drain_cq(grpc_completion_queue *cq) { + (void)setUp { [super setUp]; -/*** FILE *roots_file; - size_t roots_size = strlen(test_root_cert);*/ + /*** FILE *roots_file; + size_t roots_size = strlen(test_root_cert);*/ char *argv[] = {"CoreCronetEnd2EndTests"}; grpc_test_init(1, argv); @@ -83,8 +83,8 @@ static void drain_cq(grpc_completion_queue *cq) { [Cronet setSslKeyLogFileName:@"Documents/key"]; [Cronet enableTestCertVerifierForTesting]; NSURL *url = [[[NSFileManager defaultManager] - URLsForDirectory:NSDocumentDirectory - inDomains:NSUserDomainMask] lastObject]; + URLsForDirectory:NSDocumentDirectory + inDomains:NSUserDomainMask] lastObject]; NSLog(@"Documents directory: %@", url); [Cronet start]; [Cronet startNetLogToFile:@"Documents/cronet_netlog.json" logBytes:YES]; @@ -104,28 +104,28 @@ void init_ssl(void) { OpenSSL_add_ssl_algorithms(); } -void cleanup_ssl(void) { - EVP_cleanup(); -} +void cleanup_ssl(void) { EVP_cleanup(); } int alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) { // Always select "h2" as the ALPN protocol to be used - *out = (const unsigned char*)"h2"; + *out = (const unsigned char *)"h2"; *outlen = 2; return SSL_TLSEXT_ERR_OK; } void init_ctx(SSL_CTX *ctx) { // Install server certificate - BIO *pem = BIO_new_mem_buf((void*)test_server1_cert, (int)strlen(test_server1_cert)); + BIO *pem = BIO_new_mem_buf((void *)test_server1_cert, + (int)strlen(test_server1_cert)); X509 *cert = PEM_read_bio_X509_AUX(pem, NULL, NULL, ""); SSL_CTX_use_certificate(ctx, cert); X509_free(cert); BIO_free(pem); // Install server private key - pem = BIO_new_mem_buf((void *)test_server1_key, (int)strlen(test_server1_key)); + pem = + BIO_new_mem_buf((void *)test_server1_key, (int)strlen(test_server1_key)); EVP_PKEY *key = PEM_read_bio_PrivateKey(pem, NULL, NULL, ""); SSL_CTX_use_PrivateKey(ctx, key); EVP_PKEY_free(key); @@ -139,29 +139,34 @@ void init_ctx(SSL_CTX *ctx) { } unsigned int parse_h2_length(const char *field) { - return ((unsigned int)(unsigned char)(field[0])) * 65536 + - ((unsigned int)(unsigned char)(field[1])) * 256 + - ((unsigned int)(unsigned char)(field[2])); + return ((unsigned int)(unsigned char)(field[0])) * 65536 + + ((unsigned int)(unsigned char)(field[1])) * 256 + + ((unsigned int)(unsigned char)(field[2])); } - (void)testInternalError { grpc_call *c; grpc_slice request_payload_slice = - grpc_slice_from_copied_string("hello world"); + grpc_slice_from_copied_string("hello world"); grpc_byte_buffer *request_payload = - grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_raw_byte_buffer_create(&request_payload_slice, 1); gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5); - grpc_metadata meta_c[2] = { - {"key1", "val1", 4, 0, {{NULL, NULL, NULL, NULL}}}, - {"key2", "val2", 4, 0, {{NULL, NULL, NULL, NULL}}}}; + grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), + grpc_slice_from_static_string("val1"), + 0, + {{NULL, NULL, NULL, NULL}}}, + {grpc_slice_from_static_string("key2"), + grpc_slice_from_static_string("val2"), + 0, + {{NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); char *addr; gpr_join_host_port(&addr, "127.0.0.1", port); grpc_completion_queue *cq = grpc_completion_queue_create(NULL); stream_engine *cronetEngine = [Cronet getGlobalEngine]; - grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, - NULL, NULL); + grpc_channel *client = + grpc_cronet_secure_channel_create(cronetEngine, addr, NULL, NULL); cq_verifier *cqv = cq_verifier_create(cq); grpc_op ops[6]; @@ -173,12 +178,11 @@ unsigned int parse_h2_length(const char *field) { grpc_call_details call_details; grpc_status_code status; grpc_call_error error; - char *details = NULL; - size_t details_capacity = 0; + grpc_slice details; - c = grpc_channel_create_call( - client, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/foo", - NULL, deadline, NULL); + c = grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, cq, + grpc_slice_from_static_string("/foo"), NULL, + deadline, NULL); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -217,40 +221,40 @@ unsigned int parse_h2_length(const char *field) { 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->data.recv_status_on_client.status_details_capacity = &details_capacity; op->flags = 0; op->reserved = NULL; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), (void*)1, NULL); + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), (void *)1, NULL); GPR_ASSERT(GRPC_CALL_OK == error); - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - int sl = socket(AF_INET, SOCK_STREAM, 0); - GPR_ASSERT(sl >= 0); - - // Make and TCP endpoint to accept the connection - struct sockaddr_in s_addr; - memset(&s_addr, 0, sizeof(s_addr)); - s_addr.sin_family = AF_INET; - s_addr.sin_addr.s_addr = htonl(INADDR_ANY); - s_addr.sin_port = htons(port); - GPR_ASSERT(0 == bind(sl, (struct sockaddr*)&s_addr, sizeof(s_addr))); - GPR_ASSERT(0 == listen(sl, 5)); - int s = accept(sl, NULL, NULL); - GPR_ASSERT(s >= 0); - - // Close the connection after 1 second to trigger Cronet's on_failed() - sleep(1); - close(s); - close(sl); - }); - - CQ_EXPECT_COMPLETION(cqv, (void*)1, 1); + dispatch_async( + dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + int sl = socket(AF_INET, SOCK_STREAM, 0); + GPR_ASSERT(sl >= 0); + + // Make and TCP endpoint to accept the connection + struct sockaddr_in s_addr; + memset(&s_addr, 0, sizeof(s_addr)); + s_addr.sin_family = AF_INET; + s_addr.sin_addr.s_addr = htonl(INADDR_ANY); + s_addr.sin_port = htons(port); + GPR_ASSERT(0 == bind(sl, (struct sockaddr *)&s_addr, sizeof(s_addr))); + GPR_ASSERT(0 == listen(sl, 5)); + int s = accept(sl, NULL, NULL); + GPR_ASSERT(s >= 0); + + // Close the connection after 1 second to trigger Cronet's on_failed() + sleep(1); + close(s); + close(sl); + }); + + CQ_EXPECT_COMPLETION(cqv, (void *)1, 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); - gpr_free(details); + 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); @@ -262,7 +266,7 @@ unsigned int parse_h2_length(const char *field) { grpc_byte_buffer_destroy(request_payload); grpc_byte_buffer_destroy(response_payload_recv); - + grpc_channel_destroy(client); grpc_completion_queue_shutdown(cq); drain_cq(cq); @@ -273,17 +277,22 @@ unsigned int parse_h2_length(const char *field) { grpc_arg arg; arg.key = GRPC_ARG_USE_CRONET_PACKET_COALESCING; arg.type = GRPC_ARG_INTEGER; - arg.value.integer = use_coalescing ? 1:0; + arg.value.integer = use_coalescing ? 1 : 0; grpc_channel_args *args = grpc_channel_args_copy_and_add(NULL, &arg, 1); grpc_call *c; grpc_slice request_payload_slice = - grpc_slice_from_copied_string("hello world"); + grpc_slice_from_copied_string("hello world"); grpc_byte_buffer *request_payload = - grpc_raw_byte_buffer_create(&request_payload_slice, 1); - gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5); - grpc_metadata meta_c[2] = { - {"key1", "val1", 4, 0, {{NULL, NULL, NULL, NULL}}}, - {"key2", "val2", 4, 0, {{NULL, NULL, NULL, NULL}}}}; + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5); + grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), + grpc_slice_from_static_string("val1"), + 0, + {{NULL, NULL, NULL, NULL}}}, + {grpc_slice_from_static_string("key2"), + grpc_slice_from_static_string("val2"), + 0, + {{NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); char *addr; @@ -303,12 +312,11 @@ unsigned int parse_h2_length(const char *field) { grpc_call_details call_details; grpc_status_code status; grpc_call_error error; - char *details = NULL; - size_t details_capacity = 0; + grpc_slice details; - c = grpc_channel_create_call( - client, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/foo", - NULL, deadline, NULL); + c = grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, cq, + grpc_slice_from_static_string("/foo"), NULL, + deadline, NULL); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -325,7 +333,7 @@ unsigned int parse_h2_length(const char *field) { op->reserved = NULL; op++; op->op = GRPC_OP_SEND_MESSAGE; - op->data.send_message = request_payload; + op->data.send_message.send_message = request_payload; op->flags = 0; op->reserved = NULL; op++; @@ -334,12 +342,12 @@ unsigned int parse_h2_length(const char *field) { op->reserved = NULL; op++; op->op = GRPC_OP_RECV_INITIAL_METADATA; - op->data.recv_initial_metadata = &initial_metadata_recv; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; op->flags = 0; op->reserved = NULL; op++; op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message = &response_payload_recv; + op->data.recv_message.recv_message = &response_payload_recv; op->flags = 0; op->reserved = NULL; op++; @@ -347,79 +355,80 @@ unsigned int parse_h2_length(const char *field) { 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->data.recv_status_on_client.status_details_capacity = &details_capacity; op->flags = 0; op->reserved = NULL; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), (void*)1, NULL); + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), (void *)1, NULL); GPR_ASSERT(GRPC_CALL_OK == error); - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - int sl = socket(AF_INET, SOCK_STREAM, 0); - GPR_ASSERT(sl >= 0); - struct sockaddr_in s_addr; - memset(&s_addr, 0, sizeof(s_addr)); - s_addr.sin_family = AF_INET; - s_addr.sin_addr.s_addr = htonl(INADDR_ANY); - s_addr.sin_port = htons(port); - GPR_ASSERT(0 == bind(sl, (struct sockaddr*)&s_addr, sizeof(s_addr))); - GPR_ASSERT(0 == listen(sl, 5)); - int s = accept(sl, NULL, NULL); - GPR_ASSERT(s >= 0); - struct timeval tv; - tv.tv_sec = 2; - tv.tv_usec = 0; - setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); - - // Make an TLS endpoint to receive Cronet's transmission - SSL_CTX *ctx = SSL_CTX_new(TLSv1_2_server_method()); - init_ctx(ctx); - SSL *ssl = SSL_new(ctx); - SSL_set_fd(ssl, s); - SSL_accept(ssl); - - const char magic[] = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"; - - char buf[4096]; - long len; - bool coalesced = false; - while ((len = SSL_read(ssl, buf, sizeof(buf))) > 0) { - gpr_log(GPR_DEBUG, "Read len: %ld", len); - - // Analyze the HTTP/2 frames in the same TLS PDU to identify if - // coalescing is successful - unsigned int p = 0; - while (p < len) { - if (len - p >= 24 && 0 == memcmp(&buf[p], magic, 24)) { - p += 24; - continue; + dispatch_async( + dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + int sl = socket(AF_INET, SOCK_STREAM, 0); + GPR_ASSERT(sl >= 0); + struct sockaddr_in s_addr; + memset(&s_addr, 0, sizeof(s_addr)); + s_addr.sin_family = AF_INET; + s_addr.sin_addr.s_addr = htonl(INADDR_ANY); + s_addr.sin_port = htons(port); + GPR_ASSERT(0 == bind(sl, (struct sockaddr *)&s_addr, sizeof(s_addr))); + GPR_ASSERT(0 == listen(sl, 5)); + int s = accept(sl, NULL, NULL); + GPR_ASSERT(s >= 0); + struct timeval tv; + tv.tv_sec = 2; + tv.tv_usec = 0; + setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + + // Make an TLS endpoint to receive Cronet's transmission + SSL_CTX *ctx = SSL_CTX_new(TLSv1_2_server_method()); + init_ctx(ctx); + SSL *ssl = SSL_new(ctx); + SSL_set_fd(ssl, s); + SSL_accept(ssl); + + const char magic[] = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"; + + char buf[4096]; + long len; + bool coalesced = false; + while ((len = SSL_read(ssl, buf, sizeof(buf))) > 0) { + gpr_log(GPR_DEBUG, "Read len: %ld", len); + + // Analyze the HTTP/2 frames in the same TLS PDU to identify if + // coalescing is successful + unsigned int p = 0; + while (p < len) { + if (len - p >= 24 && 0 == memcmp(&buf[p], magic, 24)) { + p += 24; + continue; + } + + if (buf[p + 3] == 0 && // Type is DATA + parse_h2_length(&buf[p]) == 0x10 && // Length is correct + (buf[p + 4] & 1) != 0 && // EOS bit is set + 0 == memcmp("hello world", &buf[p + 14], + 11)) { // Message is correct + coalesced = true; + break; + } + p += (parse_h2_length(&buf[p]) + 9); + } + if (coalesced) { + break; + } } - if (buf[p+3] == 0 && // Type is DATA - parse_h2_length(&buf[p]) == 0x10 && // Length is correct - (buf[p+4] & 1) != 0 && // EOS bit is set - 0 == memcmp("hello world", &buf[p+14], 11)) { // Message is correct - coalesced = true; - break; - } - p += (parse_h2_length(&buf[p]) + 9); - } - if (coalesced) { - break; - } - } - - XCTAssert(coalesced == use_coalescing); - SSL_free(ssl); - SSL_CTX_free(ctx); - close(s); - close(sl); - }); - - CQ_EXPECT_COMPLETION(cqv, (void*)1, 1); + XCTAssert(coalesced == use_coalescing); + SSL_free(ssl); + SSL_CTX_free(ctx); + close(s); + close(sl); + }); + + CQ_EXPECT_COMPLETION(cqv, (void *)1, 1); cq_verify(cqv); - gpr_free(details); + 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); @@ -431,7 +440,7 @@ unsigned int parse_h2_length(const char *field) { grpc_byte_buffer_destroy(request_payload); grpc_byte_buffer_destroy(response_payload_recv); - + grpc_channel_destroy(client); grpc_completion_queue_shutdown(cq); drain_cq(cq);