QPS, latencies recorded with authentication

pull/2151/head
Siddharth Rakesh 10 years ago
parent b15d37a3c8
commit 922ea81877
  1. 39
      Makefile
  2. 6
      build.json
  3. 103
      test/cpp/qps/report.cc
  4. 14
      test/cpp/qps/report.h
  5. 87
      test/cpp/qps/run_authenticated_test.sh
  6. 99
      test/cpp/qps/user_data.proto
  7. 100
      test/cpp/qps/user_data_client.cc
  8. 88
      test/cpp/qps/user_data_client.h
  9. 6
      test/cpp/util/benchmark_config.cc

@ -2457,6 +2457,21 @@ $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc: test/cpp/qps/qpstest.proto $(PROTOBUF
$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/test/cpp/qps/user_data.pb.cc: protoc_dep_error
$(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/test/cpp/qps/user_data.pb.cc: test/cpp/qps/user_data.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
$(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc: test/cpp/qps/user_data.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/test/cpp/util/echo.pb.cc: protoc_dep_error
$(GENDIR)/test/cpp/util/echo.grpc.pb.cc: protoc_dep_error
@ -3452,7 +3467,9 @@ endif
LIBGRPC++_BENCHMARK_CONFIG_SRC = \
$(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc \
$(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc \
test/cpp/qps/report.cc \
test/cpp/qps/user_data_client.cc \
test/cpp/util/benchmark_config.cc \
@ -3497,8 +3514,9 @@ ifneq ($(NO_DEPS),true)
-include $(LIBGRPC++_BENCHMARK_CONFIG_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/benchmark_config.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc $(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/user_data_client.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc $(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/benchmark_config.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc $(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc
LIBGRPC++_TEST_CONFIG_SRC = \
@ -4011,6 +4029,7 @@ $(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o: $(GENDIR)/examples/pubsub/labe
LIBQPS_SRC = \
$(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc \
$(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc \
test/cpp/qps/client_async.cc \
test/cpp/qps/client_sync.cc \
test/cpp/qps/driver.cc \
@ -4018,6 +4037,7 @@ LIBQPS_SRC = \
test/cpp/qps/server_async.cc \
test/cpp/qps/server_sync.cc \
test/cpp/qps/timer.cc \
test/cpp/qps/user_data_client.cc \
LIBQPS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBQPS_SRC))))
@ -4061,13 +4081,14 @@ ifneq ($(NO_DEPS),true)
-include $(LIBQPS_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_sync.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc $(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc $(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc $(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc $(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc $(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_sync.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc $(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc $(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/user_data_client.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc $(GENDIR)/test/cpp/qps/user_data.pb.cc $(GENDIR)/test/cpp/qps/user_data.grpc.pb.cc
LIBGRPC_CSHARP_EXT_SRC = \

@ -537,7 +537,9 @@
"language": "c++",
"src": [
"test/cpp/qps/qpstest.proto",
"test/cpp/qps/user_data.proto",
"test/cpp/qps/report.cc",
"test/cpp/qps/user_data_client.cc",
"test/cpp/util/benchmark_config.cc"
]
},
@ -707,13 +709,15 @@
],
"src": [
"test/cpp/qps/qpstest.proto",
"test/cpp/qps/user_data.proto",
"test/cpp/qps/client_async.cc",
"test/cpp/qps/client_sync.cc",
"test/cpp/qps/driver.cc",
"test/cpp/qps/qps_worker.cc",
"test/cpp/qps/server_async.cc",
"test/cpp/qps/server_sync.cc",
"test/cpp/qps/timer.cc"
"test/cpp/qps/timer.cc",
"test/cpp/qps/user_data_client.cc"
],
"deps": [
"grpc_test_util",

@ -35,6 +35,7 @@
#include <grpc/support/log.h>
#include "test/cpp/qps/stats.h"
#include "user_data_client.h"
namespace grpc {
namespace testing {
@ -120,5 +121,107 @@ void GprLogReporter::ReportTimes(const ScenarioResult& result) const {
[](ResourceUsage u) { return u.wall_time; }));
}
UserDataClient userDataClient(grpc::CreateChannel("localhost:50052", grpc::InsecureCredentials(),
ChannelArguments()));
//Leaderboard Reported implementation.
void UserDatabaseReporter::ReportQPS(const ScenarioResult& result) const {
double qps = result.latencies.Count() /
average(result.client_resources,
[](ResourceUsage u) { return u.wall_time; });
userDataClient.setAccessToken(access_token_);
userDataClient.setQPS(qps);
int userDataState = userDataClient.sendDataIfReady();
switch(userDataState) {
case 1:
gpr_log(GPR_INFO, "Data sent to user database successfully");
break;
case -1:
gpr_log(GPR_INFO, "Data could not be sent to user database");
break;
}
}
void UserDatabaseReporter::ReportQPSPerCore(const ScenarioResult& result,
const ServerConfig& server_config) const {
double qps = result.latencies.Count() /
average(result.client_resources,
[](ResourceUsage u) { return u.wall_time; });
double qpsPerCore = qps / server_config.threads();
userDataClient.setAccessToken(access_token_);
//TBD
userDataClient.setQPSPerCore(qpsPerCore);
int userDataState = userDataClient.sendDataIfReady();
switch(userDataState) {
case 1:
gpr_log(GPR_INFO, "Data sent to user database successfully");
break;
case -1:
gpr_log(GPR_INFO, "Data could not be sent to user database");
break;
}
}
void UserDatabaseReporter::ReportLatency(const ScenarioResult& result) const {
userDataClient.setAccessToken(access_token_);
userDataClient.setLatencies(result.latencies.Percentile(50) / 1000,
result.latencies.Percentile(90) / 1000,
result.latencies.Percentile(95) / 1000,
result.latencies.Percentile(99) / 1000,
result.latencies.Percentile(99.9) / 1000);
int userDataState = userDataClient.sendDataIfReady();
switch(userDataState) {
case 1:
gpr_log(GPR_INFO, "Data sent to user database successfully");
break;
case -1:
gpr_log(GPR_INFO, "Data could not be sent to user database");
break;
}
}
void UserDatabaseReporter::ReportTimes(const ScenarioResult& result) const {
double serverSystemTime = 100.0 * sum(result.server_resources,
[](ResourceUsage u) { return u.system_time; }) /
sum(result.server_resources,
[](ResourceUsage u) { return u.wall_time; });
double serverUserTime = 100.0 * sum(result.server_resources,
[](ResourceUsage u) { return u.user_time; }) /
sum(result.server_resources,
[](ResourceUsage u) { return u.wall_time; });
double clientSystemTime = 100.0 * sum(result.client_resources,
[](ResourceUsage u) { return u.system_time; }) /
sum(result.client_resources,
[](ResourceUsage u) { return u.wall_time; });
double clientUserTime = 100.0 * sum(result.client_resources,
[](ResourceUsage u) { return u.user_time; }) /
sum(result.client_resources,
[](ResourceUsage u) { return u.wall_time; });
userDataClient.setAccessToken(access_token_);
userDataClient.setTimes(serverSystemTime, serverUserTime,
clientSystemTime, clientUserTime);
int userDataState = userDataClient.sendDataIfReady();
switch(userDataState) {
case 1:
gpr_log(GPR_INFO, "Data sent to user database successfully");
break;
case -1:
gpr_log(GPR_INFO, "Data could not be sent to user database");
break;
}
}
} // namespace testing
} // namespace grpc

@ -106,6 +106,20 @@ class GprLogReporter : public Reporter {
void ReportTimes(const ScenarioResult& result) const GRPC_OVERRIDE;
};
/** Reporter for client leaderboard. */
class UserDatabaseReporter : public Reporter {
public:
UserDatabaseReporter(const string& name, const string& access_token) : Reporter(name), access_token_(access_token) {}
private:
std::string access_token_;
void ReportQPS(const ScenarioResult& result) const GRPC_OVERRIDE;
void ReportQPSPerCore(const ScenarioResult& result,
const ServerConfig& config) const GRPC_OVERRIDE;
void ReportLatency(const ScenarioResult& result) const GRPC_OVERRIDE;
void ReportTimes(const ScenarioResult& result) const GRPC_OVERRIDE;
};
} // namespace testing
} // namespace grpc

@ -0,0 +1,87 @@
#!/bin/sh
CLIENT_ID='1018396037782-tv81fshn76nemr24uuhuginceb9hni2m.apps.googleusercontent.com'
CLIENT_SECRET='_HGHXg4DAA59r4w4x8p6ARzD'
GRANT_TYPE='http://oauth.net/grant_type/device/1.0'
ACCESS_TOKENS_DIR='/tmp/auth_lead_access_tokens'
AUTH_TOKEN_LINK='https://www.googleapis.com/oauth2/v3/token'
GOOGLE_ACCOUNTS_LINK='https://accounts.google.com/o/oauth2/device/code'
USER_INFO_LINK='https://www.googleapis.com/oauth2/v1/userinfo'
#Performs first time authentication
#Or re-authentication if refresh token expires
RE_AUTHENTICATE() {
INIT_AUTH_JSON=$(curl -s -d "client_id=$CLIENT_ID&scope=email profile" $GOOGLE_ACCOUNTS_LINK)
USER_CODE=$(echo $INIT_AUTH_JSON | jq .user_code | sed -e 's/^"//' -e 's/"$//')
echo 'Please use the following user code in the browser:' $USER_CODE
echo
VERIFICATION_URL=$(echo $INIT_AUTH_JSON | jq '.verification_url' | sed -e 's/^"//' -e 's/"$//')
echo 'Verification URL:' $VERIFICATION_URL
echo
xdg-open $VERIFICATION_URL
DEVICE_CODE=$(echo $INIT_AUTH_JSON | jq '.device_code' | sed -e 's/^"//' -e 's/"$//')
INTERVAL=$(echo $INIT_AUTH_JSON | jq '.interval' | sed -e 's/^"//' -e 's/"$//')
AUTH_JSON=$(curl -s -d "client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&code=$DEVICE_CODE&grant_type=$GRANT_TYPE" $AUTH_TOKEN_LINK)
ACCESS_TOKEN=$(echo $AUTH_JSON | jq '.access_token' | sed -e 's/^"//' -e 's/"$//')
while [ $ACCESS_TOKEN == 'null' ]
do
sleep $INTERVAL
AUTH_JSON=$(curl -s -d "client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&code=$DEVICE_CODE&grant_type=$GRANT_TYPE" $AUTH_TOKEN_LINK)
ACCESS_TOKEN=$(echo $AUTH_JSON | jq '.access_token' | sed -e 's/^"//' -e 's/"$//')
done
USER_DETAILS=$(curl -s $USER_INFO_LINK?access_token=$ACCESS_TOKEN)
USER_ID=$(echo $USER_DETAILS | jq '.email' | sed -e 's/^"//' -e 's/"$//' | awk -F"@" '{print $1}' | sed -e 's/\.//g' | awk '{print tolower($0)}')
echo $AUTH_JSON > $ACCESS_TOKENS_DIR/$USER_ID
}
#Use existing access token
USE_ACCESS_TOKEN() {
ACCESS_TOKEN=$(jq '.access_token' $ACCESS_TOKENS_DIR/$USER_ID | sed -e 's/^"//' -e 's/"$//')
USER_DETAILS=$(curl -s $USER_INFO_LINK?access_token=$ACCESS_TOKEN)
ID=$(echo $USER_DETAILS | jq '.id' | sed -e 's/^"//' -e 's/"$//')
if [ $ID == 'null' ]; then
REFRESH_ACCESS_TOKEN
fi
}
#Obtain new access token using refresh token
REFRESH_ACCESS_TOKEN() {
REFRESH_TOKEN=$(jq '.refresh_token' $ACCESS_TOKENS_DIR/$USER_ID | sed -e 's/^"//' -e 's/"$//')
if [ $REFRESH_TOKEN == 'null' ]; then
RE_AUTHENTICATE
else
REFRESH_JSON=$(curl -s -d "refresh_token=$REFRESH_TOKEN&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&grant_type=refresh_token" $AUTH_TOKEN_LINK)
ACCESS_TOKEN=$(echo $REFRESH_JSON | jq '.access_token')
if [ $ACCESS_TOKEN == 'null' ]; then
RE_AUTHENTICATE
else
NEW_AUTH_JSON=$(jq ".access_token=$ACCESS_TOKEN" $ACCESS_TOKENS_DIR/$USER_ID)
echo $NEW_AUTH_JSON > $ACCESS_TOKENS_DIR/$USER_ID
fi
fi
}
#create directory to store tokens, if not already present
[ ! -d $ACCESS_TOKENS_DIR ] && mkdir $ACCESS_TOKENS_DIR
#Convert user entered email id to unique string by converting to splitting on '@' symbol, if present,
#removing '.'s and converting to lowercase
USER_ID=$(echo $2 | awk -F"@" '{print $1}' | sed -e 's/\.//g' | awk '{print tolower($0)}')
if [ -s $ACCESS_TOKENS_DIR/$USER_ID ]; then
USE_ACCESS_TOKEN
else
RE_AUTHENTICATE
fi
./$1 --access_token=$ACCESS_TOKEN

@ -0,0 +1,99 @@
// Copyright 2015, 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.
syntax = "proto2";
package UserData;
service UserDataTransfer {
// Sends client info
rpc RecordSingleClientData (SingleUserRecordRequest) returns (SingleUserRecordReply) {}
rpc RetrieveSingleUserData (SingleUserRetrieveRequest) returns (SingleUserRetrieveReply) {}
rpc RetrieveAllUsersData (AllUsersRetrieveRequest) returns (AllUsersRetrieveReply) {}
}
//Metrics to be stored
message Metrics {
required double qps = 1;
required double perc_lat_50 = 2;
required double perc_lat_90 = 3;
required double perc_lat_95 = 4;
required double perc_lat_99 = 5;
required double perc_lat_99_point_9 = 6;
}
//Timestamped details
message DataDetails {
required string timestamp = 1;
required Metrics metrics = 2;
}
//User details
message UserDetails {
required string id = 1;
required string name = 2;
required string link = 3;
}
//Stored to database
message SingleUserDetails {
repeated DataDetails data_details = 1;
required UserDetails user_details = 2;
}
//Request for storing a single user's data
message SingleUserRecordRequest {
required string access_token = 1;
required Metrics metrics = 2;
}
//Reply to request for storing single user's data
message SingleUserRecordReply {
}
//Request for retrieving single user's data
message SingleUserRetrieveRequest {
required string client_id = 1;
}
//Reply for request to retrieve single user's data
message SingleUserRetrieveReply {
required SingleUserDetails details = 1;
}
//Request for retrieving all users' data
message AllUsersRetrieveReply {
repeated SingleUserDetails user_data = 1;
}
//Reply to request for retrieving all users' data
message AllUsersRetrieveRequest {
}

@ -0,0 +1,100 @@
/*
*
* Copyright 2015, 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 "user_data_client.h"
void UserDataClient::setAccessToken(std::string access_token) {
access_token_ = access_token;
}
void UserDataClient::setQPS(double QPS) {
QPS_ = QPS;
qpsSet = true;
}
void UserDataClient::setQPSPerCore(double qpsPerCore) {
//TBD
}
void UserDataClient::setLatencies(double percentileLatency50, double percentileLatency90,
double percentileLatency95, double percentileLatency99, double percentileLatency99Point9) {
percentileLatency50_ = percentileLatency50;
percentileLatency90_ = percentileLatency90;
percentileLatency95_ = percentileLatency95;
percentileLatency99_ = percentileLatency99;
percentileLatency99Point9_ = percentileLatency99Point9;
latenciesSet = true;
}
void UserDataClient::setTimes(double serverSystemTime, double serverUserTime,
double clientSystemTime, double clientUserTime) {
//TBD
}
int UserDataClient::sendDataIfReady() {
if(!(qpsSet && latenciesSet))
return 0;
SingleUserRecordRequest singleUserRecordRequest;
singleUserRecordRequest.set_access_token(access_token_);
Metrics* metrics = singleUserRecordRequest.mutable_metrics();
metrics->set_qps(QPS_);
metrics->set_perc_lat_50(percentileLatency50_);
metrics->set_perc_lat_90(percentileLatency90_);
metrics->set_perc_lat_95(percentileLatency95_);
metrics->set_perc_lat_99(percentileLatency99_);
metrics->set_perc_lat_99_point_9(percentileLatency99Point9_);
SingleUserRecordReply singleUserRecordReply;
ClientContext context;
Status status = stub_->RecordSingleClientData(&context, singleUserRecordRequest, &singleUserRecordReply);
if (status.IsOk()) {
return 1;
} else {
return -1;
}
}
// Get current date/time, format is YYYY-MM-DD.HH:mm:ss
const std::string currentDateTime() {
time_t now = time(0);
struct tm tstruct;
char buf[80];
tstruct = *localtime(&now);
strftime(buf, sizeof(buf), "%Y/%m/%d, %X", &tstruct);
return buf;
}

@ -0,0 +1,88 @@
/*
*
* Copyright 2015, 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 <iostream>
#include <memory>
#include <string>
#include <grpc/grpc.h>
#include <grpc++/channel_arguments.h>
#include <grpc++/channel_interface.h>
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/credentials.h>
#include <grpc++/status.h>
#include "test/cpp/qps/user_data.grpc.pb.h"
using grpc::ChannelArguments;
using grpc::ChannelInterface;
using grpc::ClientContext;
using grpc::Status;
using UserData::UserDataTransfer;
using UserData::Metrics;
using UserData::SingleUserRecordRequest;
using UserData::SingleUserRecordReply;
class UserDataClient {
public:
UserDataClient(std::shared_ptr<ChannelInterface> channel)
: stub_(UserDataTransfer::NewStub(channel)) {}
~UserDataClient() {}
void setAccessToken(std::string access_token);
void setQPS(double QPS);
void setQPSPerCore(double qpsPerCore);
void setLatencies(double percentileLatency50, double percentileLatency90,
double percentileLatency95, double percentileLatency99, double percentileLatency99Point9);
void setTimes(double serverSystemTime, double serverUserTime,
double clientSystemTime, double clientUserTime);
int sendDataIfReady();
private:
std::unique_ptr<UserDataTransfer::Stub> stub_;
std::string access_token_;
double QPS_;
double percentileLatency50_;
double percentileLatency90_;
double percentileLatency95_;
double percentileLatency99_;
double percentileLatency99Point9_;
bool qpsSet = false;
bool latenciesSet = false;
};

@ -37,6 +37,8 @@
DEFINE_bool(enable_log_reporter, true,
"Enable reporting of benchmark results through GprLog");
DEFINE_string(access_token, "", "Authorizing JSON string for leaderboard");
// In some distros, gflags is in the namespace google, and in some others,
// in gflags. This hack is enabling us to find both.
namespace google {}
@ -57,6 +59,10 @@ static std::shared_ptr<Reporter> InitBenchmarkReporters() {
composite_reporter->add(
std::unique_ptr<Reporter>(new GprLogReporter("LogReporter")));
}
if(!FLAGS_access_token.empty())
composite_reporter->add(
std::unique_ptr<Reporter>(new UserDatabaseReporter("UserDataReporter", FLAGS_access_token)));
return std::shared_ptr<Reporter>(composite_reporter);
}

Loading…
Cancel
Save