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