1/* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19/* 20 * This test file is derived from fixture h2_ssl.c in core end2end test 21 * (test/core/end2end/fixture/h2_ssl.c). The structure of the fixture is 22 * preserved as much as possible 23 * 24 * This fixture creates a server full stack using chttp2 and a client 25 * full stack using Cronet. End-to-end tests are run against this 26 * configuration 27 * 28 */ 29 30#import <XCTest/XCTest.h> 31#include "test/core/end2end/end2end_tests.h" 32 33#include <stdio.h> 34#include <string.h> 35 36#include <grpc/support/alloc.h> 37#include <grpc/support/log.h> 38 39#include "src/core/lib/channel/channel_args.h" 40#include "src/core/lib/gpr/env.h" 41#include "src/core/lib/gpr/host_port.h" 42#include "src/core/lib/gpr/string.h" 43#include "src/core/lib/gpr/tmpfile.h" 44#include "src/core/lib/security/credentials/credentials.h" 45#include "test/core/end2end/data/ssl_test_data.h" 46#include "test/core/util/port.h" 47#include "test/core/util/test_config.h" 48 49#import <Cronet/Cronet.h> 50#include <grpc/grpc_cronet.h> 51 52typedef struct fullstack_secure_fixture_data { 53 char *localaddr; 54} fullstack_secure_fixture_data; 55 56static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( 57 grpc_channel_args *client_args, grpc_channel_args *server_args) { 58 grpc_end2end_test_fixture f; 59 int port = grpc_pick_unused_port_or_die(); 60 fullstack_secure_fixture_data *ffd = 61 (fullstack_secure_fixture_data *)gpr_malloc(sizeof(fullstack_secure_fixture_data)); 62 memset(&f, 0, sizeof(f)); 63 64 gpr_join_host_port(&ffd->localaddr, "127.0.0.1", port); 65 66 f.fixture_data = ffd; 67 f.cq = grpc_completion_queue_create_for_next(NULL); 68 f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL); 69 70 return f; 71} 72 73static void process_auth_failure(void *state, grpc_auth_context *ctx, const grpc_metadata *md, 74 size_t md_count, grpc_process_auth_metadata_done_cb cb, 75 void *user_data) { 76 GPR_ASSERT(state == NULL); 77 cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL); 78} 79 80static void cronet_init_client_secure_fullstack(grpc_end2end_test_fixture *f, 81 grpc_channel_args *client_args, 82 stream_engine *cronetEngine) { 83 fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; 84 grpc_arg arg; 85 arg.key = const_cast<char *>(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); 86 arg.type = GRPC_ARG_INTEGER; 87 arg.value.integer = 1; 88 client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1); 89 f->client = grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL); 90 grpc_channel_args_destroy(client_args); 91 GPR_ASSERT(f->client != NULL); 92} 93 94static void chttp2_init_server_secure_fullstack(grpc_end2end_test_fixture *f, 95 grpc_channel_args *server_args, 96 grpc_server_credentials *server_creds) { 97 fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; 98 if (f->server) { 99 grpc_server_destroy(f->server); 100 } 101 f->server = grpc_server_create(server_args, NULL); 102 grpc_server_register_completion_queue(f->server, f->cq, NULL); 103 GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); 104 grpc_server_credentials_release(server_creds); 105 grpc_server_start(f->server); 106} 107 108static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { 109 fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; 110 gpr_free(ffd->localaddr); 111 gpr_free(ffd); 112} 113 114static void cronet_init_client_simple_ssl_secure_fullstack(grpc_end2end_test_fixture *f, 115 grpc_channel_args *client_args) { 116 grpc_core::ExecCtx exec_ctx; 117 stream_engine *cronetEngine = [Cronet getGlobalEngine]; 118 119 grpc_channel_args *new_client_args = grpc_channel_args_copy(client_args); 120 cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine); 121 grpc_channel_args_destroy(new_client_args); 122} 123 124static int fail_server_auth_check(grpc_channel_args *server_args) { 125 size_t i; 126 if (server_args == NULL) return 0; 127 for (i = 0; i < server_args->num_args; i++) { 128 if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) == 0) { 129 return 1; 130 } 131 } 132 return 0; 133} 134 135static void chttp2_init_server_simple_ssl_secure_fullstack(grpc_end2end_test_fixture *f, 136 grpc_channel_args *server_args) { 137 grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, test_server1_cert}; 138 grpc_server_credentials *ssl_creds = 139 grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL); 140 if (fail_server_auth_check(server_args)) { 141 grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL}; 142 grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); 143 } 144 chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); 145} 146 147/* All test configurations */ 148 149static grpc_end2end_test_config configs[] = { 150 {"chttp2/simple_ssl_fullstack", 151 FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, nullptr, 152 chttp2_create_fixture_secure_fullstack, cronet_init_client_simple_ssl_secure_fullstack, 153 chttp2_init_server_simple_ssl_secure_fullstack, chttp2_tear_down_secure_fullstack}, 154}; 155 156static char *roots_filename; 157 158@interface CoreCronetEnd2EndTests : XCTestCase 159 160@end 161 162@implementation CoreCronetEnd2EndTests 163 164// The setUp() function is run before the test cases run and only run once 165+ (void)setUp { 166 [super setUp]; 167 168 FILE *roots_file; 169 size_t roots_size = strlen(test_root_cert); 170 171 char *argv[] = {(char *)"CoreCronetEnd2EndTests"}; 172 grpc_test_init(1, argv); 173 grpc_end2end_tests_pre_init(); 174 175 /* Set the SSL roots env var. */ 176 roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); 177 GPR_ASSERT(roots_filename != NULL); 178 GPR_ASSERT(roots_file != NULL); 179 GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); 180 fclose(roots_file); 181 gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); 182 183 grpc_init(); 184 185 [Cronet setHttp2Enabled:YES]; 186 [Cronet enableTestCertVerifierForTesting]; 187 NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory 188 inDomains:NSUserDomainMask] lastObject]; 189 NSLog(@"Documents directory: %@", url); 190 [Cronet start]; 191 [Cronet startNetLogToFile:@"cronet_netlog.json" logBytes:YES]; 192} 193 194// The tearDown() function is run after all test cases finish running 195+ (void)tearDown { 196 grpc_shutdown(); 197 198 /* Cleanup. */ 199 remove(roots_filename); 200 gpr_free(roots_filename); 201 202 [super tearDown]; 203} 204 205- (void)testIndividualCase:(char *)test_case { 206 char *argv[] = {(char *)"h2_ssl", test_case}; 207 208 for (int i = 0; i < sizeof(configs) / sizeof(*configs); i++) { 209 grpc_end2end_tests(sizeof(argv) / sizeof(argv[0]), argv, configs[i]); 210 } 211} 212 213// TODO(mxyan): Use NSStringFromSelector(_cmd) to acquire test name from the 214// test case method name, so that bodies of test cases can stay identical 215- (void)testAuthorityNotSupported { 216 [self testIndividualCase:(char *)"authority_not_supported"]; 217} 218 219- (void)testBadHostname { 220 [self testIndividualCase:(char *)"bad_hostname"]; 221} 222 223- (void)testBinaryMetadata { 224 [self testIndividualCase:(char *)"binary_metadata"]; 225} 226 227- (void)testCallCreds { 228 // NOT SUPPORTED 229 // [self testIndividualCase:(char *)"call_creds"]; 230} 231 232- (void)testCancelAfterAccept { 233 [self testIndividualCase:(char *)"cancel_after_accept"]; 234} 235 236- (void)testCancelAfterClientDone { 237 [self testIndividualCase:(char *)"cancel_after_client_done"]; 238} 239 240- (void)testCancelAfterInvoke { 241 [self testIndividualCase:(char *)"cancel_after_invoke"]; 242} 243 244- (void)testCancelAfterRoundTrip { 245 [self testIndividualCase:(char *)"cancel_after_round_trip"]; 246} 247 248- (void)testCancelBeforeInvoke { 249 [self testIndividualCase:(char *)"cancel_before_invoke"]; 250} 251 252- (void)testCancelInAVacuum { 253 [self testIndividualCase:(char *)"cancel_in_a_vacuum"]; 254} 255 256- (void)testCancelWithStatus { 257 [self testIndividualCase:(char *)"cancel_with_status"]; 258} 259 260- (void)testCompressedPayload { 261 [self testIndividualCase:(char *)"compressed_payload"]; 262} 263 264- (void)testConnectivity { 265 // NOT SUPPORTED 266 // [self testIndividualCase:(char *)"connectivity"]; 267} 268 269- (void)testDefaultHost { 270 [self testIndividualCase:(char *)"default_host"]; 271} 272 273- (void)testDisappearingServer { 274 [self testIndividualCase:(char *)"disappearing_server"]; 275} 276 277- (void)testEmptyBatch { 278 [self testIndividualCase:(char *)"empty_batch"]; 279} 280 281- (void)testFilterCausesClose { 282 // NOT SUPPORTED 283 // [self testIndividualCase:(char *)"filter_causes_close"]; 284} 285 286- (void)testGracefulServerShutdown { 287 [self testIndividualCase:(char *)"graceful_server_shutdown"]; 288} 289 290- (void)testHighInitialSeqno { 291 [self testIndividualCase:(char *)"high_initial_seqno"]; 292} 293 294- (void)testHpackSize { 295 // NOT SUPPORTED 296 // [self testIndividualCase:(char *)"hpack_size"]; 297} 298 299- (void)testIdempotentRequest { 300 // NOT SUPPORTED 301 // [self testIndividualCase:(char *)"idempotent_request"]; 302} 303 304- (void)testInvokeLargeRequest { 305 // NOT SUPPORTED (frame size) 306 // [self testIndividualCase:(char *)"invoke_large_request"]; 307} 308 309- (void)testLargeMetadata { 310 // NOT SUPPORTED 311 // [self testIndividualCase:(char *)"large_metadata"]; 312} 313 314- (void)testMaxConcurrentStreams { 315 [self testIndividualCase:(char *)"max_concurrent_streams"]; 316} 317 318- (void)testMaxMessageLength { 319 // NOT SUPPORTED (close_error) 320 // [self testIndividualCase:(char *)"max_message_length"]; 321} 322 323- (void)testNegativeDeadline { 324 [self testIndividualCase:(char *)"negative_deadline"]; 325} 326 327- (void)testNetworkStatusChange { 328 [self testIndividualCase:(char *)"network_status_change"]; 329} 330 331- (void)testNoOp { 332 [self testIndividualCase:(char *)"no_op"]; 333} 334 335- (void)testPayload { 336 [self testIndividualCase:(char *)"payload"]; 337} 338 339- (void)testPing { 340 // NOT SUPPORTED 341 // [self testIndividualCase:(char *)"ping"]; 342} 343 344- (void)testPingPongStreaming { 345 [self testIndividualCase:(char *)"ping_pong_streaming"]; 346} 347 348- (void)testRegisteredCall { 349 [self testIndividualCase:(char *)"registered_call"]; 350} 351 352- (void)testRequestWithFlags { 353 // NOT SUPPORTED 354 // [self testIndividualCase:(char *)"request_with_flags"]; 355} 356 357- (void)testRequestWithPayload { 358 [self testIndividualCase:(char *)"request_with_payload"]; 359} 360 361- (void)testServerFinishesRequest { 362 [self testIndividualCase:(char *)"server_finishes_request"]; 363} 364 365- (void)testShutdownFinishesCalls { 366 [self testIndividualCase:(char *)"shutdown_finishes_calls"]; 367} 368 369- (void)testShutdownFinishesTags { 370 [self testIndividualCase:(char *)"shutdown_finishes_tags"]; 371} 372 373- (void)testSimpleDelayedRequest { 374 [self testIndividualCase:(char *)"simple_delayed_request"]; 375} 376 377- (void)testSimpleMetadata { 378 [self testIndividualCase:(char *)"simple_metadata"]; 379} 380 381- (void)testSimpleRequest { 382 [self testIndividualCase:(char *)"simple_request"]; 383} 384 385- (void)testStreamingErrorResponse { 386 [self testIndividualCase:(char *)"streaming_error_response"]; 387} 388 389- (void)testTrailingMetadata { 390 [self testIndividualCase:(char *)"trailing_metadata"]; 391} 392 393@end 394