1 //
2 //
3 // Copyright 2017 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 #include <grpc/grpc.h>
20 #include <grpcpp/server.h>
21 #include <grpcpp/server_builder.h>
22 #include <grpcpp/support/config.h>
23 #include <gtest/gtest.h>
24
25 #include <memory>
26
27 #include "src/core/lib/iomgr/socket_mutator.h"
28 #include "src/proto/grpc/testing/echo.grpc.pb.h"
29 #include "test/core/test_util/port.h"
30 #include "test/core/test_util/test_config.h"
31
32 // This test does a sanity check that grpc_socket_mutator's
33 // are used by servers. It's meant to protect code and end-to-end
34 // tests that rely on this functionality but which live outside
35 // of the grpc github repo.
36
37 namespace grpc {
38 namespace {
39
40 bool mock_socket_mutator_mutate_fd(int, grpc_socket_mutator*);
41 int mock_socket_mutator_compare(grpc_socket_mutator*, grpc_socket_mutator*);
42 void mock_socket_mutator_destroy(grpc_socket_mutator*);
43
44 const grpc_socket_mutator_vtable mock_socket_mutator_vtable = {
45 mock_socket_mutator_mutate_fd,
46 mock_socket_mutator_compare,
47 mock_socket_mutator_destroy,
48 nullptr,
49 };
50
51 class MockSocketMutator : public grpc_socket_mutator {
52 public:
MockSocketMutator()53 MockSocketMutator() : mutate_fd_call_count_(0) {
54 grpc_socket_mutator_init(this, &mock_socket_mutator_vtable);
55 }
56 int mutate_fd_call_count_;
57 };
58
mock_socket_mutator_mutate_fd(int,grpc_socket_mutator * m)59 bool mock_socket_mutator_mutate_fd(int /*fd*/, grpc_socket_mutator* m) {
60 MockSocketMutator* s = reinterpret_cast<MockSocketMutator*>(m);
61 s->mutate_fd_call_count_++;
62 return true;
63 }
64
mock_socket_mutator_compare(grpc_socket_mutator * a,grpc_socket_mutator * b)65 int mock_socket_mutator_compare(grpc_socket_mutator* a,
66 grpc_socket_mutator* b) {
67 return reinterpret_cast<uintptr_t>(a) - reinterpret_cast<uintptr_t>(b);
68 }
69
mock_socket_mutator_destroy(grpc_socket_mutator * m)70 void mock_socket_mutator_destroy(grpc_socket_mutator* m) {
71 MockSocketMutator* s = reinterpret_cast<MockSocketMutator*>(m);
72 delete s;
73 }
74
75 class MockSocketMutatorServerBuilderOption : public grpc::ServerBuilderOption {
76 public:
MockSocketMutatorServerBuilderOption(MockSocketMutator * mock_socket_mutator)77 explicit MockSocketMutatorServerBuilderOption(
78 MockSocketMutator* mock_socket_mutator)
79 : mock_socket_mutator_(mock_socket_mutator) {}
80
UpdateArguments(ChannelArguments * args)81 void UpdateArguments(ChannelArguments* args) override {
82 args->SetSocketMutator(mock_socket_mutator_);
83 }
84
UpdatePlugins(std::vector<std::unique_ptr<ServerBuilderPlugin>> *)85 void UpdatePlugins(
86 std::vector<std::unique_ptr<ServerBuilderPlugin>>*) override {};
87
88 MockSocketMutator* mock_socket_mutator_;
89 };
90
91 class ServerBuilderWithSocketMutatorTest : public ::testing::Test {
92 protected:
SetUpTestSuite()93 static void SetUpTestSuite() { grpc_init(); }
94
TearDownTestSuite()95 static void TearDownTestSuite() { grpc_shutdown(); }
96 };
97
TEST_F(ServerBuilderWithSocketMutatorTest,CreateServerWithSocketMutator)98 TEST_F(ServerBuilderWithSocketMutatorTest, CreateServerWithSocketMutator) {
99 auto address = "localhost:" + std::to_string(grpc_pick_unused_port_or_die());
100 auto mock_socket_mutator = new MockSocketMutator();
101 std::unique_ptr<grpc::ServerBuilderOption> mock_socket_mutator_builder_option(
102 new MockSocketMutatorServerBuilderOption(mock_socket_mutator));
103 testing::EchoTestService::Service echo_service;
104 EXPECT_EQ(mock_socket_mutator->mutate_fd_call_count_, 0);
105 ServerBuilder builder;
106 builder.RegisterService(&echo_service);
107 builder.AddListeningPort(address, InsecureServerCredentials());
108 builder.SetOption(std::move(mock_socket_mutator_builder_option));
109 std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
110 EXPECT_NE(server, nullptr);
111 // Only assert that the socket mutator was used.
112 EXPECT_GE(mock_socket_mutator->mutate_fd_call_count_, 1);
113 server->Shutdown();
114 }
115
116 } // namespace
117 } // namespace grpc
118
main(int argc,char ** argv)119 int main(int argc, char** argv) {
120 grpc::testing::TestEnvironment env(&argc, argv);
121 ::testing::InitGoogleTest(&argc, argv);
122 int ret = RUN_ALL_TESTS();
123 return ret;
124 }
125