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/string.h" 41#include "src/core/lib/gpr/tmpfile.h" 42#include "src/core/lib/gprpp/host_port.h" 43#include "src/core/lib/security/credentials/credentials.h" 44#include "src/core/lib/security/security_connector/ssl_utils_config.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 52#import "../ConfigureCronet.h" 53 54struct fullstack_secure_fixture_data { 55 std::string localaddr; 56}; 57 58static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( 59 grpc_channel_args *client_args, grpc_channel_args *server_args) { 60 grpc_end2end_test_fixture f; 61 int port = grpc_pick_unused_port_or_die(); 62 fullstack_secure_fixture_data *ffd = new fullstack_secure_fixture_data(); 63 memset(&f, 0, sizeof(f)); 64 65 ffd->localaddr = grpc_core::JoinHostPort("127.0.0.1", port); 66 67 f.fixture_data = ffd; 68 f.cq = grpc_completion_queue_create_for_next(NULL); 69 f.shutdown_cq = grpc_completion_queue_create_for_pluck(NULL); 70 71 return f; 72} 73 74static void process_auth_failure(void *state, grpc_auth_context *ctx, const grpc_metadata *md, 75 size_t md_count, grpc_process_auth_metadata_done_cb cb, 76 void *user_data) { 77 GPR_ASSERT(state == NULL); 78 cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL); 79} 80 81static void cronet_init_client_secure_fullstack(grpc_end2end_test_fixture *f, 82 grpc_channel_args *client_args, 83 stream_engine *cronetEngine) { 84 fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; 85 f->client = 86 grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr.c_str(), client_args, NULL); 87 GPR_ASSERT(f->client != NULL); 88} 89 90static void chttp2_init_server_secure_fullstack(grpc_end2end_test_fixture *f, 91 grpc_channel_args *server_args, 92 grpc_server_credentials *server_creds) { 93 fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; 94 if (f->server) { 95 grpc_server_destroy(f->server); 96 } 97 f->server = grpc_server_create(server_args, NULL); 98 grpc_server_register_completion_queue(f->server, f->cq, NULL); 99 GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.c_str(), server_creds)); 100 grpc_server_credentials_release(server_creds); 101 grpc_server_start(f->server); 102} 103 104static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { 105 fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; 106 delete ffd; 107} 108 109static void cronet_init_client_simple_ssl_secure_fullstack(grpc_end2end_test_fixture *f, 110 grpc_channel_args *client_args) { 111 grpc_core::ExecCtx exec_ctx; 112 stream_engine *cronetEngine = [Cronet getGlobalEngine]; 113 114 grpc_channel_args *new_client_args = grpc_channel_args_copy(client_args); 115 cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine); 116 grpc_channel_args_destroy(new_client_args); 117} 118 119static int fail_server_auth_check(grpc_channel_args *server_args) { 120 size_t i; 121 if (server_args == NULL) return 0; 122 for (i = 0; i < server_args->num_args; i++) { 123 if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) == 0) { 124 return 1; 125 } 126 } 127 return 0; 128} 129 130static void chttp2_init_server_simple_ssl_secure_fullstack(grpc_end2end_test_fixture *f, 131 grpc_channel_args *server_args) { 132 grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, test_server1_cert}; 133 grpc_server_credentials *ssl_creds = 134 grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL); 135 if (fail_server_auth_check(server_args)) { 136 grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL}; 137 grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); 138 } 139 chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); 140} 141 142/* All test configurations */ 143 144static grpc_end2end_test_config configs[] = { 145 {"chttp2/simple_ssl_fullstack", 146 FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, nullptr, 147 chttp2_create_fixture_secure_fullstack, cronet_init_client_simple_ssl_secure_fullstack, 148 chttp2_init_server_simple_ssl_secure_fullstack, chttp2_tear_down_secure_fullstack}, 149}; 150 151static char *roots_filename; 152 153@interface CoreCronetEnd2EndTests : XCTestCase 154 155@end 156 157@implementation CoreCronetEnd2EndTests 158 159// The setUp() function is run before the test cases run and only run once 160+ (void)setUp { 161 [super setUp]; 162 163 FILE *roots_file; 164 size_t roots_size = strlen(test_root_cert); 165 166 char *argv[] = {(char *)"CoreCronetEnd2EndTests"}; 167 grpc_test_init(1, argv); 168 grpc_end2end_tests_pre_init(); 169 170 /* Set the SSL roots env var. */ 171 roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); 172 GPR_ASSERT(roots_filename != NULL); 173 GPR_ASSERT(roots_file != NULL); 174 GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); 175 fclose(roots_file); 176 GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); 177 178 grpc_init(); 179 180 configureCronet(/*enable_netlog=*/false); 181} 182 183// The tearDown() function is run after all test cases finish running 184+ (void)tearDown { 185 grpc_shutdown(); 186 187 /* Cleanup. */ 188 remove(roots_filename); 189 gpr_free(roots_filename); 190 191 [super tearDown]; 192} 193 194- (void)testIndividualCase:(char *)test_case { 195 char *argv[] = {(char *)"h2_ssl", test_case}; 196 197 for (int i = 0; i < sizeof(configs) / sizeof(*configs); i++) { 198 grpc_end2end_tests(sizeof(argv) / sizeof(argv[0]), argv, configs[i]); 199 } 200} 201 202// TODO(mxyan): Use NSStringFromSelector(_cmd) to acquire test name from the 203// test case method name, so that bodies of test cases can stay identical 204- (void)testAuthorityNotSupported { 205 [self testIndividualCase:(char *)"authority_not_supported"]; 206} 207 208- (void)testBadHostname { 209 [self testIndividualCase:(char *)"bad_hostname"]; 210} 211 212- (void)testBinaryMetadata { 213 [self testIndividualCase:(char *)"binary_metadata"]; 214} 215 216- (void)testCallCreds { 217 // NOT SUPPORTED 218 // [self testIndividualCase:(char *)"call_creds"]; 219} 220 221- (void)testCancelAfterAccept { 222 [self testIndividualCase:(char *)"cancel_after_accept"]; 223} 224 225- (void)testCancelAfterClientDone { 226 [self testIndividualCase:(char *)"cancel_after_client_done"]; 227} 228 229- (void)testCancelAfterInvoke { 230 [self testIndividualCase:(char *)"cancel_after_invoke"]; 231} 232 233- (void)testCancelAfterRoundTrip { 234 [self testIndividualCase:(char *)"cancel_after_round_trip"]; 235} 236 237- (void)testCancelBeforeInvoke { 238 [self testIndividualCase:(char *)"cancel_before_invoke"]; 239} 240 241- (void)testCancelInAVacuum { 242 [self testIndividualCase:(char *)"cancel_in_a_vacuum"]; 243} 244 245- (void)testCancelWithStatus { 246 [self testIndividualCase:(char *)"cancel_with_status"]; 247} 248 249- (void)testCompressedPayload { 250 [self testIndividualCase:(char *)"compressed_payload"]; 251} 252 253- (void)testConnectivity { 254 // NOT SUPPORTED 255 // [self testIndividualCase:(char *)"connectivity"]; 256} 257 258- (void)testDefaultHost { 259 [self testIndividualCase:(char *)"default_host"]; 260} 261 262- (void)testDisappearingServer { 263 [self testIndividualCase:(char *)"disappearing_server"]; 264} 265 266- (void)testEmptyBatch { 267 [self testIndividualCase:(char *)"empty_batch"]; 268} 269 270- (void)testFilterCausesClose { 271 // NOT SUPPORTED 272 // [self testIndividualCase:(char *)"filter_causes_close"]; 273} 274 275- (void)testGracefulServerShutdown { 276 [self testIndividualCase:(char *)"graceful_server_shutdown"]; 277} 278 279- (void)testHighInitialSeqno { 280 [self testIndividualCase:(char *)"high_initial_seqno"]; 281} 282 283- (void)testHpackSize { 284 // NOT SUPPORTED 285 // [self testIndividualCase:(char *)"hpack_size"]; 286} 287 288- (void)testIdempotentRequest { 289 // NOT SUPPORTED 290 // [self testIndividualCase:(char *)"idempotent_request"]; 291} 292 293- (void)testInvokeLargeRequest { 294 // NOT SUPPORTED (frame size) 295 // [self testIndividualCase:(char *)"invoke_large_request"]; 296} 297 298- (void)testLargeMetadata { 299 // NOT SUPPORTED 300 // [self testIndividualCase:(char *)"large_metadata"]; 301} 302 303- (void)testMaxConcurrentStreams { 304 [self testIndividualCase:(char *)"max_concurrent_streams"]; 305} 306 307- (void)testMaxMessageLength { 308 // NOT SUPPORTED (close_error) 309 // [self testIndividualCase:(char *)"max_message_length"]; 310} 311 312- (void)testNegativeDeadline { 313 [self testIndividualCase:(char *)"negative_deadline"]; 314} 315 316- (void)testNoOp { 317 [self testIndividualCase:(char *)"no_op"]; 318} 319 320- (void)testPayload { 321 [self testIndividualCase:(char *)"payload"]; 322} 323 324- (void)testPing { 325 // NOT SUPPORTED 326 // [self testIndividualCase:(char *)"ping"]; 327} 328 329- (void)testPingPongStreaming { 330 [self testIndividualCase:(char *)"ping_pong_streaming"]; 331} 332 333- (void)testRegisteredCall { 334 [self testIndividualCase:(char *)"registered_call"]; 335} 336 337- (void)testRequestWithFlags { 338 // NOT SUPPORTED 339 // [self testIndividualCase:(char *)"request_with_flags"]; 340} 341 342- (void)testRequestWithPayload { 343 [self testIndividualCase:(char *)"request_with_payload"]; 344} 345 346- (void)testServerFinishesRequest { 347 [self testIndividualCase:(char *)"server_finishes_request"]; 348} 349 350- (void)testServerStreaming { 351 [self testIndividualCase:(char *)"server_streaming"]; 352} 353 354- (void)testShutdownFinishesCalls { 355 [self testIndividualCase:(char *)"shutdown_finishes_calls"]; 356} 357 358- (void)testShutdownFinishesTags { 359 [self testIndividualCase:(char *)"shutdown_finishes_tags"]; 360} 361 362- (void)testSimpleDelayedRequest { 363 [self testIndividualCase:(char *)"simple_delayed_request"]; 364} 365 366- (void)testSimpleMetadata { 367 [self testIndividualCase:(char *)"simple_metadata"]; 368} 369 370- (void)testSimpleRequest { 371 [self testIndividualCase:(char *)"simple_request"]; 372} 373 374- (void)testStreamingErrorResponse { 375 [self testIndividualCase:(char *)"streaming_error_response"]; 376} 377 378- (void)testTrailingMetadata { 379 [self testIndividualCase:(char *)"trailing_metadata"]; 380} 381 382@end 383