Add a test that tcp server posix consumes socket mutators

pull/15283/head
Alexander Polcyn 7 years ago
parent 2d894a8c3b
commit ac8b72f75b
  1. 58
      CMakeLists.txt
  2. 55
      Makefile
  3. 17
      build.yaml
  4. 8
      include/grpcpp/support/channel_arguments.h
  5. 3
      src/core/lib/iomgr/tcp_server_posix.cc
  6. 2
      src/core/lib/iomgr/tcp_server_utils_posix.h
  7. 16
      src/core/lib/iomgr/tcp_server_utils_posix_common.cc
  8. 13
      test/cpp/server/BUILD
  9. 116
      test/cpp/server/server_builder_with_socket_mutator_test.cc
  10. 26
      tools/run_tests/generated/sources_and_headers.json
  11. 18
      tools/run_tests/generated/tests.json

@ -611,6 +611,9 @@ add_dependencies(buildtests_cxx secure_sync_unary_ping_pong_test)
endif()
add_dependencies(buildtests_cxx server_builder_plugin_test)
add_dependencies(buildtests_cxx server_builder_test)
if(_gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx server_builder_with_socket_mutator_test)
endif()
add_dependencies(buildtests_cxx server_context_test_spouse_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx server_crash_test)
@ -13146,6 +13149,61 @@ target_link_libraries(server_builder_test
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_POSIX)
add_executable(server_builder_with_socket_mutator_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h
test/cpp/server/server_builder_with_socket_mutator_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/echo_messages.proto
)
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/echo.proto
)
target_include_directories(server_builder_with_socket_mutator_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(server_builder_with_socket_mutator_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc++_test_util_unsecure
grpc_test_util_unsecure
gpr_test_util
grpc++_unsecure
grpc_unsecure
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)

@ -1199,6 +1199,7 @@ secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test
secure_sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test
server_builder_plugin_test: $(BINDIR)/$(CONFIG)/server_builder_plugin_test
server_builder_test: $(BINDIR)/$(CONFIG)/server_builder_test
server_builder_with_socket_mutator_test: $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test
server_context_test_spouse_test: $(BINDIR)/$(CONFIG)/server_context_test_spouse_test
server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test
server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client
@ -1681,6 +1682,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \
$(BINDIR)/$(CONFIG)/server_builder_plugin_test \
$(BINDIR)/$(CONFIG)/server_builder_test \
$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test \
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
$(BINDIR)/$(CONFIG)/server_crash_test \
$(BINDIR)/$(CONFIG)/server_crash_test_client \
@ -1852,6 +1854,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \
$(BINDIR)/$(CONFIG)/server_builder_plugin_test \
$(BINDIR)/$(CONFIG)/server_builder_test \
$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test \
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
$(BINDIR)/$(CONFIG)/server_crash_test \
$(BINDIR)/$(CONFIG)/server_crash_test_client \
@ -2313,6 +2316,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/server_builder_plugin_test || ( echo test server_builder_plugin_test failed ; exit 1 )
$(E) "[RUN] Testing server_builder_test"
$(Q) $(BINDIR)/$(CONFIG)/server_builder_test || ( echo test server_builder_test failed ; exit 1 )
$(E) "[RUN] Testing server_builder_with_socket_mutator_test"
$(Q) $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test || ( echo test server_builder_with_socket_mutator_test failed ; exit 1 )
$(E) "[RUN] Testing server_context_test_spouse_test"
$(Q) $(BINDIR)/$(CONFIG)/server_context_test_spouse_test || ( echo test server_context_test_spouse_test failed ; exit 1 )
$(E) "[RUN] Testing server_crash_test"
@ -18962,6 +18967,56 @@ endif
$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc
SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_SRC = \
$(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
test/cpp/server/server_builder_with_socket_mutator_test.cc \
SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test
endif
endif
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_with_socket_mutator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_server_builder_with_socket_mutator_test: $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_with_socket_mutator_test.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc
SERVER_CONTEXT_TEST_SPOUSE_TEST_SRC = \
test/cpp/test/server_context_test_spouse_test.cc \

@ -5072,6 +5072,23 @@ targets:
- grpc++_unsecure
- grpc_unsecure
- gpr
- name: server_builder_with_socket_mutator_test
gtest: true
build: test
language: c++
src:
- src/proto/grpc/testing/echo_messages.proto
- src/proto/grpc/testing/echo.proto
- test/cpp/server/server_builder_with_socket_mutator_test.cc
deps:
- grpc++_test_util_unsecure
- grpc_test_util_unsecure
- gpr_test_util
- grpc++_unsecure
- grpc_unsecure
- gpr
platforms:
- posix
- name: server_context_test_spouse_test
gtest: true
build: test

@ -70,7 +70,13 @@ class ChannelArguments {
/// the resolver.
void SetGrpclbFallbackTimeout(int fallback_timeout);
/// Set the socket mutator for the channel.
/// For client channel's, the socket mutator operates on
/// "channel" sockets. For server's, the socket mutator operates
/// only on "listen" sockets.
/// TODO(apolcyn): allow socket mutators to also operate
/// on server "channel" sockets, and adjust the socket mutator
/// object to be more speficic about which type of socket
/// it should operate on.
void SetSocketMutator(grpc_socket_mutator* mutator);
/// Set the string to prepend to the user agent.

@ -346,7 +346,8 @@ static grpc_error* clone_port(grpc_tcp_listener* listener, unsigned count) {
err = grpc_create_dualstack_socket(&listener->addr, SOCK_STREAM, 0, &dsmode,
&fd);
if (err != GRPC_ERROR_NONE) return err;
err = grpc_tcp_server_prepare_socket(fd, &listener->addr, true, &port);
err = grpc_tcp_server_prepare_socket(listener->server, fd, &listener->addr,
true, &port);
if (err != GRPC_ERROR_NONE) return err;
listener->server->nports++;
grpc_sockaddr_to_string(&addr_str, &listener->addr, 1);

@ -113,7 +113,7 @@ grpc_error* grpc_tcp_server_add_all_local_addrs(grpc_tcp_server* s,
int* out_port);
/* Prepare a recently-created socket for listening. */
grpc_error* grpc_tcp_server_prepare_socket(int fd,
grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server*, int fd,
const grpc_resolved_address* addr,
bool so_reuseport, int* port);
/* Ruturn true if the platform supports ifaddrs */

@ -87,7 +87,7 @@ static grpc_error* add_socket_to_server(grpc_tcp_server* s, int fd,
char* name;
grpc_error* err =
grpc_tcp_server_prepare_socket(fd, addr, s->so_reuseport, &port);
grpc_tcp_server_prepare_socket(s, fd, addr, s->so_reuseport, &port);
if (err == GRPC_ERROR_NONE) {
GPR_ASSERT(port > 0);
grpc_sockaddr_to_string(&addr_str, addr, 1);
@ -144,7 +144,7 @@ grpc_error* grpc_tcp_server_add_addr(grpc_tcp_server* s,
}
/* Prepare a recently-created socket for listening. */
grpc_error* grpc_tcp_server_prepare_socket(int fd,
grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server* s, int fd,
const grpc_resolved_address* addr,
bool so_reuseport, int* port) {
grpc_resolved_address sockname_temp;
@ -170,6 +170,18 @@ grpc_error* grpc_tcp_server_prepare_socket(int fd,
err = grpc_set_socket_no_sigpipe_if_possible(fd);
if (err != GRPC_ERROR_NONE) goto error;
if (s->channel_args) {
for (size_t i = 0; i < s->channel_args->num_args; i++) {
if (0 == strcmp(s->channel_args->args[i].key, GRPC_ARG_SOCKET_MUTATOR)) {
GPR_ASSERT(s->channel_args->args[i].type == GRPC_ARG_POINTER);
grpc_socket_mutator* mutator = static_cast<grpc_socket_mutator*>(
s->channel_args->args[i].value.pointer.p);
err = grpc_set_socket_with_mutator(fd, mutator);
if (err != GRPC_ERROR_NONE) goto error;
}
}
}
if (bind(fd, reinterpret_cast<grpc_sockaddr*>(const_cast<char*>(addr->addr)),
addr->len) < 0) {
err = GRPC_OS_ERROR(errno, "bind");

@ -31,6 +31,19 @@ grpc_cc_test(
],
)
grpc_cc_test(
name = "server_builder_with_socket_mutator_test",
srcs = ["server_builder_with_socket_mutator_test.cc"],
deps = [
"//:grpc++_unsecure",
"//src/proto/grpc/testing:echo_proto",
"//test/core/util:grpc_test_util_unsecure",
],
external_deps = [
"gtest",
],
)
grpc_cc_test(
name = "server_request_call_test",
srcs = ["server_request_call_test.cc"],

@ -0,0 +1,116 @@
/*
*
* Copyright 2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpcpp/impl/codegen/config.h>
#include <gtest/gtest.h>
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
#include <grpc/grpc.h>
#include <memory>
#include "src/core/lib/iomgr/socket_mutator.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
/* This test does a sanity check that grpc_socket_mutator's
* are used by servers. It's meant to protect code and end-to-end
* tests that rely on this functionality but which live outside
* of the grpc github repo. */
namespace grpc {
namespace {
bool mock_socket_mutator_mutate_fd(int, grpc_socket_mutator*);
int mock_socket_mutator_compare(grpc_socket_mutator*, grpc_socket_mutator*);
void mock_socket_mutator_destroy(grpc_socket_mutator*);
const grpc_socket_mutator_vtable mock_socket_mutator_vtable = {
mock_socket_mutator_mutate_fd,
mock_socket_mutator_compare,
mock_socket_mutator_destroy,
};
class MockSocketMutator : public grpc_socket_mutator {
public:
MockSocketMutator() : mutate_fd_call_count_(0) {
grpc_socket_mutator_init(this, &mock_socket_mutator_vtable);
}
int mutate_fd_call_count_;
};
bool mock_socket_mutator_mutate_fd(int fd, grpc_socket_mutator* m) {
MockSocketMutator* s = reinterpret_cast<MockSocketMutator*>(m);
s->mutate_fd_call_count_++;
return true;
}
int mock_socket_mutator_compare(grpc_socket_mutator* a,
grpc_socket_mutator* b) {
return (uintptr_t)a - (uintptr_t)b;
}
void mock_socket_mutator_destroy(grpc_socket_mutator* m) {
MockSocketMutator* s = reinterpret_cast<MockSocketMutator*>(m);
delete s;
}
class MockSocketMutatorServerBuilderOption : public grpc::ServerBuilderOption {
public:
MockSocketMutatorServerBuilderOption(MockSocketMutator* mock_socket_mutator)
: mock_socket_mutator_(mock_socket_mutator) {}
void UpdateArguments(ChannelArguments* args) override {
args->SetSocketMutator(mock_socket_mutator_);
}
void UpdatePlugins(
std::vector<std::unique_ptr<ServerBuilderPlugin>>*) override{};
MockSocketMutator* mock_socket_mutator_;
};
TEST(ServerBuilderWithSocketMutatorTest, CreateServerWithSocketMutator) {
auto address = "localhost:" + std::to_string(grpc_pick_unused_port_or_die());
auto mock_socket_mutator = new MockSocketMutator();
std::unique_ptr<grpc::ServerBuilderOption> mock_socket_mutator_builder_option(
new MockSocketMutatorServerBuilderOption(mock_socket_mutator));
testing::EchoTestService::Service echo_service;
EXPECT_EQ(mock_socket_mutator->mutate_fd_call_count_, 0);
ServerBuilder builder;
builder.RegisterService(&echo_service);
builder.AddListeningPort(address, InsecureServerCredentials());
builder.SetOption(std::move(mock_socket_mutator_builder_option));
std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
EXPECT_NE(server, nullptr);
// Only assert that the socket mutator was used.
EXPECT_GE(mock_socket_mutator->mutate_fd_call_count_, 1);
server->Shutdown();
}
} // namespace
} // namespace grpc
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc_init();
int ret = RUN_ALL_TESTS();
grpc_shutdown();
return ret;
}

@ -4341,6 +4341,32 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_test_util_unsecure",
"grpc_unsecure"
],
"headers": [
"src/proto/grpc/testing/echo.grpc.pb.h",
"src/proto/grpc/testing/echo.pb.h",
"src/proto/grpc/testing/echo_messages.grpc.pb.h",
"src/proto/grpc/testing/echo_messages.pb.h",
"src/proto/grpc/testing/echo_messages_mock.grpc.pb.h",
"src/proto/grpc/testing/echo_mock.grpc.pb.h"
],
"is_filegroup": false,
"language": "c++",
"name": "server_builder_with_socket_mutator_test",
"src": [
"test/cpp/server/server_builder_with_socket_mutator_test.cc"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",

@ -4745,6 +4745,24 @@
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "server_builder_with_socket_mutator_test",
"platforms": [
"posix"
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save