|  | @@ -48,9 +48,12 @@
 | 
	
		
			
				|  |  |  #include <grpc/support/log.h>
 | 
	
		
			
				|  |  |  #include <grpc/support/sync.h>
 | 
	
		
			
				|  |  |  #include <grpc/support/time.h>
 | 
	
		
			
				|  |  | +#include <grpc/support/useful.h>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +#include "src/core/lib/channel/channel_args.h"
 | 
	
		
			
				|  |  |  #include "src/core/lib/iomgr/ev_posix.h"
 | 
	
		
			
				|  |  |  #include "src/core/lib/iomgr/iomgr.h"
 | 
	
		
			
				|  |  | +#include "src/core/lib/iomgr/socket_factory_posix.h"
 | 
	
		
			
				|  |  |  #include "test/core/util/test_config.h"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
 | 
	
	
		
			
				|  | @@ -94,16 +97,59 @@ static void on_fd_orphaned(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
 | 
	
		
			
				|  |  |    g_number_of_orphan_calls++;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +struct test_socket_factory {
 | 
	
		
			
				|  |  | +  grpc_socket_factory base;
 | 
	
		
			
				|  |  | +  int number_of_socket_calls;
 | 
	
		
			
				|  |  | +  int number_of_bind_calls;
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +typedef struct test_socket_factory test_socket_factory;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static int test_socket_factory_socket(grpc_socket_factory *factory, int domain,
 | 
	
		
			
				|  |  | +                                      int type, int protocol) {
 | 
	
		
			
				|  |  | +  test_socket_factory *f = (test_socket_factory *)factory;
 | 
	
		
			
				|  |  | +  f->number_of_socket_calls++;
 | 
	
		
			
				|  |  | +  return socket(domain, type, protocol);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static int test_socket_factory_bind(grpc_socket_factory *factory, int sockfd,
 | 
	
		
			
				|  |  | +                                    const grpc_resolved_address *addr) {
 | 
	
		
			
				|  |  | +  test_socket_factory *f = (test_socket_factory *)factory;
 | 
	
		
			
				|  |  | +  f->number_of_bind_calls++;
 | 
	
		
			
				|  |  | +  return bind(sockfd, (struct sockaddr *)addr->addr, (socklen_t)addr->len);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static int test_socket_factory_compare(grpc_socket_factory *a,
 | 
	
		
			
				|  |  | +                                       grpc_socket_factory *b) {
 | 
	
		
			
				|  |  | +  return GPR_ICMP(a, b);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void test_socket_factory_destroy(grpc_socket_factory *factory) {
 | 
	
		
			
				|  |  | +  test_socket_factory *f = (test_socket_factory *)factory;
 | 
	
		
			
				|  |  | +  gpr_free(f);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static const grpc_socket_factory_vtable test_socket_factory_vtable = {
 | 
	
		
			
				|  |  | +    test_socket_factory_socket, test_socket_factory_bind,
 | 
	
		
			
				|  |  | +    test_socket_factory_compare, test_socket_factory_destroy};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static test_socket_factory *test_socket_factory_create(void) {
 | 
	
		
			
				|  |  | +  test_socket_factory *factory = gpr_malloc(sizeof(test_socket_factory));
 | 
	
		
			
				|  |  | +  grpc_socket_factory_init(&factory->base, &test_socket_factory_vtable);
 | 
	
		
			
				|  |  | +  factory->number_of_socket_calls = 0;
 | 
	
		
			
				|  |  | +  factory->number_of_bind_calls = 0;
 | 
	
		
			
				|  |  | +  return factory;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static void test_no_op(void) {
 | 
	
		
			
				|  |  |    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 | 
	
		
			
				|  |  | -  grpc_udp_server *s = grpc_udp_server_create();
 | 
	
		
			
				|  |  | +  grpc_udp_server *s = grpc_udp_server_create(NULL);
 | 
	
		
			
				|  |  |    grpc_udp_server_destroy(&exec_ctx, s, NULL);
 | 
	
		
			
				|  |  |    grpc_exec_ctx_finish(&exec_ctx);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void test_no_op_with_start(void) {
 | 
	
		
			
				|  |  |    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 | 
	
		
			
				|  |  | -  grpc_udp_server *s = grpc_udp_server_create();
 | 
	
		
			
				|  |  | +  grpc_udp_server *s = grpc_udp_server_create(NULL);
 | 
	
		
			
				|  |  |    LOG_TEST("test_no_op_with_start");
 | 
	
		
			
				|  |  |    grpc_udp_server_start(&exec_ctx, s, NULL, 0, NULL);
 | 
	
		
			
				|  |  |    grpc_udp_server_destroy(&exec_ctx, s, NULL);
 | 
	
	
		
			
				|  | @@ -115,7 +161,7 @@ static void test_no_op_with_port(void) {
 | 
	
		
			
				|  |  |    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 | 
	
		
			
				|  |  |    grpc_resolved_address resolved_addr;
 | 
	
		
			
				|  |  |    struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
 | 
	
		
			
				|  |  | -  grpc_udp_server *s = grpc_udp_server_create();
 | 
	
		
			
				|  |  | +  grpc_udp_server *s = grpc_udp_server_create(NULL);
 | 
	
		
			
				|  |  |    LOG_TEST("test_no_op_with_port");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    memset(&resolved_addr, 0, sizeof(resolved_addr));
 | 
	
	
		
			
				|  | @@ -131,12 +177,44 @@ static void test_no_op_with_port(void) {
 | 
	
		
			
				|  |  |    GPR_ASSERT(g_number_of_orphan_calls == 1);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static void test_no_op_with_port_and_socket_factory(void) {
 | 
	
		
			
				|  |  | +  g_number_of_orphan_calls = 0;
 | 
	
		
			
				|  |  | +  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 | 
	
		
			
				|  |  | +  grpc_resolved_address resolved_addr;
 | 
	
		
			
				|  |  | +  struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  test_socket_factory *socket_factory = test_socket_factory_create();
 | 
	
		
			
				|  |  | +  grpc_arg socket_factory_arg =
 | 
	
		
			
				|  |  | +      grpc_socket_factory_to_arg(&socket_factory->base);
 | 
	
		
			
				|  |  | +  grpc_channel_args *channel_args =
 | 
	
		
			
				|  |  | +      grpc_channel_args_copy_and_add(NULL, &socket_factory_arg, 1);
 | 
	
		
			
				|  |  | +  grpc_udp_server *s = grpc_udp_server_create(channel_args);
 | 
	
		
			
				|  |  | +  grpc_channel_args_destroy(&exec_ctx, channel_args);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  LOG_TEST("test_no_op_with_port_and_socket_factory");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  memset(&resolved_addr, 0, sizeof(resolved_addr));
 | 
	
		
			
				|  |  | +  resolved_addr.len = sizeof(struct sockaddr_in);
 | 
	
		
			
				|  |  | +  addr->sin_family = AF_INET;
 | 
	
		
			
				|  |  | +  GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, on_read, on_write,
 | 
	
		
			
				|  |  | +                                      on_fd_orphaned));
 | 
	
		
			
				|  |  | +  GPR_ASSERT(socket_factory->number_of_socket_calls == 1);
 | 
	
		
			
				|  |  | +  GPR_ASSERT(socket_factory->number_of_bind_calls == 1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  grpc_udp_server_destroy(&exec_ctx, s, NULL);
 | 
	
		
			
				|  |  | +  grpc_exec_ctx_finish(&exec_ctx);
 | 
	
		
			
				|  |  | +  grpc_socket_factory_unref(&socket_factory->base);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* The server had a single FD, which should have been orphaned. */
 | 
	
		
			
				|  |  | +  GPR_ASSERT(g_number_of_orphan_calls == 1);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static void test_no_op_with_port_and_start(void) {
 | 
	
		
			
				|  |  |    g_number_of_orphan_calls = 0;
 | 
	
		
			
				|  |  |    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 | 
	
		
			
				|  |  |    grpc_resolved_address resolved_addr;
 | 
	
		
			
				|  |  |    struct sockaddr_in *addr = (struct sockaddr_in *)resolved_addr.addr;
 | 
	
		
			
				|  |  | -  grpc_udp_server *s = grpc_udp_server_create();
 | 
	
		
			
				|  |  | +  grpc_udp_server *s = grpc_udp_server_create(NULL);
 | 
	
		
			
				|  |  |    LOG_TEST("test_no_op_with_port_and_start");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    memset(&resolved_addr, 0, sizeof(resolved_addr));
 | 
	
	
		
			
				|  | @@ -160,7 +238,7 @@ static void test_receive(int number_of_clients) {
 | 
	
		
			
				|  |  |    grpc_resolved_address resolved_addr;
 | 
	
		
			
				|  |  |    struct sockaddr_storage *addr = (struct sockaddr_storage *)resolved_addr.addr;
 | 
	
		
			
				|  |  |    int clifd, svrfd;
 | 
	
		
			
				|  |  | -  grpc_udp_server *s = grpc_udp_server_create();
 | 
	
		
			
				|  |  | +  grpc_udp_server *s = grpc_udp_server_create(NULL);
 | 
	
		
			
				|  |  |    int i;
 | 
	
		
			
				|  |  |    int number_of_reads_before;
 | 
	
		
			
				|  |  |    gpr_timespec deadline;
 | 
	
	
		
			
				|  | @@ -243,6 +321,7 @@ int main(int argc, char **argv) {
 | 
	
		
			
				|  |  |    test_no_op();
 | 
	
		
			
				|  |  |    test_no_op_with_start();
 | 
	
		
			
				|  |  |    test_no_op_with_port();
 | 
	
		
			
				|  |  | +  test_no_op_with_port_and_socket_factory();
 | 
	
		
			
				|  |  |    test_no_op_with_port_and_start();
 | 
	
		
			
				|  |  |    test_receive(1);
 | 
	
		
			
				|  |  |    test_receive(10);
 |