| 
					
				 | 
			
			
				@@ -38,18 +38,19 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <grpc/support/alloc.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <grpc/support/host_port.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <grpc/support/log.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#include <grpc/support/time.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <grpc/support/string_util.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <grpc/support/time.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "src/core/channel/channel_stack.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "src/core/channel/client_channel.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "src/core/client_config/lb_policies/round_robin.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "src/core/client_config/lb_policy_registry.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#include "src/core/surface/channel.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "src/core/support/string.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "src/core/surface/channel.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "src/core/surface/server.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#include "test/core/util/test_config.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#include "test/core/util/port.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "test/core/end2end/cq_verifier.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "test/core/util/port.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "test/core/util/test_config.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 typedef struct servers_fixture { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   size_t num_servers; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -136,8 +137,9 @@ static void kill_server(const servers_fixture *f, size_t i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_log(GPR_INFO, "KILLING SERVER %d", i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_ASSERT(f->servers[i] != NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_server_shutdown_and_notify(f->servers[i], f->cq, tag(10000)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(10000), n_millis_time(5000), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                         NULL).type == GRPC_OP_COMPLETE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_completion_queue_pluck(f->cq, tag(10000), n_millis_time(5000), NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          .type == GRPC_OP_COMPLETE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_server_destroy(f->servers[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   f->servers[i] = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -203,8 +205,8 @@ static void teardown_servers(servers_fixture *f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (f->servers[i] == NULL) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_server_shutdown_and_notify(f->servers[i], f->cq, tag(10000)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(10000), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                           n_millis_time(5000), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                           NULL).type == GRPC_OP_COMPLETE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                           n_millis_time(5000), NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                   .type == GRPC_OP_COMPLETE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_server_destroy(f->servers[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_completion_queue_shutdown(f->cq); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -225,8 +227,8 @@ static void teardown_servers(servers_fixture *f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** Returns connection sequence (server indices), which must be freed */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-int *perform_request(servers_fixture *f, grpc_channel *client, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                     request_data *rdata, const test_spec *spec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int *perform_request(servers_fixture *f, grpc_channel *client, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            request_data *rdata, const test_spec *spec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_call *c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   int s_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   int *s_valid; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -242,8 +244,6 @@ int *perform_request(servers_fixture *f, grpc_channel *client, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   s_valid = gpr_malloc(sizeof(int) * f->num_servers); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   connection_sequence = gpr_malloc(sizeof(int) * spec->num_iters); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /* Send a trivial request. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (iter_num = 0; iter_num < spec->num_iters; iter_num++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cq_verifier *cqv = cq_verifier_create(f->cq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     rdata->details = NULL; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -304,8 +304,8 @@ int *perform_request(servers_fixture *f, grpc_channel *client, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     s_idx = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while ((ev = grpc_completion_queue_next( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                f->cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1), NULL)).type != 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           GRPC_QUEUE_TIMEOUT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                f->cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1), NULL)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               .type != GRPC_QUEUE_TIMEOUT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       read_tag = ((int)(gpr_intptr)ev.tag); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       gpr_log(GPR_DEBUG, "EVENT: success:%d, type:%d, tag:%d iter:%d", 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -324,8 +324,6 @@ int *perform_request(servers_fixture *f, grpc_channel *client, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    gpr_log(GPR_DEBUG, "s_idx=%d", s_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (s_idx >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       op = ops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       op->op = GRPC_OP_SEND_INITIAL_METADATA; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -371,7 +369,7 @@ int *perform_request(servers_fixture *f, grpc_channel *client, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                      &rdata->call_details[s_idx], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                      &f->request_metadata_recv[s_idx], f->cq, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                      f->cq, tag(1000 + (int)s_idx))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { /* no response from server */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       grpc_call_cancel(c, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if (!completed_client) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cq_expect_completion(cqv, tag(1), 1); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -397,6 +395,42 @@ int *perform_request(servers_fixture *f, grpc_channel *client, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return connection_sequence; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static grpc_call **perform_multirequest(servers_fixture *f, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                        grpc_channel *client, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                        size_t concurrent_calls) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call **calls; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_op ops[6]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_op *op; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  size_t i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  calls = gpr_malloc(sizeof(grpc_call *) * concurrent_calls); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < f->num_servers; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    kill_server(f, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op = ops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_INITIAL_METADATA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_initial_metadata.count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < concurrent_calls; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    calls[i] = grpc_channel_create_call( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq, "/foo", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        "foo.test.google.fr", gpr_inf_future(GPR_CLOCK_REALTIME), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GPR_ASSERT(calls[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(calls[i], ops, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                     (size_t)(op - ops), tag(1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                     NULL)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return calls; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void assert_channel_connectivity( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_channel *ch, size_t num_accepted_conn_states, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_connectivity_state accepted_conn_state, ...) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -487,8 +521,110 @@ void run_spec(const test_spec *spec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_free(actual_connection_sequence); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_free(rdata.call_details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_channel_destroy(client); /* calls the LB's shutdown func */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  teardown_servers(f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static grpc_channel *create_client(const servers_fixture *f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_channel *client; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  char *client_hostport; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  char *servers_hostports_str; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_arg arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_channel_args args; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  servers_hostports_str = gpr_strjoin_sep((const char **)f->servers_hostports, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          f->num_servers, ",", NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_asprintf(&client_hostport, "ipv4:%s?lb_policy=round_robin", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               servers_hostports_str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  arg.type = GRPC_ARG_INTEGER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  arg.key = "grpc.testing.fixed_reconnect_backoff"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  arg.value.integer = 100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  args.num_args = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  args.args = &arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  client = grpc_insecure_channel_create(client_hostport, &args, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_free(client_hostport); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_free(servers_hostports_str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return client; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void test_ping() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_channel *client; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  request_data rdata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  servers_fixture *f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_verifier *cqv; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_connectivity_state state = GRPC_CHANNEL_IDLE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const size_t num_servers = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  rdata.call_details = gpr_malloc(sizeof(grpc_call_details) * num_servers); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  f = setup_servers("127.0.0.1", &rdata, num_servers); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cqv = cq_verifier_create(f->cq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  client = create_client(f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_channel_ping(client, f->cq, tag(0), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_expect_completion(cqv, tag(0), 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* check that we're still in idle, and start connecting */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(grpc_channel_check_connectivity_state(client, 1) == 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             GRPC_CHANNEL_IDLE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* we'll go through some set of transitions (some might be missed), until 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     READY is reached */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  while (state != GRPC_CHANNEL_READY) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_channel_watch_connectivity_state( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f->cq, tag(99)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cq_expect_completion(cqv, tag(99), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cq_verify(cqv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    state = grpc_channel_check_connectivity_state(client, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GPR_ASSERT(state == GRPC_CHANNEL_READY || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               state == GRPC_CHANNEL_CONNECTING || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               state == GRPC_CHANNEL_TRANSIENT_FAILURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 1; i <= 5; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_channel_ping(client, f->cq, tag(i), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cq_expect_completion(cqv, tag(i), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cq_verify(cqv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_free(rdata.call_details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_channel_destroy(client); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   teardown_servers(f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_verifier_destroy(cqv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void test_pending_calls(size_t concurrent_calls) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  size_t i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call **calls; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_channel *client; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  request_data rdata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  servers_fixture *f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_spec *spec = test_spec_create(0, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  rdata.call_details = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_malloc(sizeof(grpc_call_details) * spec->num_servers); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  f = setup_servers("127.0.0.1", &rdata, spec->num_servers); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  client = create_client(f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  calls = perform_multirequest(f, client, concurrent_calls); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_cancel( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      calls[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      NULL); /* exercise the cancel pick path whilst there are pending picks */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_free(rdata.call_details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_channel_destroy(client); /* calls the LB's shutdown func */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* destroy the calls after the channel so that they are still around for the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * LB's shutdown func to process */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < concurrent_calls; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_call_destroy(calls[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_free(calls); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  teardown_servers(f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_spec_destroy(spec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void print_failed_expectations(const int *expected_connection_sequence, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -715,13 +851,14 @@ int main(int argc, char **argv) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_test_init(argc, argv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_init(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_lb_round_robin_trace = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_ASSERT(grpc_lb_policy_create("this-lb-policy-does-not-exist", NULL) == 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				              NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_ASSERT(grpc_lb_policy_create(NULL, NULL) == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /* everything is fine, all servers stay up the whole time and life's peachy */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   spec = test_spec_create(NUM_ITERS, NUM_SERVERS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* everything is fine, all servers stay up the whole time and life's peachy */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   spec->verifier = verify_vanilla_round_robin; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   spec->description = "test_all_server_up"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   run_spec(spec); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -735,7 +872,8 @@ int main(int argc, char **argv) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   run_spec(spec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /* at the start of the 2nd iteration, kill all but the first and last servers. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* at the start of the 2nd iteration, kill all but the first and last 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * servers. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    * This should knock down the server bound to be selected next */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   test_spec_reset(spec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   spec->verifier = verify_vanishing_floor_round_robin; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -764,9 +902,11 @@ int main(int argc, char **argv) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     spec->revive_at[3][i] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   run_spec(spec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   test_spec_destroy(spec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_pending_calls(4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_ping(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_shutdown(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |