1 // 2 // 3 // Copyright 2015 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 #ifndef GRPC_TEST_CPP_QPS_SERVER_H 20 #define GRPC_TEST_CPP_QPS_SERVER_H 21 22 #include <vector> 23 24 #include <grpc/support/cpu.h> 25 #include <grpc/support/log.h> 26 #include <grpcpp/channel.h> 27 #include <grpcpp/resource_quota.h> 28 #include <grpcpp/security/server_credentials.h> 29 #include <grpcpp/server_builder.h> 30 31 #include "src/core/lib/gprpp/crash.h" 32 #include "src/proto/grpc/testing/control.pb.h" 33 #include "src/proto/grpc/testing/messages.pb.h" 34 #include "test/core/end2end/data/ssl_test_data.h" 35 #include "test/core/util/port.h" 36 #include "test/cpp/qps/usage_timer.h" 37 #include "test/cpp/util/test_credentials_provider.h" 38 39 namespace grpc { 40 namespace testing { 41 42 class Server { 43 public: Server(const ServerConfig & config)44 explicit Server(const ServerConfig& config) 45 : timer_(new UsageTimer), last_reset_poll_count_(0) { 46 cores_ = gpr_cpu_num_cores(); 47 if (config.port()) { // positive for a fixed port, negative for inproc 48 port_ = config.port(); 49 } else { // zero for dynamic port 50 port_ = grpc_pick_unused_port_or_die(); 51 } 52 } ~Server()53 virtual ~Server() {} 54 Mark(bool reset)55 ServerStats Mark(bool reset) { 56 UsageTimer::Result timer_result; 57 int cur_poll_count = GetPollCount(); 58 int poll_count = cur_poll_count - last_reset_poll_count_; 59 if (reset) { 60 std::unique_ptr<UsageTimer> timer(new UsageTimer); 61 timer.swap(timer_); 62 timer_result = timer->Mark(); 63 last_reset_poll_count_ = cur_poll_count; 64 } else { 65 timer_result = timer_->Mark(); 66 } 67 68 ServerStats stats; 69 stats.set_time_elapsed(timer_result.wall); 70 stats.set_time_system(timer_result.system); 71 stats.set_time_user(timer_result.user); 72 stats.set_total_cpu_time(timer_result.total_cpu_time); 73 stats.set_idle_cpu_time(timer_result.idle_cpu_time); 74 stats.set_cq_poll_count(poll_count); 75 return stats; 76 } 77 SetPayload(PayloadType type,int size,Payload * payload)78 static bool SetPayload(PayloadType type, int size, Payload* payload) { 79 // TODO(yangg): Support UNCOMPRESSABLE payload. 80 if (type != PayloadType::COMPRESSABLE) { 81 return false; 82 } 83 payload->set_type(type); 84 // Don't waste time creating a new payload of identical size. 85 if (payload->body().length() != static_cast<size_t>(size)) { 86 std::unique_ptr<char[]> body(new char[size]()); 87 payload->set_body(body.get(), size); 88 } 89 return true; 90 } 91 port()92 int port() const { return port_; } cores()93 int cores() const { return cores_; } CreateServerCredentials(const ServerConfig & config)94 static std::shared_ptr<ServerCredentials> CreateServerCredentials( 95 const ServerConfig& config) { 96 if (config.has_security_params()) { 97 std::string type; 98 if (config.security_params().cred_type().empty()) { 99 type = kTlsCredentialsType; 100 } else { 101 type = config.security_params().cred_type(); 102 } 103 104 return GetCredentialsProvider()->GetServerCredentials(type); 105 } else { 106 return InsecureServerCredentials(); 107 } 108 } 109 GetPollCount()110 virtual int GetPollCount() { 111 // For sync server. 112 return 0; 113 } 114 115 virtual std::shared_ptr<Channel> InProcessChannel( 116 const ChannelArguments& args) = 0; 117 118 protected: ApplyConfigToBuilder(const ServerConfig & config,ServerBuilder * builder)119 static void ApplyConfigToBuilder(const ServerConfig& config, 120 ServerBuilder* builder) { 121 if (config.resource_quota_size() > 0) { 122 builder->SetResourceQuota(ResourceQuota("AsyncQpsServerTest") 123 .Resize(config.resource_quota_size())); 124 } 125 for (const auto& channel_arg : config.channel_args()) { 126 switch (channel_arg.value_case()) { 127 case ChannelArg::kStrValue: 128 builder->AddChannelArgument(channel_arg.name(), 129 channel_arg.str_value()); 130 break; 131 case ChannelArg::kIntValue: 132 builder->AddChannelArgument(channel_arg.name(), 133 channel_arg.int_value()); 134 break; 135 case ChannelArg::VALUE_NOT_SET: 136 gpr_log(GPR_ERROR, "Channel arg '%s' does not have a value", 137 channel_arg.name().c_str()); 138 break; 139 } 140 } 141 } 142 143 private: 144 int port_; 145 int cores_; 146 std::unique_ptr<UsageTimer> timer_; 147 int last_reset_poll_count_; 148 }; 149 150 std::unique_ptr<Server> CreateSynchronousServer(const ServerConfig& config); 151 std::unique_ptr<Server> CreateAsyncServer(const ServerConfig& config); 152 std::unique_ptr<Server> CreateAsyncGenericServer(const ServerConfig& config); 153 std::unique_ptr<Server> CreateCallbackServer(const ServerConfig& config); 154 155 } // namespace testing 156 } // namespace grpc 157 158 #endif // GRPC_TEST_CPP_QPS_SERVER_H 159