Skip to content
Snippets Groups Projects
Select Git revision
  • 04a468122f0072cbd8a67d66dfd8243ce3ddface
  • master default protected
  • arm-aarch-platform
  • arm-platform
  • vjpai-patch-3
  • vjpai-patch-1
  • v1.27.x
  • jtattermusch-patch-2
  • jtattermusch-patch-1
  • update-java-worker-example-in-performance-docs
  • revert-21805-revert-21797-reintroduce_21527
  • revert-21804-tls-credentials-1
  • zhen_cleanup_namecheck
  • revert-21806-revert-21767-revert-21725-revert-21680-cq_ordering
  • vjpai-patch-2
  • revert-21766-tls-credentials-1
  • revert-21640-change_local_tcp_security_level
  • revert-21680-cq_ordering
  • revert-21527-unify_boringssl_deps2
  • revert-20803-grpclb_stabilization
  • fix-kokoro-rvm-key
  • v1.27.0
  • v1.27.0-pre2
  • v1.27.0-pre1
  • v1.26.0
  • v1.26.0-pre1
  • v1.25.0
  • v1.25.0-pre1
  • v1.24.3
  • v1.24.2
  • v1.24.1
  • v1.23.1
  • v1.24.0
  • v1.24.0-pre2
  • v1.24.0-pre1
  • v1.22.1
  • v1.23.0
  • v1.23.0-pre1
  • v1.22.0
  • v1.22.0-pre1
  • v1.21.4
41 results

server_builder_plugin_test.cc

Blame
  • server_builder_plugin_test.cc 8.75 KiB
    /*
     *
     * Copyright 2016, Google Inc.
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are
     * met:
     *
     *     * Redistributions of source code must retain the above copyright
     * notice, this list of conditions and the following disclaimer.
     *     * Redistributions in binary form must reproduce the above
     * copyright notice, this list of conditions and the following disclaimer
     * in the documentation and/or other materials provided with the
     * distribution.
     *     * Neither the name of Google Inc. nor the names of its
     * contributors may be used to endorse or promote products derived from
     * this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    
    #include <grpc++/channel.h>
    #include <grpc++/client_context.h>
    #include <grpc++/create_channel.h>
    #include <grpc++/impl/server_builder_option.h>
    #include <grpc++/impl/server_builder_plugin.h>
    #include <grpc++/impl/server_initializer.h>
    #include <grpc++/impl/thd.h>
    #include <grpc++/security/credentials.h>
    #include <grpc++/security/server_credentials.h>
    #include <grpc++/server.h>
    #include <grpc++/server_builder.h>
    #include <grpc++/server_context.h>
    #include <grpc/grpc.h>
    #include <gtest/gtest.h>
    
    #include "src/proto/grpc/testing/echo.grpc.pb.h"
    #include "test/core/util/port.h"
    #include "test/core/util/test_config.h"
    #include "test/cpp/end2end/test_service_impl.h"
    
    #define PLUGIN_NAME "TestServerBuilderPlugin"
    
    namespace grpc {
    namespace testing {
    
    class TestServerBuilderPlugin : public ServerBuilderPlugin {
     public:
      TestServerBuilderPlugin() : service_(new TestServiceImpl()) {
        init_server_is_called_ = false;
        finish_is_called_ = false;
        change_arguments_is_called_ = false;
        register_service_ = false;
      }
    
      grpc::string name() GRPC_OVERRIDE { return PLUGIN_NAME; }
    
      void InitServer(ServerInitializer* si) GRPC_OVERRIDE {
        init_server_is_called_ = true;
        if (register_service_) {
          si->RegisterService(service_);
        }
      }
    
      void Finish(ServerInitializer* si) GRPC_OVERRIDE { finish_is_called_ = true; }
    
      void ChangeArguments(const grpc::string& name, void* value) GRPC_OVERRIDE {
        change_arguments_is_called_ = true;
      }
    
      bool has_async_methods() const GRPC_OVERRIDE {
        if (register_service_) {
          return service_->has_async_methods();
        }
        return false;
      }
    
      bool has_sync_methods() const GRPC_OVERRIDE {
        if (register_service_) {
          return service_->has_synchronous_methods();
        }
        return false;
      }
    
      void SetRegisterService() { register_service_ = true; }
    
      bool init_server_is_called() { return init_server_is_called_; }
      bool finish_is_called() { return finish_is_called_; }
      bool change_arguments_is_called() { return change_arguments_is_called_; }
    
     private:
      bool init_server_is_called_;
      bool finish_is_called_;
      bool change_arguments_is_called_;
      bool register_service_;
      std::shared_ptr<TestServiceImpl> service_;
    };
    
    class InsertPluginServerBuilderOption : public ServerBuilderOption {
     public:
      InsertPluginServerBuilderOption() { register_service_ = false; }
    
      void UpdateArguments(ChannelArguments* arg) GRPC_OVERRIDE {}
    
      void UpdatePlugins(std::vector<std::unique_ptr<ServerBuilderPlugin>>* plugins)
          GRPC_OVERRIDE {
        plugins->clear();
    
        std::unique_ptr<TestServerBuilderPlugin> plugin(
            new TestServerBuilderPlugin());
        if (register_service_) plugin->SetRegisterService();
        plugins->emplace_back(std::move(plugin));
      }
    
      void SetRegisterService() { register_service_ = true; }
    
     private:
      bool register_service_;
    };
    
    std::unique_ptr<ServerBuilderPlugin> CreateTestServerBuilderPlugin() {
      return std::unique_ptr<ServerBuilderPlugin>(new TestServerBuilderPlugin());
    }
    
    void AddTestServerBuilderPlugin() {
      static bool already_here = false;
      if (already_here) return;
      already_here = true;
      ::grpc::ServerBuilder::InternalAddPluginFactory(
          &CreateTestServerBuilderPlugin);
    }
    
    // Force AddServerBuilderPlugin() to be called at static initialization time.
    struct StaticTestPluginInitializer {
      StaticTestPluginInitializer() { AddTestServerBuilderPlugin(); }
    } static_plugin_initializer_test_;
    
    // When the param boolean is true, the ServerBuilder plugin will be added at the
    // time of static initialization. When it's false, the ServerBuilder plugin will
    // be added using ServerBuilder::SetOption().
    class ServerBuilderPluginTest : public ::testing::TestWithParam<bool> {
     public:
      ServerBuilderPluginTest() {}
    
      void SetUp() GRPC_OVERRIDE {
        port_ = grpc_pick_unused_port_or_die();
        builder_.reset(new ServerBuilder());
      }
    
      void InsertPlugin() {
        if (GetParam()) {
          // Add ServerBuilder plugin in static initialization
          CheckPresent();
        } else {
          // Add ServerBuilder plugin using ServerBuilder::SetOption()
          builder_->SetOption(std::unique_ptr<ServerBuilderOption>(
              new InsertPluginServerBuilderOption()));
        }
      }
    
      void InsertPluginWithTestService() {
        if (GetParam()) {
          // Add ServerBuilder plugin in static initialization
          auto plugin = CheckPresent();
          EXPECT_TRUE(plugin);
          plugin->SetRegisterService();
        } else {
          // Add ServerBuilder plugin using ServerBuilder::SetOption()
          std::unique_ptr<InsertPluginServerBuilderOption> option(
              new InsertPluginServerBuilderOption());
          option->SetRegisterService();
          builder_->SetOption(std::move(option));
        }
      }
    
      void StartServer() {
        grpc::string server_address = "localhost:" + to_string(port_);
        builder_->AddListeningPort(server_address, InsecureServerCredentials());
        // we run some tests without a service, and for those we need to supply a
        // frequently polled completion queue
        cq_ = builder_->AddCompletionQueue();
        cq_thread_ = grpc::thread(std::bind(&ServerBuilderPluginTest::RunCQ, this));
        server_ = builder_->BuildAndStart();
        EXPECT_TRUE(CheckPresent());
      }
    
      void ResetStub() {
        string target = "dns:localhost:" + to_string(port_);
        channel_ = CreateChannel(target, InsecureChannelCredentials());
        stub_ = grpc::testing::EchoTestService::NewStub(channel_);
      }
    
      void TearDown() GRPC_OVERRIDE {
        auto plugin = CheckPresent();
        EXPECT_TRUE(plugin);
        EXPECT_TRUE(plugin->init_server_is_called());
        EXPECT_TRUE(plugin->finish_is_called());
        server_->Shutdown();
        cq_->Shutdown();
        cq_thread_.join();
      }
    
      string to_string(const int number) {
        std::stringstream strs;
        strs << number;
        return strs.str();
      }
    
     protected:
      std::shared_ptr<Channel> channel_;
      std::unique_ptr<ServerBuilder> builder_;
      std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
      std::unique_ptr<ServerCompletionQueue> cq_;
      std::unique_ptr<Server> server_;
      grpc::thread cq_thread_;
      TestServiceImpl service_;
      int port_;
    
     private:
      TestServerBuilderPlugin* CheckPresent() {
        auto it = builder_->plugins_.begin();
        for (; it != builder_->plugins_.end(); it++) {
          if ((*it)->name() == PLUGIN_NAME) break;
        }
        if (it != builder_->plugins_.end()) {
          return static_cast<TestServerBuilderPlugin*>(it->get());
        } else {
          return nullptr;
        }
      }
    
      void RunCQ() {
        void* tag;
        bool ok;
        while (cq_->Next(&tag, &ok))
          ;
      }
    };
    
    TEST_P(ServerBuilderPluginTest, PluginWithoutServiceTest) {
      InsertPlugin();
      StartServer();
    }
    
    TEST_P(ServerBuilderPluginTest, PluginWithServiceTest) {
      InsertPluginWithTestService();
      StartServer();
      ResetStub();
    
      EchoRequest request;
      EchoResponse response;
      request.set_message("Hello hello hello hello");
      ClientContext context;
      context.set_compression_algorithm(GRPC_COMPRESS_GZIP);
      Status s = stub_->Echo(&context, request, &response);
      EXPECT_EQ(response.message(), request.message());
      EXPECT_TRUE(s.ok());
    }
    
    INSTANTIATE_TEST_CASE_P(ServerBuilderPluginTest, ServerBuilderPluginTest,
                            ::testing::Values(false, true));
    
    }  // namespace testing
    }  // namespace grpc
    
    int main(int argc, char** argv) {
      grpc_test_init(argc, argv);
      ::testing::InitGoogleTest(&argc, argv);
      return RUN_ALL_TESTS();
    }